QEMU Networking

QEMU has a number of really nice ways to set up networking for its guests. It can be a little bewildering to figure out how each of the options work, so I thought I'd write up what I found. Excuse the 'orrid ascii art :-)

VLANs and NICs

A VLAN is a network switch running in the context of a qemu process. There can be multiple vlans in each qemu process. Multiple interfaces can be connected to each vlan. Anything sent via one of the interfaces on a vlan is received by all the other interfaces on that vlan.

The most obvious type of interface which you can create is an interface which looks just like a specific network card to the guest OS. Any frames sent by the guest OS over that nic will appear on the vlan which the nic is a member of. Any frames sent to the vlan from other interfaces will be received by the guest OS via the nic.

         +-----------+
| Guest |
| OS |
| +---+ |
| |NIC| |
+---+-+-+---+
^ +--------+
| | +<------> Other IF
+---------->+ VLAN |
| +<------> Other IF
+--------+

So, for example, if you do:

 $> qemu -net nic,model=rtl8139,vlan=1,macaddr=52:54:00:12:34:56 ...

It will create a rtl8139 nic in the guest, with the given MAC address, and connect to vlan numbered 1. You can then use further -net options to connect other interfaces to that vlan.

Connecting VLANs Together

One possibility is to connect together vlans from multiple qemu processes. The way this works is that one qemu process connects to a socket in another qemu process. When a frame appears on the vlan in the first qemu process, it is forwarded to the corresponding vlan in the other qemu process and vice-versa.

 +-----------+                                      +-----------+
| Guest | | Guest |
| A | | B |
| +---+ | | +---+ |
| |NIC| | | |NIC| |
+---+-+-+---+ +---+-+-+---+
^ +--------+ +--------+ ^
| | | | | |
+------>+ VLAN 0 +<--> Socket <-->+ VLAN 2 +<------+
| | | |
+--------+ +--------+

For example, you might start Guest A with:

 $> qemu -net nic -net socket,listen=:8010 ...

This qemu process is hosting a guest with a nic connected to VLAN 0, which in turn has a socket interface listening for connections on port 8010.

You could then start Guest B with:

 $> qemu -net nic,vlan=2 -net socket,vlan=2,connect=127.0.0.1:8010 ...

This qemu process would then have a guest with a nic connected to VLAN 2, which in turn has a socket interface connected to VLAN 0 in the first qemu process.

Thus, any frames transmitted by Guest A is received by Guest B, and vice versa.

(Note, the two vlans do not need to be numbered differently. It is only done here for illustrative purposes)

An extension of this concept is to connect vlans together using a multicast socket. For example, with:

 $> qemu -net nic -net socket,mcast=230.0.0.1:1234 ...
$> qemu -net nic -net socket,mcast=230.0.0.1:1234 ...

you have two guests with their vlan 0 connected together over a multicase bus. Any number of guests can connect to the same multicast address and receive the frames sent by any guest to that vlan.

It's interesting to note that any of the above can be done by unpriviledged users.

Connecting VLANs To TAP Devices

Another option is to make a vlan available through a device in the host OS. Any frames transmitted via this device will appear on a vlan in the qemu process (and thus received by another other interfaces on the vlan) and frames sent to the vlan will be received by the device.

 +-----------+                            +-------+
| Guest | | TAP |
| OS | | Device|
| +---+ | |(qtap0)|
| |NIC| | +---+---+
+---+-+-+---+ |
^ +------+ +---+-----+
| | | | Kernel |
+------>+ VLAN +<--> File <-->+ TUN/TAP |
| | Descriptor | Driver |
+------+ +---------+
  $> qemu -net nic -net tap,ifname=qtap0 ...

This works using the kernel's TUN/TAP device driver. This driver basically allows a user-space application to obtain a file descriptor which is connected to a network device. Any frames sent to the kernel over the file descriptor will be received by the device and any frames transmitted via the device will be received by the application.

If you e.g. assign an IP address to the TAP device, applications in the guest will be able to connect to applications in the host listening for connections on that IP address. And if you enable port forwarding in the host, packets sent from the guest can be forwarded by the host kernel to the Internet.

Essentially, the TAP device looks just like a network device connected to a physical network to which the guest is also connected.

TAP devices are obtained by opening /dev/net/tun and invoking the TUNSETIFF ioctl(). This is not usually allowed for unpriviledged users so, in general, only root can use this method.

Connecting VLANs Using VDE

An extension of this idea is possible using VDE (Virtual Distributed Ethernet). This is a user-space program which can obtain a TAP device and allow a number of other programs to connect to it and bridge those connections to the TAP device. It would be quite similar in effect to connecting multiple qemu vlans together and connecting one of those vlans to a TAP device.

    +-----------+                           +-----------+
| Guest | | Guest |
| A | | B |
| +---+ | | +---+ |
| |NIC| | | |NIC| |
+---+-+-+---+ +---+-+-+---+
^ +------+ +------+ ^
| | | +-----+ | | |
+------>+ VLAN +-+ VDE +-+ VLAN +<------+
| | +--+--+ | |
+------+ | +------+
|
+---+-----+ +--------+
| Kernel | | TAP |
| TUN/TAP +--+ Device |
| Driver | | (qtap) |
+---------+ +--------+
 $> vde_switch -hub -tap qtap -sock /var/run/qtap-ctl
$> vqeq -vdesock /var/run/qtap-ctl qemu -net nic ...
$> vqeq -vdesock /var/run/qtap-ctl qemu -net nic ...

Here we end up with the vde_switch receiving packets from the vlans in both qemu processes and forwarding to the qtap network interface in the host, and likewise, forwarding packets from the qtap device to both vlans. Since both guests have nics on these vlans, they can transmit/receive frames to/from the host OS and each other.

Now, if you think something as hairy as that hasn't been since the woolly mammoth, wait until you see the last option ...

Usermode Network Stack

QEMU's final, and most bizarre, networking option is also its default option. What this does is connect a "usermode network stack" to a vlan. This network stack is a standalone implementation of the ip, tcp, udp, dhcp and tftp (etc.) protocols. It can handle frames from the vlan by e.g. responding to dhcp requests with a valid address, responding to tftp requests with a file from the host filesystem or by creating udp/tcp sockets over which packet data can be forwarded.

  $> qemu -net nic,vlan=1 -net user,vlan=1 ...

Note that this network stack is running within the qemu process itself. So, for example there is no separate dhcp or tftp process handling those requests. Also, the stack is effectively acting as a proxy by unpacking application data from udp/tcp packets and forwarding them over a socket connecting the qemu process and the destination process.

Although bizarre, this option does provide a very useful default in that the guest OS will have largely transparent network access almost like any other application running on the host.

QEMU Networking的更多相关文章

  1. Using QEMU for Embedded Systems Development

    http://www.opensourceforu.com/2011/06/qemu-for-embedded-systems-development-part-1/ http://www.opens ...

  2. 路由器逆向分析------MIPS系统网络的配置(QEMU)

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/69378333 MIPS系统网络的配置  使用QEMU 模拟正在运行的MIPS系统并 ...

  3. kvm上安装xp

    主要为了看看图像显示是否有问题,跑起来系能如何,网络连接.文件共享是怎样的. 用的是雨林木风xp sp3的iso.为了提高性能,决定使用qcow2格式,预分配metadata,cache=none(查 ...

  4. ARM64调试环境

    自从上一次ZCTF做了一道ARM64的逆向题目后,我决定记录下利用qemu搭建ARM64的环境的过程,以后肯定会遇到更多ARM平台下的Reverse和PWN. 一 安装QEMU 我要模拟的是64位的A ...

  5. 别以为真懂Openstack: 虚拟机创建的50个步骤和100个知识点(4)

    六.Libvirt 对于Libvirt,在启动虚拟机之前,首先需要define虚拟机,是一个XML格式的文件 列出所有的Instance # virsh list Id    Name         ...

  6. 构建嵌入式小型Linux系统

    构建嵌入式小型Linux系统 摘要:用buildroot构建x86的交叉编译工具链:裁减linux内核,尽可能做到最小:手工构建根文件系统:安装qemu虚拟机,仿真新配置的Linux系统:为新配置的L ...

  7. KVM/QEMU桥接网络设置及kvm资料

    KVM/QEMU桥接网络设置 配置kvm的网络有2种方法.其一,默认方式为用户模式网络(Usermode Networking),数据包由NAT方式通过主机的接口进行传送.其二,使用桥接方式(Brid ...

  8. 以Qemu模拟Linux,学习Linux内核

    文章名称:以Qemu模拟Linux,学习Linux内核作      者:five_cent文章地址:http://www.cnblogs.com/senix/archive/2013/02/21/29 ...

  9. 干货分享: 长达250页的Libvirt Qemu KVM的ppt,不实验无真相

    下载地址:Libvirt Qemu KVM 教程大全 http://files.cnblogs.com/popsuper1982/LibvirtQemuKVM.pptx 1. 概论 1.1 虚拟化的基 ...

随机推荐

  1. 《Java从入门到精通》学习总结2

    1. 在JAVA语言中对静态方法有两点规定: 在静态方法中不可以使用this关键字 在静态方法中不可以直接调用非静态方法 2. 不能将方法体内的局部变量声明为static的 3. 引用只是存放一个对象 ...

  2. Spring--基础介绍一:IOC和DI

    前面学习了Struts2和Hibernate. Struts2主要是用来控制业务层面逻辑和显示,告诉你什么时候走哪个action,跑去运行哪个class的什么方法,后面调到哪个jsp. Struts2 ...

  3. 《剑指Offer》第20题(Java实现):定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。

    一.题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1)). 二.思路解析 首先定义一个Integer类型的栈,记为stack,此栈用来完成数据 ...

  4. API Test WebApiTestClient工具安装及使用

    一.guget安装: 1.解决方案右键-管理解决方案的nuget程序包打开如下图: 搜索WebApiTestClient,然后选择查询出的项目,右边点击安装即可:   2.安装会有如下图提示: 确定即 ...

  5. 安装mitmproxy

    https://www.jianshu.com/p/1dd40826113b 先连接到同一个局域网,再访问官网下载描述文件

  6. tomcat中如何禁止列目录下的文件

    tomcat中如何禁止列目录下的文件在{tomcat_home}/conf/web.xml中,把listings参数设置成false即可,如下: <servlet> <servlet ...

  7. 在MSYS2环境下 用msvc 编译 zlib

    自己参考用. 在 vs2017 x64 native tools command prompt 下用  msys2_shell.cmd -use-full-path 打开 MSYS2窗口. 新建bui ...

  8. PCL-安装

    1.安装定期更新维护的PCL开发包. 通过PPA支持的Ubuntu系统,安装命令为: sudo add-apt-repository ppa:v-launched-jochen-sprickerhof ...

  9. 批处理-Java JDK环境变量配置

    setx /M JAVA_HOME "C:\Program Files\Java\jdk1.8.0_131" setx /M CLASSPATH ".;%%JAVA_HO ...

  10. Windows 10 专业版 长期服务版 激活

    这个用小白系统之后一段时间显示要求激活,或者更改产品秘钥.网上找了许多秘钥也是没啥用,又不想用激活工具的话,可以试试用win+R 输入cmd : 依次输入:slmgr /skms kms.digibo ...