OpenVPN 安装及使用

环境信息

  • Centos 7 5.4.221
  • openvpn 2.4.12
  • easy-rsa-3.0.8
  • iptables

OpenVPN 服务端安装配置步骤

安装 openvpn 服务端程序

epel 仓库源中包含了 OpenVPN 的安装包

$ yum info openvpn

* epel: mirror.sfo12.us.leaseweb.net
* extras: download.cf.centos.org
* updates: download.cf.centos.org
Available Packages
Name : openvpn
Arch : x86_64
Version : 2.4.12
Release : 1.el7
Size : 529 k
Repo : epel/x86_64
Summary : A full-featured SSL VPN solution
URL : https://community.openvpn.net/
License : GPLv2

$ yum install -y openvpn

安装 easy-rsa

easy-rsa 主要用来生成证书

yum install easy-rsa

初始化,生成证书、密钥和参数文件

初始化 Esay-RSA

Esay-RSA 默认安装目录在 /usr/share/easy-rsa/3.0.8,文档配置文件模板在 /usr/share/doc/easy-rsa-3.0.8

文档建议我们拷贝一份到别的目录使用,以免将来升级的时候被覆盖掉。此处目录选择的 OpenVPN 配置目录下 /etc/openvpn/easy-rsa[1]

拷贝配置文件模板,安装文档要求,必须重命名为 vars 才可以被自动加载。

cp -a /usr/share/easy-rsa/3.0.8 /etc/openvpn/easy-rsa

cp -a /usr/share/doc/easy-rsa-3.0.8/vars.example /etc/openvpn/easy-rsa/vars

编辑配置文件 vars,主要修改证书相关的参数。

/etc/openvpn/easy-rsa/vars
set_var EASYRSA_REQ_COUNTRY    "CN"
set_var EASYRSA_REQ_PROVINCE "JiangSu"
set_var EASYRSA_REQ_CITY "Nanjing"
set_var EASYRSA_REQ_ORG "SIMAEK"
set_var EASYRSA_REQ_EMAIL "master@simaek.com"
set_var EASYRSA_REQ_OU "Development Dept."

说明

EASYRSA_REQ_COUNTRY “所在的国家”

EASYRSA_REQ_PROVINCE “所在的省份”

EASYRSA_REQ_CITY “所在的城市”

EASYRSA_REQ_ORG “所属的组织”

EASYRSA_REQ_EMAIL “邮件地址”

EASYRSA_REQ_OU “组织单位,部门”

说明一下我们需要创建的证书:

  • CA 根证书,用于给服务器和客户端证书签名使用。
  • OpenVPN 服务器证书
  • Diffie-Hellman 算法用到的 key

进入 easy-rsa 脚本所在目录,初始 pki 目录,创建的证书和生成的中间文件都会存放在这个目录里,默认位置为脚本执行的路径。

$ cd /etc/openvpn/easy-rsa
$ ./easyrsa init-pki

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

init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /etc/openvpn/easy-rsa/pki

创建 CA 根证书

根据提示输入 Common Name,名字自定义。在这部分会提示 Enter New CA Key Passphrase,输入两次 PEM 密码,此密码必须记住,不然以后不能为证书签名。可以加 nopass 参数表示不用密码

$ ./easyrsa build-ca

Note: using Easy-RSA configuration from: /etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017

Enter New CA Key Passphrase:
Re-Enter New CA Key Passphrase:
Generating RSA private key, 2048 bit long modulus
..................................................+++
.............................................................................................+++
e is 65537 (0x10001)
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]:myca

CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/etc/openvpn/easy-rsa/pki/ca.crt

生成的 CA 证书位于 pki/ca.crt,私钥位于 pki/private/

创建 OpenVPN 服务端证书

命令中的 openvpn-server 为自定义名称,这里建议用使用 nopass 参数,否则以后启动服务时需要输入密码。创建过程中需要输入之前的 CA 根证书的 PEM 密码。

$ ./easyrsa build-server-full openvpn-server nopass

Note: using Easy-RSA configuration from: /etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 1.0.2k-fips 26 Jan 2017
Generating a 2048 bit RSA private key
........................................................+++
................+++
writing new private key to '/etc/openvpn/easy-rsa/pki/easy-rsa-4754.a78E4M/tmp.ubswzT'
-----
Using configuration from /etc/openvpn/easy-rsa/pki/easy-rsa-4754.a78E4M/tmp.zSlCOO
Enter pass phrase for /etc/openvpn/easy-rsa/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'openvpn-server'
Certificate is to be certified until May 21 09:13:22 2025 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

生成的 OpenVPN 服务端证书位于 pki/issued/,私钥位于 pki/private/

$ ls pki/issued/
openvpn-server.crt

$ ls pki/private/
ca.key openvpn-server.key

生成 Diffie-Hellman 算法需要的密钥文件

创建 Diffie-Hellman,确保 key 穿越不安全网络的命令,时间会有点长,耐心等待。

./easyrsa gen-dh

生成 tls-auth key

此配置是为了防止 DDOS 和 TLS 攻击,这个属于可选安全配置。

强认证方式,防攻击。如果 OpenVPN 配置文件中启用此项(默认是启用的),就需要执行此命令,并把 ta.key 放到 /etc/openvpn/server 目录。

配置文件中服务端第二个参数为 0,同时客户端也要有此文件,且 client.conf 中此指令的第二个参数需要为1。服务端有该配置,那么客户端也必须要有

openvpn --genkey --secret ta.key

收集证书文件

创建目录,将需要的证书文件统一放入此目录

mkdir /etc/openvpn/server/certs

cp /etc/openvpn/easy-rsa/pki/ca.crt /etc/openvpn/server/certs
cp /etc/openvpn/easy-rsa/pki/private/ca.key /etc/openvpn/server/certs
cp /etc/openvpn/easy-rsa/pki/private/openvpn-server.key /etc/openvpn/server/certs
cp /etc/openvpn/easy-rsa/pki/issued/openvpn-server.crt /etc/openvpn/server/certs
cp /etc/openvpn/easy-rsa/pki/dh.pem /etc/openvpn/server/certs

cp /etc/openvpn/easy-rsa/ta.key /etc/openvpn/server/certs

配置 OpenVPN 服务端

修改 OpenVPN 服务端配置文件,拷贝配置模板文件并修改

cd /etc/openvpn/server/
cp /usr/share/doc/openvpn-2.4.12/sample/sample-config-files/server.conf ./

配置文件中主要内容如下,配置文件详细说明参考

/etc/openvpn/server/server.conf
local 192.168.88.88
port 1194
proto udp
dev tun
ca server_certs/ca.crt
cert server_certs/openvpn-server.crt
key server_certs/openvpn-server.key
dh dh.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
client-to-client
keepalive 10 120
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
log openvpn.log
verb 3

开启系统 IPv4 转发功能

修改内核配置文件 /etc/sysctl.conf,增加以下配置,开启内核 IPv4 转发功能

/etc/sysctl.conf
net.ipv4.ip_forward = 1

执行命令使配置生效

sysctl -p

添加 iptables 防火墙规则

配置 iptables 防火墙规则,允许 OpenVPN 分配的网段 NAT

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE

配置 iptables 防火墙规则(filter 表),允许转发,同时放通 OpenVPN 监听的端口

iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT
iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

iptables -I INPUT -p udp --dport 1194 -j ACCEPT -m comment --comment "openvpn"

要持久化配置,可以在 iptables 配置文件中增加如下主要配置

/etc/sysconfig/iptables
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [4:368]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p udp --dport 1194 -j ACCEPT -m comment --comment "openvpn"
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited

-A FORWARD -s 10.8.0.0/24 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

*nat
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [4:368]
-A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE
COMMIT

启动 OpenVPN 服务

执行以下命令可以在前台启动 OpenVPN 服务,并观察错误信息

openvpn /etc/openvpn/server/server.conf

启动之后,检查系统是否监听了 1194/udp

$ netstat -anutp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 0.0.0.0:739 0.0.0.0:* 620/rpcbind
udp 0 0 0.0.0.0:1194 0.0.0.0:* 9898/openvpn
udp 0 0 0.0.0.0:68 0.0.0.0:* 931/dhclient
udp 0 0 0.0.0.0:111 0.0.0.0:* 620/rpcbind
udp6 0 0 :::739 :::* 620/rpcbind
udp6 0 0 :::111 :::* 620/rpcbind

端口监听后,说明服务启动无异常,如果端口未监听,检查日志解决。

OpenVPN 客户端安装配置

Windows 客户端配置

下载 OpenVPN Windows 客户端

常用工具下载链接

在 OpenVPN 服务端为客户端生成证书

在 OpenVPN 服务器的 /etc/openvpn/easy-rsa/ 目录下,执行以下命令,为客户端生成无密码的证书

./easyrsa build-client-full client nopass 

命令选项中,nopass 指定证书无密码,不安全,建议生产环境中配置密码

./easyrsa build-client-full vpn1

为指定用户生成证书,会首先询问设置用户证书密码,签发时会询问 CA 证书密码

证书创建完成后,证书和私钥分别位于以下位置:

$ ls pki/issued/
openvpn-server.crt vpn1.crt

$ ls pki/private/
ca.key openvpn-server.key vpn1.key

客户端需要 CA 根证书(/etc/openvpn/easy-rsa/pki/ca.crt),客户端证书(/etc/openvpn/easy-rsa/pki/issued/vpn1.crt)和私钥(/etc/openvpn/easy-rsa/pki/private/vpn1.key)

生成 OpenVPN 客户端配置文件

OpenVPN 客户端配置文件说明

客户端配置文件名默认 windows 为 client.ovpn,Linux 为 client.conf

创建客户端配置文件目录,假设为 /home/openvpn/vpn1/,并拷贝相应的证书文件到此目录

cp /etc/openvpn/easy-rsa/pki/ca.crt /home/openvpn/vpn1/ca.crt
cp /etc/openvpn/easy-rsa/pki/private/vpn1.key /home/openvpn/vpn1/client.key
cp /etc/openvpn/easy-rsa/pki/issued/vpn1.crt /home/openvpn/vpn1/client.crt

为客户端 vpn1 创建 openvpn 客户端配置文件 /home/openvpn/vpn1/client.ovpn

client.ovpn
client
dev tun
proto udp
remote 39.xxx.xxx.xxx 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
comp-lzo
verb 3

ca.crt , client.ovpn , client.crt , client.key 发送到客户端。

在 Windows 上使用 OpenVPN 客户端导入配置 client.ovpn,即可正常连接。

OpenVPN 服务端配置文件详解

/etc/openvpn/server/server.conf
# 表示 openvpn 服务端监听的地址
local 0.0.0.0

# 监听的端口,默认是 1194
port 1194

# 使用的协议,有 udp 和 tcp。建议选择 tcp
proto tcp

# 使用三层路由 IP 隧道( tun )还是二层以太网隧道( tap )。一般都使用 tun
dev tun

# ca证书、服务端证书、服务端密钥和密钥交换文件。如果它们和 server.conf 在同一个目录下则可以不写绝对路径,否则需要写绝对路径调用
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem

# vpn 服务端为自己和客户端分配 IP 的地址池。
# 服务端自己获取网段的第一个地址(此处为 10.8.0.1),后为客户端分配其他的可用地址。以后客户端就可以和 10.8.0.1 进行通信。
# 注意:该网段地址池不要和已有网段冲突或重复。其实一般来说是不用改的。除非当前内网使用了 10.8.0.0/24 的网段。

server 10.8.0.0 255.255.255.0

# 使用一个文件记录已分配虚拟 IP 的客户端和虚拟 IP 的对应关系,
# 以后 openvpn 重启时,将可以按照此文件继续为对应的客户端分配此前相同的 IP。也就是自动续借 IP 的意思。

ifconfig-pool-persist ipp.txt

# 使用tap模式的时候考虑此选项。
server-bridge XXXXXX

# vpn 服务端向客户端推送 vpn 服务端内网网段的路由配置,以便让客户端能够找到服务端内网。多条路由就写多个 push 指令
# 分配网关
# dhcp分配dns
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"

push "route 10.0.10.0 255.255.255.0"
push "route 192.168.10.0 255.255.255.0"

# 让 vpn 客户端之间可以互相看见对方,即能互相通信。默认情况客户端只能看到服务端一个人;
# 默认是注释的,不能客户端之间相互看见
client-to-client

# 允许多个客户端使用同一个 VPN 帐号连接服务端
# 默认是注释的,不支持多个客户登录一个账号
duplicate-cn

# 每 10 秒 ping 一次,120 秒后没收到 ping 就说明对方挂了
keepalive 10 120

# 加强认证方式,防攻击。如果配置文件中启用此项(默认是启用的)
# 需要执行 openvpn --genkey --secret ta.key,并把 ta.key 放到 /etc/openvpn/server 目录
# 服务端第二个参数为 0;同时客户端也要有此文件,且 client.conf 中此指令的第二个参数需要为 1。
tls-auth ta.key 0

# 选择一个密码。如果在服务器上使用了 cipher 选项,那么您也必须在这里指定它。
# 注意,v2.4 客户端/服务器将在 TLS 模式下自动协商 AES-256-GCM。
cipher AES-256-CBC

# openvpn 2.4 版本的 vpn 才能设置此选项。表示服务端启用 lz4 的压缩功能,传输数据给客户端时会压缩数据包。
# push 后在客户端也配置启用 lz4 的压缩功能,向服务端发数据时也会压缩。如果是 2.4 版本以下的老版本,则使用用 comp-lzo 指令

compress lz4-v2
push "compress lz4-v2"

# 启用 lzo 数据压缩格式。此指令用于低于 2.4 版本的老版本。且如果服务端配置了该指令,客户端也必须要配置
comp-lzo

# 并发客户端的连接数
max-clients 100

# 通过 ping 得知超时时,当重启 vpn 后将使用同一个密钥文件以及保持 tun 连接状态
persist-key
persist-tun

# 在文件中输出当前的连接信息,每分钟截断并重写一次该文件
status openvpn-status.log

# 默认vpn的日志会记录到rsyslog中,使用这两个选项可以改变。
# log 指令表示每次启动 vpn 时覆盖式记录到指定日志文件中,
# log-append 则表示每次启动 vpn 时追加式的记录到指定日志中。
# 但两者只能选其一,或者不选时记录到rsyslog中
;log openvpn.log
;log-append openvpn.log

# 日志记录的详细级别。
verb 3

# 沉默的重复信息。最多 20 条相同消息类别的连续消息将输出到日志。
;mute 20

# 当服务器重新启动时,通知客户端,以便它可以自动重新连接。仅在 UDP 协议是可用
explicit-exit-notify 1

OpenVPN 客户端配置文件详解

# 标识这是个客户端
client

# 使用三层路由IP隧道(tun)还是二层以太网隧道(tap)。服务端是什么客户端就是什么
dev tun

# 使用的协议,有udp和tcp。服务端是什么客户端就是什么
proto tcp

# 服务端的地址和端口
remote 10.0.0.190 1194

# 一直尝试解析 OpenVPN 服务器的主机名。
# 在机器上非常有用,不是永久连接到互联网,如笔记本电脑。
resolv-retry infinite

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

# 初始化后的降级特权(仅非 windows)
;user nobody
;group nobody

# 尝试在重新启动时保留某些状态。
persist-key
persist-tun

# ca 证书、客户端证书、客户端密钥
# 如果它们和 client.conf 或 client.ovpn 在同一个目录下则可以不写绝对路径,否则需要写绝对路径调用
ca ca.crt
cert client.crt
key client.key

# 通过检查 certificate 是否具有正确的密钥使用设置来验证服务器证书。
remote-cert-tls server

# 加强认证方式,防攻击。服务端有配置,则客户端必须有
tls-auth ta.key 1

# 选择一个密码。如果在服务器上使用了 cipher 选项,那么您也必须在这里指定它。注意,v2.4 客户端/服务器将在 TLS 模式下自动协商 AES-256-GCM。
cipher AES-256-CBC

# 服务端用的什么,客户端就用的什么
# 表示客户端启用lz4的压缩功能,传输数据给客户端时会压缩数据包。
compress lz4-v2

# 日志级别
verb 3

# 沉默的重复信息。最多20条相同消息类别的连续消息将输出到日志。
;mute 20

脚注