15. 服务器配置文件(wg0.conf)
15.1 [Interface]部分
15.1.1 PrivateKey(服务器私钥)
参数说明:
PrivateKey是WireGuard服务器的私钥,用于加密通信和身份验证。这是整个VPN系统安全性的核心。
语法格式:
PrivateKey = <base64编码的私钥>
生成方法:
# 生成私钥
wg genkey | sudo tee /etc/wireguard/server_private.key
# 查看私钥内容
sudo cat /etc/wireguard/server_private.key
输出示例:
8Phv4OQlc88y4o8v0dSPr9loJudYDxqvnzIkK6SnWkQ=
本项目使用的私钥:
PrivateKey = 8Phv4OQlc88y4o8v0dSPr9loJudYDxqvnzIkK6SnWkQ=
安全要求:
- ✅ 私钥必须保密,不能泄露
- ✅ 文件权限必须为600(仅所有者可读写)
- ✅ 不能在公网传输或存储
- ✅ 定期轮换(建议每3-6个月)
- ❌ 不要通过邮件、聊天工具发送
- ❌ 不要提交到Git仓库
权限设置:
# 设置私钥文件权限为600
sudo chmod 600 /etc/wireguard/server_private.key
# 验证权限
ls -l /etc/wireguard/server_private.key
# 输出:-rw------- 1 root root 45 Mar 23 10:00 server_private.key
技术细节:
- 算法:Curve25519椭圆曲线
- 密钥长度:256位(32字节)
- 编码方式:Base64
- 熵要求:需要高质量随机源(/dev/urandom)
私钥泄露后果:
- 攻击者可以冒充服务器
- 可以解密所有历史流量(如果有记录)
- 可以发起中间人攻击
- 整个VPN系统安全性失效
应急处理:
# 1. 立即生成新密钥对
wg genkey | sudo tee /etc/wireguard/server_private_new.key
sudo cat /etc/wireguard/server_private_new.key | wg pubkey | sudo tee /etc/wireguard/server_public_new.key
# 2. 更新配置文件
sudo nano /etc/wireguard/wg0.conf
# 替换PrivateKey为新密钥
# 3. 重启WireGuard
sudo wg-quick down wg0
sudo wg-quick up wg0
# 4. 通知所有客户端更新公钥
15.1.2 Address(虚拟IP地址)
参数说明:
Address定义服务器在VPN虚拟网络中的IP地址和子网掩码。
语法格式:
Address = <IP地址>/<子网掩码位数>
本项目配置:
Address = 10.8.0.1/24
参数解析:
10.8.0.1:服务器虚拟IP地址/24:子网掩码,等价于255.255.255.0- 可用IP范围:10.8.0.1 - 10.8.0.254(共254个可用IP)
- 网络地址:10.8.0.0
- 广播地址:10.8.0.255
子网规划:
| 子网掩码 | CIDR | 可用IP数 | 适用场景 |
|---|---|---|---|
| 255.255.255.252 | /30 | 2 | 点对点连接 |
| 255.255.255.248 | /29 | 6 | 小型团队 |
| 255.255.255.240 | /28 | 14 | 部门级 |
| 255.255.255.224 | /27 | 30 | 中小企业 |
| 255.255.255.192 | /26 | 62 | 中型企业 |
| 255.255.255.128 | /25 | 126 | 大型部门 |
| 255.255.255.0 | /24 | 254 | 企业级(本项目) |
| 255.255.254.0 | /23 | 510 | 大型企业 |
多地址配置:
# 同时配置IPv4和IPv6
Address = 10.8.0.1/24, fd42:42:42::1/64
# 多个IPv4地址
Address = 10.8.0.1/24, 10.9.0.1/24
地址冲突检查:
# 检查地址是否与物理网络冲突
ip route show | grep 10.8.0
# 检查地址是否已被使用
ping -c 1 10.8.0.1
# 查看所有网络接口
ip addr show
修改虚拟网段:
# 如果10.8.0.0/24冲突,可以使用其他私有地址段
# 选项1:10.x.x.x (A类私有地址)
Address = 10.100.0.1/24
# 选项2:172.16.x.x - 172.31.x.x (B类私有地址)
Address = 172.16.0.1/24
# 选项3:192.168.x.x (C类私有地址)
Address = 192.168.100.1/24
⚠️ 重要提示:修改地址后,所有客户端配置也需要同步修改。
15.1.3 ListenPort(UDP端口)
参数说明:
ListenPort指定WireGuard服务器监听的UDP端口号。
语法格式:
ListenPort = <端口号>
本项目配置:
ListenPort = 51820
端口说明:
- 默认端口:51820(WireGuard官方默认)
- 协议:UDP(WireGuard仅使用UDP)
- 范围:1024-65535(推荐使用1024以上端口)
- 用途:接收客户端连接请求和数据包
常用端口选择:
# 默认端口(推荐)
ListenPort = 51820
# 替代端口(避免扫描)
ListenPort = 41194
ListenPort = 58172
ListenPort = 60123
# 伪装成常见服务端口(不推荐)
ListenPort = 53 # DNS
ListenPort = 123 # NTP
ListenPort = 500 # IPsec
💡 建议:生产环境使用非默认端口,降低被扫描风险。
修改端口后的配置:
服务器端:
[Interface]
ListenPort = 41194
客户端对应修改:
[Peer]
Endpoint = 192.168.1.66:41194
端口占用检查:
# 检查端口是否被占用
sudo lsof -i :51820
sudo netstat -ulnp | grep 51820
sudo ss -ulnp | grep 51820
# 查看WireGuard实际监听端口
sudo wg show wg0 | grep "listening port"
防火墙配置:
# 允许WireGuard端口(UDP)
sudo ufw allow 51820/udp
# 如果修改了端口
sudo ufw allow 41194/udp
# 删除旧规则
sudo ufw delete allow 51820/udp
端口转发(NAT环境):
如果服务器在NAT后,需要在路由器配置端口转发:
外部端口:51820 (UDP)
内部IP:192.168.1.66
内部端口:51820 (UDP)
协议:UDP
动态端口(高级):
# 不指定端口,使用随机端口
# ListenPort = 0
# 注意:客户端需要使用Endpoint的实际端口
❌ 不推荐:随机端口不利于防火墙管理和客户端配置。
15.1.4 PostUp(启动后执行)
参数说明:
PostUp定义WireGuard接口启动后自动执行的命令,通常用于配置防火墙规则和路由。
语法格式:
PostUp = <命令1>; <命令2>; <命令3>
本项目配置:
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
命令拆解分析:
命令1:允许转发
iptables -A FORWARD -i wg0 -j ACCEPT
参数说明:
-A FORWARD:添加规则到FORWARD链-i wg0:匹配从wg0接口进入的数据包-j ACCEPT:动作为接受(允许通过)
作用:允许从WireGuard接口(wg0)进入的数据包被转发到其他网络接口。
命令2:NAT地址转换
iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
参数说明:
-t nat:操作nat表-A POSTROUTING:添加规则到POSTROUTING链(路由后)-o pnet0:匹配从pnet0接口出去的数据包-j MASQUERADE:动作为地址伪装(动态SNAT)
作用:将从pnet0接口出去的数据包源地址改为pnet0接口的IP地址。
完整流程示例:
客户端(10.8.0.2)访问互联网(8.8.8.8):
1. 客户端发送数据包:
源IP: 10.8.0.2
目标IP: 8.8.8.8
2. 通过VPN隧道到达服务器wg0接口
3. FORWARD链规则允许转发:
iptables -A FORWARD -i wg0 -j ACCEPT
4. 路由决策:从pnet0接口出去
5. POSTROUTING链进行NAT转换:
源IP: 10.8.0.2 → 192.168.1.66
目标IP: 8.8.8.8
6. 数据包从pnet0发出,源IP已变为服务器IP
常用PostUp命令组合:
基础配置(本项目使用):
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
启用IP转发:
PostUp = sysctl -w net.ipv4.ip_forward=1; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
限制客户端互访:
# 禁止客户端之间互相访问
PostUp = iptables -A FORWARD -i wg0 -o wg0 -j DROP; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
仅允许访问特定服务:
# 仅允许访问服务器的80和443端口
PostUp = iptables -A FORWARD -i wg0 -p tcp --dport 80 -j ACCEPT; iptables -A FORWARD -i wg0 -p tcp --dport 443 -j ACCEPT; iptables -A FORWARD -i wg0 -j DROP
IPv6支持:
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
DNS转发:
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE; iptables -t nat -A PREROUTING -i wg0 -p udp --dport 53 -j DNAT --to-destination 8.8.8.8
调试模式(记录日志):
PostUp = iptables -A FORWARD -i wg0 -j LOG --log-prefix "WG-FORWARD: "; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
查看日志:
sudo dmesg | grep "WG-FORWARD"
sudo journalctl -k | grep "WG-FORWARD"
多行写法(便于阅读):
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
PostUp = echo "WireGuard started at $(date)" >> /var/log/wireguard.log
💡 提示:%i会被自动替换为接口名(wg0)。
执行外部脚本:
# 创建脚本
sudo nano /etc/wireguard/postup.sh
脚本内容:
#!/bin/bash
# WireGuard启动后脚本
# 配置防火墙
iptables -A FORWARD -i wg0 -j ACCEPT
iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
# 记录日志
echo "[$(date)] WireGuard interface wg0 started" >> /var/log/wireguard.log
# 发送通知(可选)
# curl -X POST https://api.example.com/notify -d "WireGuard started"
设置权限:
sudo chmod +x /etc/wireguard/postup.sh
配置文件中引用:
PostUp = /etc/wireguard/postup.sh
常见错误处理:
错误1:命令未找到
Error: bash: iptables: command not found
解决:安装iptables
sudo apt install iptables
错误2:权限不足
Error: iptables: Permission denied
解决:确保wg-quick以root权限运行
sudo wg-quick up wg0
错误3:接口名错误
Error: RTNETLINK answers: Cannot assign requested address
解决:检查接口名是否正确(pnet0、eth0等)
15.1.5 PostDown(关闭前执行)
参数说明:
PostDown定义WireGuard接口关闭前自动执行的命令,通常用于清理PostUp添加的防火墙规则。
语法格式:
PostDown = <命令1>; <命令2>; <命令3>
本项目配置:
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o pnet0 -j MASQUERADE
命令解析:
与PostUp对应,使用-D(Delete)删除规则:
# 删除FORWARD规则
iptables -D FORWARD -i wg0 -j ACCEPT
# 删除NAT规则
iptables -t nat -D POSTROUTING -o pnet0 -j MASQUERADE
为什么需要PostDown:
- 清理规则:避免规则累积(多次启动)
- 释放资源:停止不必要的防火墙规则
- 安全考虑:关闭VPN后不应继续转发流量
- 避免冲突:防止规则冲突导致网络问题
PostUp/PostDown配对原则:
✅ 正确配对:
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
❌ 错误配对:
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostDown = iptables -F FORWARD # 会删除所有FORWARD规则,影响其他服务
完整配对示例:
# 示例1:基础配置
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o pnet0 -j MASQUERADE
# 示例2:包含IP转发
PostUp = sysctl -w net.ipv4.ip_forward=1; iptables -A FORWARD -i %i -j ACCEPT
PostDown = sysctl -w net.ipv4.ip_forward=0; iptables -D FORWARD -i %i -j ACCEPT
# 示例3:多条规则
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
PostUp = iptables -A INPUT -i %i -p udp --dport 53 -j ACCEPT
PostDown = iptables -D FORWARD -i %i -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o pnet0 -j MASQUERADE
PostDown = iptables -D INPUT -i %i -p udp --dport 53 -j ACCEPT
使用脚本清理:
创建清理脚本:
sudo nano /etc/wireguard/postdown.sh
脚本内容:
#!/bin/bash
# WireGuard关闭前脚本
# 删除防火墙规则
iptables -D FORWARD -i wg0 -j ACCEPT 2>/dev/null
iptables -t nat -D POSTROUTING -o pnet0 -j MASQUERADE 2>/dev/null
# 记录日志
echo "[$(date)] WireGuard interface wg0 stopped" >> /var/log/wireguard.log
配置文件:
PostDown = /etc/wireguard/postdown.sh
验证清理是否成功:
# 启动前查看规则
sudo iptables -L FORWARD -n -v
sudo iptables -t nat -L POSTROUTING -n -v
# 启动WireGuard
sudo wg-quick up wg0
# 再次查看规则(应该增加)
sudo iptables -L FORWARD -n -v
# 停止WireGuard
sudo wg-quick down wg0
# 最后查看规则(应该恢复原状)
sudo iptables -L FORWARD -n -v
15.1.6 MTU(最大传输单元)
参数说明:
MTU(Maximum Transmission Unit)定义通过WireGuard接口传输的数据包的最大大小。
语法格式:
MTU = <字节数>
推荐配置:
MTU = 1420
MTU值计算:
标准以太网MTU:1500字节
WireGuard开销:
- IPv4头部:20字节
- UDP头部:8字节
- WireGuard头部:32字节
- 对齐填充:20字节
- 总开销:80字节
最优MTU = 1500 - 80 = 1420字节
不同场景的MTU值:
| 场景 | MTU值 | 说明 |
|---|---|---|
| 标准以太网 | 1420 | 推荐值 |
| PPPoE | 1412 | PPPoE额外8字节开销 |
| IPv6 | 1400 | IPv6头部更大 |
| 移动网络 | 1280 | 兼容性最好 |
| 巨型帧 | 8920 | 需要底层支持 |
测试最优MTU:
# 从客户端测试到服务器
# Windows
ping 192.168.1.66 -f -l 1472
# 1472 + 28 (IP+ICMP头) = 1500
# Linux
ping -M do -s 1472 192.168.1.66
# 如果成功,MTU够用
# 如果失败,降低数值重试
# 测试WireGuard隧道MTU
ping -M do -s 1392 10.8.0.1
# 1392 + 28 = 1420
MTU不匹配的症状:
- 网页加载缓慢或卡顿
- SSH连接建立后无响应
- 大文件传输失败
- 部分网站无法访问
修复MTU问题:
# 方法1:降低MTU(最简单)
sudo ip link set dev wg0 mtu 1280
# 方法2:在配置文件中设置
echo "MTU = 1280" | sudo tee -a /etc/wireguard/wg0.conf
# 方法3:启用MSS钳制(TCP)
iptables -t mangle -A FORWARD -i wg0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
客户端MTU配置:
客户端配置文件也需要设置相同MTU:
[Interface]
MTU = 1420
动态MTU发现(高级):
# 不设置MTU,让系统自动协商
# MTU = 0
# 或使用路径MTU发现
PostUp = ip link set dev %i mtu 1420; iptables -t mangle -A FORWARD -i %i -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
⚠️ 注意:过小的MTU会增加开销,过大的MTU会导致分片,都会影响性能。
15.2 [Peer]部分
15.2.1 PublicKey(客户端公钥)
参数说明:
PublicKey是客户端的公钥,用于服务器验证客户端身份。
语法格式:
PublicKey = <base64编码的公钥>
生成流程:
客户端生成密钥对:
# 生成私钥
wg genkey | tee client_private.key
# 从私钥派生公钥
cat client_private.key | wg pubkey > client_public.key
# 查看公钥
cat client_public.key
本项目使用的客户端公钥:
PublicKey = QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
服务器配置:
[Peer]
PublicKey = QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
AllowedIPs = 10.8.0.2/32
多客户端配置:
# 客户端1
[Peer]
PublicKey = QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
AllowedIPs = 10.8.0.2/32
# 客户端2
[Peer]
PublicKey = XyZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabc=
AllowedIPs = 10.8.0.3/32
# 客户端3
[Peer]
PublicKey = AbC9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyx=
AllowedIPs = 10.8.0.4/32
公钥管理最佳实践:
创建密钥管理表:
# 创建密钥记录文件
sudo nano /etc/wireguard/keys.txt
内容示例:
# WireGuard密钥管理表
# 日期 用户名 IP地址 公钥 状态
2025-03-23 user1 10.8.0.2 QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4= 活跃
2025-03-23 user2 10.8.0.3 XyZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabc= 活跃
2025-03-20 user3 10.8.0.4 AbC9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyx= 禁用
撤销客户端访问:
# 方法1:从配置文件删除Peer段
sudo nano /etc/wireguard/wg0.conf
# 删除对应的[Peer]块
# 重新加载配置
sudo wg syncconf wg0 <(wg-quick strip wg0)
# 方法2:动态删除(临时)
sudo wg set wg0 peer <公钥> remove
验证公钥:
# 查看当前所有peer
sudo wg show wg0 peers
# 查看特定peer的详细信息
sudo wg show wg0 peer QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
公钥格式验证:
有效公钥特征:
- 长度:44个字符(Base64编码的32字节)
- 字符集:A-Z, a-z, 0-9, +, /
- 结尾:通常是=或==
- 示例:
QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
15.2.2 AllowedIPs(允许的IP)
参数说明:
AllowedIPs定义该客户端允许使用的IP地址范围,同时也是路由策略。
语法格式:
AllowedIPs = <IP地址/掩码>, <IP地址/掩码>, ...
本项目配置:
AllowedIPs = 10.8.0.2/32
参数解析:
10.8.0.2:客户端的虚拟IP地址/32:单个IP(255.255.255.255)
作用双重性:
- 身份验证:只接受来自该IP的数据包
- 路由策略:将目标地址为该IP的数据包发送给此peer
常用配置模式:
模式1:单个IP(最严格)
[Peer]
PublicKey = QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
AllowedIPs = 10.8.0.2/32
- 客户端只能使用10.8.0.2
- 来自其他IP的数据包会被拒绝
模式2:子网(客户端作为网关)
[Peer]
PublicKey = XyZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabc=
AllowedIPs = 10.8.0.0/24, 192.168.100.0/24
- 客户端可以转发整个子网
- 适用于站点到站点VPN
模式3:全流量(0.0.0.0/0)
[Peer]
PublicKey = AbC9876543210ZYXWVUTSRQPONMLKJIHGFEDCBAzyx=
AllowedIPs = 0.0.0.0/0
- 接受所有IP地址
- ⚠️ 安全风险:客户端可以伪造任何源IP
模式4:多个不连续IP
[Peer]
PublicKey = DefGhi789...
AllowedIPs = 10.8.0.5/32, 10.8.0.10/32, 10.8.0.15/32
- 客户端可以使用多个虚拟IP
- 适用于高可用场景
安全建议:
✅ 推荐做法:
# 每个客户端使用唯一的/32地址
[Peer]
PublicKey = ...
AllowedIPs = 10.8.0.2/32
[Peer]
PublicKey = ...
AllowedIPs = 10.8.0.3/32
❌ 不推荐做法:
# 多个客户端共享同一个AllowedIPs
[Peer]
PublicKey = client1_pubkey
AllowedIPs = 10.8.0.0/24 # 太宽泛
[Peer]
PublicKey = client2_pubkey
AllowedIPs = 10.8.0.0/24 # 与上面冲突
测试AllowedIPs:
# 服务器端查看peer配置
sudo wg show wg0 allowed-ips
# 客户端尝试使用错误IP
# 会被服务器拒绝,无法通信
动态修改AllowedIPs:
# 临时修改(重启后失效)
sudo wg set wg0 peer <公钥> allowed-ips 10.8.0.2/32,10.8.0.100/32
# 永久修改
sudo nano /etc/wireguard/wg0.conf
# 修改AllowedIPs
sudo wg syncconf wg0 <(wg-quick strip wg0)
15.2.3 Endpoint(客户端地址,可选)
参数说明:
Endpoint指定客户端的公网IP地址和端口,用于服务器主动连接客户端。
语法格式:
Endpoint = <IP地址或域名>:<端口>
使用场景:
- 站点到站点VPN:两端都是固定IP
- 服务器在NAT后:需要客户端主动连接
- 对等连接:双向通信需求
配置示例:
# 客户端有固定公网IP
[Peer]
PublicKey = QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
AllowedIPs = 10.8.0.2/32
Endpoint = 203.0.113.10:51820
# 客户端有动态IP(常见情况)
[Peer]
PublicKey = QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
AllowedIPs = 10.8.0.2/32
# 不设置Endpoint,等待客户端连接
本项目配置:
服务器端不设置Endpoint(客户端主动连接):
[Peer]
PublicKey = QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
AllowedIPs = 10.8.0.2/32
# 无Endpoint配置
WireGuard的智能路由:
- 客户端第一次连接时,服务器自动学习客户端IP
- 后续通信自动使用学到的IP
- 即使不配置Endpoint也能正常工作
查看实际Endpoint:
# 服务器端查看客户端实际地址
sudo wg show wg0 endpoints
# 输出示例
# QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4= 192.168.1.100:54231
使用域名:
# 使用DDNS域名(动态IP)
[Peer]
PublicKey = ...
AllowedIPs = 10.8.0.2/32
Endpoint = client.example.com:51820
💡 提示:域名会定期解析,适合动态IP客户端。
Endpoint更新频率:
# 设置PersistentKeepalive强制更新
[Peer]
PublicKey = ...
AllowedIPs = 10.8.0.2/32
Endpoint = 203.0.113.10:51820
PersistentKeepalive = 25
15.3 多客户端配置示例
15.3.1 标准多客户端配置
完整配置文件:
[Interface]
PrivateKey = 8Phv4OQlc88y4o8v0dSPr9loJudYDxqvnzIkK6SnWkQ=
Address = 10.8.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o pnet0 -j MASQUERADE
# 客户端1:Windows用户
[Peer]
PublicKey = QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
AllowedIPs = 10.8.0.2/32
# 客户端2:Linux用户
[Peer]
PublicKey = AbC1234567890XYZabcdefghijklmnopqrstuvwxyz=
AllowedIPs = 10.8.0.3/32
# 客户端3:移动设备
[Peer]
PublicKey = MobileDevicePublicKey1234567890ABCDEFGH=
AllowedIPs = 10.8.0.4/32
# 客户端4:Mac用户
[Peer]
PublicKey = MacUserPublicKey9876543210ZYXWVUTSRQPo=
AllowedIPs = 10.8.0.5/32
# 客户端5:远程办公室(站点到站点)
[Peer]
PublicKey = RemoteOfficeGateway123456789ABC=
AllowedIPs = 10.8.0.10/32, 192.168.100.0/24
Endpoint = 203.0.113.20:51820
15.3.2 按用户组织配置
添加注释便于管理:
[Interface]
PrivateKey = 8Phv4OQlc88y4o8v0dSPr9loJudYDxqvnzIkK6SnWkQ=
Address = 10.8.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o pnet0 -j MASQUERADE
# ==================== 管理员 ====================
# 用户:admin1
# 设备:MacBook Pro
# 添加日期:2025-03-01
[Peer]
PublicKey = AdminPublicKey123456789...
AllowedIPs = 10.8.0.2/32
# ==================== 开发团队 ====================
# 用户:developer1
# 设备:Ubuntu 22.04
# 添加日期:2025-03-10
[Peer]
PublicKey = DevPublicKey1234567890...
AllowedIPs = 10.8.0.10/32
# 用户:developer2
# 设备:Windows 11
# 添加日期:2025-03-11
[Peer]
PublicKey = DevPublicKey2345678901...
AllowedIPs = 10.8.0.11/32
# ==================== 远程办公 ====================
# 用户:remote_worker1
# 设备:iPhone
# 添加日期:2025-03-15
[Peer]
PublicKey = MobilePublicKey3456789012...
AllowedIPs = 10.8.0.20/32
15.3.3 客户端管理脚本
添加客户端脚本:
#!/bin/bash
# 添加新客户端到WireGuard配置
# 配置文件路径
CONFIG_FILE="/etc/wireguard/wg0.conf"
# 检查参数
if [ $# -ne 3 ]; then
echo "使用方法: $0 <用户名> <IP地址> <公钥>"
echo "示例: $0 user1 10.8.0.100 QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4="
exit 1
fi
USERNAME=$1
IP_ADDRESS=$2
PUBLIC_KEY=$3
# 添加peer配置
cat >> $CONFIG_FILE << EOF
# 用户:${USERNAME}
# 添加日期:$(date +%Y-%m-%d)
[Peer]
PublicKey = ${PUBLIC_KEY}
AllowedIPs = ${IP_ADDRESS}/32
EOF
echo "✅ 客户端 ${USERNAME} 添加成功"
echo "IP地址: ${IP_ADDRESS}"
# 重新加载配置
wg syncconf wg0 <(wg-quick strip wg0)
echo "✅ 配置已重新加载"
# 显示当前peer列表
echo ""
echo "当前所有客户端:"
wg show wg0 peers
使用方法:
sudo ./add-client.sh user1 10.8.0.100 QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
15.4 完整注释版配置
生产环境配置模板:
#######################################
# WireGuard服务器配置文件
#
# 服务器:192.168.1.66
# VPN网段:10.8.0.0/24
# 创建日期:2025-03-23
# 维护人员:谢北然
#######################################
[Interface]
# 服务器私钥(严格保密)
# 生成命令:wg genkey
PrivateKey = 8Phv4OQlc88y4o8v0dSPr9loJudYDxqvnzIkK6SnWkQ=
# 服务器虚拟IP地址
# 网段:10.8.0.0/24
# 可用IP:10.8.0.1 - 10.8.0.254
Address = 10.8.0.1/24
# UDP监听端口
# 默认:51820
# 协议:仅UDP
ListenPort = 51820
# MTU(最大传输单元)
# 推荐值:1420
# 计算:1500(以太网MTU) - 80(WireGuard开销) = 1420
MTU = 1420
# 启动后执行的命令
# 功能:配置防火墙规则和NAT
# 规则1:允许wg0接口流量转发
# 规则2:对pnet0出口流量进行SNAT
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
# 关闭前执行的命令
# 功能:清理PostUp添加的规则
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o pnet0 -j MASQUERADE
#######################################
# 客户端配置列表
#######################################
# ============ 客户端1 ============
# 用户名:user1
# 设备:Windows 10
# IP地址:10.8.0.2
# 添加日期:2025-03-23
# 状态:活跃
[Peer]
# 客户端公钥
PublicKey = QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
# 允许的IP地址
# /32表示单个IP
# 作用:路由策略 + 身份验证
AllowedIPs = 10.8.0.2/32
# 客户端地址(可选)
# 适用场景:客户端有固定IP
# 本配置:不设置,等待客户端主动连接
# Endpoint = 203.0.113.10:51820
# 保活间隔(秒)
# 作用:维持NAT映射
# 推荐值:25秒
# 0 = 禁用
# PersistentKeepalive = 25
# ============ 客户端2(示例)============
# [Peer]
# PublicKey = <客户端2的公钥>
# AllowedIPs = 10.8.0.3/32
#######################################
# 配置说明
#######################################
#
# 修改配置后重新加载:
# sudo wg syncconf wg0 <(wg-quick strip wg0)
#
# 完全重启WireGuard:
# sudo wg-quick down wg0
# sudo wg-quick up wg0
#
# 查看运行状态:
# sudo wg show wg0
#
# 查看详细信息:
# sudo wg show wg0 dump
#######################################
16. 客户端配置文件详解
16.1 配置文件结构
16.1.1 基本结构
WireGuard客户端配置文件采用INI格式,包含两个主要部分:
[Interface]
# 客户端接口配置
PrivateKey = <客户端私钥>
Address = <客户端虚拟IP>
DNS = <DNS服务器>
[Peer]
# 服务器配置
PublicKey = <服务器公钥>
Endpoint = <服务器地址:端口>
AllowedIPs = <路由规则>
PersistentKeepalive = <保活间隔>
16.1.2 文件命名规范
Windows系统:
- 位置:任意位置(建议桌面或文档文件夹)
- 命名:
<配置名称>.conf - 示例:
wg-client.conf、office-vpn.conf、home-vpn.conf
Linux/macOS系统:
- 位置:
/etc/wireguard/ - 命名:
<接口名>.conf - 示例:
/etc/wireguard/wg0.conf、/etc/wireguard/wg-client.conf
权限要求(Linux/macOS):
# 设置配置文件权限
sudo chmod 600 /etc/wireguard/wg-client.conf
# 设置所有者
sudo chown root:root /etc/wireguard/wg-client.conf
# 验证权限
ls -l /etc/wireguard/wg-client.conf
# 输出:-rw------- 1 root root 456 Mar 23 10:00 wg-client.conf
16.1.3 编码格式
字符编码:
- 推荐:UTF-8
- 兼容:ASCII
- 禁止:UTF-16、GBK、GB2312
行尾格式:
- Linux/macOS:LF(\n)
- Windows:CRLF(\r\n)或LF
- 推荐:统一使用LF
创建配置文件:
Windows(记事本):
1. 打开记事本
2. 粘贴配置内容
3. 文件 → 另存为
4. 文件名:wg-client.conf
5. 编码:UTF-8
6. 保存
Linux(nano):
sudo nano /etc/wireguard/wg-client.conf
# 粘贴配置内容
# Ctrl+X → Y → Enter
16.2 [Interface]部分
16.2.1 PrivateKey(客户端私钥)
参数说明:
客户端的私钥,用于身份验证和数据加密。
语法格式:
PrivateKey = <base64编码的私钥>
生成方法:
Windows(PowerShell):
# 使用WireGuard自带工具
cd "C:\Program Files\WireGuard"
.\wg.exe genkey
Linux/macOS:
# 生成私钥
wg genkey
# 生成并保存到文件
wg genkey | tee client_private.key
# 从私钥生成公钥
cat client_private.key | wg pubkey | tee client_public.key
在线生成(不推荐):
# 一条命令生成密钥对
wg genkey | tee client_private.key | wg pubkey > client_public.key
# 查看私钥
cat client_private.key
# 查看公钥
cat client_public.key
本项目客户端私钥:
PrivateKey = eKX7A+ZxHanItaMVdEIwB3ENUZpQhX0VdPCL1CCWCmE=
对应公钥:
QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
安全注意事项:
✅ 必须做到:
- 每个客户端使用独立的密钥对
- 私钥仅存储在客户端设备
- 配置文件加密存储(如使用BitLocker、FileVault)
- 定期更换密钥(建议6个月)
❌ 绝对禁止:
- 多个客户端共享同一私钥
- 通过非加密方式传输私钥
- 将私钥存储在云盘或Git仓库
- 在不安全的设备上生成密钥
密钥泄露应急处理:
# 1. 立即在服务器端删除该客户端
sudo nano /etc/wireguard/wg0.conf
# 删除对应的[Peer]段
# 2. 重新加载服务器配置
sudo wg syncconf wg0 <(wg-quick strip wg0)
# 3. 客户端生成新密钥对
wg genkey | tee new_private.key | wg pubkey > new_public.key
# 4. 提交新公钥给管理员重新添加
16.2.2 Address(客户端虚拟IP)
参数说明:
客户端在VPN虚拟网络中的IP地址。
语法格式:
Address = <IP地址>/<子网掩码>
本项目配置:
Address = 10.8.0.2/24
参数解析:
10.8.0.2:客户端虚拟IP/24:子网掩码(255.255.255.0)- 与服务器同一网段(10.8.0.0/24)
为什么使用/24而不是/32:
# 方式1:使用/24(推荐)
Address = 10.8.0.2/24
# 优点:可以直接访问同网段其他客户端
# 缺点:需要服务器允许客户端互访
# 方式2:使用/32
Address = 10.8.0.2/32
# 优点:更严格的隔离
# 缺点:无法直接访问其他客户端
💡 建议:使用/24以获得更好的网络连通性。
IP地址分配规则:
必须与服务器配置的AllowedIPs匹配:
服务器配置:
[Peer]
PublicKey = <客户端公钥>
AllowedIPs = 10.8.0.2/32 # 只允许使用10.8.0.2
客户端配置:
Address = 10.8.0.2/24 # 必须使用10.8.0.2
IPv4+IPv6双栈配置:
Address = 10.8.0.2/24, fd42:42:42::2/64
多IP配置(高级):
# 客户端使用多个虚拟IP
Address = 10.8.0.2/24, 10.8.1.2/24
常见错误:
❌ 错误1:IP地址冲突
# 两个客户端使用相同IP
# 客户端A:Address = 10.8.0.2/24
# 客户端B:Address = 10.8.0.2/24
# 结果:网络冲突,连接不稳定
❌ 错误2:IP不在允许范围
# 服务器:AllowedIPs = 10.8.0.2/32
# 客户端:Address = 10.8.0.3/24
# 结果:服务器拒绝连接
❌ 错误3:子网掩码错误
# 错误配置
Address = 10.8.0.2/32
# 可能导致无法访问其他IP
验证IP配置:
Windows(连接后):
# 查看WireGuard接口IP
ipconfig /all | Select-String -Pattern "WireGuard"
# 测试连通性
ping 10.8.0.1
Linux/macOS:
# 查看接口IP
ip addr show wg0
# 测试连通性
ping -c 4 10.8.0.1
16.2.3 DNS(DNS服务器)
参数说明:
指定通过VPN隧道使用的DNS服务器。
语法格式:
DNS = <DNS服务器IP>, <备用DNS>
推荐配置:
方案1:使用公共DNS(推荐)
# 阿里云DNS
DNS = 223.5.5.5, 223.6.6.6
# Google DNS
DNS = 8.8.8.8, 8.8.4.4
# Cloudflare DNS
DNS = 1.1.1.1, 1.0.0.1
# 组合使用
DNS = 223.5.5.5, 8.8.8.8
方案2:使用内网DNS
# 企业内网DNS服务器
DNS = 192.168.1.1
# VPN服务器作为DNS
DNS = 10.8.0.1
方案3:不设置DNS
# 不配置DNS选项
# 使用系统默认DNS
本项目推荐配置:
DNS = 223.5.5.5, 114.114.114.114
DNS工作原理:
1. 客户端激活VPN
2. WireGuard修改系统DNS设置
3. 所有DNS查询通过指定的DNS服务器
4. DNS查询流量经过VPN加密隧道
5. 断开VPN后恢复原DNS设置
DNS泄露问题:
DNS泄露指DNS查询未经过VPN,暴露访问记录。
检测DNS泄露:
# 方法1:命令行检测
nslookup www.baidu.com
# 方法2:在线检测
# 访问 https://dnsleaktest.com
# 访问 https://ipleak.net
防止DNS泄露:
Windows:
# 配置文件中设置DNS
DNS = 223.5.5.5, 114.114.114.114
# 禁用IPv6(如果不使用)
# 控制面板 → 网络适配器 → WireGuard → 属性 → 取消勾选IPv6
Linux:
# 配置文件
DNS = 223.5.5.5, 114.114.114.114
# 禁用systemd-resolved DNS泄露
sudo nano /etc/systemd/resolved.conf
# 添加配置
[Resolve]
DNSStubListener=no
# 重启服务
sudo systemctl restart systemd-resolved
条件DNS配置(高级):
# 仅对特定域名使用VPN DNS
DNS = 10.8.0.1
# 注:需要配合dnsmasq等工具实现
DNS性能测试:
# 测试DNS解析速度
dig www.baidu.com @223.5.5.5
dig www.google.com @8.8.8.8
# 测试多个DNS服务器
for dns in 223.5.5.5 8.8.8.8 1.1.1.1; do
echo "Testing $dns:"
time nslookup www.baidu.com $dns
done
常见问题:
问题1:DNS无法解析
症状:网络连通,但无法访问域名
原因:DNS配置错误或DNS服务器不可达
解决:
1. 检查DNS配置是否正确
2. 测试DNS服务器连通性:ping 223.5.5.5
3. 尝试更换DNS服务器
问题2:DNS劫持
症状:某些域名解析到错误IP
原因:ISP或中间路由劫持DNS
解决:
1. 使用加密DNS(DoH/DoT)
2. 更换可靠的DNS服务器
3. 启用DNSSEC验证
问题3:分流DNS
需求:国内域名用国内DNS,国外域名用国外DNS
解决:使用smartdns或dnsmasq配置分流规则
16.3 [Peer]部分
16.3.1 PublicKey(服务器公钥)
参数说明:
服务器的公钥,用于客户端验证服务器身份并建立加密隧道。
语法格式:
PublicKey = <base64编码的公钥>
获取服务器公钥:
服务器端执行:
# 方法1:从私钥派生
sudo cat /etc/wireguard/server_private.key | wg pubkey
# 方法2:查看公钥文件
sudo cat /etc/wireguard/server_public.key
# 方法3:从运行中的接口获取
sudo wg show wg0 public-key
本项目服务器公钥:
PublicKey = rUEB9pR7DO7qgkbo6Ylerrh/Fvl1XA8RJuALBdlkFkk=
客户端配置:
[Peer]
PublicKey = rUEB9pR7DO7qgkbo6Ylerrh/Fvl1XA8RJuALBdlkFkk=
Endpoint = 192.168.1.66:51820
AllowedIPs = 0.0.0.0/0
公钥验证:
客户端连接时,WireGuard会:
- 使用服务器公钥加密数据
- 验证服务器响应的签名
- 确保连接到正确的服务器
- 防止中间人攻击
公钥变更处理:
服务器更换密钥后,所有客户端必须更新配置:
# 旧配置
[Peer]
PublicKey = OLD_SERVER_PUBLIC_KEY
# 新配置
[Peer]
PublicKey = NEW_SERVER_PUBLIC_KEY
安全建议:
✅ 通过安全渠道获取公钥:
- 面对面交换
- 加密邮件
- 安全聊天工具(Signal、Telegram)
- 公司内网下载
❌ 不安全的获取方式:
- 普通邮件
- 未加密的网站
- 公共论坛
- 社交媒体
公钥指纹验证(高级):
生成公钥指纹:
# 服务器端生成指纹
echo "rUEB9pR7DO7qgkbo6Ylerrh/Fvl1XA8RJuALBdlkFkk=" | base64 -d | sha256sum
# 客户端验证指纹
echo "<收到的公钥>" | base64 -d | sha256sum
# 对比两个指纹是否一致
16.3.2 Endpoint(服务器地址)
参数说明:
服务器的公网IP地址(或域名)和端口号。
语法格式:
Endpoint = <IP地址或域名>:<端口>
本项目配置:
Endpoint = 192.168.1.66:51820
配置示例:
使用IP地址:
# 公网固定IP
Endpoint = 203.0.113.10:51820
# 内网IP(局域网环境)
Endpoint = 192.168.1.66:51820
# IPv6地址
Endpoint = [2001:db8::1]:51820
使用域名:
# 固定域名
Endpoint = vpn.example.com:51820
# DDNS动态域名
Endpoint = home.ddns.net:51820
# 子域名
Endpoint = wg.company.internal:51820
端口说明:
- 默认:51820(与服务器ListenPort对应)
- 可修改:任意UDP端口(1024-65535)
- 必须与服务器配置一致
网络环境适配:
场景1:服务器有公网IP
# 直接使用公网IP
Endpoint = 203.0.113.10:51820
场景2:服务器在路由器后(NAT)
# 使用路由器公网IP
Endpoint = 203.0.113.10:51820
# 路由器需配置端口转发:
# 外部端口:51820 (UDP)
# 内部IP:192.168.1.66
# 内部端口:51820 (UDP)
场景3:服务器有动态公网IP
# 使用DDNS域名
Endpoint = myhome.ddns.net:51820
# 推荐DDNS服务:
# - No-IP (https://www.noip.com)
# - DynDNS (https://dyn.com)
# - 花生壳 (https://hsk.oray.com)
场景4:局域网直连(本项目)
# 使用内网IP
Endpoint = 192.168.1.66:51820
# 适用场景:
# - 客户端和服务器在同一局域网
# - 企业内网环境
# - 测试开发环境
Endpoint解析机制:
WireGuard对域名的处理:
- 连接时解析域名为IP地址
- 使用解析到的IP建立连接
- 定期重新解析域名(检测IP变化)
- IP变化时自动切换到新IP
多Endpoint支持(实验性):
# WireGuard不直接支持多Endpoint
# 但可以使用脚本切换
# endpoint1.conf
Endpoint = server1.example.com:51820
# endpoint2.conf
Endpoint = server2.example.com:51820
切换脚本:
#!/bin/bash
# 在多个Endpoint之间切换
wg set wg0 peer <服务器公钥> endpoint server1.example.com:51820
# 或
wg set wg0 peer <服务器公钥> endpoint server2.example.com:51820
Endpoint故障排查:
# 测试服务器连通性
ping 192.168.1.66
# 测试UDP端口(需要nc工具)
nc -u -v 192.168.1.66 51820
# Windows测试(PowerShell)
Test-NetConnection -ComputerName 192.168.1.66 -Port 51820
# 检查DNS解析(域名方式)
nslookup vpn.example.com
动态修改Endpoint:
# Linux/macOS临时修改
sudo wg set wg0 peer <服务器公钥> endpoint 192.168.1.66:51820
# Windows(管理员PowerShell)
cd "C:\Program Files\WireGuard"
.\wg.exe set wg0 peer <服务器公钥> endpoint 192.168.1.66:51820
16.3.3 AllowedIPs(路由规则)
参数说明:
定义哪些流量通过VPN隧道,是客户端最重要的配置参数。
语法格式:
AllowedIPs = <IP地址/掩码>, <IP地址/掩码>, ...
核心作用:
- 路由决策:匹配目标IP的数据包走VPN
- 加密策略:决定哪些流量需要加密
- 访问控制:限制可访问的网络范围
常用配置模式:
模式1:全流量模式(Full Tunnel)
AllowedIPs = 0.0.0.0/0, ::/0
特点:
- ✅ 所有流量都经过VPN
- ✅ 最大安全性和隐私保护
- ✅ 防止DNS泄露
- ❌ VPN断开时无网络(除非配置例外)
- ❌ 服务器带宽压力大
- ❌ 延迟较高(所有流量绕道)
适用场景:
- 公共WiFi环境
- 高安全性要求
- 需要更换出口IP
- 绕过网络限制
模式2:分流模式(Split Tunnel,推荐)
AllowedIPs = 10.8.0.0/24
特点:
- ✅ 仅VPN网段流量走隧道
- ✅ 其他流量直连,速度快
- ✅ 节省服务器带宽
- ❌ 非VPN流量未加密
- ❌ 可能存在DNS泄露
适用场景:
- 访问内网资源
- 办公环境
- 长期使用VPN
模式3:多网段访问
AllowedIPs = 10.8.0.0/24, 192.168.100.0/24, 172.16.0.0/16
特点:
- ✅ 访问多个内网网段
- ✅ 灵活控制流量路由
- ✅ 保持其他流量直连
适用场景:
- 站点到站点VPN
- 访问多个分支机构
- 企业复杂网络环境
模式4:特定服务
AllowedIPs = 192.168.1.10/32, 192.168.1.20/32
特点:
- ✅ 仅访问特定服务器
- ✅ 精确控制访问范围
- ✅ 最小化VPN流量
适用场景:
- 访问特定应用服务器
- 数据库远程连接
- 特定设备管理
本项目推荐配置:
内网访问模式:
AllowedIPs = 10.8.0.0/24
全流量模式(可选):
AllowedIPs = 0.0.0.0/0
路由优先级:
最具体的路由优先级最高:
1. /32 (单个IP)
2. /24 (256个IP)
3. /16 (65536个IP)
4. /0 (所有IP)
示例:
AllowedIPs = 10.8.0.2/32, 10.8.0.0/24, 0.0.0.0/0
访问10.8.0.2 → 匹配/32,走VPN
访问10.8.0.10 → 匹配/24,走VPN
访问8.8.8.8 → 匹配/0,走VPN
排除特定IP(高级):
WireGuard不直接支持排除规则,需要拆分网段:
# 排除192.168.1.0/24,其他全部走VPN
# 需要将0.0.0.0/0拆分为多个子网,跳过192.168.1.0/24
AllowedIPs = 0.0.0.0/1, 128.0.0.0/2, 192.0.0.0/9, 192.128.0.0/11, 192.160.0.0/13, 192.168.0.0/24, 192.168.2.0/23, 192.168.4.0/22, ...
💡 复杂:推荐使用脚本生成或使用策略路由。
常见配置示例:
访问公司内网 + 互联网直连:
AllowedIPs = 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
访问特定网站:
# 需要先解析网站IP
# 示例:访问Google服务
AllowedIPs = 8.8.8.8/32, 8.8.4.4/32, 172.217.0.0/16
验证路由规则:
Windows:
# 查看路由表
route print
# 查看特定路由
route print | Select-String "10.8.0"
Linux/macOS:
# 查看路由表
ip route show
# 查看特定路由
ip route show | grep wg0
# 测试路由
ip route get 10.8.0.1
ip route get 8.8.8.8
修改AllowedIPs:
需要重新连接VPN,配置才会生效:
# Linux
sudo wg-quick down wg0
sudo wg-quick up wg0
# 或使用wg命令动态修改(临时)
sudo wg set wg0 peer <服务器公钥> allowed-ips 10.8.0.0/24
Windows:
断开连接 → 修改配置文件 → 重新连接
16.3.4 PersistentKeepalive(保活)
参数说明:
定期向服务器发送保活包,维持NAT映射和防火墙会话。
语法格式:
PersistentKeepalive = <秒数>
推荐配置:
PersistentKeepalive = 25
参数说明:
- 单位:秒
- 范围:0-65535
- 0:禁用保活(默认)
- 推荐值:15-30秒
为什么需要保活:
问题1:NAT超时
场景:客户端在NAT路由器后
问题:NAT映射表会在无流量时超时(通常2-5分钟)
结果:服务器发送的数据包无法到达客户端
解决:定期发送保活包维持NAT映射
问题2:防火墙会话超时
场景:防火墙对UDP会话设置超时
问题:无流量时防火墙关闭会话
结果:连接中断
解决:保活包刷新会话状态
问题3:移动网络切换
场景:手机在WiFi和4G/5G之间切换
问题:IP地址变化,旧连接失效
结果:需要重新握手
解决:保活包加速连接恢复
工作原理:
1. 客户端每25秒发送空数据包
2. 数据包通过VPN隧道到达服务器
3. 服务器收到后更新客户端Endpoint
4. NAT/防火墙刷新会话超时时间
5. 连接保持活跃状态
不同场景的推荐值:
| 场景 | 推荐值 | 说明 |
|---|---|---|
| 移动设备(4G/5G) | 25 | 频繁网络切换 |
| 公共WiFi | 20 | NAT超时短 |
| 家庭宽带(NAT后) | 25 | 标准NAT环境 |
| 企业内网 | 0或60 | 无NAT或NAT超时长 |
| 服务器(固定IP) | 0 | 无需保活 |
| 省电模式 | 60 | 减少唤醒次数 |
本项目配置:
PersistentKeepalive = 25
开销分析:
网络开销:
每个保活包:约148字节(包含WireGuard头部)
每小时流量:148字节 × (3600/25) = 21,312字节 ≈ 20KB
每天流量:20KB × 24 = 480KB
每月流量:480KB × 30 = 14.4MB
电池影响:
- 移动设备:轻微增加耗电
- 建议:平衡保活间隔和电池寿命
- 省电模式:60秒或更长
服务器负载:
- 单客户端:可忽略
- 1000个客户端:约14.4GB/月
- 建议:大规模部署时考虑流量成本
禁用保活:
# 方法1:设置为0
PersistentKeepalive = 0
# 方法2:不配置该参数(等同于0)
# PersistentKeepalive = 25 # 注释掉
动态调整保活间隔:
# Linux临时修改
sudo wg set wg0 peer <服务器公钥> persistent-keepalive 60
# 永久修改需编辑配置文件
sudo nano /etc/wireguard/wg0.conf
PersistentKeepalive = 60
测试保活效果:
# 服务器端监控握手时间
sudo watch -n 1 'wg show wg0 | grep -A 4 "peer:"'
# 观察 "latest handshake" 字段
# 应该每25秒左右更新一次
输出示例:
peer: QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
endpoint: 192.168.1.100:54321
allowed ips: 10.8.0.2/32
latest handshake: 23 seconds ago # 应该<25秒
transfer: 1.23 MiB received, 856 KiB sent
常见问题:
问题1:保活包不生效
症状:latest handshake时间超过设定间隔
原因:
1. 配置文件错误
2. 客户端未重启
3. 防火墙阻止UDP包
解决:
1. 检查配置语法
2. 重新连接VPN
3. 检查防火墙规则
问题2:保活间隔过短
症状:电池消耗过快或流量异常
原因:PersistentKeepalive设置过小(如5秒)
解决:调整为25-30秒
16.4 分流隧道配置
16.4.1 分流原理
分流隧道(Split Tunneling)通过AllowedIPs控制哪些流量走VPN,哪些直连。
流量路由决策:
用户访问目标IP
↓
检查AllowedIPs配置
↓
├─ 匹配 → 加密 → VPN隧道 → 服务器 → 目标
│
└─ 不匹配 → 本地路由 → 直接访问目标
16.4.2 典型分流配置
场景1:仅访问公司内网
[Interface]
PrivateKey = eKX7A+ZxHanItaMVdEIwB3ENUZpQhX0VdPCL1CCWCmE=
Address = 10.8.0.2/24
DNS = 192.168.1.1 # 使用公司内网DNS
[Peer]
PublicKey = rUEB9pR7DO7qgkbo6Ylerrh/Fvl1XA8RJuALBdlkFkk=
Endpoint = vpn.company.com:51820
AllowedIPs = 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 # 仅私有地址
PersistentKeepalive = 25
路由效果:
10.0.0.0/8→ VPN172.16.0.0/12→ VPN192.168.0.0/16→ VPN8.8.8.8→ 直连www.google.com→ 直连
场景2:中国大陆分流(国内直连,国外VPN)
[Interface]
PrivateKey = eKX7A+ZxHanItaMVdEIwB3ENUZpQhX0VdPCL1CCWCmE=
Address = 10.8.0.2/24
DNS = 223.5.5.5, 8.8.8.8
[Peer]
PublicKey = rUEB9pR7DO7qgkbo6Ylerrh/Fvl1XA8RJuALBdlkFkk=
Endpoint = 203.0.113.10:51820
# 国外IP段(需要完整列表,这里仅示例)
AllowedIPs = 1.0.0.0/8, 3.0.0.0/8, 8.0.0.0/8, ...
PersistentKeepalive = 25
💡 注意:需要完整的国外IP段列表,配置复杂,建议使用专门工具生成。
场景3:域名分流(Netflix、YouTube等)
# 需要先解析域名获取IP段
# Netflix: 23.246.0.0/18, 37.77.184.0/21, ...
# YouTube: 172.217.0.0/16, 216.58.192.0/19, ...
[Interface]
PrivateKey = eKX7A+ZxHanItaMVdEIwB3ENUZpQhX0VdPCL1CCWCmE=
Address = 10.8.0.2/24
[Peer]
PublicKey = rUEB9pR7DO7qgkbo6Ylerrh/Fvl1XA8RJuALBdlkFkk=
Endpoint = 203.0.113.10:51820
AllowedIPs = 23.246.0.0/18, 37.77.184.0/21, 172.217.0.0/16, 216.58.192.0/19
PersistentKeepalive = 25
16.4.3 分流配置工具
手动配置:
# 逐一添加IP段
AllowedIPs = 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
使用脚本生成:
#!/bin/bash
# 生成中国大陆IP分流配置
# 下载中国IP列表
curl -o china_ip.txt https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt
# 生成AllowedIPs(排除中国IP)
# 这里需要复杂的IP段计算,推荐使用专门工具
使用第三方工具:
- WireGuard Config Generator
- WireGuard Easy
- wg-easy(Web界面)
16.5 全流量模式配置
16.5.1 全流量配置
完整配置示例:
[Interface]
PrivateKey = eKX7A+ZxHanItaMVdEIwB3ENUZpQhX0VdPCL1CCWCmE=
Address = 10.8.0.2/24
DNS = 223.5.5.5, 8.8.8.8
[Peer]
PublicKey = rUEB9pR7DO7qgkbo6Ylerrh/Fvl1XA8RJuALBdlkFkk=
Endpoint = 192.168.1.66:51820
AllowedIPs = 0.0.0.0/0, ::/0 # 所有IPv4和IPv6流量
PersistentKeepalive = 25
流量路由:
- ✅ 所有互联网流量 → VPN
- ✅ DNS查询 → VPN
- ✅ IPv4 + IPv6 → VPN
16.5.2 服务器端要求
服务器必须正确配置NAT:
[Interface]
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o pnet0 -j MASQUERADE
并启用IP转发:
sudo sysctl -w net.ipv4.ip_forward=1
16.5.3 Kill Switch(网络锁定)
防止VPN断开时流量泄露:
Linux实现:
# 添加防火墙规则
sudo iptables -I OUTPUT ! -o wg0 -m mark ! --mark $(wg show wg0 fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
# 删除规则(VPN断开后)
sudo iptables -D OUTPUT ! -o wg0 -m mark ! --mark $(wg show wg0 fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
Windows实现:
使用WireGuard GUI的PreUp/PostDown功能:
# 创建防火墙规则阻止非VPN流量
# 需要PowerShell脚本实现
16.6 完整注释版配置
16.6.1 分流模式(推荐)
#######################################
# WireGuard客户端配置文件
#
# 配置名称:公司内网访问
# 用户:user1
# 设备:Windows 10 / MacBook
# 模式:分流隧道(仅内网流量走VPN)
# 创建日期:2025-03-23
#######################################
[Interface]
# 客户端私钥(严格保密,不要分享)
# 生成命令:wg genkey
# 对应公钥:QcDIGh0MyyLJoovsb7hMccZGwMha7aqfa/3cyFtfhE4=
PrivateKey = eKX7A+ZxHanItaMVdEIwB3ENUZpQhX0VdPCL1CCWCmE=
# 客户端虚拟IP地址
# 网段:10.8.0.0/24
# 本机IP:10.8.0.2
# 网关:10.8.0.1(服务器)
Address = 10.8.0.2/24
# DNS服务器
# 主DNS:223.5.5.5(阿里云)
# 备DNS:114.114.114.114(114DNS)
# 作用:VPN连接后自动设置DNS
DNS = 223.5.5.5, 114.114.114.114
# MTU(最大传输单元)
# 推荐值:1420
# 注:如遇到网页加载慢,可尝试降低到1280
# MTU = 1420
[Peer]
# 服务器公钥
# 用途:验证服务器身份,建立加密隧道
PublicKey = rUEB9pR7DO7qgkbo6Ylerrh/Fvl1XA8RJuALBdlkFkk=
# 服务器地址和端口
# 格式:<IP或域名>:<端口>
# 协议:UDP
Endpoint = 192.168.1.66:51820
# 允许的IP地址(路由规则)
# 仅内网流量走VPN,其他流量直连
# 10.8.0.0/24:VPN虚拟网段
# 说明:访问10.8.0.x的流量会加密并通过VPN隧道
AllowedIPs = 10.8.0.0/24
# 保活间隔(秒)
# 推荐值:25
# 作用:维持NAT映射,防止连接超时
# 0:禁用保活
PersistentKeepalive = 25
#######################################
# 使用说明
#######################################
#
# Windows导入方法:
# 1. 打开WireGuard应用
# 2. 点击"从文件导入隧道"
# 3. 选择此配置文件
# 4. 点击"激活"
#
# 测试连接:
# ping 10.8.0.1
#
# 访问内网资源:
# http://10.8.0.1:8000
#######################################
16.6.2 全流量模式
#######################################
# WireGuard客户端配置文件
#
# 配置名称:全流量VPN
# 用户:user1
# 模式:全流量(所有流量走VPN)
# 创建日期:2025-03-23
#######################################
[Interface]
PrivateKey = eKX7A+ZxHanItaMVdEIwB3ENUZpQhX0VdPCL1CCWCmE=
Address = 10.8.0.2/24
# DNS使用VPN提供的DNS,防止DNS泄露
DNS = 223.5.5.5, 8.8.8.8
[Peer]
PublicKey = rUEB9pR7DO7qgkbo6Ylerrh/Fvl1XA8RJuALBdlkFkk=
Endpoint = 192.168.1.66:51820
# 所有流量走VPN
# 0.0.0.0/0:所有IPv4流量
# ::/0:所有IPv6流量
AllowedIPs = 0.0.0.0/0, ::/0
# 保活确保连接稳定
PersistentKeepalive = 25
#######################################
# 警告
#######################################
#
# 全流量模式注意事项:
# 1. 所有网络流量经过VPN服务器
# 2. VPN断开时无法访问互联网
# 3. 访问速度受VPN服务器带宽限制
# 4. 适合公共WiFi等不安全网络环境
#######################################
17. 防火墙与安全配置
17.1 iptables规则详解
17.1.1 基础概念
iptables表和链:
iptables有4个表:
1. filter表:过滤数据包(默认表)
- INPUT链:处理进入本机的数据包
- FORWARD链:处理转发的数据包
- OUTPUT链:处理本机发出的数据包
2. nat表:网络地址转换
- PREROUTING链:路由前修改目标地址(DNAT)
- POSTROUTING链:路由后修改源地址(SNAT/MASQUERADE)
- OUTPUT链:本地生成数据包的NAT
3. mangle表:修改数据包头部
4. raw表:连接跟踪相关
WireGuard需要的规则:
- FORWARD链:允许转发VPN流量
- POSTROUTING链:对出站流量进行NAT
17.1.2 FORWARD链规则
基本规则:
iptables -A FORWARD -i wg0 -j ACCEPT
参数解析:
-A FORWARD:在FORWARD链末尾追加规则-i wg0:匹配从wg0接口进入的数据包-j ACCEPT:动作为接受(允许通过)
详细规则示例:
规则1:允许VPN所有流量
iptables -A FORWARD -i wg0 -j ACCEPT
iptables -A FORWARD -o wg0 -j ACCEPT
规则2:仅允许特定协议
# 仅允许HTTP和HTTPS
iptables -A FORWARD -i wg0 -p tcp --dport 80 -j ACCEPT
iptables -A FORWARD -i wg0 -p tcp --dport 443 -j ACCEPT
iptables -A FORWARD -i wg0 -j DROP # 拒绝其他流量
规则3:禁止客户端互访
# 禁止wg0到wg0的流量(客户端间不能互访)
iptables -A FORWARD -i wg0 -o wg0 -j DROP
# 允许wg0到其他接口
iptables -A FORWARD -i wg0 -j ACCEPT
规则4:限速
# 限制每个客户端带宽为10Mbps
iptables -A FORWARD -i wg0 -m hashlimit \
--hashlimit-above 10mb/s \
--hashlimit-mode srcip \
--hashlimit-name wg_limit \
-j DROP
规则5:访问控制(基于IP)
# 仅允许10.8.0.2访问特定服务器
iptables -A FORWARD -s 10.8.0.2 -d 192.168.1.100 -j ACCEPT
iptables -A FORWARD -s 10.8.0.2 -j DROP
# 其他客户端可以访问所有
iptables -A FORWARD -i wg0 -j ACCEPT
17.1.3 POSTROUTING规则(NAT)
基本规则:
iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
参数解析:
-t nat:操作nat表-A POSTROUTING:在POSTROUTING链追加规则-o pnet0:匹配从pnet0接口出去的数据包-j MASQUERADE:动态SNAT(源地址转换)
MASQUERADE vs SNAT:
MASQUERADE(动态NAT):
# 适用于动态IP(DHCP、PPPoE)
iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
优点:
- 自动适配IP地址变化
- 配置简单
缺点:
- 性能略低(需要查询接口IP)
SNAT(静态NAT):
# 适用于固定IP
iptables -t nat -A POSTROUTING -o pnet0 -j SNAT --to-source 192.168.1.66
优点:
- 性能更好
- IP地址明确
缺点:
- IP变化需手动修改规则
本项目使用MASQUERADE的原因:
- EVE-NG环境IP可能变化
- 配置简单,易于维护
- 性能差异可忽略(小规模部署)
NAT流程示例:
客户端访问互联网:
1. 客户端(10.8.0.2) → 目标(8.8.8.8)
2. 数据包到达服务器wg0接口
3. FORWARD链允许转发
4. 路由决策:从pnet0出去
5. POSTROUTING链修改源IP:
10.8.0.2 → 192.168.1.66
6. 数据包从pnet0发出,源IP为192.168.1.66
7. 目标服务器(8.8.8.8)收到请求,响应到192.168.1.66
8. 服务器收到响应,NAT表还原:
192.168.1.66 → 10.8.0.2
9. 响应数据通过wg0发送给客户端
高级NAT规则:
规则1:多出口NAT
# 根据不同来源使用不同出口
iptables -t nat -A POSTROUTING -s 10.8.0.0/25 -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 10.8.0.128/25 -o eth1 -j MASQUERADE
规则2:端口映射
# 将VPN客户端的80端口映射到外网
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.8.0.2:80
iptables -t nat -A POSTROUTING -d 10.8.0.2 -p tcp --dport 80 -j MASQUERADE
规则3:仅NAT特定流量
# 仅对访问互联网的流量做NAT,内网流量不NAT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -d 192.168.0.0/16 -j RETURN
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o pnet0 -j MASQUERADE
17.1.4 查看和管理规则
查看规则:
# 查看filter表所有链
sudo iptables -L -n -v
# 查看FORWARD链
sudo iptables -L FORWARD -n -v --line-numbers
# 查看nat表
sudo iptables -t nat -L -n -v
# 查看POSTROUTING链
sudo iptables -t nat -L POSTROUTING -n -v --line-numbers
输出示例:
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 150 12K ACCEPT all -- wg0 * 0.0.0.0/0 0.0.0.0/0
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 150 12K MASQUERADE all -- * pnet0 0.0.0.0/0 0.0.0.0/0
删除规则:
# 方法1:按行号删除
sudo iptables -D FORWARD 1
# 方法2:按完整规则删除
sudo iptables -D FORWARD -i wg0 -j ACCEPT
# 方法3:清空整条链
sudo iptables -F FORWARD
# 方法4:清空nat表
sudo iptables -t nat -F
保存规则:
Ubuntu/Debian:
# 安装iptables-persistent
sudo apt install iptables-persistent
# 保存当前规则
sudo netfilter-persistent save
# 手动保存
sudo iptables-save > /etc/iptables/rules.v4
sudo ip6tables-save > /etc/iptables/rules.v6
CentOS/RHEL:
# 保存规则
sudo service iptables save
# 或
sudo iptables-save > /etc/sysconfig/iptables
恢复规则:
# Ubuntu/Debian
sudo iptables-restore < /etc/iptables/rules.v4
# CentOS/RHEL
sudo iptables-restore < /etc/sysconfig/iptables
17.2 INPUT链规则
17.2.1 允许WireGuard端口
基本规则:
# 允许UDP 51820端口
sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT
详细规则:
# 仅允许特定来源IP
sudo iptables -A INPUT -p udp --dport 51820 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 51820 -j DROP
# 限制连接速率(防DDoS)
sudo iptables -A INPUT -p udp --dport 51820 -m hashlimit \
--hashlimit-above 100/sec \
--hashlimit-mode srcip \
--hashlimit-name wg_ddos \
-j DROP
sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT
17.2.2 允许管理接口
允许SSH:
# 基本规则
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 限制来源IP
sudo iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j DROP
# 防暴力破解
sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
允许Web管理:
# 允许8000和5000端口
sudo iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 5000 -j ACCEPT
# 或仅允许内网访问
sudo iptables -A INPUT -p tcp --dport 8000 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 5000 -s 127.0.0.1 -j ACCEPT
17.3 规则持久化
17.3.1 使用PostUp/PostDown
WireGuard配置文件中的规则:
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o pnet0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o pnet0 -j MASQUERADE
优点:
- ✅ 与WireGuard生命周期绑定
- ✅ 自动清理规则
- ✅ 无需额外配置
缺点:
- ❌ 仅在WireGuard启动时生效
- ❌ 无法独立管理规则
17.3.2 使用iptables-persistent
安装:
sudo apt install iptables-persistent
保存规则:
# 交互式保存
sudo dpkg-reconfigure iptables-persistent
# 命令行保存
sudo netfilter-persistent save
规则文件位置:
/etc/iptables/rules.v4 # IPv4规则
/etc/iptables/rules.v6 # IPv6规则
手动编辑规则文件:
sudo nano /etc/iptables/rules.v4
内容示例:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# 允许已建立的连接
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# 允许本地回环
-A INPUT -i lo -j ACCEPT
# 允许SSH
-A INPUT -p tcp --dport 22 -j ACCEPT
# 允许WireGuard
-A INPUT -p udp --dport 51820 -j ACCEPT
# 允许WireGuard转发
-A FORWARD -i wg0 -j ACCEPT
-A FORWARD -o wg0 -j ACCEPT
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
# WireGuard NAT
-A POSTROUTING -o pnet0 -j MASQUERADE
COMMIT
重新加载规则:
sudo netfilter-persistent reload
# 或
sudo systemctl restart netfilter-persistent
17.4 ufw配置方法
17.4.1 ufw基础
ufw简介:
UFW(Uncomplicated Firewall)是iptables的前端工具,提供更简单的防火墙管理方式。
安装ufw:
# Ubuntu/Debian
sudo apt install ufw
# 检查状态
sudo ufw status
# 启用ufw
sudo ufw enable
# 禁用ufw
sudo ufw disable
基本命令:
# 查看状态(详细)
sudo ufw status verbose
# 查看规则编号
sudo ufw status numbered
# 重置所有规则
sudo ufw reset
17.4.2 WireGuard相关规则
允许WireGuard端口:
# 允许UDP 51820
sudo ufw allow 51820/udp
# 允许特定来源
sudo ufw allow from 192.168.1.0/24 to any port 51820 proto udp
# 允许任意来源(公网VPN)
sudo ufw allow from any to any port 51820 proto udp
允许Web管理端口:
# 允许Web管理界面(仅内网)
sudo ufw allow from 192.168.1.0/24 to any port 8000 proto tcp
# 允许Flask API(仅本机)
sudo ufw allow from 127.0.0.1 to any port 5000 proto tcp
允许SSH:
# 基本SSH规则
sudo ufw allow 22/tcp
# 限制SSH来源
sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp
# 限制SSH连接速率
sudo ufw limit 22/tcp
启用转发:
# 编辑ufw配置
sudo nano /etc/default/ufw
# 修改以下行
DEFAULT_FORWARD_POLICY="ACCEPT"
# 保存后重启ufw
sudo ufw disable
sudo ufw enable
配置NAT规则:
# 编辑ufw before规则文件
sudo nano /etc/ufw/before.rules
在文件开头的*filter之前添加:
# WireGuard NAT规则
*nat
:POSTROUTING ACCEPT [0:0]
# 对pnet0出口流量进行NAT
-A POSTROUTING -s 10.8.0.0/24 -o pnet0 -j MASQUERADE
COMMIT
完整示例:
#
# rules.before
#
# WireGuard NAT配置
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/24 -o pnet0 -j MASQUERADE
COMMIT
# 不要删除这些必需的行,否则会破坏配置
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
...
允许WireGuard接口转发:
继续编辑/etc/ufw/before.rules,在*filter部分添加:
# 允许wg0接口的所有转发流量
-A ufw-before-forward -i wg0 -j ACCEPT
-A ufw-before-forward -o wg0 -j ACCEPT
重新加载ufw:
sudo ufw reload
# 查看状态
sudo ufw status verbose
17.4.3 查看和管理规则
查看当前规则:
# 简单格式
sudo ufw status
# 详细格式
sudo ufw status verbose
# 带编号
sudo ufw status numbered
输出示例:
Status: active
To Action From
-- ------ ----
22/tcp ALLOW 192.168.1.0/24
51820/udp ALLOW Anywhere
8000/tcp ALLOW 192.168.1.0/24
51820/udp (v6) ALLOW Anywhere (v6)
删除规则:
# 方法1:按编号删除
sudo ufw status numbered
sudo ufw delete 3
# 方法2:按规则删除
sudo ufw delete allow 51820/udp
# 方法3:删除特定规则
sudo ufw delete allow from 192.168.1.0/24 to any port 8000
插入规则(指定位置):
# 在第1条位置插入规则
sudo ufw insert 1 allow from 192.168.1.100 to any port 22
17.4.4 默认策略
查看默认策略:
sudo ufw status verbose
输出示例:
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), allow (routed)
修改默认策略:
# 默认拒绝所有入站
sudo ufw default deny incoming
# 默认允许所有出站
sudo ufw default allow outgoing
# 默认允许转发(WireGuard需要)
sudo ufw default allow routed
# 或拒绝转发(仅允许明确规则)
sudo ufw default deny routed
应用场景:
高安全环境:
sudo ufw default deny incoming
sudo ufw default deny outgoing
sudo ufw default deny routed
# 然后明确允许需要的服务
sudo ufw allow out 53/udp # DNS
sudo ufw allow out 80/tcp # HTTP
sudo ufw allow out 443/tcp # HTTPS
标准VPN服务器:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw default allow routed # WireGuard转发需要
17.4.5 日志记录
启用日志:
# 启用日志(低级别)
sudo ufw logging low
# 中等级别
sudo ufw logging medium
# 高级别(调试用)
sudo ufw logging high
# 完全日志
sudo ufw logging full
# 禁用日志
sudo ufw logging off
查看日志:
# 查看ufw日志
sudo tail -f /var/log/ufw.log
# 查看kern.log(包含更多详细信息)
sudo tail -f /var/log/kern.log | grep UFW
# 使用journalctl
sudo journalctl -u ufw -f
日志示例:
Mar 23 10:30:15 server kernel: [UFW BLOCK] IN=pnet0 OUT= MAC=... SRC=203.0.113.50 DST=192.168.1.66 LEN=60 TOS=0x00 PREC=0x00 TTL=52 ID=12345 PROTO=TCP SPT=45678 DPT=22 WINDOW=29200 SYN
日志分析:
UFW BLOCK:被阻止的数据包SRC:源IP地址DST:目标IP地址SPT:源端口DPT:目标端口PROTO:协议(TCP/UDP/ICMP)
17.4.6 应用配置文件
查看可用应用:
sudo ufw app list
输出示例:
Available applications:
Apache
Apache Full
Apache Secure
OpenSSH
Samba
创建WireGuard应用配置:
# 创建配置文件
sudo nano /etc/ufw/applications.d/wireguard
内容:
[WireGuard]
title=WireGuard VPN
description=Fast, modern, secure VPN tunnel
ports=51820/udp
使用应用配置:
# 重新加载应用列表
sudo ufw app update wireguard
# 查看应用信息
sudo ufw app info WireGuard
# 允许应用
sudo ufw allow WireGuard
17.4.7 完整配置示例
基础VPN服务器配置:
# 1. 重置ufw(可选)
sudo ufw --force reset
# 2. 设置默认策略
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw default allow routed
# 3. 允许SSH(重要!)
sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp
# 4. 允许WireGuard
sudo ufw allow 51820/udp
# 5. 允许Web管理(可选)
sudo ufw allow from 192.168.1.0/24 to any port 8000 proto tcp
sudo ufw allow from 127.0.0.1 to any port 5000 proto tcp
# 6. 配置NAT和转发(前面步骤)
sudo nano /etc/ufw/before.rules
# 添加NAT规则和转发规则
sudo nano /etc/default/ufw
# 设置 DEFAULT_FORWARD_POLICY="ACCEPT"
# 7. 启用ufw
sudo ufw enable
# 8. 验证配置
sudo ufw status verbose
高安全配置:
# 默认全部拒绝
sudo ufw default deny incoming
sudo ufw default deny outgoing
sudo ufw default deny routed
# 仅允许必要的出站连接
sudo ufw allow out 53/udp # DNS
sudo ufw allow out 80/tcp # HTTP
sudo ufw allow out 443/tcp # HTTPS
sudo ufw allow out 123/udp # NTP
# 允许SSH(特定IP)
sudo ufw allow from 192.168.1.100 to any port 22 proto tcp
# 允许WireGuard
sudo ufw allow 51820/udp
# 允许WireGuard客户端出站
sudo ufw allow out on wg0
# 配置NAT和转发
# (同基础配置)
# 启用
sudo ufw enable
17.5 IP转发配置
17.5.1 启用IP转发
临时启用:
# 启用IPv4转发
sudo sysctl -w net.ipv4.ip_forward=1
# 启用IPv6转发(如果使用IPv6)
sudo sysctl -w net.ipv6.conf.all.forwarding=1
# 验证
sysctl net.ipv4.ip_forward
# 输出:net.ipv4.ip_forward = 1
永久启用:
# 方法1:编辑sysctl.conf
sudo nano /etc/sysctl.conf
添加或取消注释:
# 启用IPv4转发
net.ipv4.ip_forward=1
# 启用IPv6转发(可选)
net.ipv6.conf.all.forwarding=1
应用配置:
sudo sysctl -p
方法2:创建单独配置文件
# 创建WireGuard专用配置
sudo nano /etc/sysctl.d/99-wireguard.conf
内容:
# WireGuard IP转发配置
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
# 可选:禁用RP过滤(某些情况需要)
net.ipv4.conf.all.rp_filter = 0
应用:
sudo sysctl -p /etc/sysctl.d/99-wireguard.conf
17.5.2 验证IP转发
检查当前状态:
# 查看IPv4转发状态
cat /proc/sys/net/ipv4/ip_forward
# 输出:1(已启用)或0(已禁用)
# 使用sysctl查看
sysctl net.ipv4.ip_forward
# 查看所有网络参数
sysctl -a | grep forward
测试转发功能:
# 从客户端测试
# 1. 连接VPN
# 2. ping外网地址
ping 8.8.8.8
# 3. 访问网页
curl http://www.google.com
# 4. traceroute查看路由
traceroute 8.8.8.8
# 应该能看到通过10.8.0.1转发
服务器端监控转发:
# 查看转发统计
sudo iptables -L FORWARD -n -v
# 实时监控
sudo watch -n 1 'iptables -L FORWARD -n -v'
# 查看NAT表
sudo iptables -t nat -L POSTROUTING -n -v
17.5.3 高级转发选项
RP过滤(Reverse Path Filtering):
# 查看当前设置
sysctl net.ipv4.conf.all.rp_filter
# 0 = 禁用
# 1 = 严格模式(推荐)
# 2 = 宽松模式
配置:
sudo nano /etc/sysctl.d/99-wireguard.conf
内容:
# 严格RP过滤(防止IP欺骗)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# 如果遇到路由问题,可以尝试宽松模式
# net.ipv4.conf.all.rp_filter = 2
ICMP重定向:
# 禁用ICMP重定向(安全建议)
sudo nano /etc/sysctl.d/99-wireguard.conf
添加:
# 禁用ICMP重定向
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
TCP优化:
# TCP优化选项
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
net.ipv4.tcp_fastopen = 3
应用所有配置:
sudo sysctl -p /etc/sysctl.d/99-wireguard.conf
17.6 安全加固最佳实践
17.6.1 密钥安全
密钥权限:
# 设置私钥文件权限为600
sudo chmod 600 /etc/wireguard/server_private.key
sudo chmod 600 /etc/wireguard/wg0.conf
# 设置所有者为root
sudo chown root:root /etc/wireguard/server_private.key
sudo chown root:root /etc/wireguard/wg0.conf
# 验证
ls -l /etc/wireguard/
预期输出:
-rw------- 1 root root 45 Mar 23 10:00 server_private.key
-rw------- 1 root root 456 Mar 23 10:00 wg0.conf
密钥备份:
# 创建加密备份
sudo tar czf - /etc/wireguard | \
gpg --symmetric --cipher-algo AES256 -o wireguard-backup-$(date +%Y%m%d).tar.gz.gpg
# 恢复
gpg --decrypt wireguard-backup-20250323.tar.gz.gpg | sudo tar xzf - -C /
定期轮换密钥:
# 生成新密钥对
wg genkey | sudo tee /etc/wireguard/server_private_new.key
sudo cat /etc/wireguard/server_private_new.key | wg pubkey | \
sudo tee /etc/wireguard/server_public_new.key
# 更新配置文件
# 通知所有客户端更新公钥
# 替换旧密钥
17.6.2 访问控制
限制源IP:
# iptables规则
sudo iptables -A INPUT -p udp --dport 51820 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 51820 -j DROP
# ufw规则
sudo ufw allow from 192.168.1.0/24 to any port 51820 proto udp
sudo ufw deny 51820/udp
基于时间的访问控制:
# 仅允许工作时间(8:00-18:00)访问
sudo iptables -A INPUT -p udp --dport 51820 -m time \
--timestart 08:00 --timestop 18:00 \
--weekdays Mon,Tue,Wed,Thu,Fri \
-j ACCEPT
sudo iptables -A INPUT -p udp --dport 51820 -j DROP
限制连接数:
# 每个IP最多3个并发连接
sudo iptables -A INPUT -p udp --dport 51820 -m connlimit \
--connlimit-above 3 \
--connlimit-mask 32 \
-j REJECT
速率限制(防DDoS):
# 限制新连接速率
sudo iptables -A INPUT -p udp --dport 51820 -m hashlimit \
--hashlimit-above 10/min \
--hashlimit-mode srcip \
--hashlimit-name wg_conn_limit \
-j DROP
17.6.3 日志和审计
启用WireGuard调试日志:
# 查看内核日志
sudo dmesg | grep wireguard
# 持续监控
sudo dmesg -w | grep wireguard
记录连接事件:
# 在PostUp中添加日志
PostUp = iptables -A FORWARD -i wg0 -j LOG --log-prefix "WG-FORWARD: " --log-level 4; iptables -A FORWARD -i wg0 -j ACCEPT
# 查看日志
sudo journalctl -k | grep "WG-FORWARD"
自定义日志脚本:
#!/bin/bash
# /etc/wireguard/log-connections.sh
while true; do
sudo wg show wg0 dump | while read line; do
echo "$(date '+%Y-%m-%d %H:%M:%S') - $line" >> /var/log/wireguard-connections.log
done
sleep 60
done
使用:
sudo chmod +x /etc/wireguard/log-connections.sh
sudo /etc/wireguard/log-connections.sh &
日志分析:
# 统计连接的客户端
sudo wg show wg0 peers | wc -l
# 查看流量最大的peer
sudo wg show wg0 transfer | sort -k2 -rn | head -5
# 查看最近握手的peer
sudo wg show wg0 latest-handshakes | sort -k2 -rn
17.6.4 fail2ban集成
安装fail2ban:
sudo apt install fail2ban
创建WireGuard过滤器:
sudo nano /etc/fail2ban/filter.d/wireguard.conf
内容:
[Definition]
failregex = ^.*WireGuard.*SRC=<HOST>.*DPT=51820.*$
ignoreregex =
创建jail配置:
sudo nano /etc/fail2ban/jail.d/wireguard.conf
内容:
[wireguard]
enabled = true
port = 51820
protocol = udp
filter = wireguard
logpath = /var/log/kern.log
maxretry = 5
findtime = 600
bantime = 3600
action = iptables-allports[name=wireguard]
启用fail2ban:
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# 查看状态
sudo fail2ban-client status wireguard
17.6.5 入侵检测
使用psad(Port Scan Attack Detector):
# 安装psad
sudo apt install psad
# 配置
sudo nano /etc/psad/psad.conf
关键配置:
ENABLE_AUTO_IDS = Y;
ENABLE_AUTO_IDS_EMAILS = Y;
EMAIL_ADDRESSES = [email protected];
启用psad:
sudo systemctl enable psad
sudo systemctl start psad
# 查看检测到的扫描
sudo psad --Status
使用Snort IDS(高级):
# 安装Snort
sudo apt install snort
# 配置监听接口
sudo dpkg-reconfigure snort
# 创建WireGuard规则
sudo nano /etc/snort/rules/wireguard.rules
规则示例:
alert udp any any -> $HOME_NET 51820 (msg:"WireGuard connection attempt"; sid:1000001;)
alert udp any any -> $HOME_NET 51820 (msg:"WireGuard flood"; threshold:type both, track by_src, count 100, seconds 60; sid:1000002;)
17.6.6 系统加固
禁用不必要的服务:
# 列出所有启用的服务
sudo systemctl list-unit-files --state=enabled
# 禁用不需要的服务
sudo systemctl disable bluetooth
sudo systemctl disable cups
sudo systemctl disable avahi-daemon
配置自动更新:
# 安装unattended-upgrades
sudo apt install unattended-upgrades
# 启用自动安全更新
sudo dpkg-reconfigure -plow unattended-upgrades
SSH加固:
sudo nano /etc/ssh/sshd_config
推荐配置:
# 禁用root登录
PermitRootLogin no
# 仅允许密钥认证
PasswordAuthentication no
PubkeyAuthentication yes
# 限制登录用户
AllowUsers your_username
# 修改默认端口(可选)
Port 2222
# 禁用空密码
PermitEmptyPasswords no
# 设置超时
ClientAliveInterval 300
ClientAliveCountMax 2
重启SSH:
sudo systemctl restart sshd
内核参数加固:
sudo nano /etc/sysctl.d/99-security.conf
内容:
# IP欺骗保护
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# 禁用源路由
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
# 禁用ICMP重定向
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
# 启用SYN Cookies(防SYN洪水)
net.ipv4.tcp_syncookies = 1
# 禁用ICMP广播
net.ipv4.icmp_echo_ignore_broadcasts = 1
# 记录可疑数据包
net.ipv4.conf.all.log_martians = 1
应用:
sudo sysctl -p /etc/sysctl.d/99-security.conf
定期安全审计:
# 安装Lynis
sudo apt install lynis
# 运行安全审计
sudo lynis audit system
# 查看报告
cat /var/log/lynis-report.dat