跳转至

23 - VPN 配置(WireGuard / OpenVPN)

前提条件

  • 已完成 Web 服务、数据库、邮件服务基础配置
  • 以 root 身份登录,或 ops 用户执行 sudo -i 切换至 root 环境
  • 系统运行在 Debian 12 Bookworm
  • 防火墙已放行 VPN 端口(WireGuard 51820/udp,OpenVPN 1194/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: wg0listening port: 51820public 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

实践任务

  1. 安装并启动 WireGuard,创建 wg0 接口,确认 wg show 显示 listening port: 51820
  2. 生成客户端密钥对,在服务端添加 Peer,生成 client1.conf 配置文件
  3. 在客户端导入配置(或使用同一台机器的 WireGuard 客户端)连接,ping 10.66.66.1 验证隧道连通
  4. (可选)安装 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,为后续高可用、跨节点通信、远程运维提供安全隧道基础。