OpenVPN简介

VPN 介绍

一些组织需要实现跨地域的互相通信,比如:北京总公司和上海分公司之间进行网络互通,一般通过下面两种方式实现

专用网:

所谓专用网就是在两个网络(例如,北京总公司和广州分公司)的网络之间架设一条专用线路,但是它并不需要真正地去铺设光缆之类的物理线路。虽然没有实际去铺设网线,但是仍需要向电信运营商申请租用专线,在这条专用的线路上只传输自己组织之间的数据信息,所以此方式安全稳定,同时也费用高昂

1

VPN:

Virtual Private Network,虚拟私有网络,或称为虚拟专用网络,常用于在公用网络上实现专用网络功能,为了安全通常需要进行加密通讯。此方式在企业网络中有广泛应用。VPN网关通过对数据包的加密和数据包目标地址的转换实现远程访问。VPN功能可通过服务器、网络硬件、软件等多种方式实现

2

VPN 常见应用模式

点对站点 peer to site

3

站点对站点 site to site

4

OpenVPN

5

OpenVPN 是Linux下开源VPN的应用,提供了良好的性能和友好的用户GUI。

OpenVPN 是一个基于 OpenSSL 库的应用层 VPN 实现。和传统 VPN 相比,它的优点是简单易用。

OpenVPN允许参与建立VPN的单点使用共享密钥,电子证书,或者用户名/密码来进行身份验证。

OpenVPN支持在各种系统,,如:Linux、Windows、Mac OS X、Solaris、OpenBSD、FreeBSD、NetBSD 上运行,并包含了许多安全性的功能。它并不是一个基于Web的VPN软件,也不与IPsec及其他VPN软件包兼容。

官方网站:https://openvpn.net

GitHub地址:https://github.com/OpenVPN/openvpn

OpenVPN 常见适用场景

  • 实现远程主机到内网的连接
  • 实现多个远程主机之间的连接

OpenVPN 部署

准备 OpenVPN 部署环境

官文文档: https://openvpn.net/community-resources/how-to/

可选择以下两套环境之一实现OpenVPN

环境1: 阿里云 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
1 阿里云创建专有网络
指定城市和可用区:华北3张家口可用区A区
网段名wang-net1和地址段172.16.0.0/12,默认资源组
交换机名wang-net1-sw1 可用区A IPv4的地址段 172.30.0.0/24
安全组开放22端口

2 创建OpenVPN服务器有公网IP的实例1个
指定城市和可用区:华北3张家口可用区A区
计算型c6 2vCPU 4G
网络:wang-net1 交换机:wang-net1-sw1
公网IP 按量收费 10M
默认安全组 默认配置 22,3389,icmp
centos8.2
系统盘 存储默认高效云盘40G

3 创建局域网的服务器无公网IP的实例2个
按量付费
指定城市和可用区:华北3张家口可用区A区
共享型 2vCPU2G
centos8.2
系统盘 存储默认高效云盘40G
网络:wang-net1 wang-net1-sw1
无公网IP
默认安全组
主网卡sw1

4 重设所有实例密码

5 修改安全组打开 1194/TCP/UDP

环境2: 局域网 OpenVPN 实战环境

6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#共四台主机
1 openvpn server:
CentOS 8.2
eth0:10.0.0.8/24 NAT模式,模拟公网IP
eth1:172.30.0.1/24 仅主机模式,私网IP

2 内网主机两台
第一台主机
eth0:172.30.0.100/24 仅主机模式,私网IP,无需网关
第二台主机
eth0:172.30.0.200/24 仅主机模式,私网IP,无需网关

3 Windows 客户端
Windows 10

安装 OpenVPN 相关软件包

查看版本

查看官网的OpenVPN的版本

访问官网:https://openvpn.net

7

在不同OS上查看 OpenVPN 版本

CentOS系统上的EPEL源OpenVPN版本比Ubuntu的仓库中版本更新,以下选择在CentOS8上部署 OpenVPN

范例: CentOS 查看OpenVPN版本

1
2
3
4
5
[root@centos8 ~]# yum list openvpn
openvpn.x86_64 2.4.9-1.el8 epel

[root@centos8 ~]# yum list easy-rsa
easy-rsa.noarch 3.0.7-1.el8 epel

范例: Ubuntu 查看OpenVPN 和 easy-rsa 版本

1
2
3
4
5
[root@ubuntu2204 ~]# apt list openvpn
openvpn/jammy-proposed 2.5.5-1ubuntu3.1 amd64

[root@ubuntu2204 ~]# apt list easy-rsa
easy-rsa/jammy 3.0.8-1ubuntu1 all

安装 OpenVPN

后面环境以CentOS8上基于EPEL源安装OpenVPN为例

安装 OpenVPN 和证书工具

范例:Ubuntun20.04

1
[root@ubuntu2004 ~]# apt update ; apt -y install openvpn easy-rsa

注意: 需要提前配置epel源

1
2
3
4
5
6
7
8
9
10
11
12
[root@centos8 ~]# vim /etc/yum.repos.d/epel.repo
[epel]
name=EPEL
baseurl=https://mirrors.aliyun.com/epel/$releasever/Everything/$basearch
gpgcheck=0
enabled=1

#OpenVPN服务器端
[root@centos8 ~]# yum -y install openvpn

#证书管理工具
[root@centos8 ~]# yum -y install easy-rsa

查看包中相关文件

范例:Ubuntun20.04

1
[root@ubuntu2004 ~]# dpkg -L openvpn easy-rsa

范例:CentOS 8

1
2
3
[root@centos8 ~]# rpm -qi openvpn easy-rsa
[root@centos8 ~]# rpm -ql openvpn
[root@centos8 ~]# rpm -ql easy-rsa

准备相关配置文件

范例: Ubuntun20.04

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@ubuntu2004 ~]# cp -r /usr/share/easy-rsa/ /etc/openvpn/
[root@ubuntu2004 ~]# mv /etc/openvpn/easy-rsa/vars.example /etc/openvpn/easy-rsa/vars
[root@ubuntu2004 ~]# tree /etc/openvpn/easy-rsa/
/etc/openvpn/easy-rsa/
├── easyrsa
├── openssl-easyrsa.cnf
├── vars
└── x509-types
├── ca
├── client
├── code-signing
├── COMMON
├── server
└── serverClient

1 directory, 9 files

范例: CentOS8

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
#准备证书颁发相关文件
[root@centos8 ~]# cp -r /usr/share/easy-rsa/3/ /etc/openvpn/easy-rsa

#准备颁发证书相关变量的配置文件
[root@centos8 ~]# cp /usr/share/doc/easy-rsa/vars.example /etc/openvpn/easy-rsa/vars

#建议修改给CA和OpenVPN服务器颁发的证书的有效期,可适当加长
[root@centos8 ~]#vim /etc/openvpn/easy-rsa/vars

#CA的证书默认有效期为10年,可以适当延长,比如:36500天
#set_var EASYRSA_CA_EXPIRE 3650
set_var EASYRSA_CA_EXPIRE 36500

#服务器证书默为为825天,可适当加长,比如:3650天
#set_var EASYRSA_CERT_EXPIRE 825
#将上面行修改为下面
set_var EASYRSA_CERT_EXPIRE 3650

[root@centos8 ~]#tree /etc/openvpn/
/etc/openvpn/
├── client
├── easy-rsa
│ ├── easyrsa
│ ├── openssl-easyrsa.cnf
│ ├── vars
│ └── x509-types
│ ├── ca
│ ├── client
│ ├── code-signing
│ ├── COMMON
│ ├── email
│ ├── kdc
│ ├── server
│ └── serverClient
├── server
└── server.conf

准备证书相关文件

初始化PKI和CA颁发机构环境

脚本easyrsa帮助用法

1
2
3
4
5
6
[root@centos8 ~]# cd /etc/openvpn/easy-rsa

[root@centos8 easy-rsa]# file ./easyrsa
./easyrsa: POSIX shell script, ASCII text executable

[root@centos8 easy-rsa]# ./easyrsa

初始化PKI生成PKI相关目录和文件

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
[root@centos8 ~]# cd /etc/openvpn/easy-rsa/

[root@centos8 easy-rsa]# ls
easyrsa openssl-easyrsa.cnf vars x509-types

#初始化数据,在当前目录下生成pki目录及相关文件
[root@centos8 easy-rsa]# ./easyrsa init-pki

[root@centos8 easy-rsa]# tree
├── easyrsa
├── openssl-easyrsa.cnf
├── pki #生成一个新目录及相关文件
│ ├── openssl-easyrsa.cnf
│ ├── private
│ ├── reqs
│ └── safessl-easyrsa.cnf
├── vars
└── x509-types
├── ca
├── client
├── code-signing
├── COMMON
├── email
├── kdc
├── server
└── serverClient

创建 CA 机构证书环境

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
[root@centos8 ~]# cd /etc/openvpn/easy-rsa/
[root@centos8 easy-rsa]# tree pki
pki
├── openssl-easyrsa.cnf
├── private
├── reqs
└── safessl-easyrsa.cnf
2 directories, 2 files

[root@centos8 easy-rsa]# ./easyrsa build-ca nopass

[root@centos8 easy-rsa]# tree pki
pki
├── ca.crt #生成的自签名的证书文件
├── certs_by_serial
├── index.txt
├── index.txt.attr
├── issued
├── openssl-easyrsa.cnf
├── private
│ └── ca.key #生成的私钥文件
├── renewed
│ ├── certs_by_serial
│ ├── private_by_serial
│ └── reqs_by_serial
├── reqs
├── revoked
│ ├── certs_by_serial
│ ├── private_by_serial
│ └── reqs_by_serial
├── safessl-easyrsa.cnf
└── serial
12 directories, 7 files

#查看生成CA相关的文件
[root@centos8 easy-rsa]# cat pki/serial
01

[root@centos8 easy-rsa]# ll pki/index.txt
-rw------- 1 root root 0 Aug 2 16:42 pki/index.txt

[root@centos8 easy-rsa]# cat pki/serial
01

[root@centos8 easy-rsa]# ll pki/ca.crt pki/private/ca.key
-rw------- 1 root root 1204 Aug 2 16:42 pki/ca.crt
-rw------- 1 root root 1675 Aug 2 16:42 pki/private/ca.key

#查看生成的自签名证书
[root@centos8 easy-rsa]# cat pki/ca.crt
......

[root@centos8 easy-rsa]# openssl x509 -in pki/ca.crt -noout -text
......

准备服务端证书环境

创建服务端证书申请

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
[root@centos8 ~]# cd /etc/openvpn/easy-rsa

#创建服务器证书申请文件,其中server是文件前缀
[root@centos8 easy-rsa]# ./easyrsa gen-req server nopass

Common Name (eg: your user, host, or server name) [server]: #接受Common Name的默认值,直接回车

Keypair and certificate request completed. Your files are:
req: /etc/openvpn/easy-rsa/pki/reqs/server.req #生成请求文件
key: /etc/openvpn/easy-rsa/pki/private/server.key #生成私钥文件


[root@centos8 easy-rsa]# tree pki
pki
├── ca.crt
├── certs_by_serial
├── index.txt
├── index.txt.attr
├── issued
├── openssl-easyrsa.cnf
├── private
│ ├── ca.key
│ └── server.key #生成私钥文件
├── renewed
│ ├── certs_by_serial
│ ├── private_by_serial
│ └── reqs_by_serial
├── reqs
│ └── server.req #生成请求文件
├── revoked
│ ├── certs_by_serial
│ ├── private_by_serial
│ └── reqs_by_serial
├── safessl-easyrsa.cnf
└── serial

12 directories, 9 files

颁发服务端证书

查看颁发证书命令用法
1
2
3
4
5
6
7
8
9
10
11
12
[root@centos8 ~]# cd /etc/openvpn/easy-rsa/
[root@centos8 easy-rsa]# ./easyrsa help sign

Note: using Easy-RSA configuration from: /etc/openvpn/easy-rsa/vars

sign-req <type> <filename_base>
Sign a certificate request of the defined type. <type> must be a known
type such as 'client', 'server', 'serverClient', or 'ca' (or a user-added
type.)

This request file must exist in the reqs/ dir and have a .req file
extension. See import-req below for importing reqs from other sources.
颁发服务端证书
1
2
3
4
5
6
7
8
9
10
11
#将上面server.req的申请,颁发server类型的证书
[root@centos8 ~]# cd /etc/openvpn/easy-rsa

#第一个server表示证书的类型,第二个server表示请求文件名的前缀
[root@centos8 easy-rsa]# ./easyrsa sign server server

Request subject, to be signed as a server certificate for 3650 days: #可以看到vars文件指定的有效期

Confirm request details: yes #输入yes回车

Certificate created at: /etc/openvpn/easy-rsa/pki/issued/server.crt #生成服务器证书文件
验证结果
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
[root@centos8 ~]#cd /etc/openvpn/easy-rsa
[root@centos8 easy-rsa]#tree pki
pki
├── ca.crt
├── certs_by_serial
│ └── EDAEBAB8D65066D307AE58ADC1A56682.pem #生成的服务器证书文件
├── index.txt
├── index.txt.attr
├── index.txt.attr.old
├── index.txt.old
├── issued
│ └── server.crt #生成的服务器证书文件
├── openssl-easyrsa.cnf
├── private
│ ├── ca.key
│ └── server.key
├── renewed
│ ├── certs_by_serial
│ ├── private_by_serial
│ └── reqs_by_serial
├── reqs
│ └── server.req
├── revoked
│ ├── certs_by_serial
│ ├── private_by_serial
│ └── reqs_by_serial
├── safessl-easyrsa.cnf
├── serial
└── serial.old

12 directories, 14 files


[root@centos8 easy-rsa]# diff pki/certs_by_serial/EDAEBAB8D65066D307AE58ADC1A56682.pem pki/issued/server.crt

[root@centos8 easy-rsa]# ll !*
ll pki/certs_by_serial/EDAEBAB8D65066D307AE58ADC1A56682.pem
pki/issued/server.crt
-rw------- 1 root root 4608 Aug 2 17:19
pki/certs_by_serial/EDAEBAB8D65066D307AE58ADC1A56682.pem
-rw------- 1 root root 4608 Aug 2 17:19 pki/issued/server.crt

[root@centos8 easy-rsa]# cat pki/issued/server.crt
......

#查看证书相关文件
[root@centos8 easy-rsa]# cat pki/serial
EDAEBAB8D65066D307AE58ADC1A56683

[root@centos8 easy-rsa]# cat pki/index.txt
V 201031091943Z EDAEBAB8D65066D307AE58ADC1A56682 unknown /CN=server

[root@centos8 easy-rsa]# cat pki/serial.old
edaebab8d65066d307ae58adc1a56682

创建 Diffie-Hellman 密钥

Diffie-Hellman 算法说明

1
2
3
4
5
6
wiki参考链接:
https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
Diffie-Hellman 密钥交换方法是迪菲(Whitefield Diffie)和赫尔曼(Martin Hellman)在1976
年公布的一种秘钥交换算法,它是一种建立秘钥的方法,而不是加密方法,所以秘钥必须和其他一种加密算法
结合使用。这种密钥交换技术的目的在于使两个用户安全地交换一个密钥,用此密钥做为对称密钥来加密后续
的报文传输。

创建 Diffie-Hellman 密钥

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
[root@centos8 ~]# cd /etc/openvpn/easy-rsa
[root@centos8 easy-rsa]# pwd
/etc/openvpn/easy-rsa

#方法1
[root@centos8 easy-rsa]# ./easyrsa gen-dh

#查看生成的文件
[root@centos8 easy-rsa]# ll pki/dh.pem
-rw------- 1 root root 424 Aug 2 17:41 pki/dh.pem

[root@centos8 easy-rsa]# cat pki/dh.pem
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEAkOTKU13dlokdC6nPi/Saa3T0ubfb2k3YvbA+ZTSWKUPvtlzf7IC1
IF9XvWJO5jC7m2XL7Gld1i43GmUU+vYfyxQ9av6BgiT/Ug1BJbuQMtLzyS8O9zY/
nPw95ouT50y3SACe9BF+2mRm/91bX+XyrHG/XxpKpKN+6q1M4RwMFnE7iRpfUTUv
/DGml3pvLdtG7tMF5QOtmNlbRyA6iiuzABQ903tXQurOusQnDKolLp5DPgzSCKEQ
qMwMGapXzwtfk/wxsaiPHDh4Erjo4SMu4msRM9DY2Q6b5heidEihB5Ud0UXLSelg
vkqdEoqfWWzYZ5RKsugYgsIjc6uXhxxGiwIBAg==
-----END DH PARAMETERS-----

#方法2
[root@centos8 ~]# openssl dhparam -out /etc/openvpn/dh2048.pem 2048
[root@centos8 ~]# ll /etc/openvpn/dh2048.pem
-rw-r--r-- 1 root root 424 Aug 3 20:50 /etc/openvpn/dh2048.pem

准备客户端证书环境

上面服务端证书配置完成,下面是配置客户端证书

修改客户端证书有效期

1
2
3
4
5
6
7
8
9
[root@centos8 ~]# cd /etc/openvpn//easy-rsa/
[root@centos8 easy-rsa]# pwd
/etc/openvpn/easy-rsa/

#建议修改给客户端颁发证书的有效期,可适当减少,比如:90天
[root@centos8 ~]# vim /etc/openvpn/easy-rsa/vars
#set_var EASYRSA_CERT_EXPIRE 825
#将上面行修改为下面
set_var EASYRSA_CERT_EXPIRE 90

创建客户端证书申请

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
[root@centos8 ~]# cd /etc/openvpn/easy-rsa/
[root@centos8 easy-rsa]# pwd
/etc/openvpn/easy-rsa/

#生成客户端用户的证书申请
[root@centos8 easy-rsa]# ./easyrsa gen-req wangxiaochun nopass

Common Name (eg: your user, host, or server name) [wangxiaochun]: #接受默认值,直接回车

Keypair and certificate request completed. Your files are:
req: /etc/openvpn/easy-rsa/pki/reqs/wangxiaochun.req #私钥文件
key: /etc/openvpn/easy-rsa/pki/private/wangxiaochun.key #证书申请文件

#生成两个新文件
[root@centos8 easy-rsa]#tree
.
├── easyrsa
├── openssl-easyrsa.cnf
├── pki
│ ├── openssl-easyrsa.cnf
│ ├── private
│ │ └── wangxiaochun.key #私钥文件
│ ├── reqs
│ │ └── wangxiaochun.req #证书申请文件
│ └── safessl-easyrsa.cnf
├── vars
└── x509-types
├── ca
├── client
├── code-signing
├── COMMON
├── email
├── kdc
├── server
└── serverClient

颁发客户端证书

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
[root@centos8 ~]# cd /etc/openvpn/easy-rsa/
[root@centos8 easy-rsa]# pwd
/etc/openvpn/easy-rsa/

#颁发客户端证书
[root@centos8 easy-rsa]# ./easyrsa sign client wangxiaochun

Confirm request details: yes #输入yes后回车

[root@centos8 easy-rsa]# tree pki
pki
├── ca.crt
├── certs_by_serial
│ ├── 5FE114ACC4FE6AB89D17E1B0EECF2B78.pem
│ └── EDAEBAB8D65066D307AE58ADC1A56682.pem
├── dh.pem
├── index.txt
├── index.txt.attr
├── index.txt.attr.old
├── index.txt.old
├── issued
│ ├── server.crt
│ └── wangxiaochun.crt #生成客户端证书
├── openssl-easyrsa.cnf
├── private
│ ├── ca.key
│ └── server.key
│ └── wangxiaochun.key
├── renewed
│ ├── certs_by_serial
│ ├── private_by_serial
│ └── reqs_by_serial
├── reqs
│ ├── server.req
│ └── wangxiaochun.req
├── revoked
│ ├── certs_by_serial
│ ├── private_by_serial
│ └── reqs_by_serial
├── safessl-easyrsa.cnf
├── serial
└── serial.old

[root@centos8 easy-rsa]# cat pki/index.txt
V 201031091943Z EDAEBAB8D65066D307AE58ADC1A56682 unknown /CN=server
V 201031153815Z 5FE114ACC4FE6AB89D17E1B0EECF2B78 unknown /CN=wangxiaochun

[root@centos8 easy-rsa]# ll pki/issued/
total 16
-rw------- 1 root root 4608 Aug 2 17:19 server.crt
-rw------- 1 root root 4506 Aug 2 23:38 wangxiaochun.crt

[root@centos8 easy-rsa]# ll pki/certs_by_serial/
total 16
-rw------- 1 root root 4506 Aug 2 23:38 5FE114ACC4FE6AB89D17E1B0EECF2B78.pem
-rw------- 1 root root 4608 Aug 2 17:19 EDAEBAB8D65066D307AE58ADC1A56682.pem

[root@centos8 easy-rsa]# cat pki/issued/wangxiaochun.crt
......

如果需要颁发的客户端证书较多,可以使用下面脚本实现客户端证书的批量颁发

客户端证书自动颁发脚本

1
2
3
4
5
6
7
8
9
[root@centos8 ~]# cat openvpn-user-crt.sh 
#!/bin/bash
read -p "请输入用户的姓名拼音(如:${NAME}): " NAME
cd /etc/openvpn/easy-rsa/
./easyrsa gen-req ${NAME} nopass <<EOF
EOF
./easyrsa sign client ${NAME} <<EOF
yes
EOF

将CA和服务器证书相关文件复制到服务器相应的目录

1
2
3
4
5
6
7
8
9
10
11
[root@centos8 ~]# cp /etc/openvpn/easy-rsa/pki/ca.crt /etc/openvpn/server/
[root@centos8 ~]# cp /etc/openvpn/easy-rsa/pki/issued/server.crt /etc/openvpn/server
[root@centos8 ~]# cp /etc/openvpn/easy-rsa/pki/private/server.key /etc/openvpn/server
[root@centos8 ~]#cp /etc/openvpn/easy-rsa/pki/dh.pem /etc/openvpn/server

[root@centos8 ~]# ll /etc/openvpn/server
total 20
-rw------- 1 root root 1204 Aug 3 20:34 ca.crt
-rw------- 1 root root 424 Aug 3 20:35 dh.pem
-rw------- 1 root root 4608 Aug 3 20:34 server.crt
-rw------- 1 root root 1704 Aug 3 20:35 server.key

将客户端私钥与证书相关文件复制到服务器相关的目录

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@centos8 ~]# mkdir /etc/openvpn/client/wangxiaochun/
[root@centos8 ~]# find /etc/openvpn/easy-rsa -name "wangxiaochun.key" -o -name "wangxiaochun.crt" -o -name ca.crt
/etc/openvpn/easy-rsa/pki/private/wangxiaochun.key
/etc/openvpn/easy-rsa/pki/issued/wangxiaochun.crt
/etc/openvpn/easy-rsa/pki/ca.crt

[root@centos8 ~]# find /etc/openvpn/easy-rsa \( -name "wangxiaochun.key" -o -name "wangxiaochun.crt" -o -name ca.crt \) -exec cp {} /etc/openvpn/client/wangxiaochun \;

[root@centos8 ~]# ll /etc/openvpn/client/wangxiaochun/
total 16
-rw------- 1 root root 1204 Aug 3 21:05 ca.crt
-rw------- 1 root root 4506 Aug 3 21:05 wangxiaochun.crt
-rw------- 1 root root 1704 Aug 3 21:05 wangxiaochun.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
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
#生成服务器配置文件
#Ubuntu20.04配置文件路径
[root@ubuntu2004 ~]# ls /usr/share/doc/openvpn/examples/sample-config-files/

#CentOS8
[root@centos8 ~]# cp /usr/share/doc/openvpn/sample/sample-config-files/server.conf /etc/openvpn/

#服务器配置文件server.conf文件中以#或;开头的行都为注释
[root@centos8 ~]# grep -Ev "^#|^$" /etc/openvpn/server.conf
;local a.b.c.d #本机监听IP,默认为本机所有IP
port 1194 #端口
;proto tcp #协议,生产推荐使用TCP
proto udp #默认协议udp
;dev tap #创建以太网隧道设备,tap设备实现以太网帧通过Openvpn隧道,可提供非IP协议如IPX和AppleTalk等的支持,tap等当于一个以太网设备,它操作第二层数据包如以太网数据帧。
dev tun #创建IP路由隧道,生产推存使用tun.互联网使用tun,一个tun设备大多时候被用于基于IP协议的通讯。tun模拟了网络层设备,操作第三层数据包比如IP数据封包。
;dev-node MyTap #TAP-Win32的设备驱动。非windows系统不需要
ca ca.crt #ca证书文件
cert server.crt #服务器证书文件
key server.key #服务器私钥文件
dh dh2048.pem #dh参数文件
;topology subnet
server 10.8.0.0 255.255.255.0 #客户端连接后自动分配的IP网段,默认会给服务器分配此网段的第一个IP将做为客户端的网关,注意不要和内网网段相同
ifconfig-pool-persist ipp.txt #记录客户端和虚拟ip地址分配的文件
;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100 #配置网桥模式,无需配置,建议注释
;server-bridge
;push "route 192.168.10.0 255.255.255.0" #推送给客户端的到达服务器后面网段的静态路由,网关是服务器地址10.8.0.1
;push "route 192.168.10.100 255.255.255.255" #用255.255.255.255可实现只能访问内网单个主机的功能,比如:jumpserver
;push "route 192.168.20.0 255.255.255.0" #推送路由信息到客户端,以允许客户端能够连接到服务器背后的其它私有网络
;client-config-dir ccd #为特定客户端添加路由信息,此路由是客户端后面的网段而非服务端的网段,无需设置
;route 192.168.40.128 255.255.255.248
;client-config-dir ccd
;route 10.9.0.0 255.255.255.252
;learn-address ./script #指定外部脚本文件,实现创建不同组的iptables规则,无需配置
;push "redirect-gateway def1 bypass-dhcp" #启用此配置后客户端所有流量都将通过VPN服务器进行转发,因此生产一般无需配置此项
;push "dhcp-option DNS 208.67.222.222" #推送DNS服务器地址,无需配置
;push "dhcp-option DNS 208.67.220.220"
;client-to-client #允许不同的客户端直接通信,不安全,生产环境一般无需配置
;duplicate-cn #多个用户共用一个证书,一般用于测试环境,生产环境建议一个用户一个证书,无需开启
keepalive 10 120 #设置服务端活动的检测的间隔和超时时间,每隔10秒ping一次,120秒没有回应则认为已经断线
tls-auth ta.key 0 #访止DoS等攻击的安全增强配置,服务器和每个客户端都需要拥有此密钥文件。第二个参数在服务器端为0,客户端为1
cipher AES-256-CBC #加密算法
;compress lz4-v2 #启用Openvpn2.4.X新版压缩算法
;push "compress lz4-v2" #推送客户端使用新版压缩算法,和下面的comp-lzo不要同时使用
;comp-lzo #旧户端兼容的压缩配置,需要客户端配置开启压缩,openvpn2.4.X等新版可以不用开启
;max-clients 100 #最多支持的客户端数量
;user nobody #指定openvpn服务的用户
;group nobody #指定openvpn服务的组
persist-key #重启服务时默认会重新读取key文件,开启此配置后保持使用第一次的key文件,生产环境无需开启
persist-tun #Don’t close and reopen TUN/TAP device or run up/down scripts across SIGUSR1 or --ping-restart restarts,生产环境建议无需开启
status openvpn-status.log #服务器状态记录文件,每分钟记录一次相关信息
;log openvpn.log #第一种日志记录方式,并指定日志路径,log会在openvpn启动的时候清空日志文件,不建议使用
;log-append openvpn.log #第二种日志记录方式,并指定日志路径,重启openvpn后在之前的日志后面追加新的日志,生产环境建议使用
verb 3 #设置日志级别,0-9,级别越高记录的内容越详细,0 表示静默运行,只记录致命错误,4 表示合理的常规用法,5 和 6 可以帮助调试连接错误。9 表示极度冗余,输出非常详细的日志信息
;mute 20 #对相同类别的信息只记录前20条到日志文件中
explicit-exit-notify 1 #当服务端重启后通知客户端自动重新连接服务器,此项配置仅能用于udp模式,tcp模式无需配置即能实现重新连接功能,且开启此项后tcp配置后将导致openvpn服务无法启动,所以tcp时必须不能开启此项
script-security 3 # 允许使用自定义脚本
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env #指定自定义脚本路径
username-as-common-name #开启用户密码验证
client-cert-not-required #只支持用户和密码方式验证,不支持证书,无此配置表示需要证书和用户密码多种验证

修改服务器端配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@centos8 ~]# vim /etc/openvpn/server.conf
[root@centos8 ~]# grep '^[a-Z].*' /etc/openvpn/server.conf
port 1194
proto tcp
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
push "route 172.30.0.0 255.255.255.0"
keepalive 10 120
cipher AES-256-CBC
compress lz4-v2
push "compress lz4-v2"
max-clients 2048
user openvpn
group openvpn
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
mute 20

准备服务器日志相关目录

1
2
3
4
5
6
7
8
9
10
11
12
13
#Ubuntu20.04需要手动创建用户
[root@ubuntu2004 ~]# useradd -r -s /sbin/nologin openvpn

#CentOS8安装包时,自动创建相关用户和组openvpn
[root@centos8 ~]# getent passwd openvpn
openvpn:x:993:990:OpenVPN:/etc/openvpn:/sbin/nologin

##Ubuntu默认有此目录
[root@centos8 ~]# mkdir /var/log/openvpn

[root@centos8 ~]# chown openvpn.openvpn /var/log/openvpn
[root@centos8 ~]# ll -d /var/log/openvpn
drwxr-xr-x 2 openvpn openvpn 6 Aug 3 23:07 /var/log/openvpn

启动 OpenVPN 服务

准备 OpenVPN 服务的service文件

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
[root@centos7 ~]# rpm -ql openvpn|grep systemd
/usr/lib/systemd/system/openvpn-client@.service
/usr/lib/systemd/system/openvpn-server@.service
/usr/lib/systemd/system/openvpn@.service
/usr/share/doc/openvpn-2.4.9/README.systemd

#Ubuntu20.04内置service文件,无需下面操作
#CentOS8 缺失unit文件,从CentOS7复制文件
[root@centos8 ~]# rpm -ql openvpn|grep systemd
/usr/lib/systemd/system/openvpn-client@.service
/usr/lib/systemd/system/openvpn-server@.service
/usr/share/doc/openvpn/README.systemd

[root@centos7 ~]# cat /usr/lib/systemd/system/openvpn@.service
[Unit]
Description=OpenVPN Robust And Highly Flexible Tunneling Application On %I
After=network.target

[Service]
Type=notify
PrivateTmp=true
ExecStart=/usr/sbin/openvpn --cd /etc/openvpn/ --config %i.conf

[Install]
WantedBy=multi-user.target

[root@centos7 ~]# scp /lib/systemd/system/openvpn@.service 10.0.0.8:/lib/systemd/system/

#启动OpenVPN服务,注意service名称和文件名不一致
[root@centos8 ~]# systemctl daemon-reload
[root@centos8 ~]# systemctl enable --now openvpn@server

[root@ubuntu2004 ~]# systemctl enable --now openvpn@server

查看服务状态

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
[root@centos8 openvpn]# systemctl status openvpn@server

#注意端口号
[root@centos8 ~]#ss -ntlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port

LISTEN 0 32 0.0.0.0:1194 0.0.0.0:* users:(("openvpn",pid=7340,fd=9))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=761,fd=4))
LISTEN 0 100 127.0.0.1:25 0.0.0.0:* users:(("master",pid=1093,fd=16))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=761,fd=6))
LISTEN 0 100 [::1]:25 [::]:* users:(("master",pid=1093,fd=17))

[root@centos8 ~]# cat /var/log/openvpn/openvpn.log

[root@centos8 ~]# ip a
3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state
UNKNOWN group default qlen 100
link/none
inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::c8db:a8ca:b492:a3e0/64 scope link stable-privacy
valid_lft forever preferred_lft forever

[root@centos8 ~]#route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.30.0.253 0.0.0.0 UG 100 0 0 eth0
10.8.0.0 10.8.0.2 255.255.255.0 UG 0 0 0 tun0
10.8.0.2 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
172.30.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0

验证tun网卡设备:

8

准备 OpenVPN 客户端配置文件

客户端默认范例配置文件说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#Ubuntu客户端配置范例文件
[root@ubuntu2004 ~]# cat /usr/share/doc/openvpn/examples/sample-config-files/client.conf

[root@centos8 ~]# grep '^[[:alpha:]].*' /usr/share/doc/openvpn/sample/sample-config-files/client.conf
client #指明客户端
dev tun #指定和服务端一致的接口类型
proto udp #指定和服务端一致的协议类型
remote my-server-1 1194 #服务器端的ip或FQDN及端口
resolv-retry infinite #指定服务器端FQDN而非IP时,当客户端重新连接后会重新解FQDN对应的IP
nobind #客户端不绑定监听端口,随机打开端口连接到服务端的端口
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
remote-cert-tls server #使用服务器证书校验方式
tls-auth ta.key 1 #安全加强
cipher AES-256-CBC
verb 3

生成客户端用户的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#生成客户端文件,文件后缀必须为.ovpn
[root@centos8 ~]# grep '^[[:alpha:]].*' /usr/share/doc/openvpn/sample/sample-config-files/client.conf > /etc/openvpn/client/wangxiaochun/client.ovpn

#修改配置文件,内容如下
[root@centos8 ~]# vim /etc/openvpn/client/wangxiaochun/client.ovpn
[root@centos8 ~]# cat /etc/openvpn/client/wangxiaochun/client.ovpn
client
dev tun
proto tcp
remote openvpn-server 1194 #生产中为OpenVPN服务器的FQDN或者公网IP
resolv-retry infinite
nobind
#persist-key
#persist-tun
ca ca.crt
cert wangxiaochun.crt
key wangxiaochun.key
remote-cert-tls server
#tls-auth ta.key 1
cipher AES-256-CBC
verb 3 #此值不能随意指定,否则无法通信
compress lz4-v2 #此项在OpenVPN2.4.X版本使用,需要和服务器端保持一致,如不指定,默认使用comp-lz压缩

实现 OpenVPN 客户端

配置部署 Windows 的 OpenVPN 客户端

Windows 安装 OpenVPN 客户端

官方客户端下载地址:

https://openvpn.net/community-downloads/

9

openvpn客户端安装过程:

10

11

12

13

14

Windows 客户端配置准备

保存证书到openvpn 客户端安装目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#在服务器打包证书并下载发送给windows客户端
[root@centos8 ~]# cd /etc/openvpn/client/wangxiaochun/
[root@centos8 wangxiaochun]# pwd
/etc/openvpn/client/wangxiaochun

[root@centos8 wangxiaochun]# tar cf wangxiaochun.tar ./
tar: ./wangxiaochun.tar: file is the archive; not dumped

[root@centos8 wangxiaochun]# ll
total 40
-rw------- 1 root root 1204 Aug 3 21:05 ca.crt
-rw-r--r-- 1 root root 231 Aug 3 23:31 client.ovpn
-rw------- 1 root root 4506 Aug 3 21:05 wangxiaochun.crt
-rw------- 1 root root 1704 Aug 3 21:05 wangxiaochun.key
-rw-r--r-- 1 root root 20480 Aug 4 10:48 wangxiaochun.tar

[root@centos8 wangxiaochun]# tar tf wangxiaochun.tar
./
./wangxiaochun.key
./wangxiaochun.crt
./ca.crt
./client.ovpn

放置到windows客户端默认安装目录下 C:\Program Files\OpenVPN\config 目录

15

Windows 客户端建立OpenVPN连接

在windows 中打开 OpenVPN GUI 工具,稍等一会儿,在状态栏显示以下图标,右键点连接

16

17

18

19

Windows 客户端验证通信

在Windows 客户端测试访问OpenVPN后端服务器

后端服务器显示是来自于OpenVPN服务器的连接

20

观察OpenVPN服务器日志
1
[root@centos8 ~]# tail /var/log/openvpn/openvpn.log -f -n0
验证OpenVPN服务器连接状态
1
2
3
4
[root@centos8 ~]#ss -nt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 52 10.0.0.8:22 10.0.0.1:14009
ESTAB 0 0 10.0.0.8:1194 10.0.0.1:6913
验证 Windows 客户端的 IP地址

21

验证Windows 客户端的路由表

22

配置部署 Linux 的 OpenVPN 客户端

客户端安装 openvpn

1
[root@openvpn-client ~]# yum -y install openvpn

下载客户端公钥与私钥以及Ca证书至客户端

1
2
[root@openvpn-client ~]# ls /etc/openvpn/
ca.crt wangxiaochun.crt wangxiaochun.key

客户端有了公钥和私钥后,还需要准备对应的客户端配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@openvpn-client ~]# cat /etc/openvpn/client.ovpn
client #指定当前VPN是客户端
dev tun #使用tun隧道传输协议
proto tcp #使用tcp协议传输数据
remote OpenVPN服务器地址 1194 #openvpn服务器IP地址端口号
resolv-retry infinite #断线自动重新连接,在网络不稳定的情况下非常有用
nobind #不绑定本地特定的端口号
ca ca.crt #指定CA证书的文件路径
cert client.crt #指定当前客户端的证书文件路径
key client.key #指定当前客户端的私钥文件路径
verb 3 #指定日志文件的记录详细级别,可选0-9,等级越高日志内容越详细
persist-key #重启服务时默认会重新读取key文件,开启此配置后保持使用第一次的key文件
persist-tun #重新启动VPN时,仍会一直保持tun是up状态

启动 openvpn 客户端

1
2
3
4
5
6
[root@openvpn-client ~]# openvpn --daemon --cd /etc/openvpn --config client.ovpn --log-append /var/log/openvpn.log

--daemon #openvpn以daemon方式启动
--cd dir #配置文件的目录,openvpn初始化前,先切换到此目录
--config file #客户端配置文件的路径
--log-append file #日志文件路径,如果文件不存在会自动创建

配置部署 Mac OS 的 OpenVPN 客户端

由于官方并没有提供基于Mac OS的OpenVPN的客户端软件,,可以使用第三方 OpenVPN 客户端

参考链接: https://tunnelblick.net/downloads.html

需要科学访问

23

实现访问VPN服务器的内网主机

当前客户端只能连接OpenVPN服务器,无法连接OpenVPN服务器网络的中其它主机,还需要做如下配置才能实现

OpenVPN服务器打开 ip_forward功能

1
2
3
4
#在服务器开启ip_forward转发功能
[root@centos8 ~]# echo net.ipv4.ip_forward = 1 >> /etc/sysctl.conf
[root@centos8 ~]# sysctl -p
net.ipv4.ip_forward = 1

配置实现内网服务器回应外网的请求的路由

可以使用下面三种方法实现OpenVPN服务器网段中的其它主机的访问

在内网每个主机上添加路由

此方式比较麻烦,不太推荐

1
2
#阿里云服务器不支持修改路由
[root@rocky8 ~]# route add -net 10.8.0.0/24 gw 172.30.0.1

在内网主机指定的路由器上添加路由

1
[root@router ~]# route add -net 10.8.0.0/24 gw 172.30.0.1

在OpenVPN服务器配置 iptables 规则

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
#添加SNAT规则
#方法1
[root@ubuntu2004 ~]# echo 'iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE' >> /etc/rc.local
[root@centos8 ~]# echo 'iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE' >> /etc/rc.d/rc.local


#方法2
[root@centos8 ~]# echo 'iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to-source 172.30.0.1' >> /etc/rc.d/rc.local
[root@centos8 ~]# chmod +x /etc/rc.d/rc.local

[root@centos8 ~]# iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

[root@centos8 ~]# iptables -vnL -t nat
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

0 0 MASQUERADE all -- * * 10.8.0.0/24 0.0.0.0/0

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

OpenVPN 管理

OpenVPN的管理功能主要关于安全加强及客户端的证书管理,用户密码验证等

启用安全增强功能

启用防止DoS攻击的安全增强配置

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
[root@centos8 ~]# openvpn --genkey --secret /etc/openvpn/server/ta.key
[root@centos8 ~]# cat /etc/openvpn/server/ta.key
......

[root@centos8 ~]# ll /etc/openvpn/server/
total 24
-rw------- 1 root root 1204 Aug 3 20:34 ca.crt
-rw------- 1 root root 424 Aug 3 20:35 dh.pem
-rw------- 1 root root 4608 Aug 3 20:34 server.crt
-rw------- 1 root root 1704 Aug 3 20:35 server.key
-rw------- 1 root root 636 Aug 4 15:53 ta.key

[root@centos8 ~]# vim /etc/openvpn/server.conf
#tls-auth ta.key 0 # This file is secret
tls-auth /etc/openvpn/server/ta.key 0 #客户端为1,服务器端为0

[root@centos8 ~]# systemctl restart openvpn@server.service


#日志提示出错
root@centos8 ~]# tail -n 20 /var/log/openvpn/openvpn.log -f
Tue Aug 4 15:56:30 2020 TLS Error: cannot locate HMAC in incoming packet from
[AF_INET]10.0.0.1:59743
Tue Aug 4 15:56:39 2020 TLS Error: cannot locate HMAC in incoming packet from
[AF_INET]10.0.0.1:59743
Tue Aug 4 15:56:45 2020 TLS Error: cannot locate HMAC in incoming packet from
[AF_INET]10.0.0.1:59073

客户端无法直接连接

24

将ta.key 传到客户端相关目录下

25

修改客户端配置文件clent.ovpn,添加一行

1
tls-auth ta.key 1   #客户端为1,服务器端为0

26

客户端重新连接成功

27

设置客户端的私钥密码增强安全性

新建一个账户wang,并且设置证书密码,提高证书及登录VPN的安全性。

创建新用户对应的有密码的私钥和证书申请

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
[root@centos8 easy-rsa]# cd /etc/openvpn/easy-rsa/
[root@centos8 easy-rsa]# pwd
/etc/openvpn/easy-rsa/

[root@centos8 easy-rsa]# ./easyrsa gen-req wang
Note: using Easy-RSA configuration from: /etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 1.1.1c FIPS 28 May 2019
Generating a RSA private key
...............................................................+++++
................+++++
writing new private key to '/etc/openvpn/easy-rsa/pki/easy-rsa-35371.iJfHbs/tmp.9lGUMy'
Enter PEM pass phrase:
#输入两遍密码
Verifying - Enter PEM pass phrase:
#输入两遍密码
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [wang]: #接受默认值,直接回车
Keypair and certificate request completed. Your files are:
req: /etc/openvpn/easy-rsa/pki/reqs/wang.req
key: /etc/openvpn/easy-rsa/pki/private/wang.key

给新用户颁发用户证书

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
[root@centos8 easy-rsa]# cd /etc/openvpn/easy-rsa/
[root@centos8 easy-rsa]# pwd
/etc/openvpn/easy-rsa/

#确保证书有效期是合理值
[root@centos8 easy-rsa]# grep EASYRSA_CERT_EXPIRE vars
set_var EASYRSA_CERT_EXPIRE 90

#颁发证书
[root@centos8 easy-rsa]# ./easyrsa sign client wang
Note: using Easy-RSA configuration from: /etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 1.1.1c FIPS 28 May 2019
You are about to sign the following certificate.
Please check over the details shown below for accuracy. Note that this request
has not been cryptographically verified. Please be sure it came from a trusted
source or that you have verified the request checksum with the sender.
Request subject, to be signed as a client certificate for 90 days:
subject=
commonName = wang


Type the word 'yes' to continue, or any other input to abort.
Confirm request details: yes #输入yes
Using configuration from /etc/openvpn/easy-rsa/pki/easy-rsa-36053.IQvyRq/tmp.5GkGy2
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'wang'
Certificate is to be certified until Nov 2 08:30:43 2020 GMT (90 days) #有效期

Write out database with 1 new entries
Data Base Updated

Certificate created at: /etc/openvpn/easy-rsa/pki/issued/wang.crt

[root@centos8 ~]#cat /etc/openvpn/easy-rsa/pki/index.txt
V 201031091943Z EDAEBAB8D65066D307AE58ADC1A56682 unknown /CN=server
V 201031153815Z 5FE114ACC4FE6AB89D17E1B0EECF2B78 unknown
/CN=wangxiaochun
V 201102083043Z C971227DA77824C8ACB7D655D09D4081 unknown /CN=wang

将用户的证书相关文件放在指定的目录中

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
[root@centos8 ~]# mkdir /etc/openvpn/client/wang
[root@centos8 ~]# cp /etc/openvpn/easy-rsa/pki/issued/wang.crt /etc/openvpn/client/wang
[root@centos8 ~]#cp /etc/openvpn/easy-rsa/pki/private/wang.key /etc/openvpn/client/wang
[root@centos8 ~]# cp /etc/openvpn/server/{ca.crt,ta.key} /etc/openvpn/client/wang/
[root@centos8 ~]# cp /etc/openvpn/client/wangxiaochun/client.ovpn /etc/openvpn/client/wang/
[root@centos8 ~]# ll /etc/openvpn/client/wang/
total 28
-rw------- 1 root root 1204 Aug 4 16:41 ca.crt
-rw-r--r-- 1 root root 231 Aug 4 16:44 client.ovpn
-rw------- 1 root root 4492 Aug 4 16:38 wang.crt
-rw------- 1 root root 1854 Aug 4 16:38 wang.key
-rw------- 1 root root 636 Aug 4 16:41 ta.key

[root@centos8 ~]# cd /etc/openvpn/client/wang/

#根据服务器端修改下面配置,需要和服务器同步
[root@centos8 wang]# vim client.ovpn
[root@centos8 wang]# cat client.ovpn
client
dev tun
proto tcp
remote OpenVPN服务器地址 1194
resolv-retry infinite
nobind
#persist-key
#persist-tun
ca ca.crt
cert wang.crt
key wang.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-CBC
verb 3
compress lz4-v2


[root@centos8 wang]# tar cf wang.tar *
[root@centos8 wang]# tar tvf wang.tar
-rw------- root/root 1204 2020-08-04 16:41 ca.crt
-rw-r--r-- root/root 225 2020-08-04 16:47 client.ovpn
-rw------- root/root 4492 2020-08-04 16:38 wang.crt
-rw------- root/root 1854 2020-08-04 16:38 wang.key
-rw------- root/root 636 2020-08-04 16:41 ta.key

将相关文件传给客户端主机相应目录

放置到windows客户端的 C:\Program Files\OpenVPN\config 目录下

28

Windows 客户端重新连接

29

30

查看日志

1
[root@centos8 ~]# tail -n0 /var/log/openvpn/openvpn.log -f

31

账户证书管理

对新员工的入职和老员工的离职,会涉及到证书的创建和吊销

证书自动过期

前面颁发的证书都有有一定的有效期,过期后就需要重新颁发新证书

1
2
3
#过期时间由以下设置决定
[root@centos8 ~]#grep EASYRSA_CERT_EXPIRE /etc/openvpn/easy-rsa/vars
set_var EASYRSA_CERT_EXPIRE 90

如果证书过期,在服务器端可以看到以下日志

1
2
3
#让服务器时间改为2年后时间
[root@centos8 ~]#date -s '2 year'
Thu Aug 4 17:41:04 CST 2022

32

1
2
#服务器端日志中会显示用户证书过期
[root@centos8 ~]# tail -n0 /var/log/openvpn/openvpn.log -f

证书手动注销

查看当前证书的有效性

1
2
3
4
5
#证书有效为V,无效为R
[root@centos8 ~]#cat /etc/openvpn/easy-rsa/pki/index.txt
V 201031091943Z EDAEBAB8D65066D307AE58ADC1A56682 unknown /CN=server
V 201031153815Z 5FE114ACC4FE6AB89D17E1B0EECF2B78 unknown /CN=wangxiaochun
V 201102083043Z C971227DA77824C8ACB7D655D09D4081 unknown /CN=wang

吊销指定的用户的证书

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
[root@centos8 ~]# cd /etc/openvpn/easy-rsa/
[root@centos8 easy-rsa]# ./easyrsa revoke wang
Note: using Easy-RSA configuration from: /etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 1.1.1c FIPS 28 May 2019
Please confirm you wish to revoke the certificate with the following subject:
subject=
commonName = wang

Type the word 'yes' to continue, or any other input to abort.
Continue with revocation: yes
Using configuration from /etc/openvpn/easy-rsa/pki/easy-rsa3787.Q2lnW6/tmp.18ZdMO
Revoking Certificate C971227DA77824C8ACB7D655D09D4081.
Data Base Updated
IMPORTANT!!!

Revocation was successful. You must run gen-crl and upload a CRL to your
infrastructure in order to prevent the revoked cert from being accepted.

#查看当前证书的有效性,有效为V,无效为R
[root@centos8 easy-rsa]# cat /etc/openvpn/easy-rsa/pki/index.txt
V 201031091943Z EDAEBAB8D65066D307AE58ADC1A56682 unknown /CN=server
V 201031153815Z 5FE114ACC4FE6AB89D17E1B0EECF2B78 unknown /CN=wangxiaochun
R 201102083043Z 200805123127Z C971227DA77824C8ACB7D655D09D4081 unknown /CN=wang

#当前断开客户端连接,wang用户仍然能连接成功

生成证书吊销列表

1
2
3
4
5
6
7
8
9
10
11
12
#每次吊销证书后都需要更新证书吊销列表文件,并且需要重启OpenVPN服务
[root@centos8 easy-rsa]# ./easyrsa gen-crl

Note: using Easy-RSA configuration from: /etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 1.1.1c FIPS 28 May 2019
Using configuration from /etc/openvpn/easy-rsa/pki/easy-rsa-4323.gUt4WS/tmp.ybAcAU

An updated CRL has been created.
CRL file: /etc/openvpn/easy-rsa/pki/crl.pem

[root@centos8 easy-rsa]# cat pki/crl.pem
......

33

将吊销列表文件发布

1
2
3
4
5
6
#第一次吊销证时需要编辑配置文件调用吊销证书的文件,后续吊销无需此步
[root@openvpn-server ~]# vim /etc/openvpn/server.conf
crl-verify /etc/openvpn/easy-rsa/pki/crl.pem

#每次吊销证书后,都需要重新启动才能生效
[root@centos8 ~]# systemctl restart openvpn@server.service

再次测试连接失败

用户端再次连接失败

34

1
2
3
4
5
6
7
8
9
10
11
#观察OpenVPN目志
[root@centos8 easy-rsa]# tail -f /var/log/openvpn/openvpn.log -n0
Wed Aug 5 21:13:25 2020 TCP connection established with [AF_INET]10.0.0.1:7419
Wed Aug 5 21:13:26 2020 10.0.0.1:7419 TLS: Initial packet from
[AF_INET]10.0.0.1:7419, sid=169fe75b 63908b79
Wed Aug 5 21:13:26 2020 10.0.0.1:7419 WARNING: Failed to stat CRL file, not
(re)loading CRL.
Wed Aug 5 21:13:26 2020 10.0.0.1:7419 VERIFY ERROR: depth=0, error=certificate
revoked: CN=wang
Wed Aug 5 21:13:26 2020 10.0.0.1:7419 OpenSSL: error:1417C086:SSL
routines:tls_process_client_certificate:certificate verify failed

账户重名证书颁发

对于员工重名的情况,可以为新员工指定新的名称,或者删除不再使用的重名用户证书,重新创建新证书

手动重新颁发证书

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
#删除已被吊销的账户证书
[root@centos8 ~]# cd /etc/openvpn/easy-rsa/
[root@centos8 easy-rsa]# rm -f pki/private/wang.key
[root@centos8 easy-rsa]# rm -f pki/reqs/wang.req
[root@centos8 easy-rsa]# rm -f /etc/openvpn/client/wang/*
[root@centos8 easy-rsa]# rm -f /etc/openvpn/easy-rsa/pki/reqs/wang.req
[root@centos8 easy-rsa]# rm -f /etc/openvpn/easy-rsa/pki/issued/wang.crt


#删除之前的带R的吊销记录,此为可选项
[root@centos8 easy-rsa]# vim /etc/openvpn/easy-rsa/pki/index.txt

#重新生成新的账户证书申请和私钥
[root@centos8 easy-rsa]# cd /etc/openvpn//easy-rsa/
[root@centos8 easy-rsa]# ./easyrsa gen-req wang

Common Name (eg: your user, host, or server name) [wang]:#直接回车

[root@centos8 easy-rsa]# cd /etc/openvpn/easy-rsa
[root@centos8 easy-rsa]# ./easyrsa import-req /etc/openvpn/easy-rsa/pki/reqs/wang.req wang
[root@centos8 easy-rsa]# ./easyrsa sign client wang
......
Type the word 'yes' to continue, or any other input to abort.
Confirm request details: yes #输入yes
......
Write out database with 1 new entries
Data Base Updated
Certificate created at: /etc/openvpn/easy-rsa/pki/issued/wang.crt

#生成相关文件
[root@centos8 easy-rsa]# cp /etc/openvpn/easy-rsa/pki/issued/wang.crt /etc/openvpn/client/wang/
[root@centos8 easy-rsa]# cp /etc/openvpn/easy-rsa/pki/private/wang.key /etc/openvpn/client/wang/
[root@centos8 easy-rsa]# cp /etc/openvpn/server/{ca.crt,ta.key} /etc/openvpn/client/wang/
[root@centos8 easy-rsa]# cp /etc/openvpn/client/wangxiaochun/client.ovpn /etc/openvpn/client/wang/

#修改客户端配置文件
[root@centos8 easy-rsa]# vim /etc/openvpn/client/wang/client.ovpn
client
dev tun
proto tcp
remote 10.0.0.8 1194
resolv-retry infinite
nobind
#persist-key
#persist-tun
ca ca.crt
cert wang.crt
key wang.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-CBC
verb 3
compress lz4-v2

[root@centos8 ~]# tree /etc/openvpn/client/wang
/etc/openvpn/client/wang
├── ca.crt
├── client.ovpn
├── dh.pem
├── wang.crt
├── wang.key
└── ta.key
0 directories, 6 files
#将/etc/openvpn/client/wang所有文件打包传到客户端使用

自动化的证书颁发脚本

通过脚本实现自动化的证书颁发

脚本内容
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
[root@centos8 ~]#cat openvpn-user-crt.sh 
#!/bin/bash

OPENVPN_SERVER=openvpn.wangxiaochun.com
PASS=123456

remove_cert () {
rm -rf /etc/openvpn/client/${NAME}
find /etc/openvpn/ -name "$NAME.*" -delete
}

create_cert () {
cd /etc/openvpn/easy-rsa
./easyrsa gen-req ${NAME} nopass <<EOF
EOF
cd /etc/openvpn/easy-rsa
./easyrsa import-req /etc/openvpn/easy-rsa/pki/reqs/${NAME}.req ${NAME}
./easyrsa sign client ${NAME} <<EOF
yes
EOF

mkdir /etc/openvpn/client/${NAME}
cp /etc/openvpn/easy-rsa/pki/issued/${NAME}.crt /etc/openvpn/client/${NAME}
cp /etc/openvpn/easy-rsa/pki/private/${NAME}.key
/etc/openvpn/client/${NAME}
cp /etc/openvpn/server/{ca.crt,ta.key} /etc/openvpn/client/${NAME}
cat > /etc/openvpn/client/${NAME}/client.ovpn <<EOF
client
dev tun
proto tcp
remote $OPENVPN_SERVER 1194
resolv-retry infinite
nobind
#persist-key
#persist-tun
ca ca.crt
cert $NAME.crt
key $NAME.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-CBC
verb 3
compress lz4-v2
EOF

echo "证书存放路径:/etc/openvpn/client/${NAME},证书文件如下:"
echo -e
"\E[1;32m******************************************************************\E[0m"
ls -l /etc/openvpn/client/${NAME}
echo -e
"\E[1;32m******************************************************************\E[0m"
cd /etc/openvpn/client/${NAME}
zip -qP "$PASS" /root/${NAME}.zip *
echo "证书的打包文件已生成: /root/${NAME}.zip"
}

read -p "请输入用户的姓名拼音(如:wangxiaochun): " NAME

remove_cert
create_cert
执行脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@centos8 ~]# bash openvpn-user-crt.sh 
请输入用户的姓名拼音(如:): wang

证书存放路径:/etc/openvpn/client/wang,证书文件如下:
******************************************************************
total 28
-rw------- 1 root root 1204 Aug 5 21:50 ca.crt
-rw-r--r-- 1 root root 225 Aug 5 21:50 client.ovpn
-rw------- 1 root root 424 Aug 5 21:50 dh.pem
-rw------- 1 root root 4492 Aug 5 21:50 wang.crt
-rw------- 1 root root 1704 Aug 5 21:50 wang.key
-rw------- 1 root root 636 Aug 5 21:50 ta.key
******************************************************************
证书的打包文件已生成: /root/wang.zip [ OK ]

在Windows客户端用新证书连接登录

35

36

37

实现用户密码认证

基于证书验证的基础上再加上用户名密码验证可以实现更高的安全性

修改服务端配置

1
2
3
4
5
[root@centos8 ~]# vim /etc/openvpn/server.conf
# 添加三行,实现服务端支持密码认证方式
script-security 3 # 允许使用自定义脚本
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env #指定自定义脚本路径
username-as-common-name #开启用户密码验证

创建自定义脚本

官方脚本下载

1
http://openvpn.se/files/other/checkpsw.sh

范例:

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
[root@centos8 ~]# vim /etc/openvpn/checkpsw.sh
#!/bin/sh

PASSFILE="/etc/openvpn/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

#增加执行权限
[root@centos8 ~]# chmod +x /etc/openvpn/checkpsw.sh

创建用户密码文件

1
2
3
4
5
6
7
# 创建用户和密码认证文件,每行是一个用户和密码
[root@centos8 ~]# cat > /etc/openvpn/psw-file <<EOF
wang 123456
test 654321
EOF

[root@centos8 ~]# systemctl restart openvpn@server

修改客户端配置

修改客户端配置文件client.ovpn文件,增加下面一行,使其支持用户名/密码与服务器进行身份验证.

1
2
3
[root@centos8 ~]# vim /etc/openvpn/client/wangxiaochun/client.ovpn
#加下面一行,可以支持用户密码认证
auth-user-pass

客户端连接验证

38