VPN 基础知识
VPN 介绍
VPN: (Virtual Private Network) 虚拟专用网络
VPN 是虚拟专用网络,是专用网络的一种延伸,属于远程访问技术的一种
VPN 可以在公用网络的基础上建立专用网络,但其并不是物理意义上的专线,而是在公共的互联网的基 础上虚拟出一个专用网络,所以被称为虚拟专用网络
VPN 技术在现在的网络环境中有着广泛的使用。VPN网关通过对数据包的加密和数据包目标地址的转换实现远程访问。VPN可通过服务器、硬件、软件等多种方式实现
例如在企业中,员工出差到外地,所使用的终端不处于企业内网中,又需要访问企业内网,就可以使用 VPN 技术来实现
网络上所谓的 "翻墙软件",其实也是使用 VPN 相关的技术,绕过相关的IP限制,内容过滤,域名劫持等,实现对网络内容的访问
VPN 是一种网络通信技术,并不同等于翻墙软件
VPN 常见应用模式
-
点对站点 peer to site
-
站点对站点 site to site
OpenVPN 实现
OpenVPN 介绍
OpenVPN 是 Linux下开源的 VPN 应用,它提供了良好的性能和友好的用户 GUI
OpenVPN 是一个基于 OpenSSL 库的应用层 VPN 实现。和传统 VPN 相比,它的优点是简单易用
OpenVPN 提供了多种身份验证方式,用以确认参与连接双方的身份,包括:共享私钥,第三方证书以 及用户名/密码组合。共享密钥最为简单,但同时它只能用于建立点对点的 VPN;基于 PKI 的第三方证书 提供了最完善的功能,但是需要额外的精力去维护一个 PKI 证书体系。 OpenVPN2.0 后引入了用户名/ 口令组合的身份验证方式,它可以省略客户端证书,但是仍有一份服务器证书需要被用作加密
配置 OpenVPN 证书
安装相关软件
#安装openvpn,安装证书管理工具
apt install openvpn easy-rsa
tree /etc/openvpn/
/etc/openvpn/
├── client
├── server
└── update-resolv-conf
配置CA证书
准备证书环境
#准备证书环境,让证书和 openvpn 配置处于一个目录,方便迁移
cp -r /usr/share/easy-rsa/ /etc/openvpn/
tree /etc/openvpn/
/etc/openvpn/
├── client
├── easy-rsa
│ ├── easyrsa
│ ├── openssl-easyrsa.cnf
│ ├── vars.example
│ └── x509-types
│ ├── ca
│ ├── client
│ ├── code-signing
│ ├── COMMON
│ ├── email
│ ├── kdc
│ ├── server
│ └── serverClient
├── server
└── update-resolv-conf
vars 文件中相关配置说明
cat /etc/openvpn/easy-rsa/vars
#CA机构证书有效期
#set_var EASYRSA_CA_EXPIRE 3650
#openvpn 服务器证书有效期
#set_var EASYRSA_CERT_EXPIRE
脚本工具使用说明
[root@vpn-server ~]# cd /etc/openvpn/easy-rsa/
[root@vpn-server easy-rsa]# mv vars.example vars
[root@vpn-server easy-rsa]# ls
easyrsa openssl-easyrsa.cnf vars x509-types
[root@vpn-server easy-rsa]# file easyrsa
easyrsa: POSIX shell script, ASCII text executable
[root@vpn-server easy-rsa]# ./easyrsa
Note: using Easy-RSA configuration from: /etc/openvpn/easy-rsa/vars
Easy-RSA 3 usage and overview
USAGE: easyrsa [options] COMMAND [command-options]
A list of commands is shown below. To get detailed usage and help for a
command, run:
./easyrsa help COMMAND
For a listing of options that can be supplied before the command, use:
./easyrsa help options
Here is the list of commands available with a short syntax reminder. Use the
'help' command above to get full usage details.
init-pki #初始化环境,创建相关目录
build-ca [ cmd-opts ] #创建CA机构证书
gen-dh #创建 Diffie-Hellman 参数文件
gen-req <filename_base> [ cmd-opts ] #证书申请
sign-req <type> <filename_base>
build-client-full <filename_base> [ cmd-opts ]
build-server-full <filename_base> [ cmd-opts ]
revoke <filename_base> [cmd-opts]
renew <filename_base> [cmd-opts]
build-serverClient-full <filename_base> [ cmd-opts ]
gen-crl
update-db
show-req <filename_base> [ cmd-opts ]
show-cert <filename_base> [ cmd-opts ]
show-ca [ cmd-opts ] #查看CA机构证书相关信息
import-req <request_file_path> <short_basename>
export-p7 <filename_base> [ cmd-opts ]
export-p8 <filename_base> [ cmd-opts ]
export-p12 <filename_base> [ cmd-opts ]
set-rsa-pass <filename_base> [ cmd-opts ]
set-ec-pass <filename_base> [ cmd-opts ]
。。。
#查看指定子命令帮助
[root@vpn-server easy-rsa]# ./easyrsa help build-ca
Note: using Easy-RSA configuration from: /etc/openvpn/easy-rsa/vars
build-ca [ cmd-opts ]
Creates a new CA
cmd-opts is an optional set of command options from this list:
nopass - do not encrypt the CA key (default is encrypted)
subca - create an intermediate CA keypair and request (default is a root CA)
intca - alias to the above
初始化证书目录
[root@vpn-server easy-rsa]# ./easyrsa init-pki
#在当前目录下创建了一个 pki 目录,用来存放证书文件
[root@vpn-server easy-rsa]# tree
.
├── easyrsa
├── openssl-easyrsa.cnf
├── pki
│ ├── openssl-easyrsa.cnf
│ ├── private
│ ├── reqs
│ └── safessl-easyrsa.cnf
├── vars
└── x509-types
├── ca
├── client
├── code-signing
├── COMMON
├── email
├── kdc
├── server
└── serverClient
-
自己给自己签发一个证书,使其成成CA机构
-
使用者发送证书申请文件给 CA机构
-
CA 机构签发证书,返还给申请者,
-
申请者在自己的服务器上部署证书
生成CA机构证书
#生成CA机构证书,不使用密码
[root@vpn-server easy-rsa]# ./easyrsa build-ca nopass
。。。
/etc/openvpn/easy-rsa/pki/ca.crt #新生成的CA自签名证书
配置OpenVPN服务器证书
生成证书申请文件
# server 表示文件前缀
[root@vpn-server easy-rsa]# ./easyrsa gen-req server nopass
。。。
Common Name (eg: your user, host, or server name) [server]:linux.jose-404.com #输入申请者信息
Keypair and certificate request completed. Your files are:
req: /etc/openvpn/easy-rsa/pki/reqs/server.req #证书申请文件
key: /etc/openvpn/easy-rsa/pki/private/server.key #私钥
#证书申请文件必须存在于reqs目录,以 .req 结尾的文件
#根据提交的申请颁发证书
#type 证书类型 client|server|serverClient|ca
#filename_base 申请文件路径,必须是在reqs目录以 .req结尾
颁发机构证书
#颁发机构证书,第一个 server 指证书类型,第二个server 指申请文件
[root@vpn-server easy-rsa]# ./easyrsa sign-req server server
。。。
Certificate created at: /etc/openvpn/easy-rsa/pki/issued/server.crt #CA机构根据申请文件签发的证书
#查看证书内容
[root@vpn-server easy-rsa]# file pki/issued/server.crt
pki/issued/server.crt: ASCII text
[root@vpn-server easy-rsa]# ./easyrsa show-cert server
#用 openssl 命令查看
[root@vpn-server easy-rsa]# openssl x509 -in pki/issued/server.crt -noout -text
#创建参数文件
[root@vpn-server easy-rsa]# ./easyrsa gen-dh
。。。
DH parameters of size 2048 created at /etc/openvpn/easy-rsa/pki/dh.pem
#用 openssl 命令也可以创建
openssl dhparam -out /etc/openvpn/dh2048.pem 2048
#查看
[root@vpn-server easy-rsa]# cat ./pki/dh.pem
配置OpenVPN客户端证书
客户端证书交由具体使用者作为登录 VPN 服务器的凭证,有效期不能太长
#修改配置文件,将证书有效时长改为180天
[root@vpn-server easy-rsa]# vim vars
#set_var EASYRSA_CERT_EXPIRE 825
set_var EASYRSA_CERT_EXPIRE 180
#生成客户证书申请文件
[root@vpn-server easy-rsa]# ./easyrsa gen-req tom nopass
。。。
Keypair and certificate request completed. Your files are:
req: /etc/openvpn/easy-rsa/pki/reqs/tom.req #证书申请文件
key: /etc/openvpn/easy-rsa/pki/private/tom.key #私钥
#签发客户端证书
[root@vpn-server easy-rsa]# ./easyrsa sign-req client tom
。。。
Certificate created at: /etc/openvpn/easy-rsa/pki/issued/tom.crt
#查看客户端证书
[root@vpn-server easy-rsa]# ./easyrsa show-cert tom
#openssl 命令查看
[root@vpn-server easy-rsa]# openssl x509 -in pki/issued/tom.crt -noout -text
整理目录
将 openVPN 服务端相关证书文件复制到 server 目录中
[root@vpn-server ~]# cp /etc/openvpn/easy-rsa/pki/ca.crt /etc/openvpn/server/
[root@vpn-server ~]# cp /etc/openvpn/easy-rsa/pki/issued/server.crt /etc/openvpn/server/
[root@vpn-server ~]# cp /etc/openvpn/easy-rsa/pki/private/server.key /etc/openvpn/server/
[root@vpn-server ~]# cp /etc/openvpn/easy-rsa/pki/dh.pem /etc/openvpn/server/
为客户端用户创建目录,并将相关文件放到指定目录
[root@vpn-server ~]# ls -lh /etc/openvpn/client/
total 0
[root@vpn-server ~]# mkdir /etc/openvpn/client/tom
[root@vpn-server ~]# cp /etc/openvpn/easy-rsa/pki/ca.crt /etc/openvpn/client/tom/
[root@vpn-server ~]# cp /etc/openvpn/easy-rsa/pki/private/tom.key /etc/openvpn/client/tom/
[root@vpn-server ~]# cp /etc/openvpn/easy-rsa/pki/issued/tom.crt /etc/openvpn/client/tom/
[root@vpn-server ~]# tree /etc/openvpn/client/
/etc/openvpn/client/
└── tom
├── ca.crt
├── tom.crt
└── tom.key
OpenVPN 服务端配置
服务端配置文件说明
配置文件默认不存在,需要手动创建
[root@vpn-server ~]# cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn
#配置文件中以 #开头或 ; 开头的都是注释
[root@vpn-server ~]# cd /etc/openvpn/
[root@vpn-server openvpn]# cat server.conf
#常用配置项
;local a.b.c.d #服务端监听的本机IP,默认所有IP
port 1194 #默认端口
;proto tcp #使用TCP协议,生产环境建议使用TCP协议
proto udp #默认使用UDP协议
;dev tap #创建以太网隧道设备,此设备操作的是第二层数据包
dev tun #创建IP路由隧道设备,此选项模拟的是网络层设备,其操作的是第三层的数据包,生产环境建议使用
;dev-node MyTap #TAP-Win32的设备驱动。非windows系统不需要
ca ca.crt #CA机构证书文件路径
cert server.crt #OpenVPN服务器证书文件路径
key server.key #OpenVPN服务器
dh dh2048.pem #DH参数文件
;topology subnet
server 10.8.0.0 255.255.255.0 #客户端连接后自动分配的IP网段,
#默认会给服务器分配此网段的第一个IP将做为客户端的网关,注意不要和内网网段相同
ifconfig-pool-persist ipp.txt #记录客户端和虚拟IP地址分配的文件
;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100 #配置网桥模式,无需配置,建议注释
;server-bridge
;push "route 192.168.10.0 255.255.255.0" #推送给客户端的到达服务器后面网段的静态路由,网关是服务器地址10.8.0.1
;push "route 192.168.20.0 255.255.255.0" #推送路由信息到客户端,以允许客户端能够连接到服务器背后的其它私有网络
;client-config-dir ccd #为特定客户端添加路由信息,此路由是客户端后面的网段而非服务端的网段,无需设置
;route 192.168.40.128 255.255.255.248
;client-config-dir ccd
;route 10.9.0.0 255.255.255.252
;learn-address ./script #指定外部脚本文件,实现创建不同组的iptables规则,无需配置
;push "redirect-gateway def1 bypass-dhcp" #启用此配置后客户端所有流量都将通过VPN服务器进行转发,因此生产一般无需配置此项
;push "dhcp-option DNS 208.67.222.222" #推送DNS服务器地址,无需配置
;push "dhcp-option DNS 208.67.220.220"
;client-to-client #允许不同的客户端直接通信,不安全,生产环境一般无需配置
;duplicate-cn #多用户共用一个证书,一般用于测试环境,生产环境建议一个用户一个证书
keepalive 10 120 #服务端活动的检测的间隔和超时时间,10秒ping一次,120S没有回应认为下线
tls-auth ta.key 0 #访止DoS等攻击的安全增强配置,服务器和每个客户端都需要拥有此密钥文件。
#第二个参数在服务器端为0,客户端为1
cipher AES-256-CBC #加密算法
;compress lz4-v2 #启用Openvpn2.4.X新版压缩算法
;push "compress lz4-v2" #推送客户端使用新版压缩算法,和下面的comp-lzo不要同时使用
;comp-lzo #旧户端兼容的压缩配置,需要客户端配置开启压缩,openvpn2.4.X等新版可以不用开
;max-clients 100 #最多支持的客户端数量
;user nobody #指定openvpn服务的用户
;group nobody #指定openvpn服务的组
persist-key #重启服务时默认会重新读取key文件,开启此配置后保持使用第一次的key文件,
#生产环境无需开启
persist-tun
status openvpn-status.log #服务器状态记录文件,每分钟记录一次相关信息
;log openvpn.log #日志记录模式,此项表示每次重启服务后重新生成日志
;log-append openvpn.log #日志记录模式,此项表示在原有日志后面追加verb 3 #日志级别,0-9,0 只记录错误
;mute 20 #对相同类别的信息只记录前20条到日志文件中
explicit-exit-notify 1 #当服务端重启后通知客户端自动重新连接服务器,此项配置仅能用于udp模式,
#tcp模式无需配置即能实现重新连接功能,
#且开启此项后tcp配置后将导致openvpn服务无法启动,所以tcp时必须不能开启此项
script-security 3 # 允许使用自定义脚本
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env #指定自定义脚本路径
username-as-common-name #开启用户密码验证
client-cert-not-required #只支持用户和密码方式验证,不支持证书,
#无此配置表示需要证书和用户密码多种验证
设置服务端配置文件
[root@vpn-server openvpn]# mv server.conf server.conf.bak
#新建配置文件
[root@vpn-server openvpn]# vim server.conf
port 1194
proto tcp
dev tun
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key
dh /etc/openvpn/server/dh.pem
server 10.8.0.0 255.255.255.0
push "route 172.30.0.0 255.255.255.0"
keepalive 10 120
cipher AES-256-CBC
compress lz4-v2
push "compress lz4-v2"
max-clients 2048
user root
group root
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
mute 20
[root@vpn-server openvpn]# ls
client easy-rsa server server.conf server.conf.bak update-resolv-conf
查看日志目录
[root@vpn-server ~]# ll /var/log/openvpn/ -d
drwxr-xr-x 2 root root 4096 Jul 14 2024 /var/log/openvpn//
[root@vpn-server ~]# tree /var/log/openvpn/
/var/log/openvpn/
启动服务并查看状态
#如果初始状态起不来,enable 一下
[root@vpn-server ~]# systemctl enable --now openvpn.service
[root@vpn-server ~]# systemctl is-active openvpn.service
active
#重启一下
[root@vpn-server ~]# systemctl restart openvpn.service
#查看端口,监听了TCP的1194
#在公有云上要在安全组中放行1194端口,如果有防火墙,也要放行1194
[root@vpn-server ~]# ss -tnlp | grep 1194
LISTEN 0 32 0.0.0.0:1194 0.0.0.0:* users:(("openvpn",pid=26183,fd=6))
#查看日志
[root@vpn-server ~]# ls -lh /var/log/openvpn/
#查看网卡,多了一个tun0 设备,这是一个点对点的设备
71: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel
state UNKNOWN group default qlen 500
link/none
inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::9bb:caa:7358:70b7/64 scope link stable-privacy
valid_lft forever preferred_lft forever
OpenVPN 客户端配置
客户端配置文件说明
[root@vpn-server ~]# cat /usr/share/doc/openvpn/examples/sample-configfiles/client.conf | grep -Ev "^#|^$"
client #指明客户端
;dev tap #客户端隧道设备类型,要求和服务端保持一致
dev tun #同上
;dev-node MyTap #TAP-Win32的设备驱动。非windows系统不需要
;proto tcp #协议类型,要求和服务端保持一致
proto udp #同上
remote my-server-1 1194 #服务端 IP/域名 端口
;remote my-server-2 1194 #服务端 IP/域名 端口
;remote-random #从主机列表中随机选择服务端主机进行连接
resolv-retry infinite #指定服务器端FQDN而非IP时,当客户端重新连接后会重新解FQDN对应的IP
nobind #客户端不绑定监听端口,随机打开端口连接到服务端的端口
;user nobody #属主
;group nobody #属组
persist-key #重新连接时使用原来加载的key
persist-tun #重新连接时使用原来加载的隧道
;http-proxy-retry #代理连接失败是否重试
;http-proxy [proxy server] [proxy port #] #是否启用客户端代理,如果启此,此处填写代理服务器IP和端口
;mute-replay-warnings #取消重复数据包告警
ca ca.crt #CA机构证书
cert client.crt #客户端证书
key client.key #客户端证书私钥
remote-cert-tls server #使用服务器证书校验方式
tls-auth ta.key 1 #安全加强
cipher AES-256-CBC #加密算法
verb 3 #日志级别
;mute 20 #同类型日志只记录前20条
为用户设置配置文件
[root@openvpn-server openvpn]# vim client/tom/client.ovpn
client
dev tun
proto tcp
remote 47.93.28.236 1194 #生产中为OpenVPN服务器的FQDN或者公网IP
resolv-retry infinite
nobind
#persist-key
#persist-tun
ca ca.crt
cert tom.crt
key tom.key
remote-cert-tls server
#tls-auth ta.key 1
cipher AES-256-CBC
verb 3 #此值不能随意指定,否则无法通信
compress lz4-v2 #此项在OpenVPN2.4.X版本使用,需要和服务器端保持一致,如不指定,默认使用comp-lz压缩
[root@vpn-server openvpn]# tree client/
client/
└── tom
├── ca.crt
├── client.ovpn
├── tom.crt
└── tom.key
remote 项对应的服务端IP可以写成域名,将域名解析到对应的IP即可,这样即使以后服务端IP发生了变 化,也只需要修改域名解析,而不用修改此处的配置文件。
部署 OpenVPN 客户端
部署 Windows 客户端
下载
https://openvpn.net/community-downloads/
下载后在Windows 中完成安装
将客户端配置下载到 windows 中,将相关文件放到 C:\Program Files\OpenVPN\config 目录下
[root@vpn-server openvpn]# cd client/
[root@vpn-server openvpn]# tar zcvf tom.tar.gz tom/
tom/
tom/tom.key
tom/tom.crt
tom/ca.crt
tom/client.ovpn
[root@vpn-server openvpn]# sz tom.tar.gz
解压缩到 windows 中的C:\Program Files\OpenVPN\config目录
查看此时windows主机上的IP
C:\Program Files\OpenVPN\config>ipconfig
Windows IP 配置
未知适配器 OpenVPN Wintun:
媒体状态 . . . . . . . . . . . . : 媒体已断开连接
连接特定的 DNS 后缀 . . . . . . . :
未知适配器 OpenVPN TAP-Windows6:
媒体状态 . . . . . . . . . . . . : 媒体已断开连接
连接特定的 DNS 后缀 . . . . . . . :
在Windows 桌面上找到 OpenVPN 图标,以管理员身份运行连接成功后,在Windows 主机的右下角 会出现绿色图标
再次查看windows主机上的IP
C:\Program Files\OpenVPN\config>ipconfig
Windows IP 配置
未知适配器 OpenVPN Wintun:
媒体状态 . . . . . . . . . . . . : 媒体已断开连接
连接特定的 DNS 后缀 . . . . . . . :
未知适配器 OpenVPN TAP-Windows6:
连接特定的 DNS 后缀 . . . . . . . :
本地链接 IPv6 地址. . . . . . . . : fe80::c145:9efe:8e72:7b76%22
IPv4 地址 . . . . . . . . . . . . : 10.8.0.6
子网掩码 . . . . . . . . . . . . : 255.255.255.252
默认网关. . . . . . . . . . . . . :
可以看到,此时windows主机多出来了一个 10.8.0.6 的IP地址,而且生成了一条指向指向 172.30.0.0/255.255.255.0的路由记录。
PS C:\WINDOWS\system32> route print -4 |findstr 172.30
172.30.0.0 255.255.255.0 10.8.0.5 10.8.0.6 281
该路由记录是从OpenVPN服务端推送过来的
[root@vpn-server ~]# cat /etc/openvpn/server.conf | grep route
push "route 172.30.0.0 255.255.255.0"
查看服务端连接状态
[root@vpn-server ~]# ss -tnp | grep openvpn
ESTAB 0 0 172.30.0.66:1194 115.171.61.106:4497 users:(("openvpn",pid=26183,fd=8))
客户端测试,此时无法ping 通 OpenVPN 服务器后端内网主机,但可以 ping 通 OpenVPN 服务器
配置后端主机转发
当前客户端主机还是无法连通后端内网主机
OpenVPN 服务端开启 ip_forward 转发
[root@vpn-server ~]# echo net.ipv4.ip_forward = 1 >> /etc/sysctl.conf
[root@vpn-server ~]# sysctl -p
[root@vpn-server ~]# sysctl -p | grep ip_forward
net.ipv4.ip_forward = 1
还是无法ping通,server 主机只有来,没有回。后端主机有来有回。因为后端主机没有可达 10.8.0.6 主机的路由,会交给默认路由。
在OpenVPN server 主机上设置 SNAT 转发,将从 10.8.0.0/24 网段主机请求的源IP转换成本机 IP(172.30.0.66)
[root@vpn-server ~]# iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
#或者是这一句
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to-source 172.30.0.66
再次测试,可以ping通,后端内网主机收到的请求己经变成了源地址是 172.30.0.66 了
将 OpenVPN server 主机的 iptables 规则设置为开机加载,保证重启后有效
[root@vpn-server ~]# echo 'iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE' >> /etc/rc.d/rc.local
[root@vpn-server ~]# chmod a+x /etc/rc.d/rc.local
[root@vpn-server ~]# ll /etc/rc.d/rc.local
-rwxr-xr-x. 1 root root 550 Feb 25 21:17 /etc/rc.d/rc.local
除了在 OpenVPN server 主机上配置 SNAT 规则之外,也可以修改后端主机的网关,将 10.8.0.0/24 网 段的网关指向 172.30.0.66
此方法理论可行,但在此处不行,因为我们设置的是点对点网络,后端主机并不是处于 OpenVPN 的客 户端角色,所以在配置了网关的基础上,也无法使用 OpenVPN 的相关功能
OpenVPN 管理
OpenVPN 的管理功能主要关于安全加强及客户端的证书管理,用户密码验证等
启用安全增强功能
服务端配置
[root@vpn-server ~]# openvpn --genkey --secret /etc/openvpn/server/ta.key
#修改服务端配置文件
[root@vpn-server ~]# vim /etc/openvpn/server.conf
tls-auth /etc/openvpn/server/ta.key 0 #增加此行,服务端后面要跟数字0,客户端后面数字是1
#重启服务端,客户端会断开连接,小图标会变成黄色
[root@vpn-server ~]# systemctl restart openvpn.service
客户端配置
#将key文件下载到本地,到到 C:\Program Files\OpenVPN\config 目录下
[root@vpn-server ~]# sz /etc/openvpn/server/ta.key
#修改客户端配置文件 C:\Program Files\OpenVPN\config\client.ovpn
#新增此行
tls-auth ta.key 1
#客户端重新连接即可
设置客户端私钥密码
新建一个用户 user1,并设置证书密码,以提高安全性
[root@vpn-server ~]# cd /etc/openvpn/easy-rsa/
#创建私钥,并生成证书申请文件
[root@vpn-server easy-rsa]# ./easyrsa gen-req user1
...
Enter PEM pass phrase: #输入密码
Verifying - Enter PEM pass phrase: #确认密码
...
req: /etc/openvpn/easy-rsa/pki/reqs/user1.req #证书申请文件
key: /etc/openvpn/easy-rsa/pki/private/user1.key #私钥
#签发证书
[root@vpn-server easy-rsa]# ./easyrsa sign client user1
...
Certificate created at: /etc/openvpn/easy-rsa/pki/issued/user1.crt
#查看证书索引
[root@vpn-server easy-rsa]# cat pki/index.txt
V 231223082036Z AA0AEB6839B1BCD84A2E7F82534145FA unknown /CN=tom
V 231223084540Z C8D637BF838167BAF6528F9DC8DB8786 unknown /CN=user1
#配置客户端
[root@vpn-server easy-rsa]# cd /etc/openvpn/client/
[root@vpn-server client]# mkdir user1
[root@vpn-server client]# cp /etc/openvpn/easy-rsa/pki/private/user1.key ./user1/ #用户私钥
[root@vpn-server client]# cp /etc/openvpn/easy-rsa/pki/issued/user1.crt ./user1/ #用户证书
[root@vpn-server client]# cp /etc/openvpn/server/ca.crt ./user1/ #CA证书
[root@vpn-server client]# cp /etc/openvpn/server/ta.key ./user1/ #ta
#生成客户端配置文件
[root@vpn-server client]# vim user1/client.ovpn
client
dev tun
proto tcp
remote 47.93.28.236 1194
resolv-retry infinite
nobind
#persist-key
#persist-tun
ca ca.crt
cert user1.crt
key user1.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-CBC
verb 3
compress lz4-v2
[root@vpn-server client]# ls user1/
ca.crt client.ovpn user1.crt user1.key ta.key
#打包,并下载到 windows 主机
[root@vpn-server client]# tar zcvf user1.tar.gz user1/
user1/
user1/ca.crt
user1/client.ovpn
user1/ta.key
user1/user1.crt
user1/user1.key
将客户端配置下载到 windows 主机中,放到 OpenVPN config 目录中,再次使用客户端连接,要求输 入密码
连接成功后,客户端IP发生了变化
账户证书管理
对于客户端使用者的变更,以及时间的推移,都会涉及到证书的创建和吊销
证书自动过期
每一份己签发的证书都有时期,超过时间节点后会自动过期
#证书时效配置
[root@openvpn-server ~]# grep EASYRSA_CERT_EXPIRE /etc/openvpn/easy-rsa/vars
set_var EASYRSA_CERT_EXPIRE 180
#在服务端证书索引文件中查看每个证书的过期时间,该时间是UTC时间
[root@openvpn-server ~]# cat /etc/openvpn/easy-rsa/pki/index.txt
手动吊销证书
#查看证书状态,V表示有效
[root@vpn-server easy-rsa]# cat pki/index.txt
V 231223082036Z AA0AEB6839B1BCD84A2E7F82534145FA unknown /CN=tom
V 231223084540Z C8D637BF838167BAF6528F9DC8DB8786 unknown /CN=user1
#吊销指定证书
[root@openvpn-server ~]# cd /etc/openvpn/easy-rsa/
[root@openvpn-server easy-rsa]# ./easyrsa revoke user1
#再次查看索引文件,R 表示被吊销
[root@vpn-server easy-rsa]# cat pki/index.txt
V 231223082036Z AA0AEB6839B1BCD84A2E7F82534145FA unknown /CN=tom
R 231223084540Z C8D637BF838167BAF6528F9DC8DB8786 unknown /CN=user1
#此时证书虽然被吊销,但客户端还是能使用
此时证书虽然被吊销,但客户端还是能使用,还需要在证书吊销列表文件中指定被吊销的证书,并且需 要在 OpenVPN 服务端配置文件中指定证书吊销列表文件路径,然后再重启 OpenVPN服务
#每次吊销证书后都需要更新证书吊销列表文件,并且需要重启OpenVPN服务
#更新证书吊销列表文件
[root@openvpn-server easy-rsa]# ./easyrsa gen-crl
...
CRL file: /etc/openvpn/easy-rsa/pki/crl.pem
#修改服务端配置,指定证书吊销列表文件路径
[root@openvpn-server ~]# vim /etc/openvpn/server.conf
#新增此行
crl-verify /etc/openvpn/easy-rsa/pki/crl.pem
#重启服务
[root@openvpn-server ~]# systemctl restart openvpn@server.service
客户端连接失败,查看服务端日志,提示证书被吊销
重名账户签发新证书
对于新的重名用户,可以删除不再使用的重名用户证书,再签发新证书,或者换一个用户名签发证书即 可
实现客户端用户名密码验证
在证书的基础上可以再新增用户名密码校验,以提高安全性
修改服务端配置
#添加三行
[root@openvpn-server ~]# vim /etc/openvpn/server.conf
script-security 3 #允许使用自定义脚本
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env #指定自定义脚本路径
username-as-common-name #开启用户密码验证
#准备脚本
[root@openvpn-server ~]# cd /etc/openvpn/
[root@openvpn-server openvpn]# vim checkpsw.sh
#!/bin/sh
###########################################################
# checkpsw.sh (C) 2004 Mathias Sundman <mathias@openvpn.se>
#
# This script will authenticate OpenVPN users against
# a plain text file. The passfile should simply contain
# one row per user with the username first followed by
# one or more space(s) or tab(s) and then the password.
PASSFILE="/etc/openvpn/psw-file"
#LOG_FILE="/var/log/openvpn-password.log" #修改此处
LOG_FILE="/var/log/openvpn/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
#加可执行权限
[root@openvpn-server openvpn]# chmod a+x checkpsw.sh
#创建用户名和密码文件
[root@openvpn-server openvpn]# cat /etc/openvpn/psw-file
user1 123456
user2 654321
#重启服务
[root@openvpn-server openvpn]# systemctl restart openvpn.service
修改客户端配置文件
#在client.ovpn 中加上如下行
auth-user-pass
客户端测试,连接时需要输入用户名密码,输入 user1/123456 或 user2/654321 都可以连接
部署 Linux 客户端
#安装客户端
[root@rocky86 ~]# yum install -y openvpn
[root@rocky86 ~]# tree /etc/openvpn/
/etc/openvpn/
├── client
└── server
#从服务端下载远程用户配置
[root@openvpn-server ~]# tree /etc/openvpn/client/user1/
/etc/openvpn/client/user1/
├── ca.crt
├── client.ovpn
├── user1.crt
└── user1.key
#将配置文件放到 Linux 客户端主机上
[root@rocky86 ~]# tree /etc/openvpn/client/
/etc/openvpn/client/
├── ca.crt
├── client.ovpn
├── user1.crt
├── user1.key
└── ta.key #此处不能少
#启动客户端,提示输入用户名密码
[root@rocky86 ~]# openvpn --daemon --cd /etc/openvpn/client --config client.ovpn
--log-append /var/log/openvpn.log
Enter Auth Username: user1
Enter Auth Password: ******