RockyLinux OpenVPN
第 1 步:安装软件包
sudo dnf install epel-release openvpn easy-rsa -y
第 2 步:设置 PKI (证书颁发机构)
2.1 准备 Easy-RSA 目录:
创建目录:
mkdir /etc/openvpn/easy-rsa
创建指向已安装的 easy-rsa 包文件的符号链接。
建立一个软连接,不用cp复制文件过来了
ln -s /usr/share/easy-rsa/3/* /etc/openvpn/easy-rsa/
2.2 初始化 PKI。
切换到该easy-rsa目录并初始化新的 PKI 环境。
cd /etc/openvpn/easy-rsa
sudo ./easyrsa init-pki
2.3 构建 CA(证书颁发机构)
这会创建你的根证书,用于签署所有其他证书。按照提示输入相关信息(Common Name 等)。
sudo ./easyrsa build-ca nopass
一路默认就行,没有特殊设置
2.4 创建服务器证书和密钥:
为你的 OpenVPN 服务器创建证书和密钥。server 是证书的通用名称(CN),你可以自定义。
sudo ./easyrsa gen-req server nopass
sudo ./easyrsa sign-req server server
2.5 生成 Diffie-Hellman 密钥交换文件:
这个过程可能需要一些时间。
sudo ./easyrsa gen-dh
2.6 生成 HMAC 签名密钥:
这用于增强 TLS 连接的完整性。
sudo openvpn --genkey secret pki/ta.key
2.7 整理证书和密钥文件
把前面生成的证书文件复制到/etc/openvpn/server目录中
sudo mkdir -p /etc/openvpn/server
cd /etc/openvpn/easy-rsa
sudo cp pki/ca.crt pki/issued/server.crt /etc/openvpn/server/
sudo cp pki/private/server.key /etc/openvpn/server/
sudo cp pki/dh.pem /etc/openvpn/server/
sudo cp pki/.a.key /etc/openvpn/server/
第 3 步:配置 OpenVPN 服务器
3.1 创建服务器配置文件:
使用 OpenVPN 提供的示例配置文件作为起点。
sudo cp /usr/share/doc/openvpn/sample/sample-config-files/server.conf /etc/openvpn/server/
3.2 编辑服务器配置文件:
使用 vi 或 nano 编辑 /etc/openvpn/server/server.conf。
local 0.0.0.0
port 1194
proto udp
dev tun
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key # This file should be kept secret
dh /etc/openvpn/server/dh.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
# 推送路由:告诉客户端,192.168.10.0/24网段可以通过本VPN服务器到达
push "route 192.168.10.0 255.255.255.0"
# 不强制客户端全局代理
;push "redirect-gateway def1 bypass-dhcp"
keepalive 10 120
# 如果不试用自定义解析,个人觉得就没必要设置DNS,设置不当的话还会影响客户端上网
;push "dhcp-option DNS 208.67.222.222"
;push "dhcp-option DNS 208.67.220.220"
# 这里试用tls-auth会报错,试用tls-crypt就没问题,不知道原因,反正就这么设置把
# tls-auth /etc/openvpn/server/ta.key 0 # This file is secret
tls-crypt /etc/openvpn/server/ta.key
cipher AES-256-CBC
# 如果报错就把这里注释掉试试
user nobody
group nobody
persist-key
persist-tun
status /var/log/openvpn-status.log
verb 3
explicit-exit-notify 1
# 指定用于验证用户名和密码的脚本路径
auth-user-pass-verify /etc/openvpn/server/checkpsw.sh via-env
# 告诉服务器使用用户名而不是证书的 CN。
username-as-common-name
# 允许调用外部脚本并传递密码等敏感信息。
script-security 3
verify-client-cert none
- 配置文件中证书要用绝对路径,不然会报错
- 取消注释并修改
user
和group
行,以非特权用户运行 OpenVPN,提高安全性 - 取消注释
push "redirect-gateway def1 bypass-dhcp"
行,这将引导客户端的流量通过 VPN 服务器。 - 开启账号密码验证需要借助于checkpsw.sh
auth-user-pass-verify
: 指定用于验证用户名和密码的脚本路径。username-as-common-name
: 告诉服务器使用用户名而不是证书的 CN。script-security 3
: 允许调用外部脚本并传递密码等敏感信息。
第 4 步:创建用户认证脚本和密码文件
4.1 下载认证脚本:
一个常用的脚本是 checkpsw.sh。可以试用github上的脚本:https://github.com/imldy/openvpn-checkpsw。
也可以直接复制脚本内容:/etc/openvpn/server/checkpsw.sh
#!/bin/sh
###########################################################
# checkpsw.sh (C) 2004 Mathias Sundman <mathias@openvpn.se>
#
# This script will authenticate OpenVPN users against
# a plain text file. The passfile should simply contain
# one row per user with the username first followed by
# one or more space(s) or tab(s) and then the password.
PASSFILE="/etc/openvpn/server/psw-file"
LOG_FILE="/var/log/openvpn-password.log"
TIME_STAMP=`date "+%Y-%m-%d %T"`
###########################################################
if [ ! -r "${PASSFILE}" ]; then
echo "${TIME_STAMP}: Could not open password file \"${PASSFILE}\" for reading." >> ${LOG_FILE}
exit 1
fi
CORRECT_PASSWORD=`awk '!/^;/&&!/^#/&&$1=="'${username}'"{print $2;exit}' ${PASSFILE}`
if [ "${CORRECT_PASSWORD}" = "" ]; then
echo "${TIME_STAMP}: User does not exist: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
exit 1
fi
if [ "${password}" = "${CORRECT_PASSWORD}" ]; then
echo "${TIME_STAMP}: Successful authentication: username=\"${username}\"." >> ${LOG_FILE}
exit 0
fi
echo "${TIME_STAMP}: Incorrect password: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
exit 1
这个脚本对PASSFILE的路径进行了微调,密码文件路径由/etc/openvpn/psw-file
改为了/etc/openvpn/server/psw-file
4.2 使脚本可执行
sudo chmod +x /etc/openvpn/server/checkpsw.sh
4.3 创建密码文件:
创建文件 /etc/openvpn/server/psw-file
来存储用户名和密码。格式是每行一个 用户名 密码
。
sudo vi /etc/openvpn/server/psw-file
添加你的第一个用户,例如:
myvpnuser mysecurepassword123
重要: 为了安全,修改此文件的权限,只允许 root 读写。
sudo chmod 600 /etc/openvpn/server/psw-file
sudo chown root:root /etc/openvpn/server/psw-file
第 5 步:配置网络和防火墙
5.1 启用 IP 转发:
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
5.2 配置防火墙 (firewalld):
允许 OpenVPN 的默认端口 1194/udp
,并设置 masquerade(伪装)以实现 NAT。
sudo firewall-cmd --permanent --add-port=1194/udp
sudo firewall-cmd --permanent --add-masquerade
# 如果你的VPN服务器在公有网络上,请明确指定接口,例如 --zone=public
sudo firewall-cmd --reload
5.3 关闭防火墙需要的配置
如果为了懒省事直接关闭了防火墙。这时候将来客户端通过VPN访问内网的时候,还需要配置路由规则
手动添加 iptables 规则,由于防火墙(firewalld/ufw)是关闭的,我们需要直接使用 iptables
来添加必要的 NAT 规则。这是最底层、最直接的方法。
添加 MASQUERADE 规则
这条规则的作用是:对从 VPN 网卡 (tun0) 发出,要去往内网网卡 (eth0 或你的实际内网网卡名) 的流量进行源地址伪装。让内网设备认为请求是来自服务器本身 (192.168.10.100),而不是陌生的 10.8.0.x,这样它们就会把回复包顺利地发回给服务器。
# 替换 'eth0' 为你的服务器连接内网的实际网卡名(通过 ip addr 命令查看)
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
-t nat
:操作 NAT 表。-A POSTROUTING
:在数据包即将发出网卡时(POSTROUTING 链)应用此规则。-s 10.8.0.0/24
:匹配源地址为 VPN 网段的数据包。-o eth0
:匹配要从内网网卡发出的数据包。-j MASQUERADE
:执行动作:进行 IP 伪装。
允许转发(可选但推荐)
虽然关闭防火墙通常意味着默认允许转发(ACCEPT
),但为了绝对清晰,我们可以显式地设置转发策略。检查一下:
sudo iptables -L FORWARD
如果输出中显示 Chain FORWARD (policy DROP)
,则需要设置策略为ACCEPT
:
sudo iptables -P FORWARD ACCEPT
使规则永久生效
通过 iptables 添加的规则在重启后会丢失。我们需要保存它们。
对于 Debian/Ubuntu:
# 安装iptables服务(如果尚未安装)
sudo dnf install iptables-services
# 保存当前规则到配置文件
sudo service iptables save
# 或者
sudo /sbin/iptables-save > /etc/sysconfig/iptables
# 启用并启动iptables服务(注意:这只是为了保存规则,并非开启防火墙)
sudo systemctl enable iptables
sudo systemctl start iptables
对于 Debian/Ubuntu:
# 安装iptables-persistent包
sudo apt-get install iptables-persistent
# 在安装过程中,它会询问是否保存当前规则,选择“是”
# 或者之后手动保存
sudo netfilter-persistent save
第 6 步:启动并启用 OpenVPN 服务
6.1 如果用的不是默认的1194端口
如果不是默认端口,在 RockyLinux / RHEL8+ 里,最常见的是 SELinux 或防火墙阻止了非标准端口。
如果你没特别需要,用默认 1194 更省事。很多 SELinux 策略只允许 OpenVPN 用 1194/udp。
如果你确实要改端口,比如用21194 端口。需要告诉 SELinux 这个端口是 OpenVPN 合法的:
sudo semanage port -a -t openvpn_port_t -p udp 21194
如果提示 semanage: command not found,安装:
sudo dnf install policycoreutils-python-utils -y
检查是否生效
semanage port -l | grep openvpn
6.2 启动服务
sudo systemctl enable --now openvpn-server@server
sudo systemctl status openvpn-server@server
6.3 日志查看
运行日志查看
sudo journalctl -u openvpn-server@server -f
直接运行,可直观排查出配置文件server.conf是否有错误
sudo openvpn --config /etc/openvpn/server/server.conf
第 7 步:创建客户端配置文件和测试
7.1 创建客户端配置:
创建一个名为 client.ovpn 的文件。
client
dev tun
proto udp
remote 192.168.10.251 21194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth SHA256
cipher AES-256-CBC
data-ciphers AES-256-GCM:AES-128-GCM:AES-256-CBC:AES-128-CBC
key-direction 1
verb 3
auth-user-pass
# tls-auth ta.key 1
tls-crypt ta.key
ca ca.crt
故障排除
- 查看日志:服务端日志 journalctl -u openvpn-server@server -f 和客户端日志是排查问题的首要位置。
- 防火墙:确保服务器的防火墙和云服务商的安全组都允许 UDP 1194 端口的入站流量。
- 脚本权限:确保 /etc/openvpn/server/checkpsw.sh 有可执行权限。
- 密码文件权限:确保 /etc/openvpn/server/psw-file 的权限是 600,属主是 root。