设想
ClientA(Windows 10)和 ClientB(Raspberry Pi OS)均通过 OpenVPN 通过互联网连接到 ServerA(Debian 10)。OpenVPN 网络为 10.0.0.0/24。
机器 | OpenVPN IP |
---|---|
服务器A | 10.0.0.1 |
客户A | 10.0.0.2 |
客户B | 10.0.0.3 |
ClientB 可以访问网络 192.168.0.0/24。192.168.0.250 运行网络服务器。
目标
ClientA 的所有互联网流量都通过 ServerA 的互联网连接。ClientA 到 192.168.0.0/24 的所有流量都通过 ClientB。
当前(错误)设置
什么有效
ClientA 是 ServerA 的 OpenVPN 服务的客户端,并通过 VPN 路由所有流量。ClientB
是 ServerA 的 OpenVPN 服务的客户端。ClientA
和 ClientB 可以互相 ping 通。ServerA
通过自己的互联网连接路由 ClientA 的所有互联网流量。ServerA
将所有从 ClientA 到 192.168.0.0/24 的流量路由到 ClientB。
无效的方法:
ClientA 无法与 192.168.0.0/24 上的任何机器建立连接。看来 ClientB 没有路由流量或相应地执行 NAT。
设置
客户A
IPv4 Route Table
===========================================================================
Active Routes:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.6 25
0.0.0.0 128.0.0.0 10.0.0.1 10.0.0.2 281
192.168.0.0 255.255.255.0 10.0.0.1 10.0.0.2 281
10.0.0.0 255.255.255.0 On-link 10.0.0.2 281
10.0.0.2 255.255.255.255 On-link 10.0.0.2 281
10.0.0.255 255.255.255.255 On-link 10.0.0.2 281
127.0.0.0 255.0.0.0 On-link 127.0.0.1 331
127.0.0.1 255.255.255.255 On-link 127.0.0.1 331
127.255.255.255 255.255.255.255 On-link 127.0.0.1 331
128.0.0.0 128.0.0.0 10.0.0.1 10.0.0.2 281
x.x.x.x 255.255.255.255 192.168.1.1 192.168.1.6 281 # ServerA public IP
192.168.1.0 255.255.255.0 On-link 192.168.1.6 281
192.168.1.6 255.255.255.255 On-link 192.168.1.6 281
192.168.1.255 255.255.255.255 On-link 192.168.1.6 281
224.0.0.0 240.0.0.0 On-link 127.0.0.1 331
224.0.0.0 240.0.0.0 On-link 10.0.0.2 281
224.0.0.0 240.0.0.0 On-link 192.168.1.6 281
255.255.255.255 255.255.255.255 On-link 127.0.0.1 331
255.255.255.255 255.255.255.255 On-link 10.0.0.2 281
255.255.255.255 255.255.255.255 On-link 192.168.1.6 281
===========================================================================
Persistent Routes:
None
tracert 192.168.0.250
Tracing route to 192.168.0.250 over a maximum of 30 hops
1 72 ms 71 ms 73 ms 10.0.0.3
2 * * * Request timed out.
3 * * * Request timed out.
4 ^C
ClientA 上没有防火墙。
服务器A
cat /proc/sys/net/ipv4/ip_forward
1
ifconfig -a (shortened)
ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet x.x.x.x netmask 255.255.252.0 broadcast x.x.x.255
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.0.0.1 netmask 255.255.255.0 destination 10.0.0.1
ip route show
default via x.x.x.x dev ens3
192.168.0.0/24 via 10.0.0.3 dev tun0
10.0.0.0/24 dev tun0 proto kernel scope link src 10.0.0.1
x.x.x.0/22 dev ens3 proto kernel scope link src x.x.x.x
x.x.x.x dev ens3 scope link
nft list ruleset
table ip filter {
chain INPUT {
type filter hook input priority 0; policy accept;
iifname "tun0" counter packets 5003 bytes 808157 accept
}
chain FORWARD {
type filter hook forward priority 0; policy accept;
ct state established,related counter packets 1565233 bytes 1274112205 accept
iifname "tun0" counter packets 23326 bytes 1702134 accept
iifname "ens3" oifname "tun0" ct state established,related counter packets 0 bytes 0 accept
iifname "tun0" oifname "ens3" ct state established,related counter packets 0 bytes 0 accept
}
chain OUTPUT {
type filter hook output priority 0; policy accept;
}
}
table ip nat {
chain PREROUTING {
type nat hook prerouting priority -100; policy accept;
}
chain INPUT {
type nat hook input priority 100; policy accept;
}
chain POSTROUTING {
type nat hook postrouting priority 100; policy accept;
ip saddr 10.0.0.0/24 oifname "ens3" masquerade
oifname "ens3" ip saddr 10.0.0.0/24 counter packets 0 bytes 0 masquerade
}
chain OUTPUT {
type nat hook output priority -100; policy accept;
}
}
traceroute 192.168.0.250
traceroute to 192.168.0.250 (192.168.0.250), 30 hops max, 60 byte packets
1 10.0.0.3 (10.0.0.3) 46.951 ms 48.232 ms 48.180 ms
2 * * *
3 * * *
4 *^C
客户B
cat /proc/sys/net/ipv4/ip_forward
1
ClientB 在同一接口上拥有自己的互联网连接和到 192.168.0.0/24 的连接。从 ClientB 到这两个接口的流量都运行顺畅。
ifconfig -a (shortened)
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.178.70 netmask 255.255.255.0 broadcast 192.168.178.255
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.249 netmask 255.255.255.0 broadcast 192.168.0.255
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.0.0.3 netmask 255.255.255.0 destination 10.0.0.3
ip route show
0.0.0.0/1 via 10.0.0.1 dev tun0
default via 192.168.178.1 dev eth0 proto dhcp src 192.168.178.70 metric 202
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.249
10.0.0.0/24 via 10.0.0.1 dev tun0
128.0.0.0/1 via 10.0.0.1 dev tun0 # no clue where this comes from
x.x.x.x via 192.168.178.1 dev eth0
192.168.178.0/24 dev eth0 proto dhcp scope link src 192.168.178.70 metric 202
这是我设置 iptables 的方式:
iptables -A INPUT -i tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -o eth0:1 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0:1 -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0:1 -j MASQUERADE
iptables -A OUTPUT -o tun0 -j ACCEPT
iptables -L -n -v
Chain INPUT (policy ACCEPT 6619 packets, 2460K bytes)
pkts bytes target prot opt in out source destination
362 22004 ACCEPT all -- tun0 * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
4 240 ACCEPT all -- tun0 * 0.0.0.0/0 0.0.0.0/0 # 4 ICMP (ping) packets have been received, but not forwarded correctly
0 0 ACCEPT all -- tun0 eth0:1 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT all -- eth0:1 tun0 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
Chain OUTPUT (policy ACCEPT 6849 packets, 2466K bytes)
pkts bytes target prot opt in out source destination
280 52688 ACCEPT all -- * tun0 0.0.0.0/0 0.0.0.0/0
traceroute 192.168.0.250
traceroute to 192.168.0.250 (192.168.0.250), 30 hops max, 60 byte packets
1 192.168.0.250 (192.168.0.250) 1.630 ms 1.479 ms 0.927 ms
假设
我认为 ClientB 没有正确路由流量或执行 NAT。
我尝试过在 ClientB 上设置不同的 iptables,但无法使其正常工作。
有任何想法吗?
答案1
我终于找到了解决方案。
问题是,iptables 不支持虚拟网络适配器(就我而言eth0:1
)。
因此,不要像这样在 ClientB 上配置 iptables
...
iptables -A FORWARD -i tun0 -o eth0:1 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0:1 -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0:1 -j MASQUERADE
...
它必须像这样配置(没有虚拟适配器的扩展:1
):
...
iptables -A FORWARD -i tun0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
...
现在流量已按预期路由。希望这对其他人有所帮助。