|
|
Understanding networking in QEMU GuestsThe QEMU VM's basic network model - "User net"The QEMU VM is capable of presenting different "emulated" network cards to a guest. Through the emulated NIC, the guest can communicate to the host and out to the local network, using the QEMU VM process as the firewall. Packets coming from the QEMU Guest will appear to come from the QEMU Host once they exit the Host. This is the feature of the old networking protocol called "slirp", which was designed when dialup meant you logged into a server and did things. Slirp allowed you to have "emulated" networking between your dialup client, and dialup host, allowing things like telnet, ftp, http concurrently. When QEMU is started without defaults, it will present an NE2000 NIC to the guest. However, getting drivers for that card is harder, and the Realtek 8139 is a preferred NIC for most X86 emulated systems. Besides the routing and firewall features of the QEMU VM process, it also can provide DHCP addressing, DNS and SAMBA services to the QEMU Guest. The basic setup of a QEMU Guest is to setup for DHCP client, and unless you change the defaults, your QEMU Guest's IP will always be 10.0.2.15. Because this address is never seen outside of the QEMU VM, there is no worry unless your QEMU Host's network is also in the 10.0.2.0 network, or if you're VLAN'ing QEMU Guests together. (However, that is an advance topic and will not be covered here) From the QEMU Guest, you can typically test connectivity via telnet or ssh to either 10.0.2.2 (the QEMU VM's address for the Host), or the IP Address of the Host. Note: Ping from the QEMU Guest is unreliable. Do not use ping to test connectivity from a QEMU Guest when the network model is "User Net".
QEMU VLAN QEMU Process Provides
+----------------------------+
QEMU Guest <-------> | Firewall/DHCP/TFTP server | <-----> Internet
(10.0.2.15) | | (10.0.2.2) |
| | |
----> | DNS server (10.0.2.3) |
| | |
----> | SMB server (10.0.2.4) |
+----------------------------+
Standard TCP and UDP protocols automatically pass through the QEMU firewall,
although some protocols (like FTP) may not work without a little help with
the "-redir" parameter, because access back into the QEMU guest by default
is blocked by the firewall.
When qemu is started like: ./qemu -k en-us -localtime -hda winxp.img the implied parameters to this command line are "-net user -net nic" Defining the interface that the QEMU VM presents to the guestOften, it's easier to tell the QEMU VM to present a different NIC to the QEMU guest. In the case of installing Solaris into a QEMU guest, we would prefer to use an interface that Solaris recognizes (rtls) as opposed to having to load a special driver (Juergen Kiel's modified version of Masayuki Murayama's ne2000 ni driver). To define a different interface, use the following parameters: -net user -net nic,model=rtl8139 like:./qemu -m 384 -k en-us -localtime -hda sol11.img -cdrom sol11.iso -boot d -net user -net nic,model=rtl8139 which tells qemu to start a virtual machine with 384MB of memory, use a keymap of "en-us", a virtual hard disk called sol11.img (created by qemu-img), a CD/DVD image file with Solaris 11, to boot from the DVD, and to present a Realtek 8139 NIC to the QEMU guest (instead of an NE2000 which is the default) Allowing access from the QEMU Host to the QEMU GuestIn the previous example, a QEMU virtual machine was started, to perform an Solaris 11 install from the DVD image, to the virtual hard disk. QEMU presents a Realtek 8139 to the Solaris install, and for the purpose of the example, will assume that the installer selected the Realtek 8139 (rtls) interface to be DHCP and the Solaris 11 install completed successfully. As with any system, having more than one way to log into a system is probably a wise idea. I know that occassionally, QEMU locks up the graphics screen, and being able to login to it via SSH and shut it down is less harsh than just shutting down the QEMU VM (either via kill, or if you can quit the VM from the QEMU monitor). This example extends the previous example on how to use the "-redir" parameter to allow access from the Host (and outside the Host). In this example, the port 5022 will have a port listener by the QEMU VM, and forward packets to port 22 in the QEMU Guest. ./qemu -m 384 -k en-us -localtime -hda sol11.img -net user -net nic,model=rtl8139 -redir tcp:5022::22 Using this startup of QEMU, assuming a valid login in the virtual Solaris 11 session, the command: ssh ip.address.of.host -p 5022 -l mylogin should get you a login prompt into the QEMU Guest. WarningThe files used in the next two sections are working proof of concepts that have been in use for several months, but no guarantee of security, or suitability is implied or stated. These scripts merely show off the capbilities of the TAP and BRIDGE features in QEMU and how users with Solaris Hosts can use them to improved network connectivity to the QEMU Guests they use. Please take some time and review the following modules before using them. 1) sol_qemu_tap.tar, 2) qemu-ifup, 3) dsl.sh, and 4) qemu-bridge. Each of the shell script may require your customizations for your envrionment, such as private network addresses to use in /etc/qemu-ifup, which version of sudo you're using for qemu-bridge, and general customization in dsl.sh. Make sure to do the following: chown root sol_qemu_tap; chmod 4755 sol_qemu_tap The "C" file qemu_sol_tap.c is probably in need of using RBAC privileges as opposed to setuid root, so complaints will be sent to /dev/null. Improvements to the code are happily accepted and attributed. 2007/06/05There are reports of consistent kernel panics using the tun/tap module on x86-64 hosts. Please take this into consideration when attempting to use the tun/tap and bridge modules on an x86-64 Solaris system. The updated version of the tap/bridge drivers does appear to have this problem Unrestricted network access between the QEMU Host and QEMU Guest.Because the QEMU VM acts as a firewall between the network/QEMU Host and the QEMU Guest, it can be really tedious if you want to have less restricted network access from the QEMU Host to the QEMU guest without having to code up a bunch of -redir tcp:VMHOST_PORT::GUEST_PORT parameters when starting QEMU. QEMU on Solaris can now use a TAP interface (it's a virtual interface that has network interface properties), which allows the QEMU Host unrestricted access to the QEMU Guest. The downside of this is that some "root'ish" access is required to create the TAP. Because QEMU is pretty powerful, the last thing you want to do is run QEMU as root, which necessitated the need for a setuid binary to create the TAP, drop the privileges back to the calling user and then pass the TAP file handle to QEMU via a wrapper script. The source for the TAP wrapper should be compiled and setuid root. The wrapper is a simple program which uses the setuid root permissions to create the TAP device, and initialize it using the /etc/qemu-ifup script. Once the TAP is created, permissions are dropped back to the calling user and the script that starts QEMU with user configuration (dsl.sh script in this example) is called with "-t (file descriptor of the TAP)".The shell script extracts the file descriptor and adds it to the network parameters when QEMU is started. This is an example of how sol_qemu_tap is used with the dsl.sh script to start DamnSmallLinux. While this may be an OpenSolaris page, the fact is that DamnSmallLinux is only a 50MB ISO live CD with practically all the functionality needed to fully test QEMU. It has a X environment, sound, network, an ssh-server that can be enabled, and the very small footprint makes it a really useful and inexpensive test image. ./sol_qemu_tap dsl.sh What happens behind the scenes is that sol_qemu_tap invokes root privileges, creates the TAP device, and calls /etc/qemu-ifup with the name of the TAP device, which sets the network properties of the TAP. When that is complete, sol_qemu_tap drops the permissions to the calling user and invokes the shell script passed in via the first parameter. An ifconfig of the tap device created shows: tap0: flags=1000851 where 192.168.1.250 is the address of the QEMU Host and 192.168.1.10 is the address assigned to the QEMU Guest. However, the networking is not yet complete on the QEMU Guest side. Once DamnSmallLinux boots, open a terminal window, and type sudo ifconfig eth0 192.168.1.10 up Verify the configuration settings with ifconfig eth0. The settings should now match the target of the TAP, and network connectivity between the QEMU Host and Guest should be active. If you have an ftp server running on the QEMU Host, you can test with ftp as this is one of the services that requires help if you are using "User Net". If you want to test access back to the guest, use the DSLPanel on the mainscreen to start the ssh-server. Then set the dsl user password using sudo passwd dsl and you should be able to ssh to the DamnSmallLinux QEMU Guest as dsl using ssh -l dsl 192.168.1.10 from the QEMU Host. Unrestricted network access between the QEMU Guest and the QEMU Host's Network.If you have compiled the tun/tap and bridge packages and installed them, this next section makes QEMU Guests quite interesting because they have unfettered access to the local network (and the security problems that go with that as well). The bridge module is a specialized driver which allows a TAP device and an existing Network Card (except WIFI cards) to be bridged together. Because the TAP can have a MAC address tied to it, once the QEMU Guest starts, it will appear to the network as that QEMU Guest is on the network. The advantage of this configuration is that a QEMU Guest can request a DHCP address from the Host NIC's networks DHCP server. If the Host's NIC network does not have a DHCP server, then the user can set the QEMU's Guest NIC to an IP address in the same network as the Host NIC's IP address is in. To use the bridge feature with QEMU, you will need to download the qemu-bridge script and put it in /etc. The script has some customizations which you will need to fix for your site. The script uses sudo, and this example uses the version provided by blastwave.org (/opt/csw/bin/sudo) and the comments in the qemu-bridge script tell you how to modify the sudoers file to allow this script the access to create and destroy the bridge. As with the previous example using DamnSmallLinux and qemu_sol_tap, the startup of qemu with bridging enabled is very similar. The difference in the startup is to add -b NETWORK_INTERFACE along with the shell script to start QEMU. The initialization of the script looks like: ./sol_qemu_tap -b e1000g dsl.sh Note: When you bridge a client to the hosts' network, the host cannot see the QEMU guest, and vice versaIf you need to have unfettered network access between the QEMU guest and it's host, and, use a second network interface using -net user or another TAP (non-bridged) device. A TAP is probably preferred, since it is likely that your bridge device is DHCP'd, and -user net will also be using DHCP as well. Again, the sol_qemu_tap program aquires root privileges from setuid to create the TAP, and then calls /etc/qemu-bridge with the name of the TAP and the name of the Network Interface that the TAP should be bridge to. If that succeeds, then sol_qemu_tap drops the root privileges, and calls the shell script (to start QEMU) with the "-t (file descriptor of the TAP)". An ifconfig on the QEMU Host of the tap0 interface should show this output tap0: flags=1000842To be sure that the tap0 is bridged to e1000g0, use sudo /usr/local/bin/brdgadm -l to view how the bridge is configured. If it looks like this: List of the interfaces ---------- e1000g0 tap0then everything should be configured properly. As noted above, if the network that the NIC the TAP has bridged to has a DHCP server, and the client automatically does DHCP Client, the client should have already acquired an IP address from that DHCP server. In the case where the network does not have a DHCP server, then the QEMU Guest will have to have it's network set manually. In our example using DamnSmallLinux with the Bridge, we open ATerminal from the DSL main screen. Using ifconfig eth0, we should see the output:
eth0 Link encap:Ethernet HWaddr 52:54:00:12:34:56
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:1 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:64 (64.0 B) TX bytes:2052 (2.0 KiB)
Interrupt:11 Base address:0x8000
To configure the eth0 interface, simply use the command:
sudo ifconfig eth0 192.168.0.176 netmask 255.255.255.0 broadcast 192.168.0.255 up, replacing the network parameters with ones more appropriate for your local network. Then validate the output of ifconfig eth0 to show
eth0 Link encap:Ethernet HWaddr 52:54:00:12:34:56
inet addr:192.168.0.176 Bcast:192.168.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:64 (64.0 B) TX bytes:2052 (2.0 KiB)
Interrupt:11 Base address:0x8000
Be aware that the tap0 interface in the QEMU Host will not change parameters
as the QEMU Guest's NIC does acquire an IP address.
|