23 - VPN 配置(WireGuard / OpenVPN)
前提条件
- 已完成 Web 服务、数据库、邮件服务基础配置
- 以 root 身份登录,或 ops 用户执行
sudo -i切换至 root 环境 - 系统运行在 Debian 12 Bookworm
- 防火墙已放行 VPN 端口(WireGuard
51820/udp,OpenVPN1194/udp) - 内核参数
net.ipv4.ip_forward已在第 11 章设为持久化;本章将其启用
全局参数
主机名 linuxdc,IP 192.168.1.100/24,SSH 端口 2222,运维用户 ops
VPN 隧道网段(WireGuard):10.66.66.0/24,服务端地址:10.66.66.1
WireGuard 与 OpenVPN 对比
| 维度 | WireGuard | OpenVPN |
|---|---|---|
| 内核集成 | 是(Linux 5.6+ 原生) | 否(用户态 TUN/TAP) |
| 代码量 | ~4000 行 | ~100000 行 |
| 协议 | 仅 UDP | UDP 或 TCP |
| 配置复杂度 | 低(单文件) | 高(需 PKI 体系) |
| 穿透能力 | UDP 易被封锁 | TCP 443 可伪装成 HTTPS |
| 推荐场景 | 现代内网 VPN、远程访问 | 需 TCP 穿透或兼容旧客户端 |
详细步骤 — WireGuard(推荐)
1. 安装
apt update
apt install -y wireguard
2. 生成服务端密钥对
# 生成私钥并同步输出公钥
wg genkey | tee /etc/wireguard/server-private.key \
| wg pubkey > /etc/wireguard/server-public.key
chmod 600 /etc/wireguard/server-private.key
3. 启用 IP 转发
WireGuard 作为 VPN 网关需要转发数据包:
# 即时生效
sysctl -w net.ipv4.ip_forward=1
# 持久化(写入第 11 章的 sysctl 配置文件)
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.d/99-production.conf
sysctl --system
4. 创建服务端配置
vim /etc/wireguard/wg0.conf
[Interface]
Address = 10.66.66.1/24
ListenPort = 51820
PrivateKey = <粘贴 server-private.key 内容>
# 启动时配置 NAT 转发(ens33 替换为实际网卡名)
PostUp = nft add table nat; nft add chain nat postrouting { type nat hook postrouting priority 100 \; }; nft add rule nat postrouting oif ens33 masquerade
PostDown = nft delete table nat
# 客户端 Peer 示例(下一步添加后填入)
# [Peer]
# PublicKey = <客户端公钥>
# AllowedIPs = 10.66.66.2/32
PostUp 与 iptables / nftables
原文使用 iptables 命令。Debian 12 的防火墙框架为 nftables,本文统一使用 nftables 规则。若系统同时安装了 iptables-nft,两者底层共用 nftables,但混用语法易引起规则冲突,建议统一使用 nftables。
权限保护:
chmod 600 /etc/wireguard/wg0.conf
5. 启动 WireGuard
wg-quick up wg0
systemctl enable wg-quick@wg0
wg show
检查点
wg show 输出显示 interface: wg0、listening port: 51820、public key 等信息。ip addr show wg0 显示 10.66.66.1/24。
防火墙放行:
nft add rule inet filter input udp dport 51820 ct state new accept
nft list ruleset > /etc/nftables.conf
6. 添加客户端 Peer
在服务端生成客户端密钥对(也可在客户端设备上自行生成):
wg genkey | tee /etc/wireguard/client1-private.key \
| wg pubkey > /etc/wireguard/client1-public.key
chmod 600 /etc/wireguard/client1-private.key
将客户端 Peer 追加到服务端配置:
vim /etc/wireguard/wg0.conf
在文件末尾添加:
[Peer]
# 客户端 1
PublicKey = <client1-public.key 内容>
AllowedIPs = 10.66.66.2/32
不重启服务,热加载新 Peer:
wg addconf wg0 <(wg-quick strip wg0)
# 或完整重启
wg-quick down wg0 && wg-quick up wg0
wg show
生成客户端配置文件(client1.conf,发送给客户端导入):
[Interface]
PrivateKey = <client1-private.key 内容>
Address = 10.66.66.2/24
DNS = 8.8.8.8, 8.8.4.4
[Peer]
PublicKey = <server-public.key 内容>
Endpoint = 192.168.1.100:51820
AllowedIPs = 10.66.66.0/24
# AllowedIPs = 0.0.0.0/0 # 全流量路由(开启此行则上一行注释掉)
PersistentKeepalive = 25
AllowedIPs 说明
客户端 AllowedIPs = 10.66.66.0/24 表示只有目标地址在 VPN 隧道网段的流量才走 WireGuard(分流模式,其余流量走默认路由)。若改为 0.0.0.0/0,则所有流量均通过 VPN(全量路由模式)。服务端 AllowedIPs = 10.66.66.2/32 表示该 Peer 只允许使用 10.66.66.2 这个 IP。
详细步骤 — OpenVPN(兼容性方案)
1. 安装
apt install -y openvpn easy-rsa
2. 初始化 PKI 体系
make-cadir /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa
# 初始化 PKI 目录
./easyrsa init-pki
# 创建 CA(交互式,填写 Common Name 如 "LinuxDC-CA")
./easyrsa build-ca nopass
# 生成服务端证书
./easyrsa build-server-full server nopass
# 生成 DH 参数(较慢,需等待)
./easyrsa gen-dh
# 生成 TLS-Auth 密钥(防 DoS)
openvpn --genkey secret /etc/openvpn/ta.key
3. 配置服务端
cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf \
/etc/openvpn/server.conf
vim /etc/openvpn/server.conf
关键配置项:
port 1194
proto udp
dev tun
ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/server.crt
key /etc/openvpn/easy-rsa/pki/private/server.key
dh /etc/openvpn/easy-rsa/pki/dh.pem
tls-auth /etc/openvpn/ta.key 0
server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
user nobody
group nogroup
persist-key
persist-tun
verb 3
systemctl enable --now openvpn@server
ss -tuln | grep 1194
实践任务
- 安装并启动 WireGuard,创建
wg0接口,确认wg show显示listening port: 51820 - 生成客户端密钥对,在服务端添加 Peer,生成
client1.conf配置文件 - 在客户端导入配置(或使用同一台机器的 WireGuard 客户端)连接,
ping 10.66.66.1验证隧道连通 - (可选)安装 OpenVPN,完成 PKI 初始化和服务端配置,确认
1194/udp端口监听
自测问题
1. WireGuard 的 AllowedIPs 在服务端和客户端分别代表什么含义?
在服务端 [Peer] 段:AllowedIPs 是入向过滤规则,只接受源 IP 在该范围内的数据包,同时也是路由规则——当需要发数据给该 Peer 时,将目标地址在 AllowedIPs 范围内的包路由给该 Peer。值通常是客户端的 VPN IP(/32)。
在客户端 [Peer] 段:定义哪些目标网段的流量应当发送到该 Peer(即 VPN 服务端)。10.66.66.0/24 表示只有访问 VPN 内网的流量走隧道(分流);0.0.0.0/0 表示所有流量都走隧道(全量代理)。
2. 为什么 WireGuard 推荐使用 UDP 而 OpenVPN 支持 TCP 和 UDP?
VPN 协议本身通常会在隧道内承载 TCP 流量。若外层也使用 TCP,内层 TCP 的重传机制与外层 TCP 的重传机制会相互叠加,在网络抖动时产生"TCP-over-TCP"性能崩溃问题(双重超时等待)。UDP 作为外层传输层可避免此问题,且延迟更低。WireGuard 设计时选择只支持 UDP,以保持协议的简洁性和高性能。OpenVPN 支持 TCP 的主要原因是穿越某些只允许 TCP 443 的受限网络(如企业防火墙),而非性能优势。
3. 在 PostUp/PostDown 中为什么要添加 MASQUERADE 规则?
WireGuard 建立的是第三层 VPN 隧道,客户端获得 10.66.66.x 的隧道 IP。当客户端通过 VPN 访问互联网或其他内网资源时,数据包的源地址是 10.66.66.x,目标网络不认识这个地址,无法将响应包路由回来。MASQUERADE(源地址转换,SNAT 的动态形式)将出站数据包的源地址替换为 VPN 服务器的物理网卡 IP(192.168.1.100),使目标网络认为请求来自服务器本身,响应包返回到服务器后再转发给客户端。
4. 如何让 WireGuard 客户端只路由特定网段(分流)而不是全流量?
将客户端 [Peer] 段的 AllowedIPs 设置为需要走 VPN 的具体网段,而非 0.0.0.0/0:
# 只有访问 VPN 内网的流量走隧道,其余流量走本地默认路由
AllowedIPs = 10.66.66.0/24, 192.168.1.0/24
这样客户端访问 10.66.66.x(VPN 内网)和 192.168.1.x(服务器侧局域网)的流量走 WireGuard 隧道,其他流量(访问互联网等)直接走本地网络,既减少了 VPN 服务器带宽压力,也降低了延迟。
总结
WireGuard 是当前主流首选的 VPN 方案,配置极简、性能优秀、代码量少易于审计;OpenVPN 在需要 TCP 穿透或兼容旧设备的场景下仍有价值。本章搭建了基本的远程访问 VPN,为后续高可用、跨节点通信、远程运维提供安全隧道基础。