CentOS7下搭建OpenVPN

OpenVPN 是一个用于创建虚拟专用网络加密通道的软件包,最早是由James Yonan编写的。OpenVPN允许创建的VPN使用公开密钥、电子证书、或者用户名/密码来进行身份验证.。

目前OpenVPN能在Solaris、Linux、OpenBSD、FreeBSD、NetBSD、Mac OS X与Microsoft Windows以及Android和iOS上运行,并包含了许多安全性的功能。它并不是一个基于Web的VPN软件,也不与IPsec及其他VPN软件包兼容。

OpenVPN Server/Client部署流程图

搭建n VPN 服务端—>添加防火墙规则:snat—>启动 open VPN 服务端—>创建一个用户测试连接:创建客户端 CA 证书、生成 .ovpn 配置文件、打包相关文件供客户端使用。

OpenVPN 服务端

环境准备

由于不同环境及软件版本命令使用略有差异,特别是 easy-rsa 的使用在 2.0 和 3.0 的差别有点大,所以在此先说明下安装环境及相关软件版本:

1
2
3
System Version: CentOS7
OpenVPN Version: 2.4.7
Easy-rsa Version:3.0.6

安装与配置

1. 安装 openvpn、easy-rsa、iptables-services

1
2
# yum -y install epel-release		# 安装第三方yum源
# yum -y install openvpn easy-rsa iptables-services # 安装openvpn,easy-rsa等软件

2. 使用 easy-rsa 生成需要的证书及相关文件

  • CA 根证书
  • OpenVPN 服务器 ssl 证书
  • Diffie-Hellman 算法用到的 key
2.1 将 easy-rsa 脚本复制到 /etc/openvpn/目录下,该脚本主要用来方便地生成 CA 证书和各种 key
1
# cp -r /usr/share/easy-rsa/ /etc/openvpn/
2.2 跳到 easy-rsa 目录并编辑 vars 文件,添加一些生成证书时用到的变量
1
2
3
4
5
6
7
8
9
10
# cd /etc/openvpn/easy-rsa/<easy-rsa 版本号>/  # 查看 easy-rsa 版本号:yum info easy-rsa
# vim vars # 没这个文件的话新建,填写如下内容(变量值根据实际情况随便填写):
export KEY_COUNTRY="CN"
export KEY_PROVINCE="Guangdong Province"
export KEY_CITY="ShenZhen"
export KEY_ORG="Linuxops ORG"
export KEY_EMAIL="email@email.com"

然后执行以下命令,使vars文件的变量立即生效
# source ./vars # 使变量立即生效
2.3 生成 CA 根证书
1
2
# ./easyrsa init-pki    #初始化 pki 相关目录
# ./easyrsa build-ca nopass #生成 CA 根证书, 需要输入 Common Name,名字随便起,然后回车。
2.4 生成 OpenVPN 服务器证书和密钥

第一个参数 server 为证书名称,可以随便起,比如 ./easyrsa build-server-full openvpn nopass

第二个参数 nopass 表示生成服务端密钥时不设置密码

1
# ./easyrsa build-server-full server nopass
2.5 生成 Diffie-Hellman 算法需要的密钥文件
1
# ./easyrsa gen-dh   # 创建Diffie-Hellman,这可能得等一小会儿
2.6 生成 tls-auth key

这个 key 主要用于防止 DoS 和 TLS 攻击,这一步其实是可选的,但为了安全还是生成一下,该文件在后面配置 OpenVPN 的配置文件时会用到。

1
# openvpn --genkey --secret ta.key
2.7 将上面生成的相关证书文件整理到 /etc/openvpn/server/certs
1
2
3
4
5
6
# mkdir /etc/openvpn/server/certs && cd /etc/openvpn/server/certs/
# cp /etc/openvpn/easy-rsa/3/pki/dh.pem ./ # SSL 协商时 Diffie-Hellman 算法需要的 key
# cp /etc/openvpn/easy-rsa/3/pki/ca.crt ./ # CA 根证书
# cp /etc/openvpn/easy-rsa/3/pki/issued/server.crt ./ # OpenVPN 服务器证书
# cp /etc/openvpn/easy-rsa/3/pki/private/server.key ./ # OpenVPN 服务器证书 key
# cp /etc/openvpn/easy-rsa/3/ta.key ./ # 生成 tls-auth key 文件
2.8 创建 open VPN 日志目录
1
2
# mkdir -p /var/log/openvpn/
# chown openvpn:openvpn /var/log/openvpn

3. 配置 OpenVPN

可以从 /usr/share/doc/openvpn-<openvpn 版本号>/sample/sample-config-files/server.conf 复制一份 demo 到 /etc/openvpn/(openvpn 版本号查看:yum info openvpn。)然后改改,或者从头开始创建一个新的配置文件。我选择新建配置,执行以下命令新建server.conf文件

1
2
# cd /etc/openvpn  # 切换到openvpn配置文件目录下
# vim server.conf # 新建server.conf配置文件

server.conf 文件填入如下内容,很多配置项不需要特别了解,重要的配置这里已经添加注释了,其他相关配置项想了解的话可以单击这个链接 https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage

注:配置文件中;开头的表示该行配置被注释, # 号后面表示该行配置的解释

server.conf 文件内容如下:

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
####################################################################
# 针对多客户端的OpenVPN 2.4的服务器端配置文件示例
#
# 本文件用于多客户端<->单服务器端的OpenVPN服务器端配置
#
# OpenVPN也支持单机<->单机的配置(更多信息请查看网站上的示例页面)
#
# 该配置支持Windows或者Linux/BSD系统。此外,在Windows上,记得将路径加上双引号,
# 并且使用两个反斜杠,例如:"C:\\Program Files\\OpenVPN\\config\\foo.key"
#
# '#' or ';'开头的均为注释内容
###################################################################

# OpenVPN监听本机的哪些IP地址,该命令是可选的,如果不设置,则默认监听本机的所有IP地址
;local a.b.c.d
# 监听的端口号
port 1194
# 服务端用的协议tcp/udp,udp能快点,所以我选择udp
proto udp

# 默认使用路由模式,tap是桥接模式
# 指定OpenVPN创建的通信隧道类型
# "dev tun"将会创建一个路由IP隧道
# "dev tap"将会创建一个以太网隧道
# 如果你是以太网桥接模式,并且提前创建了一个名为"tap0"的与以太网接口进行桥接的虚拟接口,则你可以使用"dev tap0"
# 如果你想控制VPN的访问策略,你必须为TUN/TAP接口创建防火墙规则
# 在非Windows系统中,你可以给出明确的单位编号(unit number),例如"tun0"
# 在Windows中,你也可以使用"dev-node"
# 在多数系统中,除非你部分禁用或者完全禁用了TUN/TAP接口的防火墙,否则VPN将不起作用
;dev tap
dev tun

# 如果你想配置多个隧道,你需要用到网络连接面板中TAP-Win32适配器的名称例如"MyTap")
# 在XP SP2或更高版本的系统中,你可能需要有选择地禁用掉针对TAP适配器的防火墙
# 通常情况下,非Windows系统则不需要该指令。
;dev-node MyTap

# CA根证书路径
ca /etc/openvpn/server/certs/ca.crt
# OpenVPN服务端证书路径
cert /etc/openvpn/server/certs/server.crt
# OpenVPN服务端密钥路径
key /etc/openvpn/server/certs/server.key
# Diffie-Hellman算法密钥文件路径
dh /etc/openvpn/server/certs/dh.pem

# 出于SSL/TLS之外更多的安全考虑,创建一个"HMAC 防火墙"可以帮助抵御DoS攻击和UDP端口淹没攻击。
# 你可以使用以下命令来生成:
# openvpn --genkey --secret ta.key
# 服务器和每个客户端都需要拥有该密钥的一个拷贝。
# 第二个参数在服务器端应该为'。
# tls-auth key,参数0可以省略,如果不省略,那么客户端配置文件相应的参数tls-auth该配成 1。如果省略,那么客户端不需要 tls-auth 配置
tls-auth /etc/openvpn/server/certs/ta.key 0

# 选择一个密码加密算法。
# 该配置项也必须复制到每个客户端配置文件中。
;cipher BF-CBC # Blowfish (默认)
;cipher AES--CBC # AES
;cipher DES-EDE3-CBC # Triple-DES

# 该网段为OpenVPN虚拟网卡网段,不要和内网网段冲突即可。OpenVPN默认使用10.8.0.0/24网段为客户端分配IP地址
server 10.8.0.0 255.255.255.0
# 指定用于记录客户端和虚拟IP地址的关联关系的文件,当重启OpenVPN时,再次连接的客户端将分配到与上一次分配相同的虚拟IP地址
ifconfig-pool-persist ipp.txt

# 主DNS服务器配置,可以根据需要指定其他DNS
push "dhcp-option DNS 8.8.8.8"
# 备DNS服务器配置,可以根据需要指定其他DNS
push "dhcp-option DNS 8.8.4.4"

# 推送路由信息到客户端,告诉客户端连接172.18.0.0/16这个网段的流量通过openvpn转发,以允许客户端能够连接到服务端背后的其他私有子网;
# 其中172.18.0.0/16网段是你要连接的openvpn服务端的私网ip地址段,类似于局部代理;
# 使客户端机器在浏览器访问其他正常网页时由本地网卡出去,从而达到不影响本地网络的网速。
push "route 172.18.0.0 255.255.0.0"

# 客户端所有流量都通过open VPN虚拟网卡转发,类似于全局代理,这样客户端在浏览器访问其他正常网站时;
# 也是通过OpenVPN虚拟网卡出去访问,会严重影响客户端访问正常网页的网速
;push "redirect-gateway def1"

# 该指令仅针对以太网桥接模式。
# 首先,你必须使用操作系统的桥接能力将以太网网卡接口和TAP接口进行桥接。
# 然后,你需要手动设置桥接接口的IP地址、子网掩码;
# 在这里,我们假设为10.。
# 最后,我们必须指定子网的一个IP范围(例如从10.8.0.50开始,到10.8.0.100结束),以便于分配给连接的客户端。
# 如果你不是以太网桥接模式,直接注释掉这行指令即可。
;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100

# 该指令仅针对使用DHCP代理的以太网桥接模式,
# 此时客户端将请求服务器端的DHCP服务器,从而获得分配给它的IP地址和DNS服务器地址。
# 在此之前,你也需要先将以太网网卡接口和TAP接口进行桥接。
# 注意:该指令仅用于OpenVPN客户端,并且该客户端的TAP适配器需要绑定到一个DHCP客户端上。
;server-bridge

# 允许一个用户多个终端连接
# 如果多个客户端可能使用相同的证书/私钥文件或Common Name进行连接,那么你可以取消该指令的注释。
# 建议该指令仅用于测试目的。对于生产使用环境而言,每个客户端都应该拥有自己的证书和私钥。
# 如果你没有为每个客户端分别生成Common Name唯一的证书/私钥,你可以取消该行的注释(但不推荐这样做)。
;duplicate-cn

# keepalive指令将导致类似于ping命令的消息被来回发送,以便于服务器端和客户端知道对方何时被关闭。
# 每10秒钟ping一次,如果120秒内都没有收到对方的回复,则表示远程连接已经关闭。
keepalive 10 120

# 在VPN连接上启用压缩。
# 如果你在此处启用了该指令,那么也应该在每个客户端配置文件中启用它。
comp-lzo

# 允许并发连接的客户端的最大数量
;max-clients

# 去掉该指令的注释将允许不同的客户端之间相互"可见"(允许客户端之间互相访问)。
# 该选项允许连接openvpn的客户端直接通讯而不经过openvpn服务端网关。
# 默认情况下,客户端只能"看见"服务器。为了确保客户端只能看见服务器,你还可以在服务器端的TUN/TAP接口上设置适当的防火墙规则。
client-to-client

# 持久化选项可以尽量避免访问那些在重启之后由于用户权限降低而无法访问的某些资源。
persist-key
persist-tun

# OpenVPN进程启动用户,OpenVPN用户在安装完openvpn安装包后就自动生成了
# 在完成初始化工作之后,降低OpenVPN守护进程的权限是个不错的主意。
# 该指令仅限于非Windows系统中使用。
user openvpn
group openvpn

# 默认情况下,日志消息将写入syslog(在Windows系统中,如果以服务方式运行,日志消息将写入OpenVPN安装目录的log文件夹中)。
# 你可以使用log或者log-append来改变这种默认情况。
# "log"方式在每次启动时都会清空之前的日志文件。
# "log-append"这是在之前的日志内容后进行追加。
# 你可以使用两种方式之一(但不要同时使用)。
;log /var/log/openvpn/openvpn.log
log-append /var/log/openvpn/openvpn.log
# 输出一个简短的状态文件,用于显示当前的连接状态,该文件每分钟都会清空并重写一次。
status /var/log/openvpn/openvpn-status.log

# 为日志文件设置适当的冗余级别(~)。冗余级别越高,输出的信息越详细。
# 0 表示静默运行,只记录致命错误。
# 4 表示合理的常规用法。
# 5 可以帮助调试连接错误。
# 9 表示极度冗余,输出非常详细的日志信息。
verb 3

# 重复信息的沉默度。
# 相同类别的信息只有前20条会输出到日志文件中。
;mute

# 当服务端重新启动时,通知客户端可以自动重新连接。
# 当proto使用tcp时,需要注销该行配置,否则会导致服务端无法启动
explicit-exit-notify 1

# 为指定的客户端分配指定的IP地址,或者客户端背后也有一个私有子网想要访问VPN,
# 那么你可以针对该客户端的配置文件使用ccd子目录。
# (简而言之,就是允许客户端所在的局域网成员也能够访问VPN)
# 举个例子:假设有个Common Name为/255.255.255.248。
# 首先,你需要去掉下面两行指令的注释:
;client-config-dir ccd
;route 192.168.40.128 255.255.255.248
# 然后创建一个文件ccd/Thelonious,该文件的内容为:
# iroute 192.168.40.128 255.255.255.248

# 这样客户端所在的局域网就可以访问VPN了。
# 注意,这个指令只能在你是基于路由、而不是基于桥接的模式下才能生效。
# 比如,你使用了"dev tun"和"server"指令。
# 再举个例子:假设你想给Thelonious分配一个固定的IP地址10.。
# 首先,你需要去掉下面两行指令的注释:
;client-config-dir ccd
;route 10.9.0.0 255.255.255.252
# 然后在文件ccd/Thelonious中添加如下指令:
# ifconfig-push 10.9.0.1 10.9.0.2
#

# 如果你想要为不同群组的客户端启用不同的防火墙访问策略,你可以使用如下两种方法:
# 运行多个OpenVPN守护进程,每个进程对应一个群组,并为每个进程(群组)启用适当的防火墙规则。
# (进阶)创建一个脚本来动态地修改响应于来自不同客户的防火墙规则。
# 关于learn-address脚本的更多信息请参考官方手册页面。
;learn-address ./script

4.防火墙相关配置(使用 iptables 添加 snat 规则)

4.1 禁用 Centos7 默认的 firewalld,使用经典的 iptables 防火墙管理软件:
1
2
# systemctl stop firewalld    # 停用系统默认的firewalld防火墙
# systemctl mask firewalld # 注销firewalld防火墙服务
4.2 禁用 SELinux
1
2
# setenforce 0 	# 马上关闭,立即生效
# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config # 需要重启服务器生效
4.3 启用iptables
1
2
3
# systemctl enable iptables  # 开机自启动
# systemctl start iptables # 立即启动
# iptables -F # 清理防火墙默认filter表规则,使用-t选项指定表,默认filter表,还有nat,mangle表
4.4 添加防火墙规则,将 openvpn 的网络流量转发到公网:snat 规则
1
2
# iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE
# iptables-save > /etc/sysconfig/iptables # iptables 规则持久化保存
4.5 Linux 服务器启用内核地址转发
1
2
# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
# sysctl -p # 使配置立即生效,这一步一定要执行,否则配置未生效。

5.启动 open VPN

1
2
3
# systemctl start openvpn@server  # 启动
# systemctl enable openvpn@server # 开机自启动
# systemctl status openvpn@server # 查看服务状态

至此,OpenVPN服务端搭建完成。

OpenVPN客户端部署

OpenVPN 服务端搭建完了,但是我们该如何使用呢?下面以 Windows 平台下使用为例:

安装客户端软件

要连接到 open VPN 服务端首先得需要一个客户端软件,在 Windows 下推荐使用 OpenVPN GUI,下载地址: https://openvpn.net/community-downloads/ 。OpenVPN GUI 是一个开源、免费的 Windows 版 OpenVPN 客户端软件,下载安装好OpenVPN GUI 软件。

创建一个OpenVPN用户

创建一个OpenVPN用户的方法有两种,一种是客户端使用证书密钥的认证方式连接OpenVPN服务端,一种是客户端使用用户密码的认证方式连接OpenVPN服务端,这里以客户端使用证书密钥登录的认证方式为例,关于用户密码认证方式可以查看我的博客中的 OpenVPN使用账号密码认证方式登陆 这篇博文。

创建客户端证书以及相关配置文件

接下来在服务端创建一个 OpenVPN 用户:其实创建用户的过程就是生成客户端 SSL 证书的过程,然后将其他相关的证书文件、key、.ovpn文件(客户端配置文件)打包到一起供客户端使用。由于创建一个用户的过程比较繁琐,所以在此将整个过程写成了一个脚本 ovpn_user.sh,脚本内容比较简单,一看就懂:

首先创建一个客户端配置模板文件 sample.ovpn,该文件在创建OpenVPN用户的脚本中会用到,放到 /etc/openvpn/client/ 目录下,执行以下命令:

1
2
# cd /etc/openvpn/client/
# vim sample.ovpn

sample.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
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
################################################################
# 针对多个客户端的OpenVPN 2.0 的客户端配置文件示例
#
# 该配置文件可以被多个客户端使用,当然每个客户端都应该有自己的证书和密钥文件
#
# 在Windows上此配置文件的后缀应该是".ovpn",在Linux/BSD系统中则是".conf"
################################################################

# 指定这是一个客户端,将从服务器上获取某些配置文件指令
client

# 指定连接的服务器是采用TCP还是UDP协议。
# 这里需要使用与服务器端相同的设置。
;proto tcp
proto udp

# 指定OpenVPN创建的通信隧道类型。
# "dev tun"将会创建一个路由IP隧道,
# "dev tap"将会创建一个以太网隧道。
# 如果你是以太网桥接模式,并且提前创建了一个名为"tap0"的与以太网接口进行桥接的虚拟接口,则你可以使用"dev tap0"
# 如果你想控制VPN的访问策略,你必须为TUN/TAP接口创建防火墙规则。
# 在非Windows系统中,你可以给出明确的单位编号(unit number),例如"tun0"。
# 在Windows中,你也可以使用"dev-node"。
# 在多数系统中,除非你部分禁用或者完全禁用了TUN/TAP接口的防火墙,否则VPN将不起作用
;dev tap
dev tun

# 指定服务端的主机名或者IP以及端口
# 如果有多个VPN服务器,为了实现负载均衡,可以设置多个remote指令
remote [OpenVPN服务端公网 ip,根据实际情况填写] 1194

# 如果开启多个remote指令,启动该指令将随机连接其中的一台服务器
# 否则,客户端将按照指定的先后顺序依次尝试连接
;remote-random

# 启用该指令,与服务器连接中断后将自动重新连接,这在网络不稳定的情况下(例如:笔记本电脑无线网络)非常有用。
resolv-retry infinite

# 大多数客户端不需要绑定本机特定的端口号
nobind

# 在初始化完毕后,降低OpenVPN的权限(该指令仅限于非Windows系统中使用)
;user openvpn
;group openvpn

# SSL/TLS 参数配置。
# 更多描述信息请参考服务器端配置文件。
# 最好为每个客户端单独分配.crt/.key文件对。
# 单个CA证书可以供所有客户端使用。
ca ca.crt
cert admin.crt
key admin.key

# 指定采用服务器校验方式
remote-cert-tls server

# 如果服务器端使用了tls-auth密钥,那么每个客户端也都应该有该密钥。
tls-auth ta.key 1

# 指定密码的加密算法。
# 如果服务器端启用了cipher指令选项,那么你必须也在这里指定它
;cipher AES--CBC

# 持久化选项可以尽量避免访问在重启时由于用户权限降低而无法访问的某些资源
persist-tun
persist-key

# 如果你是通过HTTP代理方式来连接到实际的VPN服务器,请在此处指定代理服务器的主机名(或IP)和端口号。
# 如果你的代理服务器需要身份认证,请参考官方手册页面
;http-proxy-retry # 如果失败将重试
;http-proxy [proxy server] [proxy port #]

# 无线网络通常会产生大量的重复数据包。设置此标识将忽略掉重复数据包的警告信息
mute-replay-warnings

# 在VPN连接中启用压缩。
# 该指令的启用/禁用应该与服务器端保持一致。
comp-lzo

# 设置日志文件冗余级别(~)。
# 表示静默运行,只记录致命错误。
# 表示合理的常规用法。
# 和 可以帮助调试连接错误。
# 表示极度冗余,输出非常详细的日志信息
verb 3

# 忽略过多的重复信息。
# 相同类别的信息只有前20条会输出到日志文件中。
;mute

# 该参数能防止密码被缓存到内存中
auth-nocache

下面编写创建 OpenVPN 用户的脚本add_vpn_user.sh,执行以下命令:

1
2
# cd /etc/openvpn/client
# vim add_vpn_user.sh

add_vpn_user.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
#!/bin/bash
set -e

OVPN_USER_KEYS_DIR=/etc/openvpn/client/keys
EASY_RSA_VERSION=3
EASY_RSA_DIR=/etc/openvpn/easy-rsa/
PKI_DIR=$EASY_RSA_DIR/$EASY_RSA_VERSION/pki

for user in "$@"
do
if [ -d "$OVPN_USER_KEYS_DIR/$user" ]; then
rm -rf $OVPN_USER_KEYS_DIR/$user
rm -rf $PKI_DIR/reqs/$user.req
sed -i '/'"$user"'/d' $PKI_DIR/index.txt
fi
cd $EASY_RSA_DIR/$EASY_RSA_VERSION
# 生成客户端 ssl 证书文件
./easyrsa build-client-full $user nopass
# 整理下生成的文件
mkdir -p $OVPN_USER_KEYS_DIR/$user
cp $PKI_DIR/ca.crt $OVPN_USER_KEYS_DIR/$user/ # CA 根证书
cp $PKI_DIR/issued/$user.crt $OVPN_USER_KEYS_DIR/$user/ # 客户端证书
cp $PKI_DIR/private/$user.key $OVPN_USER_KEYS_DIR/$user/ # 客户端证书密钥
cp /etc/openvpn/client/sample.ovpn $OVPN_USER_KEYS_DIR/$user/$user.ovpn # 客户端配置文件
sed -i 's/admin/'"$user"'/g' $OVPN_USER_KEYS_DIR/$user/$user.ovpn
cp /etc/openvpn/server/certs/ta.key $OVPN_USER_KEYS_DIR/$user/ta.key # auth-tls 文件
cd $OVPN_USER_KEYS_DIR
zip -r $user.zip $user
done
exit 0

注:执行上面的脚本创建一个OpenVPN用户,脚本用法如下:

1
2
> # sh add_vpn_user.sh <username>
>

其中 username 可以随意命名

执行完创建用户的脚本后会在 /etc/openvpn/client/keys 目录下生成以命名的 zip 打包文件,将该压缩包下载到本地解压,然后将里面的客户端证书和key以及.ovpn 文件拖拽到 OpenVPN GUI 客户端软件安装路径下的config目录下即可使用。
zip压缩包里面的文件如下,示例:

1
2
3
4
5
6
.
├── ca.crt
├── username.crt
├── username.key
├── username.ovpn
└── ta.key

至此,OpenVPN客户端安装配置完成,测试连接OpenVPN服务端,见如下图所示,表示连接成功并可以服务端通信了。

删除一个 OpenVPN 用户

上面我们知道了如何添加一个用户,那么如果公司员工离职了或者其他原因,想删除对应用户 OpenVPN 的使用权,该如何操作呢?其实很简单,OpenVPN 的客户端和服务端的认证主要通过 SSL 证书进行双向认证,所以只要吊销对应用户的 SSL 证书,分别执行以下3个步骤即可。

  1. 吊销用户证书,假设要吊销的用户名为 username
1
2
3
# cd /etc/openvpn/easy-rsa/3/
# ./easyrsa revoke username
# ./easyrsa gen-crl
  1. 编辑 OpenVPN 服务端配置文件 server.conf 添加如下配置:
1
# crl-verify /etc/openvpn/easy-rsa/3/pki/crl.pem
  1. 重启 OpenVPN 服务端使其生效
1
# systemctl start openvpn@server

为了方便,也将上面步骤整理成了一个脚本,执行以下命令,创建一键删除OpenVPN用户的脚del_vpn_user.sh:

1
2
# cd /etc/openvpn/client
# vim add_vpn_user.sh

del_vpn_user.sh脚本内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
set -e
OVPN_USER_KEYS_DIR=/etc/openvpn/client/keys
EASY_RSA_VERSION=3
EASY_RSA_DIR=/etc/openvpn/easy-rsa/

for user in "$@"
do
cd $EASY_RSA_DIR/$EASY_RSA_VERSION
echo -e 'yes\n' | ./easyrsa revoke $user
./easyrsa gen-crl
# 吊销掉证书后清理客户端相关文件
if [ -d "$OVPN_USER_KEYS_DIR/$user" ]; then
rm -rf $OVPN_USER_KEYS_DIR/${user}*
fi
systemctl restart openvpn@server
done

exit 0

注:执行上面的脚本创建一个OpenVPN用户,脚本用法如下:

1
2
> # sh del_vpn_user.sh <username>
>

其中 username 是你要删除的OpenVPN用户名

安装过程中遇到的问题及解决方法

问题 1:

搭建好OpenVPN,配置好server.conf文件和iptables防火墙后,使用systemctl无法启动openvpn 服务端。

问题原因及解决方法:

可以查看/var/log/openvpn/openvpn.log日志文件,查看报错;或者执行 journalctl -u openvpn@server 看看log报什么错。 博主出现服务端无法启动的原因是服务端配置文件的注释内容格式(中文字符一行太长)有问题导致无法启动服务端,只要将注释分成多行即可。

问题 2:

open VPN 客户端可以正常连接到服务端,但是无法上网,ping 任何地址都不通,只有服务端公网 ip 可以 ping 通。

问题原因及解决方法:

主要原因是服务的地址转发功能没打开,其实我前面配置了 echo net.ipv4.ip_forward = 1 >> /etc/sysctl.conf,但是没有执行 sysctl -p 使其立即生效,所以才导致出现问题。因此一定要记得两条命令都要执行。

问题 3:

open VPN 可以正常使用,但是看客户端日志却有如下错误:

1
2
2019-06-15 02:39:03.957926 AEAD Decrypt error: bad packet ID (may be a replay): [ #6361 ] -- see the man page entry for --no-replay and --replay-window for more info or silence this warning with --mute-replay-warnings
2019-06-15 02:39:23.413750 AEAD Decrypt error: bad packet ID (may be a replay): [ #6508 ] -- see the man page entry for --no-replay and --replay-window for more info or silence this warning with --mute-replay-warnings

问题原因及解决方法:

其实这个问题一般在 open VPN 是 UDP 服务的情况下出现,主要原因是 UDP 数据包重复发送导致,在 Wi-Fi 网络下经常出现,这并不影响使用,但是我们可以选择禁止掉该错误:根据错误提示可知使用 –mute-replay-warnings 参数可以消除该警告,我们使用的 open VPN 是 GUI 的,所以修改客户端 .ovpn 配置文件,末尾添加:mute-replay-warnings 即可解决。

该问题在这里有讨论:
https://sourceforge.net/p/openvpn/mailman/message/10655695/

相关文档

关于 open VPN 客户端和服务端配置文件配置项说明:很全面,可以随时查看不懂的配置项

https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage

https://openvpn.net/ | OpenVPN 官网

https://www.bbsmax.com/A/D854pyPw5E/

https://www.fandenggui.com/post/centos7-install-openvpn.html | Centos7 安装 OpenVPN
https://www.howtoing.com/how-to-install-openvpn-on-centos-7 | Centos7 安装 OpenVPN

https://www.xiaohui.com/dev/server/20070904-revoke-openvpn-client.htm | 吊销客户端证书
https://scott.stevensononthe.net/2015/02/how-to-addremove-additional-users-to-openvpn/ | 吊销客户端证书
https://tunnelblick.net/cConnectedBut.html | open VPN 一些常见问题
https://tunnelblick.net/ipinfo | 本地公网 ip 查看