WireGuard 服务器端配置指南¶
状态: ✅ 已完成
客户端信息¶
- 客户端公钥:
GGPfzpN4Mf5acZrsJmQf8cRO93uUoJhsAdIitvv2mmM= - 虚拟网络 IP:
192.168.0.100/32 - 客户端类型: 动态 IP 客户端(需要 PersistentKeepalive)
添加客户端 Peer 配置¶
步骤 1: 编辑服务器端配置文件¶
在每个服务器上(cab4, cab5, cab6),编辑 WireGuard 配置文件:
步骤 2: 添加客户端 Peer 配置¶
在配置文件的 [Peer] 部分添加以下内容:
[Peer]
PublicKey = GGPfzpN4Mf5acZrsJmQf8cRO93uUoJhsAdIitvv2mmM=
AllowedIPs = 192.168.0.100/32
# 注意:客户端是动态IP,不需要配置 Endpoint
步骤 3: 重启 WireGuard 服务¶
步骤 4: 验证配置¶
# 查看 WireGuard 状态
sudo wg show
# 应该能看到新添加的 peer,显示类似:
# peer: GGPfzpN4Mf5acZrsJmQf8cRO93uUoJhsAdIitvv2mmM=
# allowed ips: 192.168.0.100/32
nftables 防火墙配置(已验证方案)¶
关键配置要求¶
服务器使用 nftables 防火墙时,必须在 drop 规则之前添加 WireGuard 相关规则,否则连接无法建立。
已验证的配置方案(使用 handle 9)¶
重要:在所有服务器上,handle 9 对应 ct state established,related accept,这个位置稳定且安全。
PostUp 配置(单行格式)¶
PostUp = nft add table ip nat; nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }; nft add rule ip nat postrouting oifname "eno1" masquerade; nft add table ip filter; nft add chain ip filter forward { type filter hook forward priority 0 \; }; nft add rule ip filter forward iifname "wg0" accept; nft add rule ip filter forward oifname "eno1" ct state related,established accept; nft add rule ip filter forward oifname "eno1" ip saddr 192.168.0.0/24 accept; nft -a list chain inet filter input 2>/dev/null | grep "udp dport 51820" | awk '{print $NF}' | xargs -r -I {} nft delete rule inet filter input handle {} 2>/dev/null || true; nft -a list chain inet filter input 2>/dev/null | grep "iifname \"wg0\"" | awk '{print $NF}' | xargs -r -I {} nft delete rule inet filter input handle {} 2>/dev/null || true; nft insert rule inet filter input handle 9 udp dport 51820 accept; nft insert rule inet filter input handle 9 iifname "wg0" accept
PostDown 配置(单行格式)¶
PostDown = nft delete table ip nat; nft delete table ip filter; nft -a list chain inet filter input 2>/dev/null | grep "udp dport 51820" | awk '{print $NF}' | xargs -r -I {} nft delete rule inet filter input handle {} 2>/dev/null || true; nft -a list chain inet filter input 2>/dev/null | grep "iifname \"wg0\"" | awk '{print $NF}' | xargs -r -I {} nft delete rule inet filter input handle {} 2>/dev/null || true
规则执行顺序¶
配置后,规则执行顺序应该是:
1. iif "lo" accept (handle 8)
2. udp dport 51820 accept ← WireGuard 端口规则
3. iifname "wg0" accept ← WireGuard 接口规则
4. ct state established,related accept (handle 9)
5. ... 其他规则
6. drop (handle 24/25)
验证防火墙规则¶
# 检查规则是否正确添加(推荐命令)
sudo nft list chain inet filter input | grep -E "(51820|wg0|established)" -A 1 -B 1
# 应该看到:
# udp dport 51820 accept
# iifname "wg0" accept
# ct state established,related accept
检测防火墙设置效果¶
配置完成后,使用以下命令检测防火墙规则是否正确:
预期输出示例:
iif "lo" accept
udp dport 51820 accept
iifname "wg0" accept
ct state established,related accept
ct state invalid drop
检查要点:
- ✅
udp dport 51820 accept必须在ct state established,related accept之前 - ✅
iifname "wg0" accept必须在ct state established,related accept之前 - ✅ 两个规则都必须在
drop规则之前 - ❌ 如果规则在
drop之后,说明配置失败,需要重新配置
手动添加规则(临时测试)¶
如果需要临时测试,可以手动添加:
# 在 handle 9 之前插入(推荐,更稳定)
sudo nft insert rule inet filter input handle 9 udp dport 51820 accept
sudo nft insert rule inet filter input handle 9 iifname "wg0" accept
重要注意事项¶
- 规则顺序至关重要:WireGuard 规则必须在
drop之前,否则流量会被丢弃 - 使用 handle 9 更稳定:
handle 9在所有服务器上都是established,related accept,比 drop handle 更稳定 - 删除重复规则:PostUp 中先删除可能存在的重复规则,避免规则累积
- PostDown 清理:确保 PostDown 删除添加的规则,避免重启后规则重复
完整服务器端配置示例¶
cab4 服务器配置示例¶
[Interface]
PrivateKey = <服务器私钥>
Address = 192.168.0.1/24, 192.168.0.101/32
ListenPort = 51820
PostUp = nft add table ip nat; nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }; nft add rule ip nat postrouting oifname "eno1" masquerade; nft add table ip filter; nft add chain ip filter forward { type filter hook forward priority 0 \; }; nft add rule ip filter forward iifname "wg0" accept; nft add rule ip filter forward oifname "eno1" ct state related,established accept; nft add rule ip filter forward oifname "eno1" ip saddr 192.168.0.0/24 accept; nft -a list chain inet filter input 2>/dev/null | grep "udp dport 51820" | awk '{print $NF}' | xargs -r -I {} nft delete rule inet filter input handle {} 2>/dev/null || true; nft -a list chain inet filter input 2>/dev/null | grep "iifname \"wg0\"" | awk '{print $NF}' | xargs -r -I {} nft delete rule inet filter input handle {} 2>/dev/null || true; nft insert rule inet filter input handle 9 udp dport 51820 accept; nft insert rule inet filter input handle 9 iifname "wg0" accept
PostDown = nft delete table ip nat; nft delete table ip filter; nft -a list chain inet filter input 2>/dev/null | grep "udp dport 51820" | awk '{print $NF}' | xargs -r -I {} nft delete rule inet filter input handle {} 2>/dev/null || true; nft -a list chain inet filter input 2>/dev/null | grep "iifname \"wg0\"" | awk '{print $NF}' | xargs -r -I {} nft delete rule inet filter input handle {} 2>/dev/null || true
[Peer]
# 其他客户端...
PublicKey = <其他客户端公钥>
AllowedIPs = <其他客户端IP>/32
[Peer]
# 新客户端:pengxin
PublicKey = GGPfzpN4Mf5acZrsJmQf8cRO93uUoJhsAdIitvv2mmM=
AllowedIPs = 192.168.0.100/32
cab5 服务器配置示例¶
[Interface]
PrivateKey = <服务器私钥>
Address = 192.168.0.2/24, 192.168.0.102/32
ListenPort = 51820
PostUp = nft add table ip nat; nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }; nft add rule ip nat postrouting oifname "eno1" masquerade; nft add table ip filter; nft add chain ip filter forward { type filter hook forward priority 0 \; }; nft add rule ip filter forward iifname "wg0" accept; nft add rule ip filter forward oifname "eno1" ct state related,established accept; nft add rule ip filter forward oifname "eno1" ip saddr 192.168.0.0/24 accept; nft -a list chain inet filter input 2>/dev/null | grep "udp dport 51820" | awk '{print $NF}' | xargs -r -I {} nft delete rule inet filter input handle {} 2>/dev/null || true; nft -a list chain inet filter input 2>/dev/null | grep "iifname \"wg0\"" | awk '{print $NF}' | xargs -r -I {} nft delete rule inet filter input handle {} 2>/dev/null || true; nft insert rule inet filter input handle 9 udp dport 51820 accept; nft insert rule inet filter input handle 9 iifname "wg0" accept
PostDown = nft delete table ip nat; nft delete table ip filter; nft -a list chain inet filter input 2>/dev/null | grep "udp dport 51820" | awk '{print $NF}' | xargs -r -I {} nft delete rule inet filter input handle {} 2>/dev/null || true; nft -a list chain inet filter input 2>/dev/null | grep "iifname \"wg0\"" | awk '{print $NF}' | xargs -r -I {} nft delete rule inet filter input handle {} 2>/dev/null || true
[Peer]
# 其他客户端...
PublicKey = <其他客户端公钥>
AllowedIPs = <其他客户端IP>/32
[Peer]
# 新客户端:pengxin
PublicKey = GGPfzpN4Mf5acZrsJmQf8cRO93uUoJhsAdIitvv2mmM=
AllowedIPs = 192.168.0.100/32
故障排查¶
常见问题诊断¶
1. 客户端显示 0 B received¶
症状:客户端 wg show 显示所有 peer 都是 0 B received, XXX B sent
原因:服务器端防火墙规则缺失或位置错误
解决方案:
# 检查服务器端防火墙规则
sudo nft list chain inet filter input | grep -E "(51820|wg0|drop)"
# 如果缺少规则,手动添加
sudo nft insert rule inet filter input handle 9 udp dport 51820 accept
sudo nft insert rule inet filter input handle 9 iifname "wg0" accept
# 验证规则位置
sudo nft list chain inet filter input | grep -E "(51820|wg0|established)" -A 1 -B 1
2. 规则在 drop 之后(无效)¶
症状:规则存在但连接不通
原因:规则添加在 drop 之后,永远不会被执行
解决方案:
# 检查规则位置
sudo nft list chain inet filter input | grep -E "(51820|wg0|drop)" -A 1 -B 1
# 如果规则在 drop 之后,需要删除并重新添加
# 先删除
sudo nft -a list chain inet filter input | grep "udp dport 51820" | awk '{print $NF}' | xargs -I {} sudo nft delete rule inet filter input handle {}
sudo nft -a list chain inet filter input | grep "iifname \"wg0\"" | awk '{print $NF}' | xargs -I {} sudo nft delete rule inet filter input handle {}
# 在 handle 9 之前重新添加
sudo nft insert rule inet filter input handle 9 udp dport 51820 accept
sudo nft insert rule inet filter input handle 9 iifname "wg0" accept
3. 规则重复累积¶
症状:每次重启后规则重复添加
原因:PostDown 没有正确删除规则
解决方案:
- 确保 PostDown 包含删除规则的命令
- 或者在 PostUp 中先删除可能存在的规则
快速命令参考¶
WireGuard 管理¶
# 查看配置
sudo cat /etc/wireguard/wg0.conf
# 查看状态
sudo wg show
# 重启服务
sudo systemctl restart wg-quick@wg0
# 检查端口
sudo ss -ulnp | grep 51820
nftables 防火墙管理¶
# 查看 input 链
sudo nft list chain inet filter input
# 查看带 handle 的规则
sudo nft -a list chain inet filter input
# 查找特定规则
sudo nft list chain inet filter input | grep -E "(51820|wg0)"
# 手动添加规则(在 handle 9 之前)
sudo nft insert rule inet filter input handle 9 udp dport 51820 accept
sudo nft insert rule inet filter input handle 9 iifname "wg0" accept
# 删除规则(需要知道 handle)
sudo nft -a list chain inet filter input | grep "udp dport 51820" | awk '{print $NF}' | xargs -I {} sudo nft delete rule inet filter input handle {}
客户端配置信息¶
macOS 安装 WireGuard¶
方法一:使用 Homebrew(推荐)¶
方法二:使用 Mac App Store¶
- 打开 Mac App Store
- 搜索 "WireGuard"
- 安装官方 WireGuard 应用
注意:使用 Mac App Store 版本时,配置文件的路径和启动方式可能不同。
生成密钥对¶
# 创建配置目录
mkdir -p ~/.wireguard
# 生成密钥对
cd ~/.wireguard
wg genkey | tee privatekey | wg pubkey > publickey
# 查看公钥(需要发送给服务器管理员)
cat publickey
客户端配置示例¶
[Interface]
PrivateKey = <客户端私钥>
Address = 192.168.0.100/32
[Peer]
# cab4
PublicKey = jLSYsezLxQ2n4uuTvCJYIktBNy1RiPLzxr0WrjiYFiQ=
Endpoint = 167.114.208.35:51820
AllowedIPs = 192.168.0.1/32, 192.168.0.101/32
PersistentKeepalive = 25
[Peer]
# cab5
PublicKey = s1LYdLBpNsb6NmCI3csTPD4jxms/IiEhF50WL9puvGI=
Endpoint = 167.114.208.45:51820
AllowedIPs = 192.168.0.2/32, 192.168.0.102/32
PersistentKeepalive = 25
客户端管理命令(macOS)¶
# 启动 WireGuard
sudo wg-quick up ~/.wireguard/wg0.conf
# 停止 WireGuard
sudo wg-quick down wg0
# 或
sudo wg-quick down utun6
# 查看状态
sudo wg show
重要提示¶
- 动态 IP 客户端:客户端 IP 不固定,使用
PersistentKeepalive = 25保持连接 - 服务器端不需要 Endpoint:客户端配置中需要指定服务器的 Endpoint,但服务器端不需要配置客户端的 Endpoint
- macOS 接口名称:macOS 上 WireGuard 接口可能是
utun6而不是wg0,这是正常的