WireGuard搭建教程和异地组网

简介

WireGuard 是一个极简、高性能的 VPN 协议,运行在 Linux 内核中(其他平台也有实现)。它基于现代加密技术(Curve25519、ChaCha20、Poly1305 等),设计目标是在保持安全性的同时,比传统的 IPsec 和 OpenVPN 配置更简单、速度更快。

  • 无连接设计:每个 Peer 独立配置,无需守护进程。
  • 加密与认证:使用公钥加密和预共享密钥(可选),每个数据包都经过身份验证。
  • 路由控制:通过 AllowedIPs 控制哪些 IP 地址的流量进入隧道,实现精细化路由。

官网地址:WireGuard: fast, modern, secure VPN tunnel

安装(服务端/客户端)

Debian / Ubuntu

1
2
sudo apt update
sudo apt install wireguard wireguard-tools resolvconf # resolvconf 用于 DNS 管理

一键脚步安装工具:GitHub - skilladd/skills_tools: 一个方便你在服务器上快速部署服务的脚本文件 · GitHub

生成密钥对

每个节点(服务器、每个客户端)都需要自己的密钥对。私钥绝不可泄露,公钥需告知对方。

  • wg genkey:生成随机私钥(base64 编码)。
  • tee privatekey:将私钥保存到文件并输出到管道。
  • wg pubkey:从私钥计算公钥。
1
2
3
4
5
wg genkey | tee privatekey | wg pubkey > publickey


wg genkey > privatekey
wg pubkey < privatekey > publickey

配置文件详解

WireGuard 配置文件位于 /etc/wireguard/,通常命名为 wg0.conf(可以有多个接口,如 wg0wg1 等)。配置文件由 [Interface] 段和若干个 [Peer] 段组成。

[Interface] 段:本机配置

选项 说明 示例
PrivateKey 本机的私钥(必须) PrivateKey = gG7t4E…
Address 本机在 VPN 网络中的 IP 地址,可以指定多个(逗号分隔) Address = 10.0.0.1/24 或 Address = 10.0.0.1/24, fd86:ea04:1111::1/64
ListenPort 监听 UDP 端口,服务端需要固定,客户端通常不指定 ListenPort = 51820
DNS 指定 DNS 服务器,写入 /etc/resolv.conf(仅 wg-quick 支持) DNS = 1.1.1.1, 8.8.8.8
MTU 手动设置 MTU,避免分片(默认 1420) MTU = 1350
Table 控制路由表,默认 auto(添加到主表)。设置为 off 可完全由用户管理路由 Table = 12345
PreUp / PostUp 在接口启动前后执行的命令(常用于防火墙规则) PostUp = iptables -A FORWARD -i %i -j ACCEPT
PreDown / PostDown 在接口关闭前后执行的命令 PostDown = iptables -D FORWARD -i %i -j ACCEPT

注意%i 会被自动替换为接口名(如 wg0)。

[Peer] 段:对端配置

选项 说明 示例
PublicKey 对端的公钥(必须) PublicKey = r3F4g…
AllowedIPs 允许通过此 Peer 访问的 IP 地址段。用于路由决策 AllowedIPs = 10.0.0.2/32 或 AllowedIPs = 0.0.0.0/0
Endpoint 对端的公网地址(IP:端口)。只有发起连接的一端需要指定 Endpoint = 203.0.113.1:51820
PersistentKeepalive 发送 keepalive 包的间隔(秒),用于 NAT 穿透 PersistentKeepalive = 25
PresharedKey 可选,预共享密钥,增加安全性 PresharedKey = …

远程访问内网

移动设备(客户端)可以安全访问公司内网,并可选择所有流量走 VPN。

服务端配置

(/etc/wireguard/wg0.conf)

1
2
3
4
5
6
7
8
9
10
11
[Interface]
PrivateKey = <服务端私钥>
Address = 10.0.0.1/24
ListenPort = 51820
# 开启 IP 转发,并配置 NAT
PostUp = sysctl -w net.ipv4.ip_forward=1; iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o %i -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o %i -j MASQUERADE

[Peer]
PublicKey = <客户端公钥>
AllowedIPs = 10.0.0.2/32

客户端配置

/etc/wireguard/wg0.conf

1
2
3
4
5
6
7
8
9
10
[Interface]
PrivateKey = <客户端私钥>
Address = 10.0.0.2/24
DNS = 1.1.1.1

[Peer]
PublicKey = <服务端公钥>
Endpoint = 服务器公网IP:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

点对点直连

两个不同地区的办公室(各有自己的局域网)通过 VPN 互联。
假设:

  • 站点 A:VPN IP 10.0.0.1,内网 192.168.1.0/24
  • 站点 B:VPN IP 10.0.0.2,内网 192.168.2.0/24

站点 A 配置

1
2
3
4
5
6
7
8
9
10
11
12
[Interface]
PrivateKey = <A私钥>
Address = 10.0.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o %i -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -s 192.168.1.0/24 -o %i -j MASQUERADE

[Peer]
PublicKey = <B公钥>
AllowedIPs = 10.0.0.2/32, 192.168.2.0/24
Endpoint = B的公网IP:51820
PersistentKeepalive = 25

站点 B 配置

1
2
3
4
5
6
7
8
9
10
11
12
[Interface]
PrivateKey = <B私钥>
Address = 10.0.0.2/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o %i -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -s 192.168.2.0/24 -o %i -j MASQUERADE

[Peer]
PublicKey = <A公钥>
AllowedIPs = 10.0.0.1/32, 192.168.1.0/24
Endpoint = A的公网IP:51820
PersistentKeepalive = 25
  • 双方都需要配置 AllowedIPs 包含对方的内网网段,这样路由才能正确指向。
  • PostUp 中添加了针对内网网段的 SNAT,确保内网主机访问对方内网时能够返回(如果双方内网没有直接路由,需要做双向 NAT 或配置路由)。

使用命令

启动接口

1
sudo wg-quick up wg0

如果配置文件不在默认路径,可以指定:

1
sudo wg-quick up /path/to/wg0.conf

查看状态

1
sudo wg show
1
2
3
4
5
6
7
8
9
10
interface: wg0
public key: ...
private key: (hidden)
listening port: 51820

peer: ...
endpoint: 203.0.113.5:51820
allowed ips: 10.0.0.2/32
latest handshake: 1 minute, 23 seconds ago
transfer: 1.23 MiB received, 2.45 MiB sent
  • latest handshake 表示最近一次握手时间,如果长时间没有握手或显示 none,说明连接有问题。

关闭接口

1
sudo wg-quick down wg0

设置开机自启

1
sudo systemctl enable wg-quick@wg0

高级配置与优化

  1. 动态 IP 处理:如果服务端使用动态域名(DDNS),可在 Endpoint 中写域名,WireGuard 会定期解析(默认 30 秒)。但注意,如果 IP 改变,客户端需要重新握手,PersistentKeepalive 可以帮助更快地恢复。
  2. MTU 调整:当出现丢包或连接不稳定时,尝试降低 MTU MTU = 1350(某些网络(如 PPPoE)最大 MTU 较小,UDP 包过大被分片或丢弃。)
  3. 多网卡与多 IP:如果服务器有多个公网 IP,可以让 WireGuard 监听所有接口(默认)或指定 IP,ListenPort = 51820
  4. 预共享密钥(可选):为了提高安全性,可以在 [Peer] 中加入 PresharedKey,该密钥通过 wg genpsk 生成

WireGuard 生成二维码

在 Linux 上,通常使用 qrencode 命令

1
2
3
4
5
6
7
8
# Debian/Ubuntu
sudo apt install qrencode

# Arch Linux
sudo pacman -S qrencode

# macOS
brew install qrencode

假设你的 WireGuard 客户端配置文件位于 /etc/wireguard/wg0.conf,你可以直接用 qrencode 将其内容转换成二维码

显示在终端(ASCII 格式)

1
qrencode -t ansiutf8 < /etc/wireguard/wg0.conf

保存为 PNG 图片

1
qrencode -o wg0.png < /etc/wireguard/wg0.conf

直接显示二维码窗口(适用于有图形界面的服务器)

1
qrencode -t PNG -o - < /etc/wireguard/wg0.conf | display

udp2raw

udp2raw 是一个网络工具,通过Raw Socket将UDP数据包伪装成TCP或ICMP流量,主要目的是绕过网络中对UDP协议的屏蔽或限速,提升连接稳定性

WireGuard 默认使用 UDP 协议进行通信。但在某些网络环境下(如公司网络、校园网、部分运营商),UDP 流量可能会被:

  • 完全屏蔽:防火墙直接丢弃 UDP 包
  • 限速(QoS):UDP 优先级被降低,导致丢包严重、延迟高
    项目地址:Releases · wangyu-/udp2raw

工作原理

1
WireGuard Client → udp2raw Client → [伪装成TCP流量] → 防火墙/运营商 → udp2raw Server → WireGuard Server
  1. 客户端:udp2raw 接收本地 WireGuard 发出的 UDP 包,封装成 TCP 或 ICMP 包,发给服务端
  2. 网络传输:看起来是普通 TCP 连接,绕过 UDP 限制
  3. 服务端:udp2raw 解包还原 UDP,转发给本地 WireGuard 服务

udp2raw 还提供:

  • 加密:AES-128-CBC 加密数据
  • 防重放攻击:类似 IPsec 的抗重放窗口
  • 心跳保活:自动检测断开并重连

食用

服务端配置(VPS)

 WireGuard 服务监听 UDP 127.0.0.1:51820,udp2raw 对外暴露 TCP 0.0.0.0:8000

1
2
3
4
5
6
./udp2raw_amd64 -s \
-l 0.0.0.0:8000 \ # 监听外网 TCP 端口
-r 127.0.0.1:51820 \ # 转发到本地 WireGuard UDP 端口
--raw-mode faketcp \ # 伪装成 TCP
-k "your_password" \ # 加密密码(两端一致)
-a # 自动应答,提高稳定性
参数 含义
-s 服务端模式
-l 监听的地址和端口(对外暴露)
-r 转发的目标地址(本机 WireGuard)
–raw-mode 伪装模式:faketcp / icmp / udp
-k 加密密钥,客户端需一致
-a 自动应答握手

客户端配置(本地)

Linux 客户端

1
2
3
4
5
./udp2raw_amd64 -c \
-l 127.0.0.1:51820 \ # 监听本地,WireGuard 连接这个地址
-r 服务器IP:8000 \ # 连接服务端的 udp2raw 端口
--raw-mode faketcp \
-k "your_password"

Windows 客户端

1
2
3
4
5
udp2raw_mp.exe -c \
-l 127.0.0.1:51820 \
-r 服务器IP:8000 \
--raw-mode easyfaketcp \ # easyfaketcp 兼容性更好
-k "your_password"

修改 WireGuard 配置

WireGuard 不再直连远程服务器,而是连本地 udp2raw 客户端

客户端 wg0.conf

1
2
3
4
5
6
[Peer]
PublicKey = 服务端公钥
# Endpoint = 服务器IP:51820 ← 原来的直连,删除或注释
Endpoint = 127.0.0.1:51820 ← 改为连接本机 udp2raw
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

服务端 WireGuard 配置无需修改,udp2raw 只是把流量转给它。

1
2
3
4
5
6
7
# 1. 先启动 udp2raw 服务端
./udp2raw_amd64 -s -l 0.0.0.0:8000 -r 127.0.0.1:51820 --raw-mode faketcp -k "passwd" -a

# 2. 再启动 WireGuard(或已运行则无需操作)
wg-quick up wg0

# 客户端同样先启动 udp2raw,再连接 WireGuard

高级用法:udp2raw + UDPspeeder 串联

同时绕过 UDP 限制 + 加速,可将 udp2raw 与 UDPspeeder 串联

1
WireGuard → UDPspeeder(加冗余纠错)→ udp2raw(伪装TCP)→ 网络

服务端配置示例

1
2
3
4
5
# 第一层:UDPspeeder(加冗余)
./speederv2_amd64 -s -l 127.0.0.1:7776 -r 127.0.0.1:51820 -f2:4 --timeout 1

# 第二层:udp2raw(伪装TCP)
./udp2raw_amd64 -s -l 0.0.0.0:8000 -r 127.0.0.1:7776 -k "passwd" --raw-mode faketcp

注意事项与常见问题

MTU 调整

由于数据包被多次封装,建议降低 MTU 避免分片:

1
2
# WireGuard 配置中
MTU = 1300

服务端需开启 IP 转发

1
2
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p

防火墙放行

确保服务端防火墙允许 udp2raw 监听的 TCP 端口(如 8000)

1
iptables -A INPUT -p tcp --dport 8000 -j ACCEPT

客户端连接失败

  • 查 -k 密码两端是否一致
  • 检查服务端 -l 是否监听了 0.0.0.0(所有接口)而非 127.0.0.1
  • Windows 确认 npcap 已正确安装

`


WireGuard搭建教程和异地组网
https://skilladd.org/2026/04/04/47.WireGuard搭建教程和异地组网/
Author
skilladd
Posted on
April 4, 2026
Licensed under