概述
本文主要介绍在CentOS 7系统中如何配置OpenVPN。
一、准备工作
安装依赖的软件包。
yum install -y lzo openssl pam
执行以下命令,确认软件包已经安装成功。
rpm -qa lzo openssl pam
二、安装OpenVPN服务
直接使用YUM安装OpenVPN。
yum install -y epel-release
yum install -y openvpn easy-rsa iptables-services
附上源码地址,有需要的可以编译安装。
OpenVPN:https://github.com/OpenVPN/openvpn
Easy-RSA:https://github.com/OpenVPN/easy-rsa
三、配置OpenVPN服务
我安装时候的版本信息如下,主要会在一些目录上会有版本号的区别,按实际情况替换。
OpenVPN:2.4.10
EasyRSA:3.0.8
1、初始化,生成证书、密钥和参数文件
Esay-RSA默认安装目录在/usr/share/easy-rsa/3.0.8
,文档配置文件模板在/usr/share/doc/easy-rsa-3.0.8
。
文档建议我们拷贝一份到别的目录使用,以免将来升级的时候被覆盖掉。我们照做就好,目录就选择我们的OpenVPN配置目录,毕竟就是给它用的嘛。
cp -a /usr/share/easy-rsa/3.0.8 /etc/openvpn/easy-rsa
拷贝配置文件模板,安装文档要求,必须重命名为vars才可以被自动加载。
cp -a /usr/share/doc/easy-rsa-3.0.8/vars.example /etc/openvpn/easy-rsa/vars
编辑配置文件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
创建CA根证书。提示输入Common Name,名字自定义。在这部分会提示Enter New CA Key Passphrase
,输入两次PEM密码,此密码必须记住,不然以后不能为证书签名。可以加nopass
参数表示不用密码,但是我并不建议这么做。
./easyrsa build-ca
创建OpenVPN服务端证书。openvpn-server
为自定义名称,这里建议用使用nopass参数,否则以后启动服务时需要输入密码。创建过程中需要输入之前的CA根证书PEM密码。
./easyrsa build-server-full openvpn-server nopass
生成Diffie-Hellman算法需要的密钥文件,创建Diffie-Hellman,确保key穿越不安全网络的命令,时间会有点长,耐心等待。
./easyrsa gen-dh
将生成的证书拷贝到统一的目录,个人建议拷贝/etc/openvpn/server/
下和配置文件同名目录,配置文件暂时还没搞,后面再说,先创建一个目录吧,然后把需要的证书拷贝过去。
mkdir /etc/openvpn/server/server_certs
cp /etc/openvpn/easy-rsa/pki/ca.crt /etc/openvpn/server/server_certs
cp /etc/openvpn/easy-rsa/pki/private/ca.key /etc/openvpn/server/server_certs
cp /etc/openvpn/easy-rsa/pki/private/openvpn-server.key /etc/openvpn/server/server_certs
cp /etc/openvpn/easy-rsa/pki/issued/openvpn-server.crt /etc/openvpn/server/server_certs
cp /etc/openvpn/easy-rsa/pki/dh.pem /etc/openvpn/server/server_certs
生成tls-auth key,为了防止DDOS和TLS攻击,这个属于可选安全配置。强认证方式,防攻击。如果配置文件中启用此项(默认是启用的),就需要执行上述命令,并把ta.key放到/etc/openvpn/server目录。配置文件中服务端第二个参数为0,同时客户端也要有此文件,且client.conf中此指令的第二个参数需要为1。【服务端有该配置,那么客户端也必须要有】。
cd /etc/openvpn/server/server_certs
openvpn --genkey --secret ta.key
2、修改OpenVPN配置文件
进入OpenVPN的配置目录,分为client和server,OpenVPN很贴心的准备了单元文件,可以直接启动这两个目录下的配置文件。我们只需要自定义配置文件的名称就好。
cd /etc/openvpn/server
# 拷贝一份配置文件
cp -a /cp /usr/share/doc/openvpn-2.4.10/sample/sample-config-files/server.conf ./
配置文件部分解释如下。
local 0.0.0.0
表示openvpn服务端的监听地址
port 1194
监听的端口,默认是1194
proto tcp
使用的协议,有udp和tcp。建议选择tcp
dev tun
使用三层路由IP隧道(tun)还是二层以太网隧道(tap)。一般都使用tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
ca证书、服务端证书、服务端密钥和密钥交换文件。如果它们和server.conf在同一个目录下则可以不写绝对路径,否则需要写绝对路径调用
server 10.8.0.0 255.255.255.0
vpn服务端为自己和客户端分配IP的地址池。
服务端自己获取网段的第一个地址(此处为10.8.0.1),后为客户端分配其他的可用地址。以后客户端就可以和10.8.0.1进行通信。
注意:该网段地址池不要和已有网段冲突或重复。其实一般来说是不用改的。除非当前内网使用了10.8.0.0/24的网段。
ifconfig-pool-persist ipp.txt
使用一个文件记录已分配虚拟IP的客户端和虚拟IP的对应关系,
以后openvpn重启时,将可以按照此文件继续为对应的客户端分配此前相同的IP。也就是自动续借IP的意思。
server-bridge XXXXXX
使用tap模式的时候考虑此选项。
push "route 10.0.10.0 255.255.255.0"
push "route 192.168.10.0 255.255.255.0"
vpn服务端向客户端推送vpn服务端内网网段的路由配置,以便让客户端能够找到服务端内网。多条路由就写多个Push指令
client-to-client
让vpn客户端之间可以互相看见对方,即能互相通信。默认情况客户端只能看到服务端一个人;
默认是注释的,不能客户端之间相互看见
duplicate-cn
允许多个客户端使用同一个VPN帐号连接服务端
默认是注释的,不支持多个客户登录一个账号
keepalive 10 120
每10秒ping一次,120秒后没收到ping就说明对方挂了
tls-auth ta.key 0
加强认证方式,防攻击。如果配置文件中启用此项(默认是启用的)
需要执行openvpn --genkey --secret ta.key,并把ta.key放到/etc/openvpn/server目录
服务端第二个参数为0;同时客户端也要有此文件,且client.conf中此指令的第二个参数需要为1。
cipher AES-256-CBC
# 选择一个密码。如果在服务器上使用了cipher选项,那么您也必须在这里指定它。注意,v2.4客户端/服务器将在TLS模式下自动协商AES-256-GCM。
compress lz4-v2
push "compress lz4-v2"
openvpn 2.4版本的vpn才能设置此选项。表示服务端启用lz4的压缩功能,传输数据给客户端时会压缩数据包。
Push后在客户端也配置启用lz4的压缩功能,向服务端发数据时也会压缩。如果是2.4版本以下的老版本,则使用用comp-lzo指令
comp-lzo
启用lzo数据压缩格式。此指令用于低于2.4版本的老版本。且如果服务端配置了该指令,客户端也必须要配置
max-clients 100
并发客户端的连接数
persist-key
persist-tun
通过ping得知超时时,当重启vpn后将使用同一个密钥文件以及保持tun连接状态
status openvpn-status.log
在文件中输出当前的连接信息,每分钟截断并重写一次该文件
;log openvpn.log
;log-append openvpn.log
默认vpn的日志会记录到rsyslog中,使用这两个选项可以改变。
log指令表示每次启动vpn时覆盖式记录到指定日志文件中,
log-append则表示每次启动vpn时追加式的记录到指定日志中。
但两者只能选其一,或者不选时记录到rsyslog中
verb 3
日志记录的详细级别。
;mute 20
沉默的重复信息。最多20条相同消息类别的连续消息将输出到日志。
explicit-exit-notify 1
当服务器重新启动时,通知客户端,以便它可以自动重新连接。仅在UDP协议是可用
注释太多,可以通过egrep查看实际有效配置。
egrep -v "^$|^#|^;" 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 223.5.5.5"
client-to-client
keepalive 10 120
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
log openvpn.logverb 3
3、设置防火墙
禁用firewalld和SELinux。
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
执行以下命令,编辑配置文件。
vi /etc/sysctl.conf
修改成以下参数,启用IPv4转发,然后保存并退出。
net.ipv4.ip_forward = 1
执行以下命令,加载系统参数。
sysctl -p
添加以下iptables规则,确保服务器可以转发数据包到内网和外网。只需添加配置,不需要启动iptables服务。客户端连接VPN后,默认分配的10.8.0.0/24网段地址,不能直接内网机器,因此需要在iptables进行NAT配置。
方式一,所有网卡都进行NAT。
iptables -t nat -A POSTROUTING -s 172.16.0.0/16 -j MASQUERADE
iptables -nL -t nat
方式二,指定NAT。不懂的用一。
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o tun0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o ens192 -j SNAT --to-source 192.168.88.88
iptables -nL -t nat
可以使用iptables -t nat -D POSTROUTING 1
删除配置
执行以下命令,保存iptables配置。
service iptables save
启动服务,@后面跟的是配置文件名称。openvpn@server配置文件为/etc/openvpn/server.conf
,openvpn-server@server配置文件为/etc/openvpn/server/server.conf
,以此类推。
systemctl start openvpn-server@server # 启动
systemctl enable openvpn-server@server # 开机自启动
systemctl status openvpn-server@server # 查看服务状态
4、Windows客户端配置
生成客户端证书。
# ./easyrsa build-client-full client nopass # 无密码,实际应用中不推荐,客户端有密码可提高安全性
# ./easyrsa build-client-full zhangsan # 让你输入密码,后续VPN连接时会使用
# ./easyrsa build-client-full lisi # 让你输入密码,后续VPN连接时会使用
# ./easyrsa build-client-full wangwu # 让你输入密码,后续VPN连接时会使用
为客户端生成证书对并在本地签名。nopass参数生成一个无密码的证书;在此过程中都会让你确认ca密码
客户端配置文件参考:openvpn-2.4.9/sample/sample-config-files/client.conf
# 文件名 windows为client.ovpn,Linux为client.conf
client
# 标识这是个客户端
dev tun
# 使用三层路由IP隧道(tun)还是二层以太网隧道(tap)。服务端是什么客户端就是什么
proto tcp
# 使用的协议,有udp和tcp。服务端是什么客户端就是什么
remote 10.0.0.190 1194
# 服务端的地址和端口
resolv-retry infinite
# 一直尝试解析OpenVPN服务器的主机名。
# 在机器上非常有用,不是永久连接到互联网,如笔记本电脑。
nobind
# 大多数客户机不需要绑定到特定的本地端口号。
;user nobody
;group nobody
# 初始化后的降级特权(仅非windows)
persist-key
persist-tun
# 尝试在重新启动时保留某些状态。
ca ca.crt
cert client.crt
key client.key
# ca证书、客户端证书、客户端密钥
# 如果它们和client.conf或client.ovpn在同一个目录下则可以不写绝对路径,否则需要写绝对路径调用
remote-cert-tls server
# 通过检查certicate是否具有正确的密钥使用设置来验证服务器证书。
tls-auth ta.key 1
# 加强认证方式,防攻击。服务端有配置,则客户端必须有
cipher AES-256-CBC
# 选择一个密码。如果在服务器上使用了cipher选项,那么您也必须在这里指定它。注意,v2.4客户端/服务器将在TLS模式下自动协商AES-256-GCM。
compress lz4-v2
# 服务端用的什么,客户端就用的什么
# 表示客户端启用lz4的压缩功能,传输数据给客户端时会压缩数据包。
verb 3
# 日志级别
;mute 20
# 沉默的重复信息。最多20条相同消息类别的连续消息将输出到日志。
自动化脚本参考:
# ! /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