捕获 Virtualbox 虚拟机的网络流量
本文使用 wireshark 进行抓包(或查看),操作系统为 ArchLinux。
除了最后一个方案,本文的其他方案都需要一个 TAP,最终使用 wireshark 来捕获 Virtualbox 的流量也是使用这个接口的。
以下是创建一个名为 tap0 的 tap:
# ip tuntap add dev tap0 mode tap user ${USER}
$ ip tuntap show
tap0: tap UNKNOWN_FLAGS:800 user 1000
# ip link set dev tap0 up
方案一:使用 bridge
该方案不支持出口网络(需要桥接的可以连接外网)的网卡是无线网卡。在这里假定该网卡名为 eth0(可以通过 ip link show
来查看)。
- 创建虚拟网桥 br0
创建
# ip link add dev br0 type bridge
启动
# ip link set dev br0 up
查看
$ ip link show br0
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default
link/ether 4a:7b:08:56:02:8d brd ff:ff:ff:ff:ff:ff
-
将 eth0 添加到网桥 br0 上
# ip link set dev eth0 master br0
-
将 tap0 添加到网桥 br0 上
# ip link set dev tap0 master br0
-
更改 Virtualbox 虚拟机(假定该虚拟机为 vm1)网卡(假定为 NIC 1,即序号为 1)的连接方式为桥接网卡(Bridged Adapter),
界面名称为 tap0:$ VBoxManage modifyvm vm1 --nic1 bridged $ VBoxManage modifyvm vm1 --bridgeadapter1 tap0
-
使用 DHCP 为 br0 分配 ip
如果 eth0 已经 DHCP 分配了 ip,先清空它(如果 eth0 有 dhcp client daemon,要 kill 掉它)
# ip addr flush dev eth0
如果 eth0 还没启动,则启动它
# ip link set dev eth0 up
然后为 br0 分配 ip
# dhcpcd br0
然后使用 wireshark 捕获 tap0 接口的流量就可以了。
方案二:使用 static route
该方案不适用于出口网卡直连 Internet(即该网卡的 IP 是公网 IP),一般用在网卡连接路由器的情况下,并且还需要在路由器上设置路由。
这里假定该网卡接口名为 wlan0,获取到路由器分配的 IP 为 192.168.1.10/24
-
为 tap0 分配的 IP 为:192.168.2.1/24
# ip addr add 192.168.2.1/24 scope link dev tap0
-
配置 192.168.2.0/24 的 DHCP 服务器
这里使用 dhcpd 作为 DHCP 服务器,因此需要安装 dhcp 包
# pacman -S dhcp
然后编辑 /etc/dhcpd.conf
文件,加入以下代码:
subnet 192.168.2.0 netmask 255.255.255.0 {
range 192.168.2.2 192.168.2.102;
option domain-name "example.org";
option domain-name-servers 8.8.8.8, 8.8.4.4;
option routers 192.168.2.1;
option broadcast-address 192.168.2.255;
default-lease-time 1800;
max-lease-time 7200;
}
-
打开相关的内核参数
# echo '1' > /proc/sys/net/ipv4/ip_forward # echo '1' > /proc/sys/net/ipv4/conf/wlan0/proxy_arp # echo '1' > /proc/sys/net/ipv4/conf/tap0/proxy_arp
-
在路由器上设置路由,这里假定 wlan0 连接到路由器上的接口是 br-lan
# ip route add 192.168.2.0/24 via 192.168.1.10 dev br-lan
-
开启 dhcp 服务器
# dhcpd -f -d tap0
-
更改 Virtualbox 虚拟机(假定该虚拟机为 vm1)网卡(假定为 NIC 1,即序号为 1)的连接方式为桥接网卡(Bridged Adapter),
界面名称为 tap0:$ VBoxManage modifyvm vm1 --nic1 bridged $ VBoxManage modifyvm vm1 --bridgeadapter1 tap0
然后使用 wireshark 捕获 tap0 接口的流量就可以了。
方案三:使用 nat
方案二使用了静态路由来转发来自 tap0 的数据,可以使得路由器中的所有机器都可以访问 Virtualbox 虚拟机,但设置起来比较麻烦。
如果不需要这个功能的,我们可以使用 NAT 来进行数据转发,这样设置起来就没那么麻烦了(不需要知道 wlan0 的 ip,也不需要在路由器上设置路由)。
我们只需要将方案二中的第 4 步改成以下操作就可以了:
查看 iptables 是否开启了:
# systemctl status iptables.service
如果没开启,需要先开启它:
# systemctl start iptables.service
然后使用 iptables 的添加 SNAT 规则:
iptables -t nat -A POSTROUTING -o wlan0 -s 192.168.2.0/24 -j MASQUERADE
还有一个方案与上面第二、三的方案类似,这里给出链接,有兴趣的朋友可以去看下。
以上三种方案都有不同的优点跟缺点,但它们都有一个共同的缺点,那就是配置起来比较麻烦。
方案的最后,给出一个相对简单的方案: Virtualbox 本身已经自带的抓包功能了[1]。
方案四:使用 virtualbox 自带的抓包功能
-
创建一个 named pipe 文件,当然也可以不用建(使用普通文件保存)
$ mkfifo /tmp/file.pcap
-
设置 Virtualbox 的 nictrace
$ VBoxManage modifyvm vm1 --nictrace1 on --nictracefile1 /tmp/file.pcap
-
$ wireshark -k -i /tmp/file.pcap &
-
启动 Virtualbox 虚拟机
$ VBoxManage startvm vm1 --type gui
抓取结束后,需要做些扫尾工作:
-
停止 Virtualbox 的 nictrace
$ VBoxManage modifyvm vm1 --nictrace1 off
-
关闭 named pipe 文件
$ rm /tmp/file.pcap
参考: