iptables 规则无法允许特定 IP

iptables 规则无法允许特定 IP

我有一台具有 2 个网络接口的主机:wifi 和 site-site vpn(zerotier)。

root@host:~# ifconfig wlp0s20f3
wlp0s20f3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.38  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::a098:2166:78af:d78d  prefixlen 64  scopeid 0x20<link>
        ether ac:12:03:ab:6e:31  txqueuelen 1000  (Ethernet)
        RX packets 1071869  bytes 1035656551 (1.0 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 911450  bytes 134092251 (134.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


root@host:~# ifconfig ztklh3tu4b
ztklh3tu4b: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 2800
        inet 10.147.18.192  netmask 255.255.255.0  broadcast 10.147.18.255
        inet6 fe80::f8f6:d1ff:fe3d:4f09  prefixlen 64  scopeid 0x20<link>
        ether fa:f6:d1:3d:4f:09  txqueuelen 1000  (Ethernet)
        RX packets 8836  bytes 1146994 (1.1 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 667  bytes 281732 (281.7 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

我想阻止到此主机的所有流量(入站和出站),但 VPN 后面的 IP 除外。因此,我添加了以下 iptable 规则:

iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
iptables -A INPUT -s 10.147.18.80 -j ACCEPT
iptables -A OUTPUT -d 10.147.18.80 -j ACCEPT

当我 ping 这个 10.147.18.80 时,无法执行此操作。以下是 ping 结果:

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
^C
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3067ms

root@host:~# ping 10.147.18.80
PING 10.147.18.80 (10.147.18.80) 56(84) bytes of data.
^C
--- 10.147.18.80 ping statistics ---
6 packets transmitted, 0 received, 100% packet loss, time 5097ms

当我将 iptables 规则中的 IP 更改为其他 IP(例如 8.8.8.8)时,一切都按预期工作,即我无法与 8.8.8.8 之外的任何设备进行通信。

编辑 iptables -nvL 的以下输出显示了这些链:

root@host:~# iptables -nvL
Chain INPUT (policy DROP 23 packets, 4560 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  *      *       10.147.18.80         0.0.0.0/0           

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy DROP 330 packets, 25776 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    8   672 ACCEPT     all  --  *      *       0.0.0.0/0            10.147.18.80         

上述 iptables 输出显示,当规则到位时,数据包发往 IP,但没有收到回复。

我的主机上的 Tcpdump 显示出相同的行为:

tcpdump: data link type LINUX_SLL2
tcpdump: listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes


13:28:32.323064 ztklh3tu4b Out IP (tos 0x0, ttl 64, id 17342, offset 0, flags [DF], proto ICMP (1), length 84)
    10.147.18.192 > 10.147.18.80: ICMP echo request, id 61, seq 1, length 64
13:28:33.330145 ztklh3tu4b Out IP (tos 0x0, ttl 64, id 17567, offset 0, flags [DF], proto ICMP (1), length 84)
    10.147.18.192 > 10.147.18.80: ICMP echo request, id 61, seq 2, length 64
13:28:34.354178 ztklh3tu4b Out IP (tos 0x0, ttl 64, id 17694, offset 0, flags [DF], proto ICMP (1), length 84)
    10.147.18.192 > 10.147.18.80: ICMP echo request, id 61, seq 3, length 64
13:28:35.378135 ztklh3tu4b Out IP (tos 0x0, ttl 64, id 17714, offset 0, flags [DF], proto ICMP (1), length 84)
    10.147.18.192 > 10.147.18.80: ICMP echo request, id 61, seq 4, length 64

10.147.18.80 上的 Tcpdump 没有显示来自 10.147.18.192 的任何入站 ICMP 回显请求。可能出了什么问题?

答案1

如果您在此主机上使用 VPN 客户端创建第二个接口,请不要忘记允许连接到 VPN 服务器,否则你的本地 IP10.147.18.192将不再可访问。

您至少需要在接口上允许往返于 VPN 服务器的出站和入站流量wlp0s20f3

iptables -I OUTPUT -d $vpn_server_ip -p $proto --dport $vpn_port -j ACCEPT
iptables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

$proto 将是udptcp,和$vpn_server_ip$vpn_portVPN 服务器的 IP 地址或范围和端口

我无法猜测这些值,但您的 VPN 文档或与 VPN 隧道建立有效连接的 tcpdump/wireguard 应该可以为您提供这些信息。

答案2

您在问题中提到的这两个命令:

iptables -A INPUT -s 10.147.18.80 -j ACCEPT
iptables -A OUTPUT -d 10.147.18.80 -j ACCEPT

它们将这些规则附加到链的末尾。 -A选项将规则附加到末尾。如果您使用-I选项,您将把规则放在链的顶部。

这里的问题是,您可能已经在某个链中的规则之前有一个DROPREJECT规则,该ACCEPT规则在流量到达链末尾之前将其丢弃。例如,丢弃包含 IP 10.147.18.80 的整个子网的流量的规则。

如果在 ACCEPT 规则之前,链中有一个规则丢弃/拒绝到该 IP 的流量,或者根据它是 INPUT 还是 OUTPUT 链而拒绝来自该 IP 的流量,那么无论该规则仅指定该 IP 还是整个子网,流量都会被丢弃,并且链中的所有其他规则都不再处理。

DROP,,REJECTACCEPT终止目标,一旦 iptables 匹配该规则,它就会停止处理链中的其他规则,不会继续执行下一个规则。

尝试

iptables -I INPUT -s 10.147.18.80 -j ACCEPT
iptables -I OUTPUT -d 10.147.18.80 -j ACCEPT

这会将这些规则置于链的顶部,因此它们是第一个被触发的规则,并且对于这些链中的该流量,其他规则将不会被处理。

你可以使用类似下面的方式列出链中的所有规则

iptables -nvL

或者如果你想只查看特定的连锁店

iptables -nvL INPUT 
iptables -nvL OUTPUT

编辑

鉴于您粘贴的输出,以及如果您将默认操作更改为此则可以 ping 的事实ACCEPT似乎不是问题。

您可以使用 tcpdump 之类的工具来查看流量是否有任何流出并返回。

此类命令将为您提供机器发送或接收的所有 icmp 数据包

tcpdump -nnvvi any icmp

如果你在输出中看到类似这样的内容

10:13:48.866598 IP (tos 0x0, ttl 255, id 30625, offset 0, flags [DF], proto ICMP (1), length 84)
    10.147.18.192 > 10.147.18.80: ICMP echo request, id 26621, seq 4, length 64
10:13:48.867771 IP (tos 0x0, ttl 53, id 0, offset 0, flags [none], proto ICMP (1), length 84)
    10.147.18.80 > 10.147.18.192: ICMP echo reply, id 26621, seq 4, length 64

然后,您的 ping 数据包被发送出去并返回,但被其他规则拒绝。

您可以检查其他表(如 nat 或 mingle 表)中是否存在其他规则,以及其中的一些规则是否与流量相冲突。

iptables -t nat -nvL
iptables -t mingle -nvL

您还可以通过列表中的数字查看数据包是否通过了 OUTPUT 链中的 ACCEPT 规则pkts。如果在您尝试 ping 之后该数字增加,但 INPUT 链中的数字保持为 0,则问题出在传入流量规则上。

另外,使用命令或类似命令检查您的路由ip r,如果流量没有通过同一子网中的接口退出,那么返回数据包的源 IP 可能会由于途中的某些 NAT 规则而发生变化。

相关内容