跳转至

OpenVPN 实战上手:原理、部署、解决什么问题

写在前面

很多运维同学的第一次 OpenVPN,都是在这种场景下被推上去的:

老板:「研发要在家里访问公司内网的测试环境,你给配个 VPN。」
你:「好的。」(心里:什么是 VPN?)

或者面试的时候:

面试官:「你们生产环境运维通道用的什么方案?」
你:「FRP。」
面试官:「OpenVPN 用过吗?讲讲它的原理。」
你:「……」

这篇文章的目标,就是让一个没碰过 OpenVPN 的运维,用一两个小时建立起一套能在面试讲清楚、能在生产部署起来的认知

不会展开密码学和 TLS 握手的所有细节,重点放在:

  • OpenVPN 到底是个什么东西、解决什么问题
  • 它和 FRP、WireGuard、IPSec 是什么关系
  • 工作原理(一张图就能讲清楚)
  • 一套最小可用的部署流程
  • 客户端账号怎么签发、怎么吊销
  • 生产里的常见坑和面试常被问的点

一句话理解 OpenVPN

OpenVPN = 把一根"加密的虚拟网线"插进你的电脑,让你的电脑像物理接进了公司机房的内网一样。

拆开看:

  • "虚拟网线"——通过软件创建一张虚拟网卡(tun0),系统觉得你接了一根新网线
  • "加密的"——所有走这根线的流量都被 TLS 加密
  • "插进公司内网"——VPN 服务端帮你转发流量到内网的真实服务

跟 FRP 的核心区别一句话:

FRP 是"把内网的某个服务搬到公网",OpenVPN 是"把你这个人塞进内网"。

这个区别在面试里几乎必问,下面会再展开。

它解决什么问题

典型场景:

flowchart LR
    User[研发同学<br/>在家/出差] -.X.- Office[公司内网<br/>10.0.0.0/8]
    Office --> DB[(MySQL 测试库)]
    Office --> K8s[K8s 集群]
    Office --> Wiki[Confluence]

研发要访问内网的 MySQL、K8s Dashboard、Wiki,没 VPN 就得:

  • 把每个服务都开公网端口 → 安全灾难
  • 一个个用 FRP 暴露 → 服务多了管不过来,且每个都要开口子
  • 上跳板机 SSH 转发 → 体验差,K8s Dashboard / IDE 直连这些场景搞不定

OpenVPN 的解法:连上 VPN 后,研发的电脑获得一个 VPN 隧道 IP(比如 10.8.0.5),服务端再把去公司内网的流量转发过去。从使用体验上看,他像是接进了公司机房局域网;但最终能访问哪些网段,取决于服务端下发的路由、内核转发、NAT 或内网回程路由。

flowchart LR
    User[研发<br/>本地获得 10.8.0.5] -->|加密隧道| VPN[OpenVPN 服务端<br/>公网 IP]
    VPN -->|转发| Office[公司内网]
    Office --> DB[(MySQL)]
    Office --> K8s[K8s]
    Office --> Wiki[Wiki]

OpenVPN 在 VPN 家族里的位置

VPN 不是一个东西,而是一类技术。常见的有:

方案 协议层 典型场景 特点
OpenVPN 应用层(TLS over UDP/TCP) 远程办公接入 跨平台、防火墙穿透好、配置灵活
WireGuard 内核态(UDP) 站点互联、性能敏感 极简、超快、新世代
IPSec / L2TP 网络层 企业级站点对站点 老牌、复杂、防火墙容易拦
SSL VPN(Pulse/SonicWall) 应用层 商业堡垒接入产品 一般要付费、带 Web 控制台

OpenVPN 的定位:老牌、稳定、跨平台、社区生态最成熟。新项目今天会推荐 WireGuard,但企业里存量 OpenVPN 集群很多,仍然是必备技能

面试时如果对方问"为什么不用 WireGuard",标准回答:

WireGuard 性能更好、配置更简单,新建项目我会优先选 WireGuard。但 OpenVPN 在「客户端兼容性、用户认证体系(PAM/LDAP)、证书撤销列表(CRL)、灵活路由」上更成熟,存量企业场景仍然是主力。

工作原理:一张图讲完

sequenceDiagram
    participant App as 客户端 App<br/>(浏览器/MySQL Workbench)
    participant Tun as 本地 tun 虚拟网卡
    participant Client as OpenVPN 客户端进程
    participant Server as OpenVPN 服务端
    participant Intra as 公司内网

    Note over Client,Server: 1. TLS 握手期间交换并验证证书
    Client->>Server: ClientHello(发起握手、协商参数)
    Server->>Client: ServerHello + Certificate(返回服务端证书)
    Client->>Server: Certificate(提交客户端证书)
    Note over Client,Server: 2. 协商会话密钥<br/>分配虚拟 IP(10.8.0.5)

    App->>Tun: 我要访问 10.0.0.20:3306
    Tun->>Client: 内核把包交给 OpenVPN 进程
    Client->>Server: 加密封装后从公网发出(UDP 1194)
    Server->>Server: 解密 → 拿到原始 IP 包
    Server->>Intra: 按路由或 NAT 转发到 10.0.0.20:3306
    Intra->>Server: MySQL 响应
    Server->>Client: 加密回包
    Client->>Tun: 解密
    Tun->>App: App 拿到响应

关键概念:

  • tun 设备:内核里的"虚拟网卡",OpenVPN 进程从它那里收发 IP 包
  • 加密:用 TLS(OpenSSL 库),既加密内容也校验身份
  • 证书互认:服务端验客户端证书、客户端验服务端证书 —— 它比"只靠账号密码"更适合作为强身份基础,但前提是私钥独立保管、离职及时吊销
  • 路由下发:服务端在握手成功后会推送一组路由(push "route 10.0.0.0 255.0.0.0")给客户端,客户端的 10.0.0.0/8 流量就自动走 VPN

tun 和 tap 的区别(高频面试题)

  • tun 模式(推荐):工作在 IP 层(L3),虚拟网卡进出的是 IP 包。跨网段路由用这个
  • tap 模式:工作在以太网层(L2),出入的是完整以太网帧。桥接用这个(让 VPN 客户端获得跟服务端同一个广播域,能跑 ARP、DHCP、组播)。

99% 的远程办公场景用 tun。tap 主要用在「让远程用户像物理插了网线一样在内网做 PXE 启动、Wake-on-LAN」这类奇葩需求。

一套最小可用部署(CentOS/Ubuntu 通用)

下面用「Easy-RSA + 原生 OpenVPN」最经典的方式过一遍。生产里可以用自动化脚本、受维护的镜像或平台化方案来降低操作成本,但理解原生流程是基础。

1. 装 OpenVPN 和 Easy-RSA

# Ubuntu/Debian
apt install -y openvpn easy-rsa

# CentOS/RHEL
yum install -y epel-release
yum install -y openvpn easy-rsa

2. 搭建自己的 CA(这是 OpenVPN 的精髓)

make-cadir /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa

# 初始化 PKI 体系
./easyrsa init-pki

# 生成根 CA(会让你设密码,记住,签发客户端证书时要用)
./easyrsa build-ca

# 生成服务端证书 + 私钥
./easyrsa build-server-full server nopass

# 生成 Diffie-Hellman 参数(用来做前向安全密钥交换,会很慢,几分钟)
./easyrsa gen-dh

# 生成初始 CRL,后面 crl-verify 会用到
./easyrsa gen-crl

# 准备 OpenVPN 服务端运行目录
mkdir -p /etc/openvpn/server
install -m 644 pki/crl.pem /etc/openvpn/server/crl.pem

# 生成 tls-crypt 密钥,保护控制信道并减少无效握手消耗
openvpn --genkey tls-crypt /etc/openvpn/server/ta.key
# 如果发行版里的 OpenVPN 还不支持上面写法,可以退回:
# openvpn --genkey --secret /etc/openvpn/server/ta.key

到这一步你拥有了一个自己的小 CA,可以为每个员工签发独立证书。

3. 服务端配置

/etc/openvpn/server/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-crypt /etc/openvpn/server/ta.key

# 给客户端分配 10.8.0.0/24 网段
topology subnet
server 10.8.0.0 255.255.255.0

# 把公司内网路由推给客户端
push "route 10.0.0.0 255.0.0.0"

# 把 DNS 也推给客户端(让 wiki.intra 能解析)
push "dhcp-option DNS 10.0.0.2"

# 数据通道加密套件(OpenVPN 2.5+ 推荐写法)
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305
auth SHA256

# 客户端断线后保留 IP 分配,方便重连
ifconfig-pool-persist ipp.txt

# 限制最大连接数
max-clients 100

# 日志
status /var/log/openvpn-status.log
log    /var/log/openvpn.log
verb 3

# 让多个客户端可以互相通信(按需开)
# client-to-client

# 撤销列表(吊销用户证书后必填)
crl-verify /etc/openvpn/server/crl.pem

# 可选:用于踢掉在线会话
management /run/openvpn/server.sock unix
management-client-user root
management-client-group root

这里有一个很重要的取舍:如果服务端做 NAT,内网服务看到的源地址通常是 VPN 服务端的内网地址,配置最简单;如果不做 NAT,而是让内网路由器知道 10.8.0.0/24 怎么回到 OpenVPN 服务端,内网服务就能看到真实 VPN 客户端 IP,更利于审计。

启动:

# 开启内核转发(关键,否则 VPN 进得来出不去)
sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf

# 配置 NAT,让 VPN 客户端能访问内网(假设 eth0 是去内网的网卡)
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

# 放行 OpenVPN 端口,实际命令按你的防火墙工具调整
# ufw allow 1194/udp
# firewall-cmd --permanent --add-port=1194/udp && firewall-cmd --reload

systemctl enable --now openvpn-server@server

上面的 iptables 只是即时生效。生产里要用 iptables-save、firewalld、nftables 或云厂商安全组把规则持久化,否则机器重启后规则会丢。

4. 给员工签发证书

每个员工一套独立证书。这是 OpenVPN 的核心安全模型

cd /etc/openvpn/easy-rsa

# 给"zhangsan"签发
# 演示环境为了导入方便用了 nopass;生产更建议给私钥加密码,或叠加 LDAP/TOTP
./easyrsa build-client-full zhangsan nopass

# 生成的文件
ls pki/issued/zhangsan.crt
ls pki/private/zhangsan.key

把以下 5 个文件打包给员工:

  • ca.crt(根证书)
  • zhangsan.crt(员工证书)
  • zhangsan.key(员工私钥)
  • ta.key(防 DoS 预共享密钥)
  • client.ovpn(连接配置)

注意:zhangsan.key 是员工私钥,泄露后基本等于这个 VPN 身份泄露。不要用聊天工具随手传,生产里最好结合私钥密码、LDAP/TOTP 和离职吊销流程。

client.ovpn 模板:

client
dev tun
proto udp
remote vpn.example.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun

remote-cert-tls server
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305
auth SHA256

ca   ca.crt
cert zhangsan.crt
key  zhangsan.key
tls-crypt ta.key

verb 3

更专业的做法:把 5 个文件内联进单个 .ovpn 文件(用 <ca>...</ca><cert>...</cert> 标签包起来),员工只需要导入一个文件。脚本可以自动生成。

5. 吊销员工证书(员工离职必做)

cd /etc/openvpn/easy-rsa
./easyrsa revoke zhangsan
./easyrsa gen-crl
install -m 644 pki/crl.pem /etc/openvpn/server/crl.pem

# CRL 对新连接/重连生效;已经在线的会话建议主动踢掉
# 下面命令依赖 server.conf 里的 management 配置
printf "kill zhangsan\n" | socat - UNIX-CONNECT:/run/openvpn/server.sock

面试要点:证书吊销能让离职人员的客户端证书失效,但它不替代账号禁用、私钥回收和在线会话清理。生产里通常会把 CRL、LDAP 禁用和踢会话一起做。

生产里的部署捷径

手搓 Easy-RSA 适合学习。生产里可以用脚本或镜像减少重复劳动,但要先确认项目是否仍在维护、默认配置是否符合你们公司的安全基线。

方案 A:openvpn-install 一键脚本

curl -O https://raw.githubusercontent.com/Nyr/openvpn-install/master/openvpn-install.sh
bash openvpn-install.sh

这是社区里常见的一键安装脚本,菜单式选择端口、加密套件、DNS,自动签 CA、生成 client.ovpn。它很适合快速搭环境,但生产执行前一定要审脚本内容、固定版本,并记录生成的 CA、证书和配置。

方案 B:kylemanna/openvpn Docker 镜像

docker volume create openvpn-data

# 初始化配置
docker run -v openvpn-data:/etc/openvpn --rm \
  kylemanna/openvpn ovpn_genconfig -u udp://vpn.example.com

# 初始化 CA(会让你设密码)
docker run -v openvpn-data:/etc/openvpn --rm -it \
  kylemanna/openvpn ovpn_initpki

# 启动
docker run -v openvpn-data:/etc/openvpn -d \
  -p 1194:1194/udp --cap-add=NET_ADMIN \
  --name openvpn kylemanna/openvpn

# 签客户端
docker run -v openvpn-data:/etc/openvpn --rm -it \
  kylemanna/openvpn easyrsa build-client-full zhangsan nopass
docker run -v openvpn-data:/etc/openvpn --rm \
  kylemanna/openvpn ovpn_getclient zhangsan > zhangsan.ovpn

优点:所有状态在一个 docker volume 里,迁移、备份比较方便。需要注意的是,镜像方案要看维护状态;如果镜像多年不更新,就更适合作为学习或小规模内网工具,生产最好选择仍在维护的镜像,或者自己构建基础镜像。

客户端账号管理的几种姿势

方式 易用性 安全性 适合
仅证书 一般 内部团队、人数固定
证书 + 用户名密码(PAM/LDAP) 较好 很高 推荐:能复用公司 AD/LDAP
证书 + TOTP(Google Authenticator) 极高 安全敏感场景,开 2FA
仅用户名密码(不带证书) 不推荐

最常见的生产姿势是 证书 + LDAP,用 openvpn-auth-ldap 插件接公司 AD:

# server.conf 加这行
plugin /usr/lib/openvpn/plugins/openvpn-auth-ldap.so /etc/openvpn/auth-ldap.conf

这样员工的 OpenVPN 账号自动跟着 AD 走。离职禁用 AD 账号后,后续认证会失败;同时仍建议吊销证书并踢掉已经在线的会话。

路由模式:split tunnel vs full tunnel

# split tunnel(默认推荐):只把内网流量走 VPN,刷抖音不走
push "route 10.0.0.0 255.0.0.0"

# full tunnel:所有流量走 VPN(适合在不可信 WiFi 防嗅探)
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 10.0.0.2"

full tunnel 不是只加一行路由就完事。服务端还要能把客户端的公网流量 NAT 出去,并且 DNS 要走可信解析器,否则用户会出现“连上 VPN 后不能上网”或者 DNS 泄露的问题。

面试 Tip:能讲清这两种模式的差别和适用场景,会显得你确实做过远程接入方案设计。

常见故障排查

现象 多半原因
客户端连上了,但 ping 不通内网 IP 服务端 ip_forward=0 或者 NAT/路由没配
客户端连上了,能 ping IP 但解析不了内部域名 没 push DNS,或客户端没接受 push 的 DNS
连接频繁断开 客户端在弱网(4G/酒店 WiFi),优先看丢包和 MTU;UDP 被限速/丢弃时再临时试 proto tcp
突然所有人连不上 服务端证书过期、ta.key 不一致、CRL 文件损坏、防火墙或安全组变更
某个用户连不上其他人能 证书过期/被吊销,客户端文件没下发对,或 LDAP/TOTP 认证失败

排查命令:

# 服务端日志
tail -f /var/log/openvpn.log

# 当前连接状态
cat /var/log/openvpn-status.log

# 抓握手包
tcpdump -i eth0 udp port 1194 -nn

# 客户端调试模式(加详细日志)
openvpn --config zhangsan.ovpn --verb 6

面试可能被问到的点(重点)

Q1:OpenVPN 和 FRP 有什么区别?

  • FRP:把内网某个端口暴露到公网,面向"服务"。一个内网 MySQL 暴露成公网 IP:3306。访问者拿到的是公网入口
  • OpenVPN:把人接进一个受控的 VPN 隧道,面向"用户"。用户连上后获得隧道 IP,再通过路由或 NAT 访问内网资源。
  • 选型:少量服务对外、临时调试 → FRP;多人远程办公、要访问大量内网资源 → OpenVPN/WireGuard。

Q2:OpenVPN 怎么保证安全?

  • TLS 控制信道加密 + 数据通道加密(例如 AES-256-GCM / CHACHA20-POLY1305)
  • 双向证书认证(服务端验客户端、客户端验服务端)
  • 私有 CA + 每人独立证书
  • 离职可吊销证书(CRL),并踢掉在线会话
  • 可叠加 LDAP 账号密码、TOTP 二次认证

Q3:tun 和 tap 的区别?

  • tun = L3,IP 包,跨网段路由场景,99% 用这个
  • tap = L2,以太网帧,桥接场景(PXE、组播)

Q4:UDP 还是 TCP?

默认 UDP:低延迟、不会"TCP over TCP"(嵌套 TCP 重传性能灾难)。 TCP 兜底:在严格防火墙、酒店 WiFi 这类只放行 80/443 的环境,可以把 OpenVPN 改成 tcp/443 试试。注意这只是跑在 443 端口,不等于真正的 HTTPS 流量,深度检测仍然可能识别。

Q5:你怎么管理 OpenVPN 用户?离职了怎么办?

  • 入职:管理员用 Easy-RSA 签发独立证书 + 生成 .ovpn 文件下发
  • 日常:账号接 LDAP,跟着公司 AD 一起管
  • 离职:执行 easyrsa revoke + gen-crl 更新 CRL,禁掉 LDAP 账号,并通过 management 接口踢掉已在线会话

Q6:OpenVPN 高可用怎么做?

  • 多节点 + DNS 轮询 / 支持 UDP 的公网 LB,可以解决入口故障
  • 状态(IP 池、CRL、CA/证书材料)放共享存储或定时同步
  • 客户端 .ovpn 里写多个 remote vpn1.example.com 1194remote vpn2.example.com 1194,可以重连 failover,但不是无缝会话迁移

Q7:你为什么不上 WireGuard?

WireGuard 性能更好、内核态、配置简单。新项目我会优先选 WireGuard。OpenVPN 留给以下场景: - 已有的存量集群 - 需要 LDAP / AD 集成 - 客户端环境很杂(老 Windows、出差时只能用第三方 OpenVPN 客户端) - 需要严格的证书撤销列表(CRL)和审计

一句话总结

OpenVPN = 让你这个"人"通过加密隧道虚拟接入到公司内网,靠的是「自建 CA + 双向证书 + tun 虚拟网卡」三件套。

把「证书签发吊销、tun/tap 区别、split/full tunnel、UDP/TCP 选型、与 FRP 的差异」这五件事讲清楚,面试基本不会被卡。