OpenVPN部署及应用实践
VPN(Virtual Private Network)即虚拟专用网络,是通过一个公用互联网络建立一个临时的、安全的连接,VPN技术通过密钥交换、封装、认证、加密手段在公共网络上建立起私密的隧道,保障传输数据的完整性、私密性和有效性,VPN网关通过对数据包的加密和数据包目标地址的转换实现远程访问。VPN可通过服务器、硬件、软件等多种方式实现,目前在企业网络中得到了广泛应用。
OpenVPN是一个开放源码项目,其以一种全新的方式实现了SSL VPN的功能,克服了传统SSL VPN的一些缺陷,简单易用高效,扩展了应用领域,并且防火墙上只需开放TCP或UDP协议的一个端口,提供了良好的性能和友好的用户GUI,本文就OpenVPN部署及应用实践进行一些尝试。
一、网络及基础环境规划
1.1网络基础环境及访问需求
本文中通过路由H3C ER6300接入公网的内网共有2个网段,其中1个为服务器网段172.16.1.*/24,另1个为用户网段10.10.10.*/24,目的是让公网用户相对安全的方式访问内网服务器,在内网设置VPN服务器对外网提供服务,内网IP为172.16.1.123,服务端口为UDP 8899,对外开放的公网地址为111.21.*.*,对外开放的服务端口为UPD 8000,现需要在外网可以直接访问内网VPN服务器。
1.2网络拓扑结构
1.3基础环境
主机名 操作系统 内网IP 角色
openvpn Centos8.4 172.16.1.123 OpenVPN服务端
clientPC windows10 10.10.10.8 OpenVPN客户端
1.4 OpenVPN及证书工具软件
easy-rsa:easy-rsa-3.0.8-1.el8.noarch.rpm
OpenVPN服务端:openvpn-2.4.11-1.el8.x86_64.rpm
OpenVPN客户端:OpenVPN-2.5.3-I601-amd64.msi
1.5 配置出口路由器NAT端口映射
配置出口路由器端口映射,本文以H3C ER6300为例:
二、生成证书
2.1 安装证书生成工具easy-rsa
rpm -ivh easy-rsa-3.0.8-1.el8.noarch.rpm
2.2 创建证书环境目录
mkdir -p /opt/easy-rsa
cp -a /usr/share/easy-rsa/3.0.8/* /opt/easy-rsa/
cp -a /usr/share/doc/easy-rsa/vars.example /opt/easy-rsa/vars
2.3 生成秘钥前,配置vars文件
vim /opt/easy-rsa/vars
set_var EASYRSA_DN "cn_only"
set_var EASYRSA_REQ_COUNTRY "CN"
set_var EASYRSA_REQ_PROVINCE "Xian"
set_var EASYRSA_REQ_CITY "Xian"
set_var EASYRSA_REQ_ORG "test001"
set_var EASYRSA_REQ_EMAIL "test001@qq.com"
set_var EASYRSA_NS_SUPPORT "yes"
2.4 初始化,在easy-rsa目录下创建pki目录,用于存储证书
cd /opt/easy-rsa/
/opt/easy-rsa/easyrsa init-pki
2.5 创建根证书,用于ca对之后生成的server和client证书签名时使用。
/opt/easy-rsa/easyrsa build-ca
#生成过程,输入CA密码并确认,Common Name 时回车
2.6 创建server端证书和私钥文件
/opt/easy-rsa/easyrsa gen-req server nopass
#nopass表示不加密私钥文件,生成过程中Common Name时直接回车
2.7 给server证书签名
/opt/easy-rsa/easyrsa sign server server
#生成过程,输入yes和CA密码
2.8 创建Diffie-Hellman文件,秘钥交换时的Diffie-Hellman算法,此过程用时较长
/opt/easy-rsa/easyrsa gen-dh
2.9 创建server端证书和私钥文件
/opt/easy-rsa/easyrsa gen-req client nopass
#nopass表示不加密私钥文件,Common Name时直接回车
2.10 给client端证书签名
/opt/easy-rsa/easyrsa sign client client
#生成过程,输入yes和CA密码
三、OpenVPN服务端部署
3.1 安装openvpn服务
cd /home/xtga/
#首先安装openvpn的依赖包pkcs11-helper,然后再安装openvpn
rpm -ivh pkcs11-helper-1.22-7.el8.x86_64.rpm
rpm -ivh openvpn-2.4.11-1.el8.x86_64.rpm
3.2 修改openvpn配置文件
vim /etc/openvpn/server/server.conf
#服务端的监听地址
local 0.0.0.0
#原端口号1194,本文修改为8899
port 8899
#协议类型,建议使用upd,提高效率
proto udp
#采用路由隧道模式tun
dev tun
#ca证书文件位置
ca /etc/openvpn/ca.crt
#服务端公钥位置
cert /etc/openvpn/server.crt
#服务端私钥位置
key /etc/openvpn/server.key
#交换证书位置
dh /etc/openvpn/dh.pem
#给客户端分配地址池,不能和VPN服务器内网网段相同
server 172.16.4.0 255.255.255.248
#允许客户端访问内网的网段
push "route 172.16.1.0 255.255.255.0"
#地址池记录文件位置
ifconfig-pool-persist ipp.txt
#存活时间,10秒ping一次,连接超时时间设为60秒
keepalive 10 60
#最多允许10个客户端连接
max-clients 10
#输出短日志,每分钟刷新一次,以显示当前的客户端
status openvpn-status.log
#定义运行的用户和组
user openvpn
group openvpn
#指定日志文件的记录详细级别,可选0-9,等级越高日志内容越详细
verb 5
#客户端与客户端之间支持通信
client-to-client
#openvpn日志记录位置
log /var/log/openvpn.log
log-append /var/log/openvpn.log
#通过keepalive检测超时后,重新启动VPN,不重新读取keys,保留第一次使用的keys。
persist-key
#检测超时后,重新启动VPN,一直保持tun是linkup的。否则网络会先linkdown然后再linkup
persist-tun
#允许多个客户端使用同一个VPN帐号连接服务端
duplicate-cn
3.3 将证书拷贝到openvpn主配置文件目录下
cp -a /opt/easy-rsa/pki/ca.crt /etc/openvpn/
cp -a /opt/easy-rsa/pki/issued/server.crt /etc/openvpn/
cp -a /opt/easy-rsa/pki/private/server.key /etc/openvpn/
cp -a /opt/easy-rsa/pki/dh.pem /etc/openvpn/
chown -R root.openvpn /etc/openvpn/*
3.4 启动openvpn
cp -a /usr/lib/systemd/system/openvpn-server@.service /usr/lib/systemd/system/openvpn.service
vim /usr/lib/systemd/system/openvpn.service
#修改以下内容
WorkingDirectory=/etc/openvpn/server
ExecStart=/usr/sbin/openvpn --status %t/openvpn-server/status-%i.log --status-version 2 --suppress-timestamps --config server.conf
# Openvpn设置为开机启动并开启服务,检查服务及进程状态
systemctl enable openvpn
systemctl restart openvpn
systemctl status openvpn
ps -ef | grep 'openvpn'
netstat -lntup | grep '进程号'
四、OpenVPN服务端开启转发功能并修改防火墙配置
#在OpenVPN服务端开启内核转发功能
echo net.ipv4.ip_forward = 1 >> /etc/sysctl.conf
sysctl -p
#客户端连接VPN后,默认分配172.16.4.0/29网段地址,不能直接访问其它机器,因此需要在firewall进行nat配置, 开启 NAT 转发功能,并放行相应服务端口
firewall-cmd --permanent --zone=public --add-masquerade
firewall-cmd --permanent --zone=public --add-port=8899/udp
systemctl restart firewalld
firewall-cmd --list-all
# 检查NAT转发是否正常
firewall-cmd --query-masquerade
五、OpenVPN客户端部署
5.1 安装OpenVPN客户端软件
本文在windows10环境下部署OpenVPN客户端,需下载并安装最新客户端软件OpenVPN-2.5.3-I601-amd64.msi
5.2 配置客户端。安装完成后,拷贝服务端生成的以下证书文件到客户端OpenVPN安装目录下config子目录中
/opt/easy-rsa/pki/ca.crt
/opt/easy-rsa/pki/issued/client.crt
/opt/easy-rsa/pki/private/client.key
5.3 生成客户端配置文件
#在客户端OpenVPN安装目录config下,新建文件client.ovpn,配置如下:
#指定当前VPN是客户端
client
#使用tun隧道传输协议
dev tun
#使用udp协议传输数据
proto udp
#openvpn服务器IP地址及端口号
remote 111.21.*.* 8000
#断线自动重新连接
resolv-retry infinite
#不绑定本地特定的端口号
nobind
#指定CA证书
ca ca.crt
#指定当前客户端的证书
cert client.crt
#指定当前客户端的私钥文件路径
key client.key
#指定日志文件的记录级别0-9,等级越高日志越详细
verb 5
#通过keepalive检测超时后,重启VPN不重新读取keys,保留第一次使用keys
persist-key
#检测超时重启,一直保持tun是linkup,否则网络会先linkdown然后再linkup
persist-tun
#在断线后防止内存中保存用户名和密码, 提高安全性
auth-nocache
#配置账号登录
auth-user-pass
#通过检查certicate是否具有正确的密钥来验证服务器证书
remote-cert-tls server
5.4 启动OpenVPN客户端软件
运行OpenVPN软件,右键点击连接,当任务栏OpenVPN图标变成绿色时,说明OpenVPN已经连接成功。连接成功后,客户端分配的IP为172.16.4.6。
六、配置openVPN服务器证书和账号双重验证登录
6.1 server端配置
在配置文件/etc/openvpn/server.conf中添加以下配置,允许使用自定义验证脚本,使用用户密码登陆方式验证方式
vim /etc/openvpn/server/server.conf
script-security 3
auth-user-pass-verify /etc/openvpn/server/check.sh via-env
username-as-common-name
#注意:如果配置client-cert-not-required参数,则仅使用用户名密码方式登录,如果无此参数则需要证书和用户名密码双重验证登录!
6.2 添加验证脚本
vim /etc/openvpn/server/check.sh
#!/bin/sh
###########################################################
PASSFILE="/etc/openvpn/client/openvpnfile"
LOG_FILE="/var/log/openvpn-password.log"
TIME_STAMP=`date "+%Y-%m-%d %T"`
if [ ! -r "${PASSFILE}" ]; then
echo "${TIME_STAMP}: Could not open password file \"${PASSFILE}\" for reading." >> ${LOG_FILE}
exit 1
fi
CORRECT_PASSWORD=`awk '!/^;/&&!/^#/&&$1=="'${username}'"{print $2;exit}' ${PASSFILE}`
if [ "${CORRECT_PASSWORD}" = "" ]; then
echo "${TIME_STAMP}: User does not exist: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
exit 1
fi
if [ "${password}" = "${CORRECT_PASSWORD}" ]; then
echo "${TIME_STAMP}: Successful authentication: username=\"${username}\"." >> ${LOG_FILE}
exit 0
fi
echo "${TIME_STAMP}: Incorrect password: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
exit 1
#给脚本赋予执行权限
chmod +x /etc/openvpn/server/check.sh
6.3 生成用户密码文件,用户名和密码间用空格隔开
vim /etc/openvpn/client/openvpnfile
test test123
6.4 重启openvpn服务
systemctl restart openvpn
6.5 修改客户端配置,在客户端openvpn所在子目录config下配置文件client.ovpn中添加如下参数:
auth-user-pass
重新连接OpenVPN客户端时,就会出现用户登录窗口了,输入用户名和密码后即可登录成功。
6.6 测试是否可以访问内网172.16.1.*段地址
用ping命令对内网网段服务器进行测试,能够正常访问,至此openvpn服务端和客户端部署完毕。