文章目录
场景
## # 实际案例
#A C 主机不能直接访问,B主机能访问A 和C
国内机房内A 主机不能访问国外,C 主机在国外,B主机在国内 并且可以访问C
核心操作逻辑
# 目的:让A主机与C主机建立wg隧道(假设在udp 51281端口上建立)
# B主机上数据转发要求(全NAT)
1、将来自A 去往B 的udp 51821 流量,源IP 改成B的,目的ip改成C
2、将来自C 去往B 的udp 51821 流量,源IP 改成B的,目的IP改成A
经典网络 (转发主机)B主机 配置实现
# 假设IP如下
A_IP=101.2.37.114
B_IP=43.13.4.10
C_IP=83.22.13.29
# 1、给B主机开启内核转发 和关闭内核源路径验证
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.ipv4.conf.default.rp_filter = 0" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.rp_filter = 0" >> /etc/sysctl.conf
sysctl -p
# 2、A → B → C(PREROUTING + POSTROUTING)
# DNAT:把 A 打到 B 的包转给 C
iptables -t nat -A PREROUTING \
-s A_IP -d B_IP -p udp --dport 51821 \
-j DNAT --to-destination C_IP:51821
# SNAT:把源 IP 改成 B(如果 B 有多个出口 IP,用 MASQUERADE 也可以)
iptables -t nat -A POSTROUTING \
-s A_IP -d C_IP -p udp --dport 51821 \
-j SNAT --to-source B_IP
# 3、C → B → A(反方向)
# DNAT:C 回包打到 B → 转给 A
iptables -t nat -A PREROUTING \
-s C_IP -d B_IP -p udp --sport 51821 \
-j DNAT --to-destination A_IP:51821
# SNAT:源 IP 统一改成 B
iptables -t nat -A POSTROUTING \
-s C_IP -d A_IP -p udp --sport 51821 \
-j SNAT --to-source B_IP
# 4、FORWARD 放行(别漏)
iptables -A FORWARD -p udp -s A_IP -d C_IP --dport 51821 -j ACCEPT
iptables -A FORWARD -p udp -s C_IP -d A_IP --sport 51821 -j ACCEPT
# 5、WireGuard 两端该怎么配(重点)
# A 端
[Peer]
Endpoint = B_IP:51821
# C 端
[Peer]
Endpoint = B_IP:51821
VPC网络(转发主机)B主机 配置实现
# 流量路径
A ──▶ B(EIP) ──▶ [云 NAT] ──▶ B(内网 IP) ──▶ VM
│
└── iptables(咱们能控制的)
# 注意点
VM 上只存在一个 IP:B 内网 IP,EIP 根本不在你的网卡上
进来时:云平台已把 dst=EIP 改成 dst=B_内网
出去时:云平台再把 src=B_内网 改回 src=EIP
因此,你在 B 上做的 NAT,只能基于内网 IP
# 假设IP如下
A_IP=101.2.37.114
B_IP=43.13.4.10
B_INNER=172.16.18.33
C_IP=83.22.13.29
# 1、给B主机开启内核转发 和关闭内核源路径验证
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.ipv4.conf.default.rp_filter = 0" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.rp_filter = 0" >> /etc/sysctl.conf
sysctl -p
# 2、A → B → C
# DNAT(目的改成 C)
iptables -t nat -A PREROUTING \
-s A_IP -d B_INNER -p udp --dport 51821 \
-j DNAT --to-destination C_IP:51821
# SNAT(源改成 B 内网 IP)(也可以用 MASQUERADE)
iptables -t nat -A POSTROUTING \
-s A_IP -d C_IP -p udp --dport 51821 \
-j SNAT --to-source B_INNER
# 3、C → B → A(回程)
# DNAT(改目的为 A)
iptables -t nat -A PREROUTING \
-s C_IP -d B_INNER -p udp --sport 51821 \
-j DNAT --to-destination A_IP:51821
# SNAT(源改成 B 内网 IP)
iptables -t nat -A POSTROUTING \
-s C_IP -d A_IP -p udp --sport 51821 \
-j SNAT --to-source B_INNER
# 4、FORWARD 放行
iptables -A FORWARD -p udp -s A_IP -d C_IP --dport 51821 -j ACCEPT
iptables -A FORWARD -p udp -s C_IP -d A_IP --sport 51821 -j ACCEPT
# 5、WireGuard 配置必须这样写(都是B_EIP)
# A 端
Endpoint = B_EIP:51821
# C 端
Endpoint = B_EIP:51821
附、QA:无法拉取docker镜像,说 TLS handshake timeout
# 1、# 知识点:WireGuard 默认 MTU 是 1420
[root@k8s-rancher ~]# docker pull nginx
Using default tag: latest
Error response from daemon: failed to resolve reference "docker.io/library/nginx:latest": failed to do request: Head "https://registry-1.docker.io/v2/library/nginx/manifests/latest": net/http: TLS handshake timeout
# 2、大概率原因是:WireGuard 隧道 MTU / MSS 不匹配,导致 TLS 握手阶段的大包被丢弃
# 3、验证方法
# 测最大 MTU(在 WG 隧道内侧执行:)
ping -M do -s 1372 registry-1.docker.io
如果失败,逐步减小:
ping -M do -s 1360 registry-1.docker.io
ping -M do -s 1340 registry-1.docker.io
# 如果 1372 不通,1360/1340 通,基本坐实。(1372 + 28 = 1400 左右,是 WG 常见安全线)
# 4、解决办法
# 在双方WG隧道接口,修改MTU为1380,然后重启接口
[Interface]
MTU = 1380
如果文章对你有帮助,欢迎点击上方按钮打赏作者
谢谢你请我吃辣条
暂无评论