通过中转主机,组建wg通道

场景

## # 实际案例
    #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
声明:本文为原创,作者为 辣条①号,转载时请保留本声明及附带文章链接:https://boke.wsfnk.com/archives/1606.html
谢谢你请我吃辣条谢谢你请我吃辣条

如果文章对你有帮助,欢迎点击上方按钮打赏作者

最后编辑于:2026/1/29作者: 辣条①号

目标:网络规划设计师、系统工程师、ceph存储工程师、云计算工程师。 不负遇见,不谈亏欠!

暂无评论

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

arrow grin ! ? cool roll eek evil razz mrgreen smile oops lol mad twisted wink idea cry shock neutral sad ???

文章目录