Akemi

OpenVPN原理与证书类型

2024/12/05

这篇博客仅供了解Openvpn原理与证书原理,内容可能并不适用于最新版Openvpn的验证
可行方案请看最新博文《Let’s Encrypt生成免费HTTPS证书,与应用与Openvpn》

OpenVpn基于SSL VPN的方式,提供数据私密性,端点验证,信息完整性等特性
SSL独立于应用,适用于企业异地或者移动用户拨号连接总部,实现VPN不间断的按需链接

OpenVpn属于C/S架构,需要单独部署OpenVpn客户端与服务器。且服务端最好需要公网IP

以前一直搞不懂证书什么巴拉巴拉的,我们公司搭的就是jumpserver+openvpn,我正好也搭一个玩玩,总算搞明白了SSL证书的生成,以及他们的关系

证书文件类型

不一定叫这个名,但是作用是一样的

server.crt 服务端证书文件,同时包含着公钥
server.key 服务端私钥文件
client.crt 客户端证书文件,同时包含着公钥
client.key 客户端私钥文件
client.csr 客户端证书请求文件
ca.crt CA的自证证书
ca.key CA的私钥
pem文件 另一种格式的证书文件,可以由crt和key结合生成

其中

ca的证书和server的证书都可以直接签发
而client的证书,需要生成证书请求文件csr
然后请求ca,联合签发client.crt

OpenVpn CA验证的过程

客户端发起连接

客户端证书文件client.crt
客户端配置文件-表明客户端要连接的vpn服务地址与端口

服务端检查客户端证书文件

服务端通过找CA机构

证明客户端证书文件合法

客户端检查服务端证书文件

客户端通过找CA机构

证明服务端证书文件合法

客户端加密数据

客户端使用server.crt进行加密

服务端通过server.key进行解密

服务端加密数据

服务端使用client.crt进行加密

客户端通过client.key进行解密

环境

1
2
3
4
CentOS7.9.2009
120.26.160.133 vpn-server 有EIP的ECS
192.168.10.220 windows-client
192.168.10.100 linux-client

OpenVpn部署

在服务端制作证书(使用easy-rsa-old)

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
https://github.com/OpenVPN/easy-rsa-old
下载master分支
unzip easy-rsa-old-master.zip

# 小小修改一下vars变量文件
sed -i 's/^export KEY_COUNTRY.*/export KEY_COUNTRY="CN"/g' easy-rsa-old-master/easy-rsa/2.0/vars
sed -i 's/^export KEY_PROVINCE.*/export KEY_PROVINCE="Beijing"/g' easy-rsa-old-master/easy-rsa/2.0/vars
sed -i 's/^export KEY_CITY.*/export KEY_CITY="Beijing"/g' easy-rsa-old-master/easy-rsa/2.0/vars
cd easy-rsa-old-master/easy-rsa/2.0/
source vars
./clean-all

# 创建ca的证书文件
./build-ca

# 创建server的证书文件
./build-key-server vpnserver

# 创建client的证书
./build-key vpnclient

# 生成密钥交换文件信息
./build-dh

# 生成一个ta.key,抗dos的,不生成会启动报错
openvpn --genkey --secret ta.key

在服务端制作证书(使用openssl)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mkdir /ssl
cd /ssl
# 生成ca.key
openssl genrsa -out ca.key 4096
# 生成ca.crt
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
# 生成vpnserver.key
openssl genrsa -out vpnserver.key 4096
# 生成vpnserver.crt
openssl req -new -x509 -key vpnserver.key -out vpnserver.crt -days 3650
# 生成vpnclient.key
openssl genrsa -out vpnclient.key 4096
# 生成vpnclient.csr
openssl req -new -key vpnclient.key -out vpnclient.csr
# 使用ca签署证书vpnclient.crt
openssl x509 -req -in vpnclient.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out vpnclient.crt -days 3650

# 生成dh2048.pem
openssl dhparam -out dh2048.pem 2048

# 生成ta.key
openvpn --genkey --secret ta.key

配置OpenVpn服务端

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
yum -y install openvpn
版本
openvpn-2.4.12

# 移动证书
cd /ssl
cp ca.crt server.crt dh2048.pem server.key /etc/openvpn/server
cp dh2048.pem ta.key /etc/openvpn/server/

# 修改OpenVpn模板配置文件
cp /usr/share/doc/openvpn-2.4.12/sample/sample-config-files/server.conf /etc/openvpn/server
cd /etc/openvpn/server

如果证书和server.conf不在同个目录下,那还需要修改server.conf中文件的相对路径

# 以下是一些字段的含义
ca ca.crt ca证书位置
cert vpnserver.crt server.crt的位置
server 10.8.0.0 255.255.255.0 vpn的端点网段信息
cipher AES-256-GCM 加密方式
push "route 192.168.10.0 255.255.255.0" 要推送的网段信息
log openvpn.log 日志位置

# 开启服务器路由转发,加载到内核中
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

# 启动服务器端OpenVpn
cd /etc/openvpn/server
openvpn --daemon --config server.conf
#ss -tunlp | grep 1194
#udp UNCONN 0 0 *:1194 *:* users:(("openvpn",pid=3354,fd=6))

配置OpenVpn客户端

思路就是先在服务端配好客户端配置,然后拿出去给别的主机用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
工作目录在/etc/openvpn/client
# 放证书
cd /ssl/
cp ca.crt vpnclient.crt vpnclient.key /etc/openvpn/client/
cp ta.key /etc/openvpn/client/

# 改配置文件
cd /etc/openvpn/client
cp /usr/share/doc/openvpn-2.4.12/sample/sample-config-files/client.conf .

一些字段:
cert client.crt crt文件位置
remote 120.26.160.133 1194 指定服务端的地址
cipher AES-256-GCM 加密方式

# 改名,必须以ovpn为后缀
mv client.conf client.ovpn

# 打包,以发送给vpn客户端
cd ..
tar -cf vpn-client.tar.gz client/

windows系统客户端

将配置文件传送到windows系统上

在OpenVpn官网下载安装客户端
https://openvpn.net/community-downloads/

设置文件加载路径,改为ovpn文件所在地址

linux系统客户端

1
2
yum -y install openvpn
openvpn --daemon --config <ovpn文件位置>

使用用户密码进行验证

如果按照上面的这个步骤连接报错,是因为CA并不是可信CA,openvpn无法验证服务端的证书,就会报错

所以使用用户密码验证

使用用户密码验证,需要在服务端额外添加验证用户密码的脚本

以及修改配置文件

创建验证脚本

指定我的密码文件为/etc/openvpn/server/pass_file

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
sudo tee > /etc/openvpn/server/auth_pass.sh <<EOF
#!/bin/sh

# checkpsw.sh (C) 2004 Mathias Sundman <mathias@openvpn.se>
#
# This script authenticates OpenVPN users against a plain text file.
# The passfile should contain one row per user with the username first,
# followed by one or more spaces or tabs, and then the password.

PASSFILE="/etc/openvpn/server/pass_file"
LOG_FILE="/etc/openvpn/server/openvpn-password.log"
TIME_STAMP=$(date "+%Y-%m-%d %T")

# Check if the password file is readable
if [ ! -r "${PASSFILE}" ]; then
echo "${TIME_STAMP}: Could not open password file \"${PASSFILE}\" for reading." >> "${LOG_FILE}"
exit 1
fi

# Extract the correct password for the given username
CORRECT_PASSWORD=$(awk -v user="${username}" '!/^;/ && !/^#/ && $1 == user {print $2; exit}' "${PASSFILE}")

# Check if the user exists in the password file
if [ "${CORRECT_PASSWORD}" = "" ]; then
echo "${TIME_STAMP}: User does not exist: username=\"${username}\", password=\"${password}\"." >> "${LOG_FILE}"
exit 1
fi

# Check if the provided password matches the stored password
if [ "${password}" = "${CORRECT_PASSWORD}" ]; then
echo "${TIME_STAMP}: Successful authentication: username=\"${username}\"." >> "${LOG_FILE}"
exit 0
else
echo "${TIME_STAMP}: Incorrect password: username=\"${username}\", password=\"${password}\"." >> "${LOG_FILE}"
exit 1
fi
EOF
chmod +x auth_pass.sh
echo "test 123456" >> /etc/openvpn/server/pass_file

修改server.conf文件

添加

1
2
3
4
5
6
7
8
9
10
11
script-security 3 ——允许执行所有脚本
auth-user-pass-verify /etc/openvpn/server/auth_pass.sh via-env ——指定脚本
username-as-common-name ——使用客户端提供的用户名
verify-client-cert none ——不需要客户端提供证书,而使用用户名和密码
client-config-dir ccd ——指定客户端配置文件存放位置为ccd目录

添加单独配置到ccd目录
cd /etc/openvpn/server
mkdir ccd
echo "ifconfig-push 10.8.0.20 255.255.255.0" > /etc/openvpn/server/ccd/test
分配一个静态IP给我的测试主机

修改client.conf文件

1
2
3
4
5
6
7
8
9
10
11
12
13
删除
cert vpnclient.crt
key vpnclient.key
不需要用证书来验证了,只需要ta.key和ca.crt

添加
auth-user-pass
auth-nocache

sudo tee > password<<EOF
test
123456
EOF

在windows和linux中添加对CA机构的信任

CentOS7.9.2009

1
2
3
cp ca.crt /etc/pki/ca-trust/source/anchors/
update-ca-trust

CATALOG
  1. 1. 证书文件类型
  2. 2. OpenVpn CA验证的过程
  3. 3. 环境
  4. 4. OpenVpn部署
    1. 4.1. 在服务端制作证书(使用easy-rsa-old)
    2. 4.2. 在服务端制作证书(使用openssl)
    3. 4.3. 配置OpenVpn服务端
    4. 4.4. 配置OpenVpn客户端
    5. 4.5. windows系统客户端
    6. 4.6. linux系统客户端
  5. 5. 使用用户密码进行验证
    1. 5.1. 创建验证脚本
    2. 5.2. 修改server.conf文件
    3. 5.3. 修改client.conf文件
  6. 6. 在windows和linux中添加对CA机构的信任
    1. 6.1. CentOS7.9.2009