Wireguard 与端口转发

2022-04-27 11:30:06 +08:00
 0o0O0o0O0o

eth0 为服务器的公网网卡,假设 IP 为 1.2.3.4 。

一直以来我对于 wireguard 的用法都是如下这样的:

# 服务器
[Interface]
Address = 10.0.0.1/32
ListenPort = 10000
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
AllowedIPs = 10.0.0.0/24
# 客户端
[Interface]
Address = 10.0.0.2/32
Table = 1

[Peer]
AllowedIPs = 10.0.0.0/24, 0.0.0.0/0
Endpoint = 1.2.3.4:10000

这样可以实现客户端通过 wireguard 对外请求:

curl --interface wg0 https://ifconfig.me

现在想要在维持当前功能的前提下,只通过在服务器修改,实现将服务器的 8888 端口通过 wireguard 转发到客户端上,并且在客户端看来,来源 IP 为 wireguard Endpoint 的 IP ,也就是 10.0.0.1

按照搜到的常用的 iptables 转发端口的办法可以转发,但是客户端看到的源 IP 是 1.2.3.4

iptables -t nat -A PREROUTING -p tcp -m tcp -d 1.2.3.4 --dport 8888 -j DNAT --to-destination 10.0.0.2:8888
iptables -t nat -A POSTROUTING -p tcp -m tcp -d 10.0.0.2 --dport 8888 -j SNAT --to-source 1.2.3.4
iptables -t nat -A PREROUTING -p udp -m udp -d 1.2.3.4 --dport 8888 -j DNAT --to-destination 10.0.0.2:8888
iptables -t nat -A POSTROUTING -p udp -m udp -d 10.0.0.2 --dport 8888 -j SNAT --to-source 1.2.3.4

对 NAT 的了解非常模糊...希望能结合这个例子讲解一下,谢谢!

7570 次点击
所在节点    Linux
18 条回复
DianQK
2022-04-27 12:45:07 +08:00
似乎没办法实现?客户端上看到源 IP 为 1.2.3.4 时,这个是 WireGuard 协议的包,如果通过 SNAT (好像是这个吧?)改成 10.0.0.1 ,那下一步客户端应该会把 WireGuard 协议的包发到 10.0.0.1 ?
(不知道我想的对不对
tavimori
2022-04-27 13:22:42 +08:00
把 SNAT 部分的 IP 改成 10.0.0.1 应该就可以?

```
iptables -t nat -A PREROUTING -p tcp -m tcp -d 1.2.3.4 --dport 8888 -j DNAT --to-destination 10.0.0.2:8888
iptables -t nat -A POSTROUTING -p tcp -m tcp -d 10.0.0.2 --dport 8888 -j SNAT --to-source 10.0.0.1
iptables -t nat -A PREROUTING -p udp -m udp -d 1.2.3.4 --dport 8888 -j DNAT --to-destination 10.0.0.2:8888
iptables -t nat -A POSTROUTING -p udp -m udp -d 10.0.0.2 --dport 8888 -j SNAT --to-source 10.0.0.1
```
wd
2022-04-27 13:29:57 +08:00
你的那个 snat 就是决定客户端看到的 ip ,你设置的不就是 1.2.3.4 吗?你改成 10.0.0.1 看看
0o0O0o0O0o
2022-04-27 13:34:09 +08:00
@tavimori #2
@wd #3

如#1 所说,这样的话 TCP 不通,而 UDP 是能收到的,但 UDP 只要用 SNAT 改变了源 IP ,客户端收到后就不知道该往哪发了
0o0O0o0O0o
2022-04-27 13:36:38 +08:00
@0o0O0o0O0o #4 抱歉试错命令了。。。TCP 是通的,UDP 不知道如何解决
wd
2022-04-27 13:38:31 +08:00
@0o0O0o0O0o 1 楼说的是啥有点没明白。这么问吧,你在 client 的 8888 的服务,在服务器上能访问通吗?
0o0O0o0O0o
2022-04-27 13:57:37 +08:00
@wd #6 可以访问,我添加了附言
0o0O0o0O0o
2022-04-27 13:58:04 +08:00
@0o0O0o0O0o #5 在 client 修改主路由表的前提下才通,不修改主路由表是不通的
tavimori
2022-04-27 14:27:58 +08:00
如果 Table = off 的话 wg-quick 并不会自动配置回程路由,即客户端不会将目标为 10.0.0.1 的包路由通过 wireguard 传回服务器。

三种修改建议(任选其一即可):
1. 将客户端 Address 字段前缀改为 /24 即:
Address = 10.0.0.2/24

2. 在客户端增加 post up 脚本设置 10.0.0.0/24 走 wireguard 路由

3. 如果 wg 只需要支持这一个应用,在服务端使用 NAT 后,客户端 AllowedIPs 里可以去掉 0.0.0.0/0 , 并启用 Table = auto ,这样只会建立 10.0.0.0/24 的路由。
0o0O0o0O0o
2022-04-27 14:54:22 +08:00
@tavimori #9 感谢耐心解答。

将客户端 Address 字段前缀改为 10.0.0.2/24 就可以解决 tcp 通过 SNAT 修改 --to-source 为 10.101.0.1 的问题。

ip route 查看,相比之前它添加了一条 `10.101.0.0/24 dev wg0 proto kernel scope link src 10.101.0.2`。
webfrogs
2022-04-27 14:58:58 +08:00
只 DNAT 不就好了么? 因为做了 SNAT 才导致 client 看到的 IP 是 1.2.3.4
0o0O0o0O0o
2022-04-27 15:07:12 +08:00
@tavimori 如果希望依然不修改客户端主路由表( Table = off ),但又希望可以在客户端拿到 TCP 的源 IP ,有办法实现吗...
0o0O0o0O0o
2022-04-27 15:19:31 +08:00
@0o0O0o0O0o #12 源 IP 可以认为是 0.0.0.0/0
tavimori
2022-04-27 16:00:26 +08:00
@0o0O0o0O0o
如果客户端收到的 TCP 请求是来自源 IP (我理解你说的源 IP 应该是 1.2.3.4 ?)的话,那么就必须确保客户端将发回该源 IP 的数据包路由经过 wireguard 。如果你想避免将 wireguard 配置成默认路由( Table = off ),那么就必须针对性的添加路由。
(以下假设 linux )例如在客户端的[Interface]下增加以下内容
PostUp = ip route add 1.2.3.4/32 dev %i
PreDown = ip route delete 1.2.3.4/32 dev %i
0o0O0o0O0o
2022-04-27 16:09:25 +08:00
@tavimori #14 我可能用词不当,应该说是服务端的 8888 端口收到的 TCP 连接的 remote address ,而不是服务端的公网 IP ,是未知的,可以假设为 0.0.0.0/0
tavimori
2022-04-27 16:47:12 +08:00
@0o0O0o0O0o
建议在客户端配置基于源地址的策略路由。即源地址为 10.0.0.2/32 的走 wg ,源地址为其他地址 ip 的走系统原来的默认路由。

(以下假设 linux )例如在客户端的[Interface]下增加以下内容:

PostUp = ip route add default dev %i table 10086 src 10.0.0.2
PostUp = ip rule add from 10.0.0.2 table 10086
PreDown = ip rule delete from 10.0.0.2 table 10086
PreDown = ip route delete default dev %i table 10086 src 10.0.0.2
zbinlin
2022-04-27 20:25:36 +08:00
如果是 http 服务的,直接用 nginx 来做反代是最简单的
orannge
2022-04-28 09:50:13 +08:00
要么 dnat+snat ,不影响当前网络,但多了一层 nat ,有连接数和保持时间的问题。要么 dnat+0.0.0.0/0 ,保留原始 ip ,但除了局域网其它流量都走 wg ,如果主机不想这样可以将 wg 和程序一起放 docker 运行。至于 iptables 必定要改的,无非手动还是自动的区别,因此用默认的`Table = auto`即可。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/849522

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX