在工作或者开发过程中,有时候需要使用VPN来连接网络,所以将讲解在Ubuntu 18.04系统下配置openvpn的方法,要说明的是VPN服务器同时也当做CA,并不是CA和VPN服务器做两个不同的服务器。以下是实现的具体方法。
安装openvpn
第一步当然是安装openvpn了,它在Ubuntu软件仓库中,可以直接安装:
sudo apt install openvpn
此外还需要安装一个辅助工具easyrsa,它包含了一系列脚本和配置,可以帮助我们快速生成openvpn所需的证书和公私钥对。因为它是一组脚本,所以我们直接克隆一下它的Github仓库即可:
git clone https://github.com/OpenVPN/easy-rsa.git
这样一来,必要的软件安装就完成了。
生成CA
首先先进入easyrsa的脚本目录:
cd easy-rsa/easyrsa3
然后将其中vars.example的文件复制一份:
cp vars.example vars
接着用文本编辑器打开vars文件:
nano vars
这个文件很长,包含了很多注释和说明,这些我们都不用管,直接翻到图中所示部分,然后按照自己的需求进行修改,但是不能留空,修改完成后保存文件。以下是修改配置文件图示:

然后用下面的命令生成公钥体系,此外easyrsa还有一些其他命令和参数,有些参数下面还会用到:
./easyrsa init-pki
会生成如下的信息,这样就成功了:
Note: using Easy-RSA configuration from: ./vars
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /home/yitian/easy-rsa/easyrsa3/pki
之后就是最后一步创建CA证书了,如果不想每次都输入一个密码,可以用nopass参数来取消密码。在输出中还会提示你输入CA的公共名称,直接默认即可,当然你想改也随意。
./easyrsa build-ca nopass
会生成如下的信息,这样一来就完成了:
Note: using Easy-RSA configuration from: ./vars
Generating RSA private key, 2048 bit long modulus
...............................+++
...............................+++
e is 65537 (0x010001)
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) [Easy-RSA CA]:
CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/home/yitian/easy-rsa/easyrsa3/pki/ca.crt
这样一来,在pki和pki/private文件夹中会生成ca.crt和ca.key文件,正是SSL证书所用的公私钥对。
生成服务器证书和加密文件
生成私钥
首先输入下面的命令,这里的server是服务器的名称,可以修改,但是由于接下来好几处命令以及生成的文件都受这个名称影响,所以还是用默认的server省事一点:
./easyrsa gen-req server nopass
输出如下:
Note: using Easy-RSA configuration from: ./vars
Generating a 2048 bit RSA private key
...............................+++
...............................+++
writing new private key to '/home/yitian/easy-rsa/easyrsa3/pki/private/server.key.IuKiwcpofq'
-----
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) [server]:
Keypair and certificate request completed. Your files are:
req: /home/yitian/easy-rsa/easyrsa3/pki/reqs/server.req
key: /home/yitian/easy-rsa/easyrsa3/pki/private/server.key
这样就生成了服务器私钥server.key和证书请求文件server.req。
然后将服务器私钥复制到openvpn配置文件目录下:
sudo cp pki/private/server.key /etc/openvpn
生成公钥
由于我只有一台服务器,同时充当CA服务器和VPN服务器,所以需要自己给自己签发,会产生同名文件,所以首先先把服务请求文件server.req重命名一下:
mv pki/reqs/server.req pki/reqs/server2.req
然后导入请求,这里的server是前面指定的服务器名称:
./easyrsa import-req pki/reqs/server2.req server
成功之后,用下面的命令签发请求,注意这里的第一个server是请求类型,可以是client或者server,第二个server是前面指定的服务器名称:
./easyrsa sign-req server server
在这一步出了一点小问题,输出提示index.txt.attr文件不存在,导致出现了部分失误,所以生成的文件被保存到了pki/issued目录下,不过后来全弄完我发现这个小错误不影响VPN连接,但是如果你运行的时候没有错误,记得改一下这里的文件路径。
这样会生成server.crt文件,将它和ca.crt一起复制到openvpn中:
sudo cp pki/ca.crt pki/issued/server.crt /etc/openvpn/
生成加密文件
然后生成Diffie-Hellman密钥文件,这会让VPN更加安全,不过生成过程可能需要几分钟时间:
./easyrsa gen-dh
等待生成完成之后,生成Diffie-Hellman签名:
openvpn --genkey --secret ta.key
然后将生成的几个文件也复制给openvpn:
sudo cp ta.key pki/dh.pem /etc/openvpn/
这样一来,服务器端的所有文件就全部生成完毕,下面开始生成客户端所需文件。
生成客户端证书和密钥对
首先准备一个目录存放客户端文件:
mkdir -p ~/client-configs/keys
然后修改权限确保安全:
sudo chmod -R 700 ~/client-configs
然后生成客户端请求文件,考虑到可能会有几个客户端,所以这里叫client1,当然名称也可以修改:
./easyrsa gen-req client1 nopass
将其复制到存放目录中:
cp pki/private/client1.key ~/client-configs/keys/
和前面一样,首先修改一下客户端请求文件的名称:
mv pki/reqs/client1.req pki/reqs/client.req
然后导入请求文件:
./easyrsa import-req pki/reqs/client.req client1
再签发请求:
./easyrsa sign-req client client1
这样会生成client1.crt文件,最后将几个文件复制到存放目录中(这里注意一下文件路径,我前面出现错误,所以文件生成在issued文件夹中,如果你没错误记得改一下路径):
cp pki/issued/client1.crt ta.key pki/ca.crt ~/client-configs/keys/
这样,所有证书文件就准备就绪了。
配置openvpn服务
必须配置
首先先复制一个样例配置文件:
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
sudo gzip -d /etc/openvpn/server.conf.gz
然后打开配置文件:
sudo nano /etc/openvpn/server.conf
先找到tls-auth一行,它应该是下面的样子,如果不是,取消注释并修改成下面的样子,并添加一句key-direction 0配置。
tls-auth ta.key 0 # This file is secret
key-direction 0
然后是cipher一行,它应该是下面的样子,如果不是,取消注释并修改成下面的样子,并添加一句auth SHA256。
cipher AES-256-CBC
auth SHA256
然后是dh一行,默认应该是dh2048.pem,修改成下面的样子:
dh dh.pem
找到用户权限一行,取消注释,在linux系统上用更低的权限运行会更加安全:
user nobody
group nogroup
可选配置
以下是可选配置,但是配置之后会更方便使用,推荐配置。
首先是让所有流量都通过VPN,找到并取消以下几行的注释:
push “redirect-gateway def1 bypass-dhcp”
push “dhcp-option DNS 208.67.222.222”
push “dhcp-option DNS 208.67.220.220”
然后修改默认端口号和协议:
port 6666
proto udp
如果将协议改为TCP,还要将explicit-exit-notify修改为0,不然会出错:
explicit-exit-notify 0
如果前面一些文件你没有使用默认名称,那么在这个配置文件中别忘了也进行一些修改:
cert server.crt
key server.key
调整服务器网络设置
首先需要允许IP转发,用下面的命令打开配置文件:
sudo nano /etc/sysctl.conf
找到并取消下面一行的注释,然后保存文件。
net.ipv4.ip_forward=1
用下面的命令可以检查一下当前配置:
sudo sysctl -p
如果你服务器还有防火墙,那么还需要配置一下防火墙允许VPN通过,这里就不介绍了(防火墙各有各的,而且我一个也不会)。
启动openvpn服务
用下面的命令启动openvpn,后面的@server代表使用的是名为server.conf的配置文件,如果没什么输出,说明一切正常。
sudo systemctl start openvpn@server
否则用下面两条命令查找并尝试改正错误:
systemctl status openvpn@server.service
journalctl -xe
如果openvpn正常启动,别忘了让它开机启动:
sudo systemctl enable openvpn@server
创建客户端配置文件
这一部分需要上面创建的客户端文件。首先创建存放生成文件的目录:
mkdir -p ~/client-configs/files
chmod 700 ~/client-configs/files
然后复制一个示例配置文件:
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf
然后编辑该文件:
nano ~/client-configs/base.conf
将下面一些配置进行修改,我就不一一说明了,基本上和服务器配置要对应:
# 服务器IP和端口
remote server_IP_address 6666
# 协议
proto udp
# 权限
user nobody
group nogroup
# 证书文件
ca ca.crt
cert client1.crt
key client1.key
cipher AES-256-CBC
# 这行没有要添加
auth SHA256
# 不用看了,这行没有,要加上,服务器上是0,客户端是1
key-direction 1
# 这几行建议添加,如果是linux客户端而且有/etc/openvpn/update-resolv-conf文件就取消注释
# 如果不是就保持注释状态
# script-security 2
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
下面来生成客户端配置文件,首先新建一个文件:
nano ~/client-configs/make_config.sh
然后将下面的内容复制进去:
#!/bin/bash
# First argument: Client identifier
KEY_DIR=~/client-configs/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf
cat ${BASE_CONFIG} \
<(echo -e ‘<ca>’) \
${KEY_DIR}/ca.crt \
<(echo -e ‘</ca>\n<cert>’) \
${KEY_DIR}/${1}.crt \
<(echo -e ‘</cert>\n<key>’) \
${KEY_DIR}/${1}.key \
<(echo -e ‘</key>\n<tls-auth>’) \
${KEY_DIR}/ta.key \
<(echo -e ‘</tls-auth>’) \
> ${OUTPUT_DIR}/${1}.ovpn
顺便修改一下权限:
chmod 700 ~/client-configs/make_config.sh
然后运行一下文件,这里的client1要和前面的名称对应:
cd ~/client-configs
./make_config.sh client1
如果所有配置都按照前面的配置进行的话,会在~/client-configs/file文件夹中生成一个.ovpn文件,然后将它复制到所需地方即可。
客户端配置
这里用windows系统举例,首先下载并安装openvpn软件。打开软件之后在系统托盘右键点击import,然后选择生成的.ovpn,导入之后点击连接,然后看看是否连接成功。以下为连接成功图示:

7、调整服务器网络配置
首先设置允许ip转发,设置并使其生效
root@AX:~/EasyRSA-3.0.5# vim /etc/sysctl.conf
…
# Uncomment the next line to enable packet forwarding for IPv4
# 取消注释
net.ipv4.ip_forward=1
#保存退出
root@AX:~/EasyRSA-3.0.5# sysctl -p
net.ipv4.ip_forward = 1
修改UFW防火墙配置,这之前要确认ubuntu启用了ufw,并做了初始设定(允许SSH等)
#确认网络接口名称,这里是ens3
root@AX:~/EasyRSA-3.0.5# ip route | grep def
default via 46.102.170.81 dev ens3 onlink
修改配置文件,在文件前面添加默认策略设置,以伪装vpn流量
root@AX:~/EasyRSA-3.0.5# vim /etc/ufw/before.rules
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0(changeto the interface you discovered!)
-A POSTROUTING -s 10.8.0.0/8 -o ens3 -j MASQUERADE
COMMIT
# END OPENVPN RULES
…
保存退出。
修改防火墙规则,允许默认转发数据包,把”DROP”改成”ACCEPT”
root@AX:~/EasyRSA-3.0.5# vim /etc/default/ufw
DEFAULT_FORWARD_POLICY=”ACCEPT”
允许vpn流量通过防火墙
root@AX:~/EasyRSA-3.0.5# ufw allow 1194/udp
root@AX:~/EasyRSA-3.0.5# ufw allow openssh
我的防火墙看起来是这个样子的
root@AX:~/EasyRSA-3.0.5# ufw status
