自建VPN服务

服务端配置

环境

1
2
3
4
服务器系统:centos7.6
外网IP:38.6.182.74
内网IP:10.0.40.175
开放端口:1194

准备工作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld

# 关闭selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config
setenforce 0

# 安装依赖
yum install -y vim wget lrzsz gcc-c++ openssl openssl-devel net-tools lzo lzo-devel pam pam-devel

# 下载安装包
mkdir /tmp/install
cd /tmp/install
wget https://swupdate.openvpn.org/community/releases/openvpn-2.5.6.tar.gz
wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.8/EasyRSA-3.0.8.tgz

安装OpenVpn和EasyRSA

安装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
# 进入安装包所在的目录
cd /tmp/install

# 在根目录中创建一个data目录
mkdir /data

# 解压OpenVpn软件包
tar -zxvf openvpn-2.5.6.tar.gz

# 进入解压后的目录
cd openvpn-2.5.6

# 安装OpenVpn到根目录/data/openvpn目录下
./configure --prefix=/data/openvpn/

# 编译
make && make install

# 添加openvpn的环境变量
echo -e "PATH=\$PATH:/data/openvpn/sbin" >/etc/profile.d/openvpn256.sh

# 加载环境变量
source /etc/profile

# 执行如下命令查看版本
openvpn --version
# 输出如下内容说明安装成功
# OpenVPN 2.5.6 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [MH/PKTINFO] [AEAD] built on May 8 2023
# library versions: OpenSSL 1.0.2k-fips 26 Jan 2017, LZO 2.06
# Originally developed by James Yonan
# Copyright (C) 2002-2022 OpenVPN Inc <sales@openvpn.net>
# Compile time defines: enable_async_push=no enable_comp_stub=no enable_crypto_ofb_cfb=yes enable_debug=yes enable_def_auth=yes enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown enable_fast_install=yes enable_fragment=yes enable_iproute2=no enable_libtool_lock=yes enable_lz4=yes enable_lzo=yes enable_management=yes enable_multihome=yes enable_pam_dlopen=no enable_pedantic=no enable_pf=yes enable_pkcs11=no enable_plugin_auth_pam=yes enable_plugin_down_root=yes enable_plugins=yes enable_port_share=yes enable_selinux=no enable_shared=yes enable_shared_with_static_runtimes=no enable_small=no enable_static=yes enable_strict=no enable_strict_options=no enable_systemd=no enable_werror=no enable_win32_dll=yes enable_x509_alt_username=no with_aix_soname=aix with_crypto_library=openssl with_gnu_ld=yes with_mem_check=no with_sysroot=no

安装EasyRSA证书签发软件

1
2
3
4
5
6
7
8
# 进入EasyRSA压缩文件存放的目录
cd /tmp/install

# 解压EasyRSA
tar -zxvf EasyRSA-3.0.8.tgz

# 将解压后的文件夹移动到根目录/data目录下
mv EasyRSA-3.0.8 /data/EasyRSA

准备CA签发机构环境

1
2
3
4
5
6
7
8
9
10
11
12
13
# 拷贝EasyRSA到OpenVpn目录中
cp -r /data/EasyRSA /data/openvpn/easy-rsa-server
cd /data/openvpn/easy-rsa-server

# 准备签发证书的默认变量文件
egrep -v "^$|^#" vars.example >vars

# 编辑vars文件,修改默认ca证书以及服务器证书有效时间
vim vars

# 在文件尾添加如下两行内容
set_var EASYRSA_CA_EXPIRE 36500 # ca证书修改有效期
set_var EASYRSA_CERT_EXPIRE 3650 # 服务器证书修改有效期

创建CA机构与服务器证书

创建CA机构

1
2
3
4
5
6
7
8
9
10
11
12
13
# 进入OpenVpn目录中的easy-rsa-server文件夹
cd /data/openvpn/easy-rsa-server

# 初始化,执行此命令会生成pki目录
./easyrsa init-pki

# 创建CA机构,nopass代表不需要密码的意思
./easyrsa build-ca nopass

# 根据指引输入CA机构名,这里我用了rsa-xxin
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:rsa-xxin

# 如果创建成功,在pki目录下会出现一个ca.crt文件,和一个private目录,目录中包含了一个ca.key文件

创建服务端证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 进入OpenVpn目录中的easy-rsa-server文件夹
cd /data/openvpn/easy-rsa-server

# 创建服务端证书,同时指定证书文件的文件名为openvpnserver
./easyrsa gen-req openvpnserver nopass

# 当提示如下时,按回车继续
Common Name (eg: your user, host, or server name) [openvpnserver]:

# 如果创建成功,将会提示如下
# Keypair and certificate request completed. Your files are:
# req: /data/openvpn/easy-rsa-server/pki/reqs/openvpnserver.req
# key: /data/openvpn/easy-rsa-server/pki/private/openvpnserver.key
# 并且在对应的目录下生成了openvpnserver.req请求文件和openvpnserver.key私钥文件

签发服务端证书

1
2
3
4
5
6
7
8
9
# 这里的第一个server代表服务器,第二个openvpnserver则代表刚刚创建的服务端证书的名称
./easyrsa sign server openvpnserver

# 当出现如下提示时,输入yes
Type the word 'yes' to continue, or any other input to abort.
Confirm request details:

# 出现如下提示时,说明得到服务端的证书文件
# Certificate created at: /data/openvpn/easy-rsa-server/pki/issued/openvpnserver.crt

创建交互密钥

1
2
3
4
5
6
7
./easyrsa gen-dh

# 出现如下提示时,说明得到交互密钥文件
# DH parameters of size 2048 created at /data/openvpn/easy-rsa-server/pki/dh.pem

# 启用安全增强配置
openvpn --genkey tls-auth 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
# 创建openvpn用户,使用该用户启动openVPN
groupadd openvpn
useradd -M -s /sbin/nologin -g openvpn openvpn

# 创建证书存放目录
mkdir /data/openvpn/certificate

# 创建日志存放目录
mkdir /data/openvpn/logs
chown openvpn. /data/openvpn/logs

# 将服务端证书秘钥和交互秘钥复制到certificate目录
cp /data/openvpn/easy-rsa-server/pki/ca.crt /data/openvpn/certificate/
cp /data/openvpn/easy-rsa-server/pki/issued/openvpnserver.crt /data/openvpn/certificate/
cp /data/openvpn/easy-rsa-server/pki/private/openvpnserver.key /data/openvpn/certificate/
cp /data/openvpn/easy-rsa-server/pki/dh.pem /data/openvpn/certificate/
cp /data/openvpn/easy-rsa-server/ta.key /data/openvpn/certificate/

# 添加配置文件,配置文件中的代码在下一个代码框中
cd /data/openvpn/
vim /data/openvpn/server.conf

# 内核转发规则
echo "net.ipv4.ip_forward=1" >>/etc/sysctl.conf
sysctl -p

# iptablesNAT规则
# 这里的ip就是server.conf 中的server 10.8.0.0 255.255.255.0 ;添加转发规则到开机启动项
echo 'iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE' >> /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local
/etc/rc.d/rc.local

  在配置文件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
# 监听端口
port 1194
# 监听协议
proto tcp
# 采用路由隧道模式
dev tun
# ca证书文件
ca /data/openvpn/certificate/ca.crt
# 服务端证书文件
cert /data/openvpn/certificate/openvpnserver.crt
# 服务端私钥文件
key /data/openvpn/certificate/openvpnserver.key
# 密钥交换协议文件
dh /data/openvpn/certificate/dh.pem
# 安全增强文件,0是服务端,1是客户端
tls-auth /data/openvpn/certificate/ta.key 0
# 分配客户端IP的网段,不能和服务器一个网段,不能冲突
server 10.8.0.0 255.255.255.0
# 运行通讯的内网路由,访问目标是哪里,IP就怎么配置,可以多条
push "route 192.168.0.0 255.255.255.0"
# 客户端之间互相通信
client-to-client
# 会话检测,每十秒测试一下,超过120秒没回应就认为对方down
keepalive 10 120
# 加密算法
cipher AES-256-CBC
# 压缩算法
compress lz4-v2
# 推送客户端使用lz4-v2算法
push "compress lz4-v2"
# 最大客户端数
max-clients 100
# 运行openvpn的用户和用户组
user openvpn
group openvpn
# 状态日志
status /data/openvpn/logs/openvpn-status.log
log-append /data/openvpn/logs/openvpn.log
# 日志级别
verb 3
mute 20
# 确保密钥文件在传输过程中不会被修改
persist-key
# 保持 TUN(传输用户数据)连接状态
persist-tun

  如果是访问外网的配置,在配置文件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
# 监听地址
local 0.0.0.0
# 监听端口
port 1194
# 监听协议
proto tcp
# 采用路由隧道模式
dev tun
# ca证书文件
ca /data/openvpn/certificate/ca.crt
# 服务端证书文件
cert /data/openvpn/certificate/openvpnserver.crt
# 服务端私钥文件
key /data/openvpn/certificate/openvpnserver.key
# 密钥交换协议文件
dh /data/openvpn/certificate/dh.pem
# 安全增强文件,0是服务端,1是客户端
tls-auth /data/openvpn/certificate/ta.key 0
# 分配客户端IP的网段,不能和服务器一个网段,不能冲突
server 10.8.0.0 255.255.255.0
# 给网关
push "redirect-gateway def1 bypass-dhcp"
# dhcp分配dns
push "dhcp-option DNS 8.8.8.8"
# 客户端之间互相通信
client-to-client
# 会话检测,每十秒测试一下,超过120秒没回应就认为对方down
keepalive 10 120
# 加密算法
cipher AES-256-CBC
# 压缩算法
compress lz4-v2
# 推送客户端使用lz4-v2算法
push "compress lz4-v2"
# 最大客户端数
max-clients 100
# 运行openvpn的用户和用户组
user openvpn
group openvpn
# 状态日志
status /data/openvpn/logs/openvpn-status.log
log-append /data/openvpn/logs/openvpn.log
# 日志级别
verb 3
mute 20
# 确保密钥文件在传输过程中不会被修改
persist-key
# 保持 TUN(传输用户数据)连接状态
persist-tun

启动OpenVPN

1
2
3
4
5
6
7
8
9
10
11
# 创建启动文件,文件中的代码在下一个代码框中
vim /etc/systemd/system/openvpn.service

# 加载系统服务
systemctl daemon-reload
# 开机启动
systemctl enable openvpn.service
# 启动服务
systemctl start openvpn.service
# 查看服务运行状态
systemctl status openvpn.service

  在配置文件openvpn.service中写入

1
2
3
4
5
6
7
8
9
10
[Unit]
Description=OpenVPN Server
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target

[Service]
ExecStart=/data/openvpn/sbin/openvpn --config /data/openvpn/server.conf

客户端文件配置

首次添加客户端证书

准备客户端证书

创建客户端证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 拷贝EasyRSA到OpenVpn目录中
cp -r /data/EasyRSA /data/openvpn/easy-rsa-client
cd /data/openvpn/easy-rsa-client

# 初始化,执行此命令会生成pki目录
./easyrsa init-pki

# 创建客户端申请证书,同时指定证书文件的文件名为xxin
./easyrsa gen-req xxin nopass

# 当提示如下时,按回车继续
# Common Name (eg: your user, host, or server name) [xxin]:

# 如果创建成功,将会提示如下
# Keypair and certificate request completed. Your files are:
# req: /data/openvpn/easy-rsa-client/pki/reqs/xxin.req
# key: /data/openvpn/easy-rsa-client/pki/private/xxin.key

# 此时已经在reqs目录和private目录下生成了xxin.req请求文件和xxin.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
cd /data/openvpn/easy-rsa-server

# 将客户端证书复制到CA工作目录,并指定证书名称为xxin,证书名称可以任意定义,复制到CA工作目录的客户端证书以指定的证书名称命名
./easyrsa import-req /data/openvpn/easy-rsa-client/pki/reqs/xxin.req xxin
# 当提示如下时,说明导入成功,客户端证书成功被复制到CA工作目录
# Note: using Easy-RSA configuration from: /data/openvpn/easy-rsa-server/vars
# Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017
#
# The request has been successfully imported with a short name of: xxin
# You may now use this name to perform signing operations on this request.
#
# 若提示如下,说明导入失败,CA工作目录下已经存在该证书文件
# Note: using Easy-RSA configuration from: /data/openvpn/easy-rsa-server/vars
# Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017
#
# Easy-RSA error:
#
# The input file does not appear to be a certificate request. Aborting import.
# File Path: /data/openvpn/easy-rsa-client/pki/reqs/xxin.req

# 设置客户端证书有效期,这里设置的是90天
sed -i "s/set_var EASYRSA_CERT_EXPIRE.*$/set_var EASYRSA_CERT_EXPIRE\t90/g" ./vars

# 签发名称为xxin的证书
./easyrsa sign client xxin

# 当提示如下时,输入yes
# Type the word 'yes' to continue, or any other input to abort.
# Confirm request details:

# 证书签发成功
# Certificate created at: /data/openvpn/easy-rsa-server/pki/issued/xxin.crt

准备客户端配置文件

1
2
3
4
5
6
7
8
9
10
11
# 创建证书存放目录
mkdir /data/openvpn/client/

# 创建xxin目录,存放xxin的三张证书
mkdir /data/openvpn/client/xxin

# 复制证书
find /data/openvpn/ \( -name "xxin.key" -o -name "xxin.crt" -o -name "ca.crt" -o -name "ta.key" \) -exec cp {} /data/openvpn/client/xxin \;

# 添加一个客户端配置文件,文件的代码在下一个代码框中
vim /data/openvpn/client/xxin/client.ovpn

  在配置文件client.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
# 指定客户端
client
# 使用tun隧道传输协议
dev tun
# 使用tcp协议传输数据
proto tcp
# openvpn服务器IP地址和端口号
remote 38.6.182.74 1194
# 断线自动重新连接
resolv-retry infinite
# 不绑定本地特定的端口号
nobind
# 通过keepalive检测超时后,重新启动VPN,不重新读取keys,保留第一次使用的keys
persist-key
# 检测超时后,重新启动VPN,一直保持tun是linkup的。否则网络会先linkdown然后再linkup
persist-tun
# 指定CA证书的文件路径
ca ca.crt
# 指定当前客户端的证书文件路径
cert xxin.crt
# 指定当前客户端的私钥文件路径
key xxin.key
# 该验证服务器证书的有效性
remote-cert-tls server
# 启用 TLS-Auth身份验证,并指定了预共享密钥文件的路径
tls-auth ta.key 1
# 使用 AES-256-CBC 加密算法来加密传输的数据
cipher AES-256-CBC
# 指定日志文件的记录详细级别,可选0-9,等级越高日志内容越详细
verb 3
# 使用 LZ4-v2 算法对传输的数据进行压缩
compress lz4-v2

继续添加客户端

  因为首次添加客户端时已经复制过RSA客户端目录了,所以这里一般不需要再次复制

1
2
3
4
5
6
# 拷贝EasyRSA到OpenVpn目录中
# 如果OpenVpn目录中已经拥有RSA客户端目录,则不需要执行拷贝
cp -r /data/EasyRSA /data/openvpn/easy-rsa-client

# 进入RSA客户端目录
cd /data/openvpn/easy-rsa-client

  如果不是首次添加客户端,pki目录应该已经存在了。生成pki目录/data/openvpn/easy-rsa-client/pki

1
2
3
# 初始化,执行此命令会生成pki目录
# 如果RSA客户端目录下已经拥有pki目录,则不需要执行该操作
./easyrsa init-pki

  创建客户端申请证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 创建客户端申请证书,同时指定证书文件的文件名为xxin-test
./easyrsa gen-req xxin-test nopass

# 将会提示如下内容,回车确定即可
# Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017
# Generating a 2048 bit RSA private key
# .............+++
# ...+++
# writing new private key to '/data/openvpn/easy-rsa-client/pki/easy-rsa-27870.RaCSZg/tmp.0a2NSo'
# -----
# 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) [xxin-test]:

# 确定后提示如下内容说明申请成功
# Keypair and certificate request completed. Your files are:
# req: /data/openvpn/easy-rsa-client/pki/reqs/xxin-test.req
# key: /data/openvpn/easy-rsa-client/pki/private/xxin-test.key

  签发证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 进入到RSA服务端目录
cd /data/openvpn/easy-rsa-server

# 导入一个证书签名请求文件
./easyrsa import-req /data/openvpn/easy-rsa-client/pki/reqs/xxin-test.req xxin-test

# 设置客户端证书有效期,这里设置的是90天
sed -i "s/set_var EASYRSA_CERT_EXPIRE.*$/set_var EASYRSA_CERT_EXPIRE\t90/g" ./vars

# 签发证书
./easyrsa sign client xxin-test

# 当提示如下时,输入yes
# Type the word 'yes' to continue, or any other input to abort.
# Confirm request details:

  复制xxin-test的证书到xxin-test存放证书的目录

1
2
3
4
5
6
7
8
# 如果没有证书存放目录,则创建
mkdir /data/openvpn/client/

# 在证书存放目录中创建xxin-test目录,用于存放xxin-test的证书
mkdir /data/openvpn/client/xxin-test

# 复制xxin-test所需的证书到证书存放目录下xxin-test的目录中
find /data/openvpn/ \( -name "xxin-test.key" -o -name "xxin-test.crt" -o -name "ca.crt" -o -name "ta.key" \) -exec cp {} /data/openvpn/client/xxin-test \;

  创建客户端配置文件

1
2
# 在xxin-testd阿证书存放目录中,添加一个客户端配置文件,填入客户端配置
vim /data/openvpn/client/xxin-test/client.ovpn

  客户端配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
client
dev tun
proto tcp
remote 38.6.182.74 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert xxin-test.crt
key xxin-test.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-CBC
verb 3
compress lz4-v2

连接测试

Windos端

导入配置

  下载客户端所需证书和配置文件

1
2
3
cd /data/openvpn/client/
tar -zcvf xxin.tar.gz xxin
sz xxin.tar.gz

安装客户端

1
https://swupdate.openvpn.org/community/releases/openvpn-install-2.4.5-I601.exe

  将xxin.tar.gz解压,并将其中的文件放置在openvpn客户端目录的config目录中

  以管理员身份运行→右击客户端任务图标→connect连接

  访问试一下

Linux端

安装客户端

1
sudo yum install openvpn

导入配置

  将配置文件和证书放置在目录/etc/openvpn/client下,client.ovpn中证书路径的配置与以往有些不同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
client
dev tun
proto tcp
remote 38.6.182.74 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca /etc/openvpn/client/ca.crt
cert /etc/openvpn/client/xxin-linux.crt
key /etc/openvpn/client/xxin-linux.key
remote-cert-tls server
tls-auth /etc/openvpn/client/ta.key 1
cipher AES-256-CBC
verb 3
compress lz4-v2

连接到VPN

  运行如下命令连接到openvpn

1
sudo openvpn --config /etc/openvpn/client/client.ovpn

停止连接

  ”Ctrl+C”或者查找openvpn进程pid

1
2
3
ps aux | grep openvpn

# user 12345 0.0 0.0 12345 6789 ? S 12:34 0:00 openvpn --config /etc/openvpn/client/client.ovpn

  然后杀死进程

1
sudo kill 12345

手机端

下载软件

这个版本是一个相当稳定好用的版本
OpenVPN Connect_3.1.0:https://lxx6.lanzoum.com/ixPa80ywom4h

导入配置

  下载配置文件,例如通过浏览器下载压缩的配置文件之后,在文件管理Download文件夹中将其解压

  下图解压后得到song-phone文件夹,包含如下配置文件

  打开OpenVPN Connect,点击加号导入配置文件

  进入Downloadsong-phone文件夹,选择clien.ovpn文件,点击底部IMPORT

  点击右上角ADD

  导入成功,打开开关即可连接。首次连接如遇卡顿,关闭软件重新打开

搭建参考

  1. Centos7安装openvp-超详细
  2. 完整CentOS搭建企业OpenVPN服务详细教程