我的本地网络中有三台计算机:A、B、C
- A 与路由器有以太网连接
- B 通过无线方式连接到路由器,并与 C 共享互联网访问权限
- C 通过以太网电缆连接到 B
这三家公司都可以上网。
- 从 B,我可以 ping A 和 C
- 从 C,我可以 ping A 和 B
- 但从 AI 只能 ping B,C 无法到达:目标端口不可达
这是 A 上的“ip route show”
default via 192.168.1.1 dev enp2s0 proto dhcp src 192.168.1.85 metric 1024
192.168.1.0/16 dev enp2s0 proto kernel scope link src 192.168.1.85 metric 1024
192.168.1.1 dev enp2s0 proto dhcp scope link src 192.168.1.85 metric 1024
这是 B 上的“ip route show”
default via 192.168.1.1 dev wlx347de4402df9 proto dhcp metric 600
10.42.0.0/24 dev enp5s0 proto kernel scope link src 10.42.0.1 metric 100
169.254.0.0/16 dev enp5s0 scope link metric 1000
192.168.1.0/24 dev wlx347de4402df9 proto kernel scope link src 192.168.1.180 metric 600
这是 C 上的“ip route show”
default via 10.42.0.1 devenp2s0 proto dhcp metric 100
10.42.0.0/24 dev enp2s0 proto kernel scope link src 10.42.0.169 metric 100
169.254.0.0/16 dev enp2s0 scope link metric 1000
现在就 IP 地址而言:
从BI可以:
- ping/ssh 192.168.1.85(A)
- ping/ssh 10.42.0.169(C)
从 CI 可以:
- ping/ssh 192.168.1.85(A)
- ping/ssh 192.168.1.180(B)
- ping/ssh 10.42.0.1 (B 也一样)
从AI可以:
- ping/ssh 192.168.1.180(B)
我无法执行 ping/ssh 10.42.0.169 和 10.42.0.1
在我用“ip route 10.42.0.0/24 via 192.168.1.180”在 A 上添加一条路由后,我现在可以以 10.42.0.1 ping B,但仍然无法访问 C。“ping 10.42.0.169”给我以下结果:
From 192.168.1.180 icmp_seq=1 Destination Port Unreachable
From 192.168.1.180 icmp_seq=2 Destination Port Unreachable
From 192.168.1.180 icmp_seq=3 Destination Port Unreachable
我怎样才能让 A 能够到达 C?
在 B 上,“iptables-save”不输出任何内容,以下是“nft list ruleset”的输出
table ip nm-shared-enp5s0 {
chain nat_postrouting {
type nat hook postrouting priority srcnat; policy accept;
ip saddr 10.42.0.0/24 ip daddr != 10.42.0.0/24 masquerade
}
chain filter_forward {
type filter hook forward priority filter; policy accept;
ip daddr 10.42.0.0/24 oifname "enp5s0" ct state { established, related } accept
ip saddr 10.42.0.0/24 iifname "enp5s0" accept
iifname "enp5s0" oifname "enp5s0" accept
iifname "enp5s0" reject
oifname "enp5s0" reject
}
}
在 C 上,“nft list ruleset”和“iptables-save”均无输出。
答案1
从技术上讲,您另外需要的只是:
ip route add 10.42.0.0/24 via 192.168.1.180
在 A 上,假设 B 上的防火墙(iptables 和/或 nftables)(以及 C 上的防火墙)没有通过任何规则禁止由 A 发起的到 C 的流量。
由于 B 似乎是一台 Linux 主机,这意味着它上的 NAT 是有状态的,这意味着它不会应用于来自 C 的回复流量,因此不会出现问题。
(并且由于 B 已经作为 C 的“网关”,因此意味着 sysctlnet.ipv4.ip_forward
已经设置为1
。)
在你的 nftables 规则集的链中hook forward
,有这样一条规则:
ip daddr 10.42.0.0/24 oifname "enp5s0" ct state { established, related } accept
它匹配并且只允许“回复流量”(嗯,ct state established
有点复杂,不是这里的重点,所以)10.42.0.0/24
通过进行转发enp5s0
。
链在拥有的同时policy accept
,也有着规则:
oifname "enp5s0" reject
它匹配并拒绝以 为目标的“原始流量”(即ct state new
;通信发起流量)10.42.0.0/24
,因为它们不会被任何先前的规则匹配,并且将根据路由表转发enp5s0
。(但规则不会只匹配这些流量。)
请注意,以下规则与流量不匹配,因为iifname "enp5s0"
它们的情况并非如此(我的意思是假设它们来自 A):
iifname "enp5s0" oifname "enp5s0" accept
TL;DR。您需要ct state { established, related }
从我上面引用的第一条规则中删除。(虽然也有ct state
invalid
,但由于您没有在任何规则中过滤此类流量,所以。)