iptables 规则如何弥合隧道(SSH/SOCKS)和客户的本地 KVM 接口之间的差距?

iptables 规则如何弥合隧道(SSH/SOCKS)和客户的本地 KVM 接口之间的差距?

定义

  • 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。所有这些都运行良好,符合预期。还有更多规则,但它们仅影响其他客户机或具有不相关的目的。客户机的所有接口都以下划线开头,因此我可以方便地使用它_+来匹配上述规则中的接口名称。

虚拟机都是 KVM 客户机。桥接接口的名称是virbr0。每个具有外部 IP 地址的虚拟机都有一个以其命名的接口,但前面带有下划线(因此客户机foo将具有接口_foo)。

另外,KVM 为每个客户机创建一个vnetXX一个数字)接口。

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接口 (确认这一点) ,因此我添加了以下规则(请记住 已经接受输入),但这应该已被 覆盖。因此,我再次删除了该规则并尝试了以下 NAT 规则:以及随后的等效规则(出于所有实际目的)。两者都没有给我想要的结果。tcpdump -i lohostiptables -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 ACCEPTiptables -t nat -I PREROUTING -d 127.0.0.1/24 -p tcp -m multiport --dports 25,465 -j DNAT --to-destination 192.168.122.10iptables -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


因此我按照 mgorven 的建议添加了规则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。这里的行为显然发生了变化,但还不是我所期望的。

如果没有这条规则我会得到:

$ 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

答案1

对于来自主机的数据包,PREROUTING 链不会被遍历(此图对于确定数据包将遍历哪些链很有用)。您需要将这些规则放入nat表的 OUTPUT 链中。

相关内容