WireGuard 与 wg-easy 速查手册

WireGuard 组网速查:路由转发与 NAT 原理、AllowedIPs 双职责、wg-easy 新旧版本差异、比赛内网代理场景在新旧两版下的配置流程与排障

WireGuard 与 wg-easy 速查手册

1. 转发:一个包到达主机后

flowchart TD
    A["网卡收到 IP 包"] --> B{"目的 IP 是本机?"}
    B -->|"是"| C["交给本机进程<br/>(ping / ssh / 浏览器)"]
    B -->|"否"| D{"ip_forward = 1?"}
    D -->|"否"| E["丢弃(普通主机默认)"]
    D -->|"是"| F["查系统路由表<br/>最长前缀匹配"]
    F --> G{"FORWARD 链放行?"}
    G -->|"否"| E
    G -->|"是"| H["从匹配接口发出<br/>(eth0 / wg0)"]
  • 路由表 = 去哪、从哪出(ip route)
  • ip_forward = 肯不肯帮别人转包
  • FORWARD 链 = 防火墙放不放转发的包

2. NAT:为什么出口端必须改写源 IP

sequenceDiagram
    participant S as 支援PC 10.8.0.3
    participant E as 出口机 192.168.80.132
    participant T as 比赛机器 192.168.80.10
    S->>E: src=10.8.0.3 dst=192.168.80.10
    Note over E: POSTROUTING 链 SNAT:<br/>源改写为 192.168.80.132,<br/>conntrack 记录映射
    E->>T: src=192.168.80.132
    T->>E: 回包 dst=192.168.80.132
    Note over E: conntrack 查表:<br/>目的地改回 10.8.0.3
    E->>S: dst=10.8.0.3(进 wg 隧道)

不改写源 IP,比赛机器不认识 10.8.0.3,回包石沉大海(回程路由问题)。

SNAT --to-source IPMASQUERADE
源 IP固定指定出口网卡当前 IP(动态)
适用IP 恒定(桥接 VM / 静态内网 IP)IP 浮动(DHCP / 云主机 / WSL2)

3. WireGuard:AllowedIPs 一个字段两件事

flowchart LR
    subgraph OUT ["出方向 = 选路"]
        A["目的地命中某 peer 的 AllowedIPs"] --> B["加密发给该 peer"]
    end
    subgraph IN ["入方向 = 门禁"]
        C["从 peer 解密出的包"] --> D{"源 IP 在该 peer<br/>AllowedIPs 内?"}
        D -->|"是"| E["放行"]
        D -->|"否"| F["静默丢弃"]
    end

客户端配置和服务端 wg0.conf 是两张独立的表,各写各的:

flowchart LR
    subgraph PC ["支援PC 下载的客户端配置"]
        A1["[Peer] 服务器<br/>AllowedIPs =<br/>10.8.0.0/24, 192.168.80.0/24"]
    end
    subgraph VPSS ["VPS 的 wg0.conf"]
        B1["peer(支援PC)<br/>AllowedIPs = 10.8.0.3/32"]
        B2["peer(出口机)<br/>AllowedIPs = 10.8.0.2/32,<br/>192.168.80.0/24(挂载网段)"]
    end
    subgraph EPC ["出口机下载的客户端配置"]
        C1["[Peer] 服务器<br/>AllowedIPs = 10.8.0.0/24"]
    end
    A1 -.加密.-> VPSS
    C1 -.加密.-> VPSS
  • 系统路由表先于密钥路由:内核先决定包走 wg0,WireGuard 才按 peer AllowedIPs 选加密对象
  • Table = auto:wg-quick up 时才为 peer 的 AllowedIPs 写系统路由;syncconf 只改 peer 表不写路由 → 改完挂载网段必须重启接口
  • PersistentKeepalive = 25:给中间每层 NAT 的 UDP 映射续费

4. 两种出口模型

flowchart LR
    A["本地PC-A"] -->|"0.0.0.0/0 全隧道"| V["VPS 原版 wg-easy<br/>MASQUERADE -o eth0"]
    B["本地PC-B"] -->|"0.0.0.0/0"| V
    V --> I["互联网<br/>所有人的出口 IP = VPS"]
flowchart LR
    A["支援PC<br/>10.8.0.3"] -->|"隧道 UDP 51820"| V["VPS<br/>纯转发,不 NAT"]
    V -->|"目的 ∈ 192.168.80.0/24<br/>按 peer AllowedIPs"| E["出口机<br/>wg:10.8.0.2<br/>内网:192.168.80.132"]
    E -->|"SNAT 源 → .132"| N["比赛内网<br/>192.168.80.0/24"]
原版 wg-easymy-wg-easy(魔改旧版)新版 wg-easy
出口VPS(MASQUERADE)指定出口机(SNAT)任意,按客户端配
挂载网段无WG_ALLOWED_IPS每客户端 Server Allowed IPs
出口端 NAT服务端固定硬编码进出口机配置每客户端 Post Up 钩子
指定出口机无按客户端名 WG_LOCAL_NAME显式逐客户端配置
配置生效重启容器重启容器Restart Interface

5. 场景全景:ping 192.168.80.10 的一生

flowchart TD
    S["① 支援PC:路由表 192.168.80.0/24 → wg0,加密"] --> V["② VPS:解密,非本机,转发<br/>需 ip_forward + FORWARD 放行<br/>需系统路由 192.168.80.0/24 → wg0<br/>密钥路由命中出口机 peer,加密"]
    V --> E["③ 出口机:解密,非本机,转发<br/>SNAT 源 10.8.0.3 → 192.168.80.132"]
    E --> T["④ 比赛机器:只看到 .132 在访问"]
    T -->|"⑤ 回包 dst=.132"| E2["⑥ 出口机:conntrack 改回 dst=10.8.0.3<br/>路由 10.8.0.0/24 → wg0,加密"]
    E2 --> V2["⑦ VPS:解密,dst=10.8.0.3<br/>/32 最长前缀命中支援PC peer,加密"]
    V2 --> S2["⑧ 支援PC:解密,源=192.168.80.10<br/>在自己 AllowedIPs 内 → 放行 ✓"]

6. 新版 wg-easy 比赛内网配置(推荐)

flowchart TD
    A["VPS 部署新版 wg-easy,默认配置"] --> B["创建客户端:出口机<br/>按下表配字段"]
    B --> C["赛场 Linux 机:<br/>sysctl -w net.ipv4.ip_forward=1<br/>wg-quick up 下载的 conf"]
    C --> D["管理后台 Restart Interface<br/>(生成 比赛网段 → wg0 系统路由)"]
    D --> E["创建客户端:支援<br/>Allowed IPs 加比赛网段"]
    E --> F["分发配置 / 二维码"]

出口机客户端字段:

字段值
Allowed IPs10.8.0.0/24
Server Allowed IPs192.168.80.0/24(比赛网段,可多个)
Post Upiptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j SNAT --to-source 192.168.80.132
Post Down同上改 -D
Persistent Keepalive25

支援客户端字段:

字段值
Allowed IPs10.8.0.0/24, 192.168.80.0/24

坑:

  • 改 Server Allowed IPs 后必须 Restart Interface(syncconf 不写系统路由)
  • 出口机须 Linux 且 wg-quick 启动(Windows 原生客户端不执行 PostUp);VM 桥接最佳;WSL2 / Docker 场景 PostUp 改用 -j MASQUERADE
  • 比赛网段勿与 WG 虚拟网段重叠
  • 新客户端默认继承全局 Allowed IPs(0.0.0.0/0),不改则支援全部流量走 VPS

7. my-wg-easy(旧版)比赛内网配置

环境变量示例含义
WG_LOCAL_NAMEl1aotest出口机的客户端名
WG_LOCAL_PASS192.168.80.132出口机内网 IP(SNAT 目标)
WG_ALLOWED_IPS192.168.80.0/24挂载网段(同时喂客户端路由 + 服务端 peer)
WG_DEFAULT_ADDRESS10.8.0.xWG 虚拟网段
WG_PERSISTENT_KEEPALIVE25NAT 保活

流程:先创建名为 WG_LOCAL_NAME 的客户端 → 重启容器(wg-quick up 才写挂载网段路由)→ 出口机用下载的 conf wg-quick up + 开 ip_forward。

8. 排障:按序检查

flowchart TD
    A["ping 不通"] --> B["支援PC:ip route get 目标<br/>走了 wg0?"]
    B -->|"否"| B1["AllowedIPs 缺比赛网段"]
    B -->|"是"| C["VPS:ip route get 目标<br/>走了 wg0?"]
    C -->|"否"| C1["改过挂载网段没重启接口<br/>→ Restart Interface"]
    C -->|"是"| D["出口机:tcpdump -ni eth0<br/>有出向包?"]
    D -->|"否"| D1["ip_forward 未开 / FORWARD 未放行"]
    D -->|"是"| E["回包到出口机却没回支援?<br/>支援 AllowedIPs 缺比赛网段<br/>(被自己 WG 门禁丢弃)"]
1
2
3
ip route get 192.168.80.10   # 本机视角:包从哪个口出
tcpdump -ni wg0              # 隧道侧抓包
tcpdump -ni eth0             # 物理侧抓包
使用 Hugo 构建
主题 Stack 由 Jimmy 设计