WireGuard 是一款现代、轻量、高性能的 VPN 协议。本文将介绍如何通过 Docker 部署 wg-easy(WireGuard 的 Web 管理面板),配置客户端分流,并让局域网内的其他设备能够访问 VPN 客户端。
环境说明
- 服务器(WireGuard 宿主机)内网 IP:
192.168.1.23 - 局域网网段:
192.168.1.0/24 - 局域网网关(路由器):
192.168.1.1 - 服务器网卡接口:
brg0(请根据实际情况替换) - VPN 网段:
10.8.0.0/24 - 公网域名:
abc.com
请根据你的实际环境替换上述参数。尤其是网卡接口名,可通过
ip route查看默认路由所使用的接口。
一、安装 Docker 与 Docker Compose
如果服务器尚未安装 Docker,先执行:
curl -fsSL https://get.docker.com | sh
sudo systemctl enable --now docker
Docker Compose 通常随 Docker 一并安装,可用 docker compose version 验证。
二、开启内核转发
WireGuard 需要服务器开启 IP 转发。在宿主机上创建 sysctl 配置文件:
sudo nano /etc/sysctl.d/90-wireguard.conf
写入以下内容:
net.ipv4.ip_forward=1
net.ipv4.conf.all.src_valid_mark=1
net.ipv6.conf.all.disable_ipv6=0
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.forwarding=1
保存后应用:
sudo sysctl -p /etc/sysctl.d/90-wireguard.conf
注意:
net.ipv4.ip_forward=1是必需的,Docker 和 WireGuard 都依赖它。
三、编写 docker-compose.yml
为了让 WireGuard 的 wg0 接口直接出现在宿主机上(便于配置路由和 iptables 规则),采用 network_mode: host 模式。
创建目录并进入:
mkdir -p ~/wg-easy && cd ~/wg-easy
新建 docker-compose.yml:
services:
wg-easy:
image: ghcr.io/wg-easy/wg-easy:15
container_name: wg-easy
network_mode: host
volumes:
- ./wg-easy:/etc/wireguard
- /lib/modules:/lib/modules:ro
environment:
- INSECURE=true
- INIT_ENABLED=true
- INIT_HOST=abc.com
- INIT_PORT=51820
- INIT_IPV4_CIDR=10.8.0.0/24
- INIT_DNS=192.168.1.1,223.5.5.5
- INIT_ALLOWED_IPS=10.0.0.0/8,192.168.1.0/24
- INIT_USERNAME=admin
- INIT_PASSWORD=请设置一个强密码
restart: unless-stopped
cap_add:
- NET_ADMIN
- SYS_MODULE
devices:
- /dev/net/tun:/dev/net/tun
要点说明:
network_mode: host:容器直接使用宿主机网络,wg0接口会在宿主机上创建,iptables 规则和路由都能正常生效。INIT_HOST=abc.com:客户端配置里Endpoint使用的域名,需解析到服务器公网 IP。INIT_IPV4_CIDR=10.8.0.0/24:VPN 内部网段。INIT_ALLOWED_IPS=10.0.0.0/8,192.168.1.0/24:客户端只把发往这两个网段的流量走隧道,其余流量仍走本地网络。这样既实现了分流,也避免了连接 VPN 后本地断网。INIT_DNS:建议使用局域网网关或公共 DNS,避免 DNS 解析走隧道造成延迟。- 生产环境请去掉
INSECURE=true,并配置 HTTPS 反向代理。
四、启动服务
docker compose up -d
查看运行状态:
docker compose ps
sudo wg show
sudo wg show 应能看到 wg0 接口及对端信息。Web 管理面板默认监听 51821 端口,浏览器访问 http://abc.com:51821 即可登录。
五、配置 MASQUERADE(关键步骤)
这一步用于让局域网内的其他设备能够访问 VPN 客户端(10.8.0.X)。
原理:局域网设备访问 10.8.0.X 时,如果服务器不做源地址转换,VPN 客户端的回应包源地址是 10.8.0.X,局域网设备会把它发给默认网关(路由器),而路由器并不认识 10.8.0.0/24,回应包就会丢失。通过在服务器上做 SNAT,把来自 VPN 网段的流量源地址改写为服务器的内网 IP,回应就能正确回到服务器,再被送回隧道。
在宿主机上添加规则(把 brg0 替换为你的实际网卡接口):
用 ip route 或 ip addr 查看 宿主机IP 绑在哪个接口上
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o brg0 -j MASQUERADE
验证规则已添加:
sudo iptables -t nat -L POSTROUTING -n -v --line-numbers
该规则在服务器重启后会丢失。如需持久化,可安装
iptables-persistent:sudo apt install iptables-persistent sudo netfilter-persistent save
六、配置路由器静态路由
在局域网路由器上添加一条静态路由,让去往 VPN 网段的流量交给 WireGuard 服务器:
| 目的地址 | 子网掩码 | 下一跳地址 | 出接口 | 描述 |
|---|---|---|---|---|
| 10.8.0.0 | 255.255.255.0 | 192.168.1.23 | LAN | wireguard |
不同品牌路由器的配置界面略有差异,关键是:目的网段 10.8.0.0/24,下一跳 192.168.1.23。
七、客户端配置
在 wg-easy 面板中新建客户端,下载生成的配置文件。配置文件内容形如:
[Interface]
PrivateKey = <客户端私钥>
Address = 10.8.0.4/32, fdcc:ad94:bacf:61a4::cafe:4/128
MTU = 1420
DNS = 192.168.1.1, 223.5.5.5
[Peer]
PublicKey = <服务器公钥>
PresharedKey = <预共享密钥>
AllowedIPs = 10.0.0.0/8, 192.168.1.0/24
PersistentKeepalive = 0
Endpoint = abc.com:51820
关键点:
AllowedIPs = 10.0.0.0/8, 192.168.1.0/24:只有访问这两个网段的流量走隧道,其余流量走本地网络。不要填写0.0.0.0/0,否则所有流量都会被强制走 VPN,可能导致本地断网。Endpoint使用域名abc.com,需确保该域名解析到服务器的公网 IP。DNS指向局域网网关或公共 DNS,避免解析卡顿。
八、验证
- 客户端连接 VPN:导入配置文件并启用,
sudo wg show应显示握手成功。 - 访问 VPN 内网:在客户端
ping 10.8.0.1(服务器隧道 IP)。 - 局域网访问 VPN 客户端:在
192.168.1.X的设备上ping 10.8.0.4。 - 验证分流:在客户端访问公网网站,确认流量没有走隧道;访问
10.8.0.X和192.168.1.X时走隧道。
如果第 3 步不通,依次检查:
- 服务器
net.ipv4.ip_forward=1是否生效。 - MASQUERADE 规则是否存在且接口名正确。
- 路由器静态路由是否生效(在局域网设备上
tracert 10.8.0.4,第二跳应为192.168.1.23)。
九、总结
通过 Docker 部署 wg-easy 并采用 network_mode: host,可以让 WireGuard 接口直接暴露在宿主机上,便于配置 MASQUERADE 和路由。配合客户端 AllowedIPs 的合理设置,既能实现 VPN 内网访问,又能保持本地网络畅通;再通过服务器 SNAT 和路由器静态路由,即可让整个局域网访问 VPN 客户端。

评论