Inspect and modify QEMU Images
On a Linux systems QEMU is the standard hypervisor for running virtual machines. It’s one of core technologies, which allows GNS3 and EVE-NG/UnetLab to emulate networking devices. In some situations it would be nice, if it’s possible to inspect and modify the QEMU images directly, without running the emulated system.
Linux can easily mount a disk image (sudo mount -o loop <file> <mount point>). But mounting a VM disk image is not that simple. A VM disk normally contains only the used disk blocks (sparse images). QEMU allows to use images, that contain only the differences from backing images. All that can’t be directly handled by Linux.
One simple solution is to convert the QEMU image to a raw disk image and mount that. The main drawback is, that the raw image can use a considerable size on the disk, because it contains also all unused disk blocks.
qemu-img -O raw <QEMU image> <raw image> sudo mount -o loop <raw image> <mount point>
A much better alternative is using guestfish from the libguestfs-tools package. Roman Dodin wrote a nice article about it: http://noshut.ru/2016/09/using-guestfish-to-modify-vm-disk-image/ The main drawback is the installation size. It needs about 100 MByte disk space, when you have already installed libvirt, otherwise 200 MByte. For casual use, it’s too heavy for me.
A very lightweight alternative is qemu-nbd, a QEMU Disk Network Block Device Server. It takes a VM disk image, that QEMU supports and exports that as a NDB device. That NBD device can be mounted and then used as any other disk. It needs no extra packages, just QEMU.
sudo modprobe nbd sudo qemu-nbd -c /dev/nbd0 -P <partition #> <QEMU image> sudo mount /dev/nbd0 <mount point> . . Use the mounted disk image . sudo umount /dev/nbd0 sudo qemu-nbd -d /dev/nbd0
I’ve created the shell scripts qemu-mount and qemu-umount, they hide the use of qemu-nbd and the allocation of a free NBD device. Download the ehlers/qemu-mount Gist to the GNS3 VM and install it:
sudo cp qemu-*mount /usr/local/bin/ sudo chmod +x /usr/local/bin/qemu-*mount
qemu-mount has the following usage:
Usage: qemu-mount [OPTIONS] qemu_image mount_point Options: -p partition_number select, which partition to mount, default #1 -r mount read-only -t fstype set filesystem type -u set owner to current user Without arguments it prints a list of mounted images.
The usage of qemu-umount is even simpler,
qemu-umount <qemu_image or mount_point>.
Both scripts can be used as a normal user, when needed the privileged commands will be started with sudo.
- Never use any image manipulation program on an image, that is currently in use by a running device. That will very likely ruin the image.
- If you want to only inspect an image,
use the option
- Modify only copies of an image. If something goes wrong, you still have the original.
Extract the configuration from an IOSv Image
First we need an utility, that can extract the configuration out of Cisco NVRAM files. GNS3 contains the Python module iou_export, that can be used for this. It’s well hidden in the gns3server package and should be copied to /usr/local/bin for easy access.
gns3@gns3vm:~$ find /usr/lib /usr/local/lib -name iou_export.py /usr/local/lib/python3.4/dist-packages/gns3server/compute/iou/utils/iou_export.py gns3@gns3vm:~$ sudo cp /usr/local/lib/python3.4/dist-packages/gns3server/compute/iou/utils/iou_export.py /usr/local/bin/iou_export gns3@gns3vm:~$ sudo chmod +x /usr/local/bin/iou_export
Alternatively you can download the latest iou_export from https://github.com/ehlers/IOUtools and install it in /usr/local/bin.
iou_export -h shows a small help text:
gns3@gns3vm:~$ iou_export -h usage: iou_export [-h] NVRAM startup-config [private-config] iou_export exports startup/private configuration from IOU NVRAM file. positional arguments: NVRAM NVRAM file startup-config startup configuration private-config private configuration optional arguments: -h, --help show this help message and exit
Now we need to know, where the IOSv image is stored. In GNS3 open the project and then right-click on the IOSv device and select “Show in file manager”. You will get an information windows similar to this:
Copy the path to the clipboard,
so you don’t have to enter it later manually.
The image gets mounted with
qemu-mount -r <paste path>/hda_disk.qcow2 /mnt.
ls -l /mnt lists the files within the image.
It contains a nvram file, that stores the configuration.
iou_export /mnt/nvram <startup config> [<private config>]
the startup config and optionally the private config can be extracted.
After that we unmount the disk image with qemu-umount.
Here a sample session, the configs are extracted and stored in the files R1-startup-config and R1-private-config:
gns3@gns3vm:~$ qemu-mount -r /opt/gns3/projects/9ee63325-78ea-4b39-b680-1d9c7f68360d/project-files/qemu/38e3f7a9-7294-4cad-838d-a7719596037a/hda_disk.qcow2 /mnt gns3@gns3vm:~$ ls -l /mnt total 140352 drwxr-xr-x 3 root root 4096 Jan 30 2013 boot drwxr-xr-x 2 root root 4096 Oct 14 2013 config -rwxr-xr-x 1 root root 419 Oct 17 14:41 config.grub -rwxr-xr-x 1 root root 79 Oct 17 14:39 e1000_bia.txt -rwxr-xr-x 1 root root 0 Oct 16 15:25 ios_config_checksum -rwxr-xr-x 1 root root 0 Oct 16 15:25 ios_config.txt -rwxr-xr-x 1 root root 524288 Oct 16 15:25 nvram -rwxr-xr-x 1 root root 143178592 Mar 22 2016 vios-adventerprisek9-m gns3@gns3vm:~$ iou_export /mnt/nvram R1-startup-config R1-private-config gns3@gns3vm:~$ qemu-umount /mnt /dev/nbd0 disconnected gns3@gns3vm:~$ gns3@gns3vm:~$ head R1-startup-config ! ! Last configuration change at 12:40:57 UTC Tue Oct 17 2017 ! version 15.6 service timestamps debug datetime msec service timestamps log datetime msec no service password-encryption ! hostname R1
Configure an ASAv Image for Telnet access
Cisco creates two versions of the ASAv appliances. The ASAv images downloadable from VIRL are using a serial console, accessible in GNS3 via Telnet. The ASAv images from software.cisco.com use the VGA console, GNS3 uses VNC to access it. The better method is serial/telnet access, as cut-and-paste is working and non-US keyboards have the correct layout.
Alec DuChene has posted a very nice guide how to change the console to serial/telnet. On the GNS3 community website search for “asav telnet” and choose the “How to configure any ASAv .qcow2 image for serial telnet…” result.
But by accessing the QEMU image directly, the change is really simple.
First make a copy of the original image, then mount the second partition.
Now create the
use_ttyS0 file and umount the image.
Finally modify the GNS3 ASAv template to use the modified image
and to use Telnet access
(right-click on the ASAv in the device area,
select “Configure template” and
change the console type to Telnet and
change the image in the HDD tab).
gns3@gns3vm:~$ cp -p /opt/gns3/images/QEMU/asav971.qcow2 /opt/gns3/images/QEMU/asav971_serial.qcow2 gns3@gns3vm:~$ qemu-mount -u -p 2 /opt/gns3/images/QEMU/asav971_serial.qcow2 /mnt gns3@gns3vm:~$ touch /mnt/use_ttyS0 gns3@gns3vm:~$ qemu-umount /mnt /dev/nbd0 disconnected gns3@gns3vm:~$