Previous Part 5. UEFI, BIOS and OVMF
QEMU provides a very flexible networking infrastructure that allows you to configure various modes (e.,g. Shared
, Bridged
) and options for networking between the guest and the host machine.1 Generally, you will be creating your own Virtual Local Area Networks (VLANs).2
Networking in QEMU, might seem scary but don't worry, it is fairly easy to do so when you learn the basics. Most of the 'complex' stuff will be abstracted from you.
Before diving into HOW-TOs, lets go over some networking basic in QEMU.
The networking in QEMU can be categorized into two parts front end
and back end
, and there are four different modes available for network connectivity.3
This part represents the virtual network device that is provided to the guest using the -device
option (e.g. Emulated NIC
, virtio-net
). Please refer to Network Devices for more information on this.
Usage (as a reminder):
$ qemu-system-x86_64 ... -device rtl8139,mac=52:54:00:12:34:56,netdev=mynetdev ...
Note the netdev=mynetdev
option above. It specifies the back end network identifier that the front end device is going to connect.
On the other hand, back end represents the network backend that interacts with the [front end] emulated NIC (e.g. puts packets onto the host's network). You can also think if this part as the one that listens to the front end handles network packets (e.g. TCP/IP
) and talks with the host machine. It's like a 'proxy server' for emulators!4
For more information on this topic refer to official QEMU documentation on Networking Basics.
To configure the back end, we use the -netdev
option followed by the TYPE of the network backend and its parameters.
Defining a back end:
$ qemu-system-x86_64 ... -netdev type=[TYPE],id=[NAME],...
The id=[NAME]
options, as you might've guessed, is the back end network identifier. The front end device is going to use this id
to connect to the back end. The type=[TYPE]
defines the TYPE of network to be used. Now, there are many back end TYPEs out there, however I will only go over some of the most used ones: user
and tap
.5
The user-mode networking, is the default networking back end and is the easiest one to use. It is implemented using "SLIRP", which provides a full TCP/IP stack within QEMU and uses that stack to implement a virtual NAT'd network. 6
Shameless plug: More [ELI5] information on NAT
Most of the time it is enough to just use user
. It is enabled by default and you don't have to do many configurations to use it.7 However, according to the official QEMU documentations, it has the following limitations:
- there is a lot of overhead so the performance is poor
- in general, ICMP traffic does not work (so you cannot use ping within a guest)
- the guest is not directly accessible from the host or the external network
Some of the above limitations can be overcomed (e.g. via port-forwarding), but other things like relatively 'poor' performance is unavoidable. The only network mode available with user
is the Shared Network.
The tap backend utilizes the TUN/TAP. It offers very good performance and can be configured to create virtually any type of network mode (e.g. Bridged). Unfortunately, it requires configuration of that network mode in the host which tends to be different depending on the operating system you are using. Generally speaking, it also requires that you have root privileges.8
The sentence above is taken almost as is from the official QEMU documentation page.
TAP network overcomes all of the limitations of user-mode networking, but requires some configurations depending on the networking mode.9.
Here are some of the most used network modes that can be configured in QEMU.10
In the shared network mode, the back end acts as a Network Addres Translation (NAT) gateway between the guest machine and the external network.11 The back end network assigns private IP addresses to the guest machines and performs the translation of network traffic between the guest and the external network (e.g. the Internet).12
To create a shared network using -netdev
:
$ -netdev type=user,id=my-shrd-net
You can then, connect it to your front end -device
:
$ qemu-system-aarch64 -netdev type=user,id=my-shrd-net -device virtio-net-device,netdev=my-shrd-net ...
This is the default network mode in QEMU. It is the easiest to use and it basically Just Works™.
In the bridged network mode, the back end is connected directly to the host's physical network interface (e.g. eth0
). This allows the guest machine to appear as a separate node on the network (e.g. your home network), with its own IP address assigned by the router's DHCP server. The guest can communicate with other nodes on the network and can be accessed by other devices.13
Warning (from ArchLinux Wiki): If you bridge together a guest [network] device and some host interface, such as
eth0
, your machines will appear directly on the external network, which will expose them to possible attack. ... a better solution might be to use Host Only networking mode and set up NAT.
This mode can be useful if you want:
- full network access: Guest machines will have their own IP addresses on the external network, enabling them to communicate with other devices.
- quickly develop/test drivers: Guest machine's network
-device
will act like a real NIC. This makes testing drivers or operating systems quick and easy.
To set up a bridged network in QEMU, the process can vary slightly depending on your host OS. Sadly, I won't be explaining that here (due to complexity). I will only give links to other useful guides I found on the internet here for you to follow. Maybe in the future I can expand on them a bit more.
Reminder, you can always contribute and help me/others <3
- extremecoders-re's GitHub Gist: Setting up Qemu with a tap interface
- Linux KVM's Documentation: Public Bridge
- OpenVPN's TAP Drivers: Managing Windows TAP Drivers
There seems to be NO ACTUL GUIDES on this. I was not able to found anything useful.. Sorry.
- SoBytes's Article: Creating a qemu bridge network on macos
- Carl Montari's Article: Qemu with Bridged Interfaces on MacOS
- andriytk'S GitHub Gist: Configure NAT-network for QEMU on macOS Mojave
In the host-only mode, the back end provides network connectivity only between the guest machine and the host machine. The guest machines can communicate with each other and with the host, but they are isolated from the external network.
The isolation this mode brings is great for security since the guest doesn't have any access to the external network. It is actually similar to Bridged in terms of how it is configured and used. From the ArchLinux's Wiki:
If the bridge is given an IP address and traffic destined for it is allowed,but no real interface (e.g.
eth0
) is connected to the bridge, then the virtual machines will be able to talk to each other and the host system. However, they will not be able to talk to anything on the external network, provided that you do not set up IP masquerading on the physical host. This configuration is called Host Only networking...
This mode can be useful if you want:
- isolated network environment: Guest machine(s) does not have access to the external network (e.g. Internet).
The setup is very similar to Bridged. Just follow the instructions there, but do NOT assign an interface to your bridge. After that, you will have host-only networking!
Next Part 7. Combining it All Together and Practices
Footnotes
-
https://wiki.qemu.org/Documentation/Networking#Network_Basics ↩
-
https://wiki.qemu.org/Documentation/Networking#User_Networking_(SLIRP) ↩
-
https://wiki.archlinux.org/title/QEMU#User-mode_networking ↩
-
https://gist.github.com/extremecoders-re/e8fd8a67a515fee0c873dcafc81d811c ↩
-
https://wiki.archlinux.org/title/QEMU#User-mode_networking ↩
-
https://wiki.archlinux.org/title/QEMU#Bridged_networking_using_qemu-bridge-helper ↩