侧边栏壁纸
博主头像
いちごみるく

行动起来,活在当下

  • 累计撰写 70 篇文章
  • 累计创建 48 个标签
  • 累计收到 55 条评论

目 录CONTENT

文章目录

WireGuard 服务端与客户端配置:密钥权限、IPv4 与 IPv6 出口

示例中的域名、地址和接口名需要按自己的部署替换。

本文以 Debian/Ubuntu 上的 wg-quick 为例,先配置客户端访问服务器的隧道地址,再按需要增加 IPv4 或 IPv6 出口。WireGuard 只负责隧道加密;公网连通性还取决于路由、转发、防火墙和上游网络。

安装与密钥权限

下面的服务器命令以 root 执行。服务器需要放行所选的 UDP 端口;示例使用 51820/udp,云平台安全组也需要核对。

apt update
apt install -y wireguard
install -d -m 700 /etc/wireguard
cd /etc/wireguard
# 仅用于首次生成;存在任一同名文件时停止,避免覆盖正在使用的密钥。
if test -e wg0.conf || test -e server.key || test -e server.pub || \
   test -e client1.key || test -e client1.pub || test -e client1.psk; then
  printf '%s\n' '已存在配置或密钥,请使用现有文件,不要重复生成。' >&2
else
  umask 077
  wg genkey > server.key
  wg pubkey < server.key > server.pub
  wg genkey > client1.key
  wg pubkey < client1.key > client1.pub
  wg genpsk > client1.psk
  chmod 600 server.key client1.key client1.psk
fi

/etc/wireguard 应为 0700,私钥、预共享密钥与含密钥的配置文件应为 0600。目录权限 0777 会允许其他本地用户改写密钥文件,不应使用。客户端私钥最好在客户端本地生成;这里集中生成只为说明公私钥的对应关系,传输后应删除服务器上的客户端私钥副本。

每增加一个客户端,都重新生成一组密钥和独立预共享密钥,分配唯一的 IPv4 /32、IPv6 /128 地址;不同 Peer 不能复制同一公钥。

服务器和客户端配置

服务器 /etc/wireguard/wg0.conf:将三个大写占位符替换为对应文件的内容,不能填写文件路径。

[Interface]
PrivateKey = SERVER_PRIVATE_KEY
Address = 172.16.0.1/24, fd86:ea04:1115::1/64
ListenPort = 51820

[Peer]
PublicKey = CLIENT1_PUBLIC_KEY
PresharedKey = CLIENT1_PRESHARED_KEY
AllowedIPs = 172.16.0.2/32, fd86:ea04:1115::2/128

客户端配置:

[Interface]
PrivateKey = CLIENT1_PRIVATE_KEY
Address = 172.16.0.2/32, fd86:ea04:1115::2/128

[Peer]
PublicKey = SERVER_PUBLIC_KEY
PresharedKey = CLIENT1_PRESHARED_KEY
AllowedIPs = 172.16.0.0/24, fd86:ea04:1115::/64
Endpoint = node.example.com:51820
PersistentKeepalive = 25

node.example.com 必须指向服务器可达的公网地址;直接填写 IPv6 Endpoint 时使用 [IPv6地址]:51820。客户端 AllowedIPs 决定哪些目的地址进入隧道;服务器 Peer 的 AllowedIPs 则限制这个客户端可使用的源地址并选择回程 Peer。

这里的 fd86:ea04:1115::/64 是 ULA,只用于隧道内部,配置成功并不表示客户端获得了公网 IPv6。暂不填 DNS,避免把不可达的局域网 DNS 推给客户端;需要时再指定通过当前路由可以到达的解析器。Linux wg-quick 的 DNS 设置还需要可用的 resolvconf 集成,其他客户端的处理方式不同。

可选:让服务器提供 IPv4 出口

先确认服务器外网接口,下面假设是 eth0。仅当客户端需要访问隧道之外的网络时才打开转发:

cat > /etc/sysctl.d/70-wireguard-forward.conf <<'EOF'
net.ipv4.ip_forward = 1
EOF
sysctl --system

在服务器配置的 [Interface] 内增加以下规则。它们限定隧道源网段和出口,并允许已建立连接的回包;使用 nftables、ufw 或 firewalld 的机器应在原有防火墙中实现等价策略,避免多套规则管理器互相覆盖。

PostUp = iptables -I FORWARD -i %i -o eth0 -s 172.16.0.0/24 -j ACCEPT
PostUp = iptables -I FORWARD -i eth0 -o %i -d 172.16.0.0/24 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -s 172.16.0.0/24 -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -o eth0 -s 172.16.0.0/24 -j ACCEPT
PostDown = iptables -D FORWARD -i eth0 -o %i -d 172.16.0.0/24 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -s 172.16.0.0/24 -o eth0 -j MASQUERADE

然后把客户端 AllowedIPs 改为 0.0.0.0/0, fd86:ea04:1115::/64。这时 IPv4 经服务器出站,IPv6 仍只访问隧道内部。wg-quick 默认会为 IPv4 默认路由配置策略路由,使 Endpoint 的外层 UDP 连接继续走物理网络。

可选:IPv6 出口

服务器必须先能直接访问公网 IPv6,再开启 net.ipv6.conf.all.forwarding = 1。如果物理出口通过 SLAAC/RA 获取默认路由,Linux 开启转发后可能停止接受 RA,需要在实际出口接口上设置 net.ipv6.conf.eth0.accept_ra = 2;静态路由或 DHCPv6 的环境不能照搬这一判断。WireGuard 隧道通常不需要接收 RA。

IPv6 有两条不同路径:

  • 上游提供一个可路由到服务器的前缀:从该前缀给客户端分配公网地址,并让上游把对应路由指向服务器。放行指定地址的转发和回包即可,不需要 NAT66。
  • 上游只给服务器一个地址:可以继续用 ULA,按环境选择 NAT66。客户端并不会因此拥有自己的公网地址,公网入站也不会自动可用。

第二种路径的 ip6tables 示例如下,同样加在服务器 [Interface] 内,并先启用 IPv6 转发:

PostUp = ip6tables -I FORWARD -i %i -o eth0 -s fd86:ea04:1115::/64 -j ACCEPT
PostUp = ip6tables -I FORWARD -i eth0 -o %i -d fd86:ea04:1115::/64 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
PostUp = ip6tables -t nat -A POSTROUTING -s fd86:ea04:1115::/64 -o eth0 -j MASQUERADE
PostDown = ip6tables -D FORWARD -i %i -o eth0 -s fd86:ea04:1115::/64 -j ACCEPT
PostDown = ip6tables -D FORWARD -i eth0 -o %i -d fd86:ea04:1115::/64 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
PostDown = ip6tables -t nat -D POSTROUTING -s fd86:ea04:1115::/64 -o eth0 -j MASQUERADE

确认出口、转发和防火墙都正常后,再把客户端 AllowedIPs 改为 0.0.0.0/0, ::/0。不要直接清空 IPv6 防火墙;ICMPv6 的邻居发现和 Packet Too Big 消息也应按现有网络策略允许。

启动与验证

chmod 600 /etc/wireguard/wg0.conf
systemctl enable --now wg-quick@wg0
wg show wg0
ip address show wg0

使用 systemd 管理时,通过 systemctl stop/start/restart wg-quick@wg0 控制服务;不要同时再次执行 wg-quick up wg0。也可以完全手动使用 wg-quick up/down,但两种管理方式要选定一种。

先检查最新握手和收发计数,再从客户端 ping 172.16.0.1、fd86:ea04:1115::1,最后验证启用的公网出口与 DNS。只有握手成功却不能上网时,优先检查 AllowedIPs、转发与回程规则;小包正常而网页卡住时再检查 MTU 和路径 MTU。

我的家庭基础设施记录也把 WireGuard 配置权限限定为目录 0700、文件 0600,并在使用 RA 的物理出口保留 accept_ra=2。其中移动端 IPv6 曾完成端到端验证,不能由此推定每台服务器的 IPv4、IPv6 出口都可直接套用。

依据:WireGuard Quick Start、wg-quick 手册、Linux IPv6 sysctl。

0

评论区