此设置中只有一台物理机,一台带有两个网络适配器的虚拟机主机系统(VM).
一个NIC(eth0)连接到内部网络(LAN子网,例如10.x.x.x / 24),并应用于内部流量.
另一个NIC(eth1)连接到公共Internet(它配置了公共可路由IP).此连接应用于将公共Internet流量端口转发到VM的内部IP(传入流量),并允许VM通过NAT访问公共Internet(传出流量).
虚拟机使用LAN-Subnet中的IP地址(10.x.x.x / 24,与eth0相同)
我有一个为虚拟机的虚拟网络接口(vnet0,vnet1,…)和LAN-NIC(eth0)配置的网桥设备(br0).这意味着:
> br0在LAN子网中有一个IP地址(10.x.x.x / 24)
> eth0被添加到桥上
> vnet0,…(由VM使用)动态添加到网桥
问题
局域网内的通信工作正常.此外,VM-Host可通过公共IP访问,并具有Internet访问权限.
我的问题是NAT配置也允许VM访问公共互联网.
我试图使用简单的(S)NAT规则:
iptables -t nat -I POSTROUTING -s 10.x.x.x/24 ! -d 10.x.x.x/24 -j SNAT --to-source y.y.y.102
而y.y.y.102是第二个NIC(eth1)的公共可路由IP.
我发现我需要启用“ip_forward”和“bridge-nf-call-iptables”:
echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
否则,桥接包将不会被iptables处理.
现在来自VM的数据包似乎经历了以下iptables链:
>“前进”(常规) – 我在那里接受(-j ACCEPT,计数器上升)
>“PREROUTING”(nat) – 我在那里接受它们(政策接受,计数器上升)
>“POSTROUTING”(nat) – 它们符合SNAT规则
但是并不是所有的数据包似乎都因为我到目前为止无法弄清楚的任何原因而到达PRE / POSTROUTING.
然而,更有趣的是tcpdump -i eth0与tcpdump -i eth1显示数据包(我试图从VM内部ping外部IP)似乎是通过错误的接口eth0(= LAN-NIC)发送的.甚至应用了NAT规则,因此源地址已更改为另一个NIC(eth1)的IP.
问题:
如何配置系统输出NATed数据包,使用公共IP作为源地址,通过正确的NIC(eth1)发送?
我是否需要将eth1添加到网桥(br0)?如果是,如何正确分配公共IP地址?通常需要在网桥设备上配置IP.我是否需要为桥接器分配别名地址(br0:0上的公共IP)?
配置细节
主机系统上的路由配置:
# ip r default via y.y.y.126 dev eth1 10.x.x.0/24 dev br0 proto kernel scope link src 10.x.x.11 y.y.y.96/27 dev eth1 proto kernel scope link src y.y.y.102
> IP:y.y.y.126是我们的公共互联网路由器.
> IP:y.y.y.102是主机的公共IP
> IP:10.x.x.11是主机的LAN IP
> SUBNET:10.x.x.0 / 24是局域网
> SUBNET:y.y.y.96 / 27是公共IP子网
网卡配置:
# ifconfig br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.x.x.11 netmask 255.255.255.0 broadcast 10.x.x.255 inet6 ####::###:####:####:#### prefixlen 64 scopeid 0x20<link> ether ##:##:##:##:##:## txqueuelen 0 (Ethernet) RX packets 2139490 bytes 243693436 (232.4 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 29085 bytes 2398024 (2.2 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 eth0: flags=4163<UP,MULTICAST> mtu 1500 inet6 ####::###:####:####:#### prefixlen 64 scopeid 0x20<link> ether ##:##:##:##:##:## txqueuelen 1000 (Ethernet) RX packets 2521995 bytes 290600491 (277.1 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 383089 bytes 48876399 (46.6 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device memory 0xdfa60000-dfa7ffff eth1: flags=4163<UP,MULTICAST> mtu 1500 inet y.y.y.102 netmask 255.255.255.224 broadcast y.y.y.127 inet6 ####::###:####:####:#### prefixlen 64 scopeid 0x20<link> ether ##:##:##:##:##:## txqueuelen 1000 (Ethernet) RX packets 2681476 bytes 597532550 (569.8 MiB) RX errors 0 dropped 130 overruns 0 frame 0 TX packets 187755 bytes 21894113 (20.8 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device memory 0xdfa00000-dfa1ffff
桥配置:
# brctl show bridge name bridge id STP enabled interfaces br0 8000.002590eb1900 no eth0 vnet0
和iptables规则:
# iptables -vnL Chain INPUT (policy ACCEPT 0 packets,0 bytes) pkts bytes target prot opt in out source destination 723 106K DROP udp -- * * y.y.y.0/24 0.0.0.0/0 udp spt:5404 586 40052 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 5 420 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 2 458 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 2 458 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT 0 packets,0 bytes) pkts bytes target prot opt in out source destination 1343 173K ACCEPT tcp -- * * 10.x.x.2 0.0.0.0/0 tcp spt:3389 1648 127K ACCEPT tcp -- * * 0.0.0.0/0 10.x.x.2 tcp dpt:3389 18 1040 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 18 1040 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 Chain OUTPUT (policy ACCEPT 525 packets,84016 bytes) pkts bytes target prot opt in out source destination # iptables -vnL -t nat Chain PREROUTING (policy ACCEPT 13 packets,1218 bytes) pkts bytes target prot opt in out source destination Chain INPUT (policy ACCEPT 5 packets,420 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 13 packets,880 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 14 packets,920 bytes) pkts bytes target prot opt in out source destination 5 300 SNAT all -- * * 10.x.x.0/24 !10.x.x.0/24 to:y.y.y.102
这里是LAN接口卡上捕获的NATed数据包(来自VM的ping):
# tcpdump -i eth0 12:53:55.243350 IP y.y.y.102 > y.y.y.110: ICMP echo request,id 2,seq 5,length 40
输出“ip规则”:
# ip rule 0: from all lookup local 32766: from all lookup main 32767: from all lookup default
解决方法
>将10.x.x.11(br0 ip address)设置为VM的默认网关
>在物理主机上启用IP转发
>启用SNAT:
iptables -t nat -A POSTROUTING -s 10.x.x.x/24 -o eth1 -j SNAT --to y.y.y.102