Write by lyc at 2022-4-22
openvpn.net
OpenVPN 中文文档
2. 配置文件说明
OpenVPN安装
Centos7 下搭建 OpenVPN 2.4.8

OpenVPN 客户端服务器模式架构图例

一、OpenVPN 服务器端部署

1.Linux 服务器环境准备

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
# 禁用 firewalld 防火墙
systemctl disable firewalld
systemctl stop firewalld

# 启用 iptables 防火墙
yum -y install iptables iptables-services
## 清空默认的防火墙规则
iptables -F && iptables -X && iptables -Z
iptables -t nat -F && iptables -t nat -X && iptables -t nat -Z
iptables-save > /etc/sysconfig/iptables
## 启动iptables
systemctl enable iptables
systemctl start iptables

# 禁用 SElinux
sed -i "/^SELINUX/s/enforcing/disabled/" /etc/selinux/config
setenforce 0

# 开启内核路由转发
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

# 操作系统及软件版本更新到最新
yum install -y epel-release
yum update -y

查看操作系统内核及版本号

1
2
3
4
5
$ cat /etc/redhat-release 
CentOS Linux release 7.9.2009 (Core)

$ uname -a
Linux 10-19-108-247 4.19.188-10.el7.ucloud.x86_64 #1 SMP Wed Apr 28 09:54:38 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

2.创建PKI证书

创建过程参考文档 《OpenVPN easy-rsa管理证书》

3.OpenVpn 服务器端配置

安装 openvpn server

1
2
3
4
5
yum install -y openvpn

# 查看版本号
$ rpm -qa|grep openvpn
openvpn-2.4.12-1.el7.x86_64

主配置文件

OpenVPN的配置模板(一)之服务器模式

创建日志目录

1
2
# 创建目录
mkdir -p /etc/openvpn/server/ccd # 自定义客户端配置的 include 目录

编排主配置文件

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
$ vim /etc/openvpn/server/server.conf
port 1194 # 默认端口号 1194
proto udp # 通讯协议 TCP 或者 UDP(推荐)。
dev tun # 使用 tun 或者 tap 设备

# 服务器证书:
ca /etc/openvpn/server/certs/ca.crt # 服务器 CA 证书
cert /etc/openvpn/server/certs/server.crt # 服务器证书
key /etc/openvpn/server/certs/server.key # 服务器证书密钥
dh /etc/openvpn/server/certs/dh.pem # diffie hellman密钥
tls-auth /etc/openvpn/server/certs/ta.key 0 # 服务器 TA 证书

server 10.201.0.0 255.255.255.0 # 启用服务器模式,设置加密隧道设置子网网段,默认是10.8.0.0/24
topology subnet

#client-config-dir /etc/openvpn/server/ccd # 客户端配置文件,可以配置客户端的IP
#ifconfig-pool-persist ipp.txt

# 推送(下发)路由、DNS 给客户端:
push "route 10.19.0.0 255.255.0.0"
# push "dhcp-option DNS 114.114.114.114"
# push "dhcp-option DNS 223.5.5.5"
# push "redirect-gateway def1 bypass-dhcp" # 开启重定向客户端默认网关。打开后客户端的所有所有流量将通过 VPN 隧道转发出去。该选项一般保持禁用。

compress lzo # 启用允许数据压缩。如果启用那么客户端的配置文件也需要有这项 comp-lzo
duplicate-cn # 启用允许多客户端接入。openvpn 点对点模式下不要启用该配置。该配置默认没有启用。
keepalive 10 60 # 10秒钟ping一次对端以确定对方是否在线,60秒未响应则断开连接,适合客户端在NAT后使用
comp-lzo # 使用 lzo 压缩

# 此选项使VPN在重连时不重新读取 key 且不会将 tun 设备关闭
persist-key # 通过 keepalive 检测超时后,重新启动 VPN,不重新读取 keys,保留第一次使用的keys
persist-tun # 通过 keepalive 检测超时后,重新启动 VPN,一直保持 tun 或者 tap 设备是 linkup 的。否则网络连接,会先 linkdown 然后再 linkup
user openvpn # 通过 yum 安装的,可将其配置为以 openvpn 用户和组运行,增加安全性
group openvpn

# 日志
log /var/log/server.log
log-append /var/log/server.log
status /var/log/status.log
#management localhost 7505 stdin
verb 3 # 日志级别
explicit-exit-notify 1
# crl-verify /etc/openvpn/easy-rsa/3/pki/crl.pem # 引用吊销证书列表

openvpn 启动

systemd 脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
$ vim /etc/systemd/system/openvpn-server.service
[Unit]
Description=openvpn
After=network.target

[Service]
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/server/server.conf
Restart=on-failure
Type=simple
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

启动

1
2
3
4
chown -R openvpn.openvpn /etc/openvpn
systemctl daemon-reload
systemctl enable openvpn-server.service
systemctl start openvpn-server.service

4.tun0 隧道的回包问题

1.9. 服务器或客户端子网中的其他计算机互相访问

从客户端表现出来的问题是:openvpn 客户端能够正常拨入 openvpn 服务端,能够建立加密的通信隧道 tun0,能够 ping 通服务端的 eth0 的内网 ip,也能够 ping 通隧道的 ip 10.201.0.0,却 ping 不通 openvpn server 所在局域网的其他服务器。

究其原因原因就是:openvpn server 所在局域网的其他服务器上并没有返回 tun0 隧道的回包路由,它们能够收到来自客户端的 ping 包,却不知道如何回包(没有路由表)。有两种方式来解决回包问题:

方式1:为需要连通 tun0 隧道的个别主机添加回包路由

该方式的优缺点:

  • 优点:可以指定个别几台服务器能够让 tun0 隧道通信,客户端访问最小化权限。
  • 缺点:配置繁琐,要逐一登录到目标服务器上去加回包路由。但是云实例 UDB, URedis 不像云主机,是无法添加路由的,所以也无法访问运实例。

注意回包路由是 openvpn server 所在局域网的其他服务器上配置的,添加的网络号是 tun0 隧道网段,下一跳指向 openvpn server eth0 的 IP 地址。

1
2
3
4
5
6
7
8
9
10
11
# 10.19.108.247 是我 openvpn eth0 网卡的内网 ip地址
$ route add -net 10.201.0.0/24 gw 10.19.108.247 dev eth0

# 查看
$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.19.0.1 0.0.0.0 UG 0 0 0 eth0
10.19.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
10.201.0.0 10.19.108.247 255.255.255.0 UG 0 0 0 eth0 # 回包路由
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0

方式2:iptables SNAT(推荐)

1.9.1. 防火墙规则

在 openvpn server 服务器上的 iptables nat 表上添加转发规则,让 tun0 隧道过来的数据包伪装成本机的内网地址发给其他局域网服务器(SNAT)。

1
2
3
4
5
6
7
# filter表如果没有其他拒绝规则,可以不添加以下两条 ACCEPT(可选配置)
## 允许进tun接口目标为“10.201.0.0/24”的访问
iptables -A FORWARD -o tun+ -d 10.201.0.0/24 -j ACCEPT # “+”也可改为实际的“tun[n]”,如“tun0”、“tun1”...
## 允许源为“10.201.0.0/24”出tun接口的访问
iptables -A FORWARD -i tun+ -s 10.201.0.0/24 -j ACCEPT
## 如果需要设置指定可以访问的服务器范围,删除上面一行,如下设置
iptables -A FORWARD -i tun+ -s 10.201.0.0/24 -d 10.66.0.33 -j ACCEPT # OpenVPN客户端不能访问到除10.66.0.33外其他的服务器(如果存在)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
*nat
# 在 nat 表上添加 MASQUERADE 表示伪装
# 添加下面一行,OpenVPN服务器可访问的地址,客户端也可以访问
iptables -t nat -A POSTROUTING -s 10.201.0.0/24 -j MASQUERADE
# 或如下设置指定网卡(若添指定了网卡,那么OpenVPN服务器自身通过该网卡不能访问的地址,客户端也不能访问)
iptables -t nat -A POSTROUTING -o eth0 -s 10.201.0.0/24 -j MASQUERADE

*filter
iptables -t filter -A FORWARD -o tun+ -d 10.201.0.0/24 -j ACCEPT
iptables -t filter -A FORWARD -i tun+ -s 10.201.0.0/24 -j ACCEPT


# 或指定从ethx出(可选配置)
iptables -t nat -A POSTROUTING -o eth0 -s 10.201.0.101/32 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth1 -s 10.201.0.105/32 -j MASQUERADE

# 保存iptables配置
iptables-save > /etc/sysconfig/iptables

三层交换机添加路由(可选)

另外如果是公司环境,应在三层交换机上添加回包路由,下一条为vpnopen服务器

1
2
3
4
# 思科3560
config terminal
switch3560-1(config)# ip route 10.201.0.0 255.255.255.0 ${openvpn_server_eth0_ip}
exit

二、OpenVpn 客户端

OepnVPN 官网下载

1.openvpn Windows 客户端

安装与配置

下载 win10 客户端,全部保持默认安装

拷贝客户端证书压缩包 user001.zip 到 openvpn client 的安装目录下 C:\Program Files\OpenVPN, 解压并重命名为 config

查看 openvpn 客户端主配置文件:C:\Program Files\OpenVPN\config\client.ovpn

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
client
proto udp
dev tun
nobind
remote xxx.xxx.xxx.xxx 1194
ca ca.crt
cert user001.crt
key user001.key
tls-auth ta.key 1
remote-cert-tls server
persist-tun
persist-key
comp-lzo
verb 3
mute-replay-warnings

启动 openvpn 客户端

双击桌面图标启动,右下角任务栏小图标右击可控制断开或重新连接。

2.openvpn Linux 客户端(CentOS7)

Linux 客户端安装 openvpn

1
2
3
4
5
6
7
# 安装
yum install -y epel-release
yum install -y openvpn

# 创建目录
mkdir -p /etc/openvpn/client/certs
mkdir -p /var/log

openvpn 客户端主配置文件

上传客户端证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cd /etc/openvpn/client/certs
rz user002.zip
unzip user002.zip

# 查看
$ tree /etc/openvpn/client/certs/user002
/etc/openvpn/client/certs/user002
├── ca.crt
├── ta.key
├── user002.crt
├── user002.key
└── user002.ovpn

0 directories, 5 files

编排主配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ vim /etc/openvpn/client/user002.conf
client # 声明为客户端
proto udp # 连接协议,必须与服务端一致
dev tun # 使用tun/tap设备,必须与服务端一致
nobind
remote ${OPENVPN_SERVER_HOST} 1194 # 远程服务器的地址和端口号,可以是域名也可以是IP地址
ca /etc/openvpn/client/certs/user002/ca.crt
cert /etc/openvpn/client/certs/user002/user002.crt
key /etc/openvpn/client/certs/user002/user002.key
tls-auth /etc/openvpn/client/certs/user002/ta.key 1
remote-cert-tls server
persist-tun
persist-key
comp-lzo
verb 3
mute-replay-warnings
log /var/log/openvpn.log
log-append /var/log/openvpn.log

授权目录

1
2
chown -R openvpn.openvpn /etc/openvpn
chown -R openvpn.openvpn /var/log

开机自启动

systemd 脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
$ vim /etc/systemd/system/openvpn-client.service 
[Unit]
Description=openvpn
After=network.target

[Service]
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/client/user002.conf
Restart=on-failure
Type=simple
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

启动

1
2
3
systemctl daemon-reload
systemctl enable openvpn-client.service
systemctl start openvpn-client.service