定义
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
规则确保从外部世界到公共 IP 的任何请求host
实际上都将以guest
. 所有这些都按预期正常工作。还有更多的规则,但它们只影响其他客人或有无关的目的。guest 的所有接口都以下划线开头,所以我可以方便地使用_+
来匹配上述规则中的接口名称。
虚拟机都是 KVM 来宾。网桥接口的名称是virbr0
. 每个具有外部 IP 地址的虚拟机都有一个以它命名的接口,但前面加了一个下划线(因此来宾foo
将具有 interface _foo
)。
此外,KVM 为每个来宾创建一个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
) 创建 SOCKS 代理,我无法guest
通过该代理连接。首先我认为原因是 SOCKS 代理可能会在旁边使用lo
接口(tcpdump -i lo
确认)host
,所以我添加了以下规则iptables -I FORWARD -i lo -p tcp -m multiport --dports 25,465 -j ACCEPT
(记住-A INPUT -i lo -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
。都没有给我想要的结果。
我怎样才能弥合这种情况下的差距?此外,我的假设是否有效,我可以通过使用来测试 SOCKS 代理是否有效telnet 127.0.0.1 25
?
所以我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
按照 mgorven 的建议添加了规则。这里的行为显然发生了变化,但这还不完全是我正在寻找的。
没有这条规则,我得到:
$ 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 链中。