Virtualbox配置Linux guest桥和修改网卡MAC

shixudong@163.com

目前新款笔记本基本不再配备有线网卡,在只有无线网卡的笔记本上启动VirtualBox guest并使用桥接网卡模式连网时,需要对guest的MAC做二层NAT转换为主机无线网卡的MAC后,才能访问外部网络。为实现这一功能,VirtualBox通过读取.vbox文件中的MACAddress参数获取guest的MAC,该MAC可通过GUI界面修改。

Guest启动时的默认MAC跟随MACAddress参数同步变化,桥接网卡的二层NAT转换功能确保guest能访问外部网络,所以平时无需关心该参数。但若后续在guest启动后修改了其MAC,二层NAT转换发现guest外出包的源MAC和其预先读取的MAC不一致,便停止转换工作,此时guest无法访问外部网络。一般情况下,我们无需修改guest的MAC,所以也不会关注到二层NAT转换其实一直在默默工作。

在linux guest上配置桥功能时,如/lib/systemd/network/99-default.link的MACAddressPolicy=persistent,根据网上资料,guest内核将为桥生成一个固定MAC,而不是通常情况下桥端口网卡的最小MAC。根据前述分析,由于该固定MAC和MACAddress参数不一致,桥接网卡模式下,Guest如使用桥将无法访问外部网络。解决方案有二:一是修改MACAddress参数,使之和guest上桥的固定MAC保持一致;二是在/etc/systemd/network/目录下自定义link文件,为bridge定制MACAddressPolicy=none,link文件名打头数字应小于99,确保其先于99-default.link被匹配,以覆盖默认的MACAddressPolicy=persistent,从而仍然使用传统的MAC生成机制。

先前例子是单台linux guest配置桥时需注意的事项,考虑一种更加特殊的情形,同一Host上的两台Linux guest测试桥组网功能。一台双网卡guest,一块配置为桥接网卡模式(必须对应MAC地址较小的网卡),另一块配置为内部网络模式(混杂模式设为允许虚拟电脑),两块网卡绑在一个桥上,假定经过先前的处置,该guest已能成功访问外部网络。另一台单网卡guest配置为内部网络模式,理论上单网卡guest也能通过双网卡guest提供的桥功能访问外部网络,但事实上却无法成功。这是由于正常情况下,双网卡网桥并不改变单网卡guest外出包的源MAC,该源MAC同样不符合VirtualBox预先读取的MAC,二层NAT转换不能正常工作所致。要解决这个问题,就比上一例复杂多了,需要在双网卡guest上启用ebtables对单网卡外出包的MAC地址做snat/dnat,将其和VirtualBox能识别的MACAddress互相转换(详见《ebtables与iptables之间的交互技巧》)。

当VirtualBox配合主机有线网卡使用桥接网卡模式连网时,虽然不再需要二层NAT转换,但MACAddress仍在guest网卡硬件层面起到过滤作用。如guest不使用bridge,修改MAC后同样网络不通,这是因为在guest里修改MAC时,在内核层面虽然认定已修改成功,但由于VirtualBox的某种限制或瑕疵,guest里网卡硬件层面并没有被真正修改,还是只认MACAddress指定的MAC。在guest里修改MAC后,正常情况下,外部发往guest的数据包,其目标MAC默认为修改后的MAC,因与MACAddress不符,直接在网卡硬件层面DROP(ARP查询为广播包,能被guest处理,所以外部获取的是guest修改后的MAC);如在外部机器设置guest的静态ARP指向MACAddress指定的MAC,以该MAC为目标MAC的数据包到达guest后,虽然在guest网卡物理层面MAC相符不再被DROP,但在网卡内核驱动层面MAC已更改,故内核认定两者不符,导致二层包类型标记为PACKET_OTHERHOST,从而被三层DROP。解决方案是guest里修改网卡MAC的同时将该网卡设置为promisc模式,guest网卡收到目标MAC为修改后的MAC时,因网卡处于promisc模式,能被网卡硬件接收,并且由于目标MAC和修改后MAC一致,二层包类型被标记为PACKET_HOST,能被三层正常处理,网络通讯即可恢复正常(GUI界面网卡混杂模式还需设为全部允许)。如guest使用bridge,只要在GUI界面网卡混杂模式设为全部允许,外部发往guest的数据包,其目标MAC默认为桥对应的最新MAC,因此时桥物理网卡已处于promisc模式,总是能被网卡硬件接收,而桥驱动自动将目标MAC和桥MAC一致的包修改为PACKET_HOST,故可以随意修改桥或桥物理网卡的MAC;也允许其他虚拟机的MAC通过桥顺利转发(GUI界面对应桥物理网卡混杂模式不能设为拒绝)。

如前所述,VirtualBox在桥接无线网卡时需要进行二层NAT转换,二层转换时guest的源MAC必须匹配MACAddress参数,导致guest里即使采用了bridge,也无法随意更改MAC(除非再另行借助ebtables对MAC进行snat/dnat二层转换)。但对于Windows环境下的VirtualBox,有一个取巧的办法,即可通过Windows无线网桥规避VirtualBox的二层NAT转换缺陷,由无线网桥完成无线网卡需要的二层NAT转换功能。虚拟机桥接网卡选择Windows无线网桥后,对于VirtualBox来说,无线桥接变成了有线桥接,此时无需VirtualBox实现二层NAT转换,guest本身再采用bridge后,便可随意更改MAC。
Windows无线网桥的这一特性,理论上很美好,然而实操中略有遗憾,由于Windows无线网桥二层NAT功能存在着其他瑕疵,无线网桥在正常工作一段时间后,就无法正确处理guest发起的DHCP请求包(会莫名其妙将chaddr字段转换为主机无线网卡MAC,guest将分配到和主机无线网卡完全一样的IP),导致guest和host之间IP冲突,但如host或guest其中之一使用静态IP的话则不受这一瑕疵影响。
此外,VirtualBox二层NAT转换机制可针对无线环境下的multicast_to_unicast包进行逆转换,而Windows无线网桥二层NAT转换机制并不具备这一功能。VirtualBox桥接网卡在选择Windows网桥后,将不再触发VirtualBox二层NAT转换机制,当无线环境下开启multicast_to_unicast功能后,目标MAC为主机无线网卡MAC的multicast_to_unicast包到达VirtualBox的桥接模式guest后(guest已启用bridge+混杂模式全部允许,否则前述包到不了guest),被标记为PACKET_OTHERHOST,后续被DROP,导致guest无法实现multicast receive功能。
最后顺便提一下,使用Windows无线网桥,同样可以解决Windows主机上Vmware Workstation Pro 17.0.1下Linux虚拟机使用无线桥接模式时无法获取DHCP的bug,Linux下常用DHCP客户端dhclient的DHCP Discover包Bootp标志总是单播,17.0.1(包括17.0.2)在无线桥接时不能将该Bootp标志从单播转换为广播,导致后续DHCP Offer包采用单播方式,永远不会到达虚拟机(其实质是到不了主机无线网卡),使用Windows无线网桥后,对于Vmware来说,无线桥接变成了有线桥接,Bootp标志单播到广播的转换也由Windows无线网桥完成,同样完美的规避了17.0.1的bug。至于Windows虚拟机,DHCP Discover时,Bootp标志先采用单播,如不成功,则改用广播,所以不受该bug影响。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值