点击展开更新日志

2026

01-04

  1. 【新增】OpenVPN 部署

nexttime

会有些什么呢(❁´◡`❁)

源起

远程家中内网设备(电脑、NAS)的需求其实一直都有,之前是用的第三方软件的方案,主要是皎月连、UU远程,也用过todesk,然后就想着试试 VPN,所以先来看看 OpenVPN 吧。

部署环境

  • 服务端:一台公网服务器做中转,生成证书密钥
    • 这里以腾讯云轻量为例
  • 客户端:Win、Android等,导入配置

服务端部署

安装OpenVPN及证书生成工具

1
2
3
4
5
6
# CentOS
sudo yum install epel-release -y
sudo yum install openvpn easy-rsa -y

# Ubuntu
sudo apt install openvpn easy-rsa

初始化PKI(公钥基础设施)并生成证书

使用Easy-RSA 3管理证书,它是一个专门为OpenVPN等OpenSSL项目设计的证书管理工具。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 复制Easy-RSA脚本到OpenVPN配置目录
make-cadir openvpn-ca/
cd openvpn-ca

# 初始化 PKI
./easyrsa init-pki

# 生成CA根证书:会要求设置密码,牢记!如果不想要密码,加上 nopass 选项
./easyrsa build-ca

# 生成服务器证书和私钥:server 是服务器标识,可自定义,与配置保持一致即可
./easyrsa build-server-full server nopass

# 生成Diffie-Hellman参数(用于密钥交换)
./easyrsa gen-dh

# 生成HMAC防火墙签名密钥(用于增强抗DoS能力)
openvpn --genkey --secret ta.key

# 复制生成的证书、密钥文件到OpenVPN配置目录
sudo cp pki/ca.crt pki/private/server.key pki/issued/server.crt pki/dh.pem ta.key /etc/openvpn/server/

启用Google Authenticator二次验证

  1. 安装Google Authenticator PAM模块

    1
    sudo apt install libpam-google-authenticator -y
  2. 为OpenVPN用户生成验证密钥

    1
    2
    3
    sudo useradd -m -s /bin/bash openvpn
    sudo su - openvpn
    google-authenticator # U5CKAS2ZATVEIKZFBAPAPOYH5A

    按照提示进行配置,配置项主要是:

    • 使用基于时间的一次性密码令牌:y
    • 更新 ~/.google_authenticator 文件:y
    • 禁止重复使用同一个验证码:y
    • 增加时间偏移量以应对时钟轻微不同步。默认前后一个令牌时间差:y
    • 每30s限制登录失败3次:y

    配置完成后会显示一个二维码密钥应急验证码,用手机Google Authenticator应用扫描二维码,并妥善保存应急验证码。

  3. 拷贝密钥位置

    1
    2
    3
    sudo mkdir /etc/openvpn/auth
    sudo chown openvpn:openvpn -R /etc/openvpn/auth
    sudo cp /home/openvpn/.google_authenticator /etc/openvpn/auth/

    之所以要单独把 .google_authenticator 文件拎出来,是因为 OpenVPN 的systemd 文件中设置了 ProtectHome=true,不能修改 /home 目录(认证过程中会创建临时文件),安全起见不建议直接修改为 false,因此就需要移出来了。参考:Failed to read .google_authenticator for user, but permissions seem correct #211

  4. 配置PAM认证模块

    1
    sudo vim /etc/pam.d/openvpn

    新增内容:

    1
    2
    # PAM configuration for OpenVPN
    auth required pam_google_authenticator.so secret=/etc/openvpn/auth/.google_authenticator user=openvpn
1
2
3
4
5
6
Your emergency scratch codes are:
70240222
39865135
75304085
23085415
58981865

创建服务器配置文件

1
2
3
sudo mkdir -p /data/logs/openvpn
sudo chmod 777 -R /data/logs/openvpn
sudo vim /etc/openvpn/server/server.conf

以下是我的参考配置,几点说明:

  1. 【允许客户端访问的内网网段】根据实际情况修改
  2. 【监听端口】根据情况修改,且控制台防火墙要放行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# 监听端口和协议(默认1194/UDP,可修改)
port 51194
proto udp
# 或 proto tcp
# 设备类型和路由模式:采用路由隧道模式
dev tun
# 指定VPN虚拟网段的子网掩码,地址池(注意:不能与阿里云服务器内网网段或家庭内网网段冲突!)
server 10.8.0.0 255.255.255.0
topology subnet

###### 证书密钥配置
# ca证书
ca ca.crt
# 服务端公钥
cert server.crt
# 服务端私钥
key server.key
# 证书校验算法
dh dh.pem

###### 安全增强选项
# tls-auth ta.key 0 # 启用HMAC防火墙
tls-crypt ta.key
cipher AES-256-CBC # 加密算法
auth SHA256 # 哈希认证算法
user nobody
group nobody


######## 网络配置和推送路由
# 将客户端的默认网关重定向到VPN,一般不建议
# push "redirect-gateway def1 bypass-dhcp"
# 向客户端推送DNS服务器
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
# *** 关键配置:推送家庭内网网段路由 ***
# 允许客户端访问的内网网段
push "route 192.168.7.0 255.255.255.0"
# push "disable-compression"

# 其他优化选项
# 存活时间,10秒ping一次,120秒如果未收到响应则视为断线
keepalive 10 120
# 通过keepalive检测超时后,重新启动VPN,不重新读取
persist-key
# 检测超时后,重新启动VPN,一直保持tun是linkup的,否则网络会先linkdown然后再linkup
persist-tun
# 允许客户端之间互相访问(可选)
client-to-client
# 最大连接数
max-clients 5
# 使用lz4-v2压缩
compress lz4-v2
# 推送给客户端压缩方式
push "compress lz4-v2"

###### 日志配置
# 日志级别(范围0-9,0为致命,3为正常,4为调试,9为最详细)
verb 3
explicit-exit-notify 1
# 日志位置,记录openvpn状态
status /data/logs/openvpn/openvpn-status.log
# 日志记录位置
# log /data/logs/openvpn/openvpn.log
log-append /data/logs/openvpn/openvpn.log # 使用 log-append 防止被覆盖




# 下发给客户端加密算法
push "cipher AES-256-CBC"

####### 认证
# 允许使用自定义脚本
script-security 1
plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so openvpn
username-as-common-name
# crl-verify /etc/openvpn/server/crl.pem # (可选) 启用证书吊销

启动服务

1
2
3
4
5
6
7
8
9
10
11
12
# 启用IP转发,让服务器能转发VPN流量到内网
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-openvpn.conf
sudo sysctl -p /etc/sysctl.d/99-openvpn.conf

# 启动 OpenVPN 服务
sudo systemctl start [email protected]

# 查看服务状态
systemctl status [email protected]

# 设置开机自启
systemctl enable [email protected]

客户端部署

生成客户端配置

回到服务器,为客户端生成证书:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
cd ~/openvpn-ca
# client 是客户端名称,可自定义,建议每个客户端不要重复
./easyrsa build-client-full client nopass

# 生成客户端配置文件(.ovpn)
# 需要提取ca.crt、ta.key、home-nas.crt、home-nas.key这四个文件的内容,并嵌入到配置文件中
# 创建一个脚本自动完成此操作
cat > ~/make_config.sh <<'EOF'
#!/bin/bash
# 第一个参数:客户端名称
CA_DIR=~/openvpn-ca
KEY_DIR=~/openvpn-ca/pki
OUTPUT_DIR=~/client-configs
BASE_CONFIG=~/base.conf

cat ${BASE_CONFIG} \
<(echo -e '<ca>') \
${KEY_DIR}/ca.crt \
<(echo -e '</ca>\n<cert>') \
${KEY_DIR}/issued/${1}.crt \
<(echo -e '</cert>\n<key>') \
${KEY_DIR}/private/${1}.key \
<(echo -e '</key>\n<tls-auth>') \
${CA_DIR}/ta.key \
<(echo -e '</tls-auth>') \
> ${OUTPUT_DIR}/${1}.ovpn
EOF

# 创建一个基础配置文件(base.conf)
cat > ~/base.conf <<'EOF'
client
dev tun
proto udp
# 将YOUR_ALIYUN_PUBLIC_IP替换为你的阿里云ECS的公网IP或域名
remote YOUR_ALIYUN_PUBLIC_IP 1194
resolv-retry infinite
nobind
user nobody
group nobody
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-CBC
auth SHA256
comp-lzo
verb 3
auth-user-pass
EOF

# 创建存放客户端配置的目录
mkdir -p ~/client-configs

# 给脚本执行权限并运行(生成client.ovpn)
chmod +x ~/make_config.sh
./make_config.sh client

现在,你将在 ~/client-configs/ 目录下得到一个包含所有必要证书和密钥的 home-nas.ovpn 文件。这是最安全的分发方式,所有内容都已嵌入,无需额外传输证书文件。

参考文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
client
dev tun
proto udp

# 公网服务器地址
remote <SERVER_HOST> 51194
resolv-retry infinite
nobind
user nobody
group nobody
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-CBC
auth SHA256
compress lz4-v2
allow-compression yes
verb 3
auth-user-pass
# key-direction 1
# tls-auth ta.key 1

<ca>
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
</ca>
<cert>
Certificate:
...
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----
</key>
<tls-crypt>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
-----END OpenVPN Static key V1-----
</tls-crypt>

客户端配置

下载 OpenVPN 客户端,可以选择 OpenVPN Connect 或 OpenVPN GUI,Connect 是官方软件,GUI 是开源社区软件,至于有啥区别,我也不知道,诶嘿。

从客户端导入上面生成的 .ovpn 文件连接,账号是创建的 openvpn 系统用户,密码是6位的 OTP 密码。

排障

如果遇到服务启动失败或报错或认证失败等问题,提供几个排查思路:

  1. sudo journalctl -xe
  2. OpenVPN 打印的日志
  3. /var/log/auth.log(ubuntu) 、/var/log/security(cent) 登录认证日志
  4. /var/log/audit 审计日志