主机中客户端的 WireGuard 端口转发

主机中客户端的 WireGuard 端口转发

我正在尝试将 wireguard 客户端的端口连接到服务器的主机网络。

我尝试使用 IPtables 来实现,但总是收到“无法访问”的回复

看来我的配置可能有问题?

谢谢!


测试连接

root@wiretest3:~# curl -I 10.7.0.2:6060
HTTP/1.1 200 OK
Server: nginx/1.20.1
Date: Sun, 18 Jul 2021 10:37:38 GMT
Content-Type: text/html
Content-Length: 988
Last-Modified: Sat, 17 Jul 2021 10:07:05 GMT
Connection: keep-alive
ETag: "60f2abc9-3dc"
Accept-Ranges: bytes

root@wiretest3:~# curl -I 192.168.1.180:6060
curl: (28) Failed to connect to 192.168.1.180 port 6060: Connection timed out
root@wiretest3:~# curl -I 127.0.0.1:6060
curl: (7) Failed to connect to 127.0.0.1 port 6060: Connection refused

服务器配置:

主机:192.168.1.183 Wireguard 网络:10.7.0.1

root@wiretest3:~# cat /etc/wireguard/wg0.conf
# Do not alter the commented lines
# They are used by wireguard-install
# ENDPOINT wireguard.demo.net

[Interface]
Address = 10.7.0.1/24
PrivateKey = QAOETAJYMK3PcDhN/y+xFJKcJetm4...........
ListenPort = 51823

# BEGIN_PEER client
[Peer]
PublicKey = YxM7cwbmBm7VIyNcRdDBhtiEwFWL........
PresharedKey = W9Y0qCku0Fv1uFiMpy5ImStbs+.........
AllowedIPs =  10.7.0.2/32, 192.168.1.183/32
# END_PEER client

知识产权

root@wiretest3:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0@if47: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 2e:f5:1e:38:32:06 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.1.183/24 brd 192.168.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::2cf5:1eff:fe38:3206/64 scope link 
       valid_lft forever preferred_lft forever
3: wg0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1420 qdisc mq state UNKNOWN group default qlen 500
    link/none 
    inet 10.7.0.1/24 scope global wg0
       valid_lft forever preferred_lft forever
    inet6 fe80::6613:2cc4:bb7d:6bd4/64 scope link stable-privacy 
       valid_lft forever preferred_lft forever

IPtables 规则:

    iptables -P FORWARD DROP;
    iptables -A FORWARD -i eth0 -j ACCEPT;
    iptables -t nat -A PREROUTING -p tcp --dport 6060:6060 -j DNAT --to-destination 10.7.0.2;
    iptables -w -t nat -A POSTROUTING -o eth0 -j MASQUERADE;

IPtables:(iptables-保存)

root@wiretest3:~# iptables-save
# Generated by iptables-save v1.8.7 on Sun Jul 18 13:17:28 2021
*filter
:INPUT ACCEPT [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -p udp -m udp --dport 51823 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 10.7.0.0/24 -j ACCEPT
-A FORWARD -i eth0 -j ACCEPT
COMMIT
# Completed on Sun Jul 18 13:17:28 2021
# Generated by iptables-save v1.8.7 on Sun Jul 18 13:17:28 2021
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -p tcp -m tcp --dport 6060 -j DNAT --to-destination 10.7.0.2
-A POSTROUTING -s 10.7.0.0/24 ! -d 10.7.0.0/24 -j SNAT --to-source 192.168.1.183
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT
# Completed on Sun Jul 18 13:17:28 2021
root@wiretest3:~# 

IPtables:iptables -L -n -t nat (现在)

root@wiretest3:~# sudo iptables -L -n -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:6060 to:10.7.0.2

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
SNAT       all  --  10.7.0.0/24         !10.7.0.0/24          to:192.168.1.183
MASQUERADE  all  --  0.0.0.0/0            0.0.0.0/0 

客户端配置:

root@wiredocker:/etc/wireguard# cat /etc/wireguard/wg0.conf
[Interface]
Address = 10.7.0.2/24
DNS = 8.8.8.8, 8.8.4.4
PrivateKey = GAF31cqwu2YSWQPdiSvlWie2Pma.........

[Peer]
PublicKey = 3VMnaI8JvoXZ6DthLcDy5MnVmNq..............
PresharedKey = W9Y0qCku0Fv1uFiMpy5ImStbs+...............
AllowedIPs = 0.0.0.0/0, ::/0, 192.168.1.0/24
Endpoint = wireguard.demo.net:51823
PersistentKeepalive = 25

知识产权

root@wiredocker:/etc/wireguard# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 76:d3:5b:64:b4:f0 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.178.178/24 brd 192.168.178.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::74d3:5bff:fe64:b4f0/64 scope link 
       valid_lft forever preferred_lft forever
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:bb:9b:28:90 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:bbff:fe9b:2890/64 scope link 
       valid_lft forever preferred_lft forever
10: veth508c767@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether ea:cd:96:6e:33:0b brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::e8cd:96ff:fe6e:330b/64 scope link 
       valid_lft forever preferred_lft forever
15: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none 
    inet 10.7.0.2/24 scope global wg0
       valid_lft forever preferred_lft forever

答案1

事实证明,DNAT对 这样做127.0.0.1似乎是不可行的(至少对于 的情况而言OUTPUT),可能是因为或类似127.0.0.0/8scope host原因。

然而,以下nftables规则集应该可以帮助您实现您的目标:

table ip rewrite {
        chain unloop {
                type route hook output priority filter; policy accept;
                ip daddr 127.0.0.1 tcp dport 80 ip daddr set 10.7.0.2 ip saddr set 10.7.0.1
        }

        chain reloop {
                type filter hook input priority 101; policy accept;
                ip saddr 10.7.0.2 tcp sport 80 ip saddr set 127.0.0.1 ip daddr set 127.0.0.1
        }
}
table ip realnat {
        chain dest {
                type nat hook output priority filter; policy accept;
                ip daddr 192.168.1.183 tcp dport 80 dnat to 10.7.0.2
        }

        chain source {
                type nat hook postrouting priority srcnat; policy accept;
                ip daddr 10.7.0.2 tcp dport 80 snat to 10.7.0.1
        }
}

您不需要执行“正确的”目标 NAT,而是需要对目标(和源)地址进行某种“未跟踪”重写。借助链type route,将执行新的路由查找。此外,您还需要使回复流量具有其源目标地址改回,127.0.0.1以便curl能够识别流量。

hook input应该(即未测试)避免对非主机本身的流量进行不必要的重写(即转发流量的回复流量)。另一方面,priority 101(即1大于srcnat/所有标准优先级)将避免对已正确 NAT 的请求的回复进行不必要的重写。

如您所见,对于这种192.168.1.183情况,在特殊情况的表之后还有另一个执行正常 NAT 的表127.0.0.1

请注意,此规则集仅适用curl于容器内部(或最多是其主机;我不熟悉容器,据我所知,容器可能有不同的联网方法)。例如,如果您需要容器转发到 中的其他主机192.168.1.0/24,您还需要dnat在 链中使用相同的规则type nat hook prerouting priority dstnat。还需要启用和允许 IP 转发。正如我所说,我不确定上面的重写技巧是否127.0.0.1会与此冲突。

相关内容