什么时候该用 OpenVPN 而不是 WireGuard
近几年 WireGuard 因为配置简单、性能高,几乎成了自建 VPN 的默认选择,本站也写过 WireGuard 的实战。但 OpenVPN 并没有过时,它仍在几个场景里更合适:一是需要 TCP 443 端口伪装成普通 HTTPS 流量、穿越严格防火墙的场景;二是需要成熟的证书体系(PKI)来管理大量客户端、按人吊销权限的场景;三是客户端平台老旧、需要最大兼容性的场景。OpenVPN 基于 OpenSSL 的证书体系,天然支持「一人一证、离职即吊销」,这在需要给多个人或设备分配访问权时非常省心。
本文按完整流程走一遍:安装、用 Easy-RSA 搭建 CA、签发服务端与客户端证书、写好服务端配置、生成客户端配置文件、开启转发与防火墙,以及最后的连通性验证。所有命令在 Debian 12 上实测通过,CentOS/Rocky 的差异会单独标注。
安装 OpenVPN 与 Easy-RSA
Debian/Ubuntu:
apt update
apt install -y openvpn easy-rsaCentOS / Rocky:
yum install -y epel-release
yum install -y openvpn easy-rsa验证:
openvpn --version | head -1
ls /usr/share/easy-rsaEasy-RSA 是 OpenVPN 官方的 PKI 管理脚本,用它来建 CA、签证书比手写 openssl 命令省太多事。
用 Easy-RSA 搭建证书颁发机构
先把 Easy-RSA 的模板复制到一个专门的目录,后续所有证书都在这里生成:
make-cadir /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa如果你用的是 Easy-RSA 3.x(现代版本),配置方式是通过 vars 文件或 ./easyrsa --vars= 传入。先初始化 PKI 目录:
./easyrsa init-pki接着建 CA。CA 是整个信任链的根,私钥 ca.key 一定要保管好,绝不能泄露,它签发的所有证书都依赖它。这一步会要求输入 CA 的 Common Name:
./easyrsa build-ca nopass生产环境给 CA 私钥设密码更安全(去掉 nopass),但要接受每次签发都要输密码。个人站按自己习惯取舍。建完后 pki/ca.crt 就是根证书。
签发服务端证书
OpenVPN 3.x 用 gen-req 生成请求、sign-req 签名两步走。先为服务端生成密钥和请求:
./easyrsa gen-req server nopass再用 CA 签名:
./easyrsa sign-req server server服务端还需要一组 Diffie-Hellman 参数用于密钥交换,生成它比较慢,放着跑就行:
./easyrsa gen-dh另外现代 OpenVPN 推荐加一层 TLS 认证密钥 ta.key,它能缓解 DoS 与端口扫描:
openvpn --genkey secret ta.key把服务端需要的东西复制到 /etc/openvpn/server/:
cp pki/ca.crt pki/issued/server.crt pki/private/server.key \
pki/dh.pem ta.key /etc/openvpn/server/签发客户端证书(一人一证)
给每个客户端单独签发证书,这是 OpenVPN 相比 WireGuard 的核心优势。以客户端 alice 为例:
./easyrsa gen-req alice nopass
./easyrsa sign-req client alice将来要吊销某个客户端,只需:
./easyrsa revoke alice
./easyrsa gen-crl然后把生成的 pki/crl.pem 复制到服务端目录,并在服务端配置里用 crl-verify 指向它,吊销即时生效。这一套「签发—吊销」流程是 OpenVPN 管理多用户的杀手锏,WireGuard 要手工维护 peer 列表,规模一大就很痛苦。
服务端配置详解
写 /etc/openvpn/server/server.conf:
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
tls-auth ta.key 0
crl-verify crl.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 8.8.8.8"
keepalive 10 120
cipher AES-256-GCM
auth SHA256
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
verb 3几个要点:dev tun 是三层隧道,比 tap 性能好、跨平台更稳;server 10.8.0.0 定义 VPN 内网段;tls-auth ta.key 0 里的 0 表示服务端方向(客户端用 1);redirect-gateway def1 把所有流量导向 VPN,如果你只想访问内网而不全局代理,就去掉这行推送。若你的网络环境封 UDP,把 proto 改成 tcp、port 改成 443,流量看起来就像普通 HTTPS,穿透性大增。
开启内核转发与防火墙
要让客户端能通过服务器访问外网,必须开启 IP 转发:
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.d/99-openvpn.conf
sysctl --system然后配置 NAT(源地址伪装)。如果你用 iptables:
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE注意把 eth0 换成你服务器实际的公网网卡名(用 ip route get 1.1.1.1 可以看出来)。如果用的是 nftables 或 firewalld,思路一样:允许 tun0 接口的转发流量,并对外网口做 masquerade。别忘了放行 OpenVPN 的端口:
iptables -A INPUT -p udp --dport 1194 -j ACCEPT持久化 iptables 规则(Debian 用 iptables-persistent,RHEL 系用 iptables-services),否则重启后 NAT 规则就没了,客户端能连上却上不了网,这是最常见的「连上但没网」故障。
启动服务与生成客户端配置
用 systemd 启动并设为开机自启:
systemctl enable --now openvpn-server@server
systemctl status openvpn-server@server日志有问题就看 journalctl -u openvpn-server@server -n 50。服务起来后,生成客户端配置文件。客户端需要这些文件:ca.crt、alice.crt、alice.key、ta.key。把它们的内容内联进一个 .ovpn 文件最方便分发:
client
dev tun
proto udp
remote 你的服务器IP 1194
resolv-retry infinite
nobind
persist-key
persist-tun
cipher AES-256-GCM
auth SHA256
key-direction 1
verb 3然后把上面四个文件的内容分别用 <ca>...</ca>、<cert>...</cert>、<key>...</key>、<tls-auth>...</tls-auth> 包裹追加到文件末尾,客户端导入这个单一文件即可。注意客户端 key-direction 要写 1,和服务端的 0 相反。
连通性验证与常见故障
客户端连上后,先在客户端看隧道接口是否有 10.8.0.x 的地址,再 ping 10.8.0.1(服务端隧道地址)。能 ping 通说明隧道本身没问题。接着 ping 8.8.8.8 测外网转发,如果这一步失败,九成是 NAT/转发没配好或没持久化。最后测 DNS,如果不通就检查 push dhcp-option DNS 是否下发。
常见故障清单:一、「连上但没网」看 NAT 与 ip_forward;二、「TLS handshake failed」多半是证书不匹配或 ta.key 方向弄反;三、「AUTH_FAILED」通常是客户端证书被吊销而 crl.pem 没更新;四、UDP 被墙就换 TCP 443;五、网卡名写错导致 masquerade 不生效,用 ip route get 确认出口网卡。
多客户端管理:把签发与吊销脚本化
当客户端多起来,手工敲 gen-req 加 sign-req 会变得很啰嗦。可以把整套流程固化成一个脚本,一个命令完成「签发证书 + 生成内联 .ovpn 文件」。脚本框架大致是这样:
#!/bin/bash
set -euo pipefail
NAME="$1"
cd /etc/openvpn/easy-rsa
./easyrsa gen-req "$NAME" nopass
./easyrsa sign-req client "$NAME"
# 拼装 ovpn
OUT=/root/clients/$NAME.ovpn
mkdir -p /root/clients
cat > "$OUT" <<'HEAD'
client
dev tun
proto udp
remote 你的服务器IP 1194
resolv-retry infinite
nobind
persist-key
persist-tun
cipher AES-256-GCM
auth SHA256
key-direction 1
verb 3
HEAD
for t in ca cert key tls-auth; do :; done
echo "<ca>" >> "$OUT"; cat pki/ca.crt >> "$OUT"; echo "</ca>" >> "$OUT"
echo "<cert>" >> "$OUT"; cat pki/issued/$NAME.crt >> "$OUT"; echo "</cert>" >> "$OUT"
echo "<key>" >> "$OUT"; cat pki/private/$NAME.key >> "$OUT"; echo "</key>" >> "$OUT"
echo "<tls-auth>" >> "$OUT"; cat ta.key >> "$OUT"; echo "</tls-auth>" >> "$OUT"
echo "generated $OUT"一个命令 ./gen-client.sh alice,就得到一个可直接分发的 alice.ovpn。吊销则单独写一个脚本,把 revoke、gen-crl、复制 crl 到服务端目录、重启服务这几步串起来。把这两个脚本放进版本控制,客户端权限的变更就有了记录。
要特别注意:.ovpn 文件里内联了客户端私钥,等同于一把钥匙,分发时务必走加密渠道(比如临时设置下载链接过期、或用 SSH/scp 直接传),别直接丢在公开目录或聊天群里。私钥泄露,别人就能冒充该客户端接入你的内网。
安全加固:别只靠证书
证书体系是基础,但还能再叠几层保险。第一层是前面提到的 tls-auth ta.key,它能过滤掉大量不带正确 TLS 认证密钥的探测流量。如果服务端是较新版本,可以换成 tls-crypt ta.key,在认证之外还给整个控制通道加密,效果更好。第二层是服务端加 duplicate-cn 的取舍——默认同一张证书只允许一个连接,这在「一人一设备」的严格策略下很合适;若你要让同一个人多设备同时在线,就得开 duplicate-cn,但要接受一张证书泄露的影响面变大。第三层是配合防火墙,只放行 1194 端口,并对 SSH 之外的端口保持最小开放。
还有一条常被忽视的:定期检查 openvpn-status.log,看看有没有陌生的客户端连上来、有没有异常的大量连接。状态日志里有每个客户端的虚拟 IP、真实 IP、连接时长与流量,定期扫一眼,比事后才发现有人长期蹭你的隧道强。
性能调优与服务端参数
OpenVPN 是用户态实现,吞吐量天生不如内核态的 WireGuard,但通过参数仍能明显改善。首先是加密算法选 AES-256-GCM,它在支持 AES-NI 指令集的 CPU 上走硬件加速,比老的 CBC 模式快很多。其次,如果 CPU 支持,可以确认 AES-NI 是否开启(grep aes /proc/cpuinfo),没开的话在多核机器上可以考虑开多实例分摊。再者,mssfix 与 fragment 参数要慎用,配错了会让性能不升反降,通常在现代网络环境下不需要动。最后,如果跑的是大量客户端,把 max-clients 和线程模型调整好,并监控 CPU 使用率,别等到隧道卡了才发现是单核跑满。
备份与迁移:别让 PKI 丢在单台机器上
整条 OpenVPN 的信任链都建立在 /etc/openvpn/easy-rsa/pki 这个目录上:CA 私钥、签发过的所有证书、吊销列表都在里面。如果这台机器磁盘损坏而你又没有备份,结果不只是 VPN 断了,而是你无法再为任何客户端签发或吊销证书,只能重建一套全新的 PKI,然后挨个给所有客户端重新分发配置。所以务必把整个 pki 目录连同 ta.key 一起定期备份到离线或另一台机器,并给备份本身加密——CA 私钥落到别人手里,对方就能签发出被你完全信任的客户端证书,这是最危险的情况。
万一需要把 OpenVPN 服务迁移到新服务器,流程其实不复杂:在新机器装好同样的软件包,把 /etc/openvpn 整个目录拷过去(内含 server.conf、证书与 ta.key),确认新机器的网卡名和端口放行一致,再改一下客户端 .ovpn 里的 remote 地址即可。因为证书体系是自包含的,客户端证书完全不用重签,这也是自建 PKI 相比依赖第三方的一个隐性好处。
小结
OpenVPN 的门槛主要在 PKI 这一套证书流程,但一旦理解和跑通,它带来的价值是清晰的:一人一证、按需吊销、TCP 伪装、跨平台兼容。对于需要给多人多设备分配内网访问权的个人站长,OpenVPN 依然是比 WireGuard 更适合的选择。把 Easy-RSA 的签发与吊销流程固化成脚本,把内核转发与 NAT 持久化配好,剩下的事就是按需签发客户端证书了。