WireGuard 的本质:工作在三层网络层(L3)的 VPN。它通过虚拟网卡 wg0 接收 IP 包,根据路由和 AllowedIPs 选择 peer,再把原始 IP 包加密封装到 UDP 中发送到对端。

本文档面向下面这个环境:

1
2
3
4
5
6
7
云服务器(有公网 IP)
公网 IP: 1.2.3.4
WireGuard IP: 10.77.0.1

本地服务器(在本地局域网内)
局域网 IP: 192.168.10.2
WireGuard IP: 10.77.0.2

目标是:云服务器和本地服务器通过 WireGuard 加入同一个私有网络,后续可以用 10.77.0.x 互相访问。生产服务器只需要开放一个 WireGuard UDP 端口,不再暴露大量测试服务端口。

适用场景

  • 远程登录生产服务器,但不想把 SSH 暴露给全网。
  • 本地测试环境主动接入生产侧,让开发人员通过 VPN 访问测试服务。
  • 本地局域网和云服务器做 site-to-site 互联。
  • 让本地测试环境的出站流量通过云服务器 NAT 出口。
  • 替代一部分 frp 端口映射和 Squid 出口代理场景。

不适用场景

  • 给不安装 VPN 客户端的外部人员访问测试服务。
  • 需要 HTTP 层缓存、域名级访问控制、代理日志审计。
  • 需要复杂账号体系、Web 管理后台、企业审计。

这些场景可能仍需要 frpSquid、Nginx、Tailscale、OpenVPN 或企业零信任方案。

网络规划

建议单独规划一个 VPN 网段:

1
2
3
4
5
6
WireGuard 网段: 10.77.0.0/24

10.77.0.1 云服务器 / VPN Hub
10.77.0.2 本地服务器 / 本地 VPN 网关
10.77.0.10 开发人员 A
10.77.0.11 开发人员 B

如果本地服务器还要代表整个本地局域网接入 VPN,可继续保留:

1
2
本地局域网: 192.168.10.0/24
本地 VPN 网关: 192.168.10.2

安装

云服务器和本地服务器都安装 WireGuard:

1
2
sudo apt update
sudo apt install -y wireguard

生成密钥:

1
2
3
4
sudo mkdir -p /etc/wireguard
cd /etc/wireguard
sudo wg genkey | sudo tee privatekey | sudo wg pubkey | sudo tee publickey
sudo chmod 600 privatekey

分别记录两台机器的公钥:

1
sudo cat /etc/wireguard/publickey

云服务器配置

编辑云服务器:

1
sudo vim /etc/wireguard/wg0.conf

基础配置:

1
2
3
4
5
6
7
8
[Interface]
Address = 10.77.0.1/24
ListenPort = 51820
PrivateKey = 云服务器私钥

[Peer]
PublicKey = 本地服务器公钥
AllowedIPs = 10.77.0.2/32

如果本地服务器还要作为整个本地局域网的 VPN 网关,让云服务器能访问 192.168.10.0/24,则改成:

1
2
3
[Peer]
PublicKey = 本地服务器公钥
AllowedIPs = 10.77.0.2/32, 192.168.10.0/24

开放云服务器安全组和系统防火墙:

1
sudo ufw allow 51820/udp

如果不用 ufw,就在云厂商安全组中开放:

1
UDP 51820

本地服务器配置

编辑本地服务器:

1
sudo vim /etc/wireguard/wg0.conf

基础配置:

1
2
3
4
5
6
7
8
9
[Interface]
Address = 10.77.0.2/32
PrivateKey = 本地服务器私钥

[Peer]
PublicKey = 云服务器公钥
Endpoint = 1.2.3.4:51820
AllowedIPs = 10.77.0.0/24
PersistentKeepalive = 25

说明:

  • Endpoint 表示本地服务器主动连接云服务器公网地址。
  • AllowedIPs = 10.77.0.0/24 表示访问 VPN 网段时走 WireGuard。
  • PersistentKeepalive = 25 用来保持 NAT 映射,适合本地服务器在路由器后面的情况。

如果希望本地服务器的所有出站流量都通过云服务器出口,可以把本地服务器配置改成:

1
AllowedIPs = 0.0.0.0/0

这个配置会接管默认路由,建议确认路由和 DNS 后再使用。

启动和验证

两端启动:

1
sudo systemctl enable --now wg-quick@wg0

查看状态:

1
2
3
sudo wg show
ip addr show wg0
ip route

本地服务器测试访问云服务器:

1
2
ping 10.77.0.1
ssh user@10.77.0.1

云服务器测试访问本地服务器:

1
2
ping 10.77.0.2
ssh user@10.77.0.2

让本地局域网访问云服务器 VPN 地址

如果本地局域网有多台测试机器,不想每台都安装 WireGuard,可以让本地服务器做 VPN 网关。

本地服务器开启 IP 转发:

1
2
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-wireguard-forward.conf
sudo sysctl --system

在本地路由器上添加静态路由:

1
2
目标网段: 10.77.0.0/24
下一跳: 192.168.10.2

这样本地局域网内机器访问 10.77.0.1 时,会把流量交给本地服务器,再由本地服务器通过 WireGuard 转发到云服务器。

如果不能改路由器,也可以在单台测试机器上加静态路由:

Linux:

1
sudo ip route add 10.77.0.0/24 via 192.168.10.2

Windows:

1
route add 10.77.0.0 mask 255.255.255.0 192.168.10.2 -p

让本地服务器通过云服务器出网

云服务器开启 IP 转发:

1
2
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-wireguard-forward.conf
sudo sysctl --system

云服务器配置 NAT。假设公网网卡是 eth0

1
2
3
sudo iptables -t nat -A POSTROUTING -s 10.77.0.0/24 -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i wg0 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o wg0 -m state --state ESTABLISHED,RELATED -j ACCEPT

本地服务器配置:

1
2
3
4
5
[Peer]
PublicKey = 云服务器公钥
Endpoint = 1.2.3.4:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

验证出口 IP:

1
curl https://ifconfig.me

如果看到的是云服务器公网 IP,说明出口已走云服务器。

防火墙建议

生产侧建议收缩为:

1
2
3
4
允许 UDP 51820
允许正式业务端口 80/443
SSH 只允许 VPN 网段或固定办公 IP
关闭测试服务、数据库、Redis、frp 映射端口公网访问

云服务器上限制测试环境不要访问生产敏感端口:

1
2
sudo iptables -A INPUT -i wg0 -s 10.77.0.2/32 -p tcp --dport 3306 -j DROP
sudo iptables -A INPUT -i wg0 -s 10.77.0.2/32 -p tcp --dport 6379 -j DROP

开发人员建议一人一个 peer:

1
2
3
张三: 10.77.0.10
李四: 10.77.0.11
测试服务器: 10.77.0.2

不要多人共用同一个客户端私钥。

常见问题

wg show 没有 latest handshake

优先检查:

  • 云服务器安全组是否开放 UDP 51820
  • 本地服务器 Endpoint 是否写对。
  • 双方公钥是否配反。
  • 本地服务器是否在 NAT 后面,是否配置 PersistentKeepalive = 25

能握手但 ping 不通

优先检查:

  • AllowedIPs 是否包含目标 IP。
  • 系统路由表是否把目标网段指向 wg0
  • 防火墙是否拦截 wg0 入站。
  • 如果跨网段转发,是否开启 net.ipv4.ip_forward=1

本地局域网机器访问不了 VPN

优先检查:

  • 本地路由器是否有 10.77.0.0/24 via 192.168.10.2
  • 本地服务器是否开启 IP 转发。
  • 云服务器 peer 是否把 192.168.10.0/24 写进 AllowedIPs

参考