host = 172.16.1.155是一个公共IP(使用sed更改它是一致的)。 guest = 192.168.122.10是在IP为172.16.1.155的物理机上运行的虚拟机的IP。 我有以下规则(转储与iptables-save和过滤)的两个主机有问题(加上所有需要了解上下文):
*filter -A INPUT -d 172.16.1.155/32 -p tcp -m multiport --dports 25,465 -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -j DROP -A FORWARD -p icmp -j ACCEPT -A FORWARD -i _+ -o _+ -j ACCEPT -A FORWARD -i _+ -o eth0 -j ACCEPT -A FORWARD -d 192.168.122.10/32 -p tcp -m multiport --dports 25,465 -j ACCEPT -A FORWARD -i virbr0 -o virbr0 -j ACCEPT -A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable -A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable -A FORWARD -j LOG -A FORWARD -j DROP COMMIT *nat -A PREROUTING -d 172.16.1.155/32 -p tcp -m multiport --dports 25,465 -j DNAT --to-destination 192.168.122.10 COMMIT
这些规则确保了任何来自外部世界的对host的公共IP的请求实际上将最终在guest端。 所有这些都可以正常工作。 还有更多的规则,但只影响其他客人或有不相干的目的。 客人的所有接口都以下划线开始,所以我可以方便地使用_+来匹配上述规则中的接口名称。
虚拟机都是KVM客人。 桥接口的名称是virbr0 。 每个具有外部IP地址的虚拟机都有一个以它的名字命名的接口,但是前面加了一个下划线(所以guest虚拟机将具有接口_foo )。
另外,KVM为每个guest vnetX创build一个vnetX ( X是一个数字)接口。
以下路线是针对host和guest提出的:
172.16.1.155 * 255.255.255.255 UH 0 0 0 eth0 192.168.122.0 * 255.255.255.0 U 0 0 0 virbr0 default 172.16.1.155 0.0.0.0 UG 100 0 0 eth0
如果我通过SSH进入host ( ssh -D )创buildSOCKS代理,则无法通过该代理连接到guest虚拟机。 首先我想,原因是SOCKS代理可能会使用host端的lo接口( tcpdump -i lo证实),所以我添加了以下规则iptables -I FORWARD -i lo -p tcp -m multiport --dports 25,465 -j ACCEPT (请记住-A INPUT -i lo -j ACCEPT已经接受input),但是应该已经被-A FORWARD -d 192.168.122.10/32 -p tcp -m multiport --dports 25,465 -j ACCEPT所覆盖-A FORWARD -d 192.168.122.10/32 -p tcp -m multiport --dports 25,465 -j ACCEPT 。 所以我再次删除规则,并尝试下面的NAT规则: iptables -t nat -I PREROUTING -d 127.0.0.1/24 -p tcp -m multiport --dports 25,465 -j DNAT --to-destination 192.168.122.10和随后其等价物(所有实际用途) iptables -t nat -I PREROUTING -i lo -p tcp -m multiport --dports 25,465 -j DNAT --to-destination 192.168.122.10 。 也没有给我我想要的结果。
我怎样才能弥补这种情况下的差距? 此外,我的假设是有效的,我可以通过使用telnet 127.0.0.1 25testingSOCKS代理是否工作?
所以我添加了规则iptables -t nat -D OUTPUT -d 127.0.0.1/24 -p tcp -m multiport --dports 25,465 -j DNAT --to-destination 192.168.122.10 mgorvenbuild议的。 这里的行为显然有所改变,但还不完全是我所期待的。
没有这个规则,我得到:
$ telnet localhost 25 Trying 127.0.0.1... telnet: Unable to connect to remote host: Connection refused
用这个规则我得到:
$ telnet localhost 25 Trying 127.0.0.1... telnet: Unable to connect to remote host: Connection timed out
对于源自主机的数据包,不传送PREROUTING链( 该图对于确定数据包将经过的链是有用的)。 你想把这些规则放到nat表的OUTPUT链中。