iptables - 使用 nat 和一个公共 IPv4 获取网络访问权限

iptables - 使用 nat 和一个公共 IPv4 获取网络访问权限

我有一个公共 IPV4 地址、一个主机和一个虚拟机(IP 192.168.100.10)。通过主机端的 iptables,我借助 nat 表成功将端口 22(ssh)重定向到主机。

NAT表:

iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
iptables -t nat -A PREROUTING -i eth0 -j DNAT --to-destination 192.168.100.10

过滤表:

iptables -A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT

现在我希望仍然能够从主机和虚拟机访问网络。

我尝试在“过滤器”选项卡上添加:

iptables -I OUTPUT -o eth0 -d 0.0.0.0/0 -j ACCEPT

但仍然无法从主机访问网络。顺便说一下,从主机到外部 IP 的 PING 运行正常。

NAT表:

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
DNAT       all  --  anywhere             anywhere             to:192.168.100.10

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

过滤表:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination                     
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     icmp --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     icmp --  anywhere             anywhere             ctstate NEW,RELATED,ESTABLISHED

欢迎任何帮助!

答案1

您无法从主机访问 Web,因为防火墙 INPUT 过滤器会丢弃(几乎)所有传入数据包,包括对主机发送的数据包的回复。只有 icmp 和 tcp 22 数据包符合 ACCEPT 规则并被接受,因此只有 ping 和 ssh 可以工作,其他任何功能都无法工作。

假设您访问 DNS,您的主机从某个端口向外部发送数据包到 udp 53,DNS 服务器使用相反的端口和地址进行回复。回复数据包进入您的主机:来自 DNS 服务器的 udp 数据包,源端口为 53,但过滤器 INPUT 中与其匹配的第一条规则是 DROP 规则。

Linux 中有一个连接跟踪器,它检查进入主机的所有数据包(原始表中设置为 NOTRACK 的数据包除外),并在确定数据包属于或与某个已知连接相关时设置一些标志(由您之前使用其他默认策略规则接受的数据包创建,例如您的过滤器 OUTPUT 链)。您可以在 INPUT 过滤器链中检查其中一些标志。在 DROP 操作之前执行此操作:

iptables -t filter -I INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

此规则使用 conntrack 标志来允许对源自本地系统的数据包进行回复。

要从虚拟机访问外部世界,您需要添加另一条转换规则:

iptables -t nat -A POSTROUTING -s 192.168.100.10 -o eth0 -j MASQUERADE

这是一种 SNAT 规则,但它说“转换为输出接口具有的任何地址”,而不是在规则中指定该地址。

请注意,从外部世界到虚拟机以及从虚拟机到外部世界的数据包都经过过滤器 FORWARD 链,但不会经过过滤器 INPUT 或过滤器 OUTPUT。如果您打算在 FORWARD 链中删除某些内容以限制虚拟机可以访问的内容以及谁可以访问它,您可能还想在过滤器 FORWARD 链的开头添加类似的 conntrack 规则,以使已建立连接的回复能够到达其目的地,就像您在过滤器 INPUT 链中为主机本身所做的那样。

在这种情况下,OUTPUT 链中的 ACCEPT 规则不会执行任何操作。您不会在 OUTPUT 过滤器中丢弃或拒绝任何内容,OUTPUT 的默认策略是 ACCEPT。您可以清空(刷新)过滤器 OUTPUT 链,它仍会起作用。

相关内容