设想

设想

设想

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
...

现在流量已按预期路由。希望这对其他人有所帮助。

相关内容