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 的了解非常模糊...希望能结合这个例子讲解一下,谢谢!
还有一个前提是客户端的 wireguard 不修改主路由表,即 Table = off
或 Table = 1
# 客户端
wg-quick up wg0
# 监听 TCP
nc -vlk 8888
# 监听 UDP
nc -vlu 8888
在以上这些条件下,server 只有将 --to-source
改为 server 的 eth0 IP,TCP 才可以正常。虽然可以通信,但是 client 无法获取源 IP 信息;
而这种条件下的 UDP,我觉得理论上 client 需要拿到源IP,并 bind device 才可以发送,就不知道该如何处理了。
1
DianQK 2022-04-27 12:45:07 +08:00 1
似乎没办法实现?客户端上看到源 IP 为 1.2.3.4 时,这个是 WireGuard 协议的包,如果通过 SNAT (好像是这个吧?)改成 10.0.0.1 ,那下一步客户端应该会把 WireGuard 协议的包发到 10.0.0.1 ?
(不知道我想的对不对 |
2
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 ``` |
3
wd 2022-04-27 13:29:57 +08:00 via iPhone 1
你的那个 snat 就是决定客户端看到的 ip ,你设置的不就是 1.2.3.4 吗?你改成 10.0.0.1 看看
|
4
0o0O0o0O0o OP |
5
0o0O0o0O0o OP @0o0O0o0O0o #4 抱歉试错命令了。。。TCP 是通的,UDP 不知道如何解决
|
6
wd 2022-04-27 13:38:31 +08:00 via iPhone
@0o0O0o0O0o 1 楼说的是啥有点没明白。这么问吧,你在 client 的 8888 的服务,在服务器上能访问通吗?
|
7
0o0O0o0O0o OP @wd #6 可以访问,我添加了附言
|
8
0o0O0o0O0o OP @0o0O0o0O0o #5 在 client 修改主路由表的前提下才通,不修改主路由表是不通的
|
9
tavimori 2022-04-27 14:27:58 +08:00 1
如果 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 的路由。 |
10
0o0O0o0O0o OP @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`。 |
11
webfrogs 2022-04-27 14:58:58 +08:00 1
只 DNAT 不就好了么? 因为做了 SNAT 才导致 client 看到的 IP 是 1.2.3.4
|
12
0o0O0o0O0o OP @tavimori 如果希望依然不修改客户端主路由表( Table = off ),但又希望可以在客户端拿到 TCP 的源 IP ,有办法实现吗...
|
13
0o0O0o0O0o OP @0o0O0o0O0o #12 源 IP 可以认为是 0.0.0.0/0
|
14
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 |
15
0o0O0o0O0o OP @tavimori #14 我可能用词不当,应该说是服务端的 8888 端口收到的 TCP 连接的 remote address ,而不是服务端的公网 IP ,是未知的,可以假设为 0.0.0.0/0
|
16
tavimori 2022-04-27 16:47:12 +08:00 1
@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 |
17
zbinlin 2022-04-27 20:25:36 +08:00
如果是 http 服务的,直接用 nginx 来做反代是最简单的
|
18
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`即可。
|