通过 VPN 路由特定目标端口的特定数据包

通过 VPN 路由特定目标端口的特定数据包

我正在尝试实现非常类似的目标iptables-目标是将数据包路由到特定接口?https://unix.stackexchange.com/questions/21093/output-traffic-on-different-interfaces-based-on-destination-port但我没有让它工作。

这是我的设置:

RPi4 (本地 IP,eth0:10.0.0.196/24;wireguard IP:10.10.10.2/24;wireguard 接口名为“客户端”) <---> 服务器 (wireguard IP:10.10.10.1/24,全局 IPv4) <---> Internet

这是我迄今为止的测试片段:

systemctl start [email protected]

sysctl -w net.ipv4.conf.all.rp_filter=0
sysctl -w net.ipv4.conf.client.rp_filter=0

for i in /proc/sys/net/ipv4/conf/*/rp_filter ; do
  echo 0 > $i
done

ip rule add fwmark 2 table 3
ip route add default via 10.10.10.1 table 3
ip route flush cache

iptables -t mangle -A OUTPUT -p tcp --dport 25 -j MARK --set-mark 2
iptables -t nat -A POSTROUTING -o client -j SNAT --to-source 10.10.10.2

如果我尝试达到例如

telnet -4 gmail-smtp-in.l.google.com 25
Trying 108.177.119.26...
telnet: Unable to connect to remote host: No route to host

任何其他流量(未标记为“2”的任何流量)都通过 eth0(而非“客户端”)正确路由并且运行良好(如ping 1.1.1.1curl ifconfig.me


这是运行上述代码片段之前和之后的路由和 iptables 的样子。

前:

# ip route show table all
default via 10.0.0.1 dev eth0 proto dhcp src 10.0.0.196 metric 100
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.196
10.0.0.1 dev eth0 proto dhcp scope link src 10.0.0.196 metric 100
broadcast 10.0.0.0 dev eth0 table local proto kernel scope link src 10.0.0.196
local 10.0.0.196 dev eth0 table local proto kernel scope host src 10.0.0.196
broadcast 10.0.0.255 dev eth0 table local proto kernel scope link src 10.0.0.196
broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1
# iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
# iptables -S -t nat
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P POSTROUTING ACCEPT
-P OUTPUT ACCEPT
# iptables -S -t mangle
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT

后:

# ip route show table all
default via 10.10.10.1 dev client table 3
default via 10.0.0.1 dev eth0 proto dhcp src 10.0.0.196 metric 100
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.196
10.0.0.1 dev eth0 proto dhcp scope link src 10.0.0.196 metric 100
10.10.10.0/24 dev client proto kernel scope link src 10.10.10.2
broadcast 10.0.0.0 dev eth0 table local proto kernel scope link src 10.0.0.196
local 10.0.0.196 dev eth0 table local proto kernel scope host src 10.0.0.196
broadcast 10.0.0.255 dev eth0 table local proto kernel scope link src 10.0.0.196
broadcast 10.10.10.0 dev client table local proto kernel scope link src 10.10.10.2
local 10.10.10.2 dev client table local proto kernel scope host src 10.10.10.2
broadcast 10.10.10.255 dev client table local proto kernel scope link src 10.10.10.2
broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1
# ip rule show
0:      from all lookup local
32765:  from all fwmark 0x2 lookup 3
32766:  from all lookup main
32767:  from all lookup default
# iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
# iptables -S -t nat
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P POSTROUTING ACCEPT
-P OUTPUT ACCEPT
-A POSTROUTING -o client -j SNAT --to-source 10.10.10.2
# iptables -S -t mangle
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A OUTPUT -p tcp -m tcp --dport 25 -j MARK --set-xmark 0x2/0xffffffff

答案1

这是网络数据包的图片流经 netfilter 表。在我看来,它不起作用,因为路由决策是由数据包通过您的 fwmark 规则,您无法让它通过另一个接口退出。

您可以直接使用基于策略的路由,无需使用 fwmark。正确阅读您的示例,这应该会重定向全部通过 Wireguard 发出的 SMTP 流量:

iptables -t nat -A POSTROUTING -o client -j SNAT --to-source 10.10.10.2
ip rule add priority 1000 dport 25 table 3
ip route add default via 10.10.10.1 table 3

man ip-rule详细信息请参阅

答案2

我理解您的需求只是建立一个 VPN 连接,通过 VPN 发送所有外部流量。如果我理解正确,请按以下方式配置您的 wireguard:

服务器端(/etc/wireguard/wg0.conf)

[Interface]
PrivateKey = <YOUR PRIVATE KEY HERE>
Address = 10.10.10.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D 
POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT

[Peer]
PublicKey = [CLIETS PUBLIC KEY]
AllowedIPs = 10.10.10.2/32   # The client's IP address

客户端(/etc/wireguard/wg0.conf)

[Interface]
PrivateKey = <Output of privatekey file that contains your private key>
Address = 10.10.10.2/24
PostUp = ip route add [SERVER_PUBLIC_IP] via [LOCAL_GATEWAY_IP] dev eth0

[Peer]
PublicKey = <Server Public key>
Endpoint = <Server Public IP>:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepAlive = 25

请注意,您需要添加一条路由,将所有流量发送到您的民众通过以太网保护 wireguard IP,否则它将断开客户端的连接。

以下方法对我非常有帮助: 如何在 Linux 中设置 WireGuard 防火墙规则

注1:在这种情况下,您只需在服务器端设置NAT MASQUERADE。

注 2:您需要在 Linux 机器上设置 IP 转发:

sudo echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sudo sysctl -p

相关内容