此法用于多个客户端通过OpenVPN服务器实现内网访问
OpenVPN服务器操作系统Amazon Linux 2 AMI (HVM) - Kernel 5.10
OpenVPN版本
2.4.11
easy-rsa版本
3.0.6
使用tun模式
openvpn客户端IP地址池
10.8.0.0/24
多个客户端直接可以通过OpenVPN实现内网通信
内网IP地址池
10.11.0.0/16
Server端
安装openvpn
$ sudo amazon-linux-extras install epel -y
$ sudo yum install -y epel-release
$ sudo yum update -y
$ sudo yum install -y openssl lzo pam openssl-devel lzo-devel pam-devel easy-rsa openvpn
# check openvpn版本
[ec2-user@ip-10-11-241-70 ~]$ openvpn --version
OpenVPN 2.4.11 x86_64-redhat-linux-gnu [Fedora EPEL patched] [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Apr 21 2021
library versions: OpenSSL 1.0.2k-fips 26 Jan 2017, LZO 2.06
Originally developed by James Yonan
Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
Compile time defines: enable_async_push=no enable_comp_stub=no enable_crypto=yes enable_crypto_ofb_cfb=yes enable_debug=yes enable_def_auth=yes enable_dependency_tracking=no enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown enable_fast_install=yes enable_fragment=yes enable_iproute2=yes enable_libtool_lock=yes enable_lz4=yes enable_lzo=yes enable_management=yes enable_multihome=yes enable_pam_dlopen=no enable_pedantic=no enable_pf=yes enable_pkcs11=yes enable_plugin_auth_pam=yes enable_plugin_down_root=yes enable_plugins=yes enable_port_share=yes enable_selinux=yes enable_server=yes enable_shared=yes enable_shared_with_static_runtimes=no enable_small=no enable_static=yes enable_strict=no enable_strict_options=no enable_systemd=yes enable_werror=no enable_win32_dll=yes enable_x509_alt_username=yes with_aix_soname=aix with_crypto_library=openssl with_gnu_ld=yes with_mem_check=no with_sysroot=no
系统初始化
修改limits参数
sudo su
cat > /etc/security/limits.d/99-centos.conf <<EOF
* - nproc 1048576
* - nofile 1048576
EOF
修改sysctl参数
cat > /etc/sysctl.conf <<EOF
# 二层的网桥在转发包时也会被iptables的FORWARD规则所过滤
net.bridge.bridge-nf-call-arptables=1
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
# 关闭严格校验数据包的反向路径,默认值1
net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.all.rp_filter=0
# 设置 conntrack 的上限
net.netfilter.nf_conntrack_max=1048576
# 端口最大的监听队列的长度
net.core.somaxconn=21644
# TCP阻塞控制算法BBR,Linux内核版本4.9开始内置BBR算法
#net.ipv4.tcp_congestion_control=bbr
#net.core.default_qdisc=fq
# 打开ipv4数据包转发
net.ipv4.ip_forward=1
# TCP FastOpen
# 0:关闭 ; 1:作为客户端时使用 ; 2:作为服务器端时使用 ; 3:无论作为客户端还是服务器端都使用
net.ipv4.tcp_fastopen=3
EOF
sysctl -p
创建配置过程中需要使用的目录
# 创建日志存放目录:
mkdir -p /etc/openvpn/server/
# 创建用户管理目录:
mkdir -p /etc/openvpn/server/user
# 配置目录权限:
chown openvpn:openvpn /etc/openvpn/server
配置openvpn
生成证书
通过yum方式安装的easy-rsa是3.x版本,可直接从安装目录中拷贝一份工具到/etc/openvpn中
cp -rf /usr/share/easy-rsa/3.0.8 /etc/openvpn/server/easy-rsa
easy-rsa初始化
cd /etc/openvpn/server/easy-rsa
# 使用命令./easyrsa init-pki进行初始化,会在当前目录创建PKI目录,用来存储一些中间变量和最终生成的证书
./easyrsa init-pki
正式制作CA证书
记住,一定要添加密码
cd /etc/openvpn/server/easy-rsa
./easyrsa build-ca
配置Server端证书:
nopass表示不加密私钥文件,生成过程中直接回车默认
cd /etc/openvpn/server/easy-rsa
./easyrsa gen-req server nopass
Server证书签名:
在一个details得添加yes,这个连接ca证书,输入密码。
cd /etc/openvpn/server/easy-rsa
./easyrsa sign server server
创建Diffie-Hellman文件
秘钥交换时的Diffie-Hellman算法。
cd /etc/openvpn/server/easy-rsa
./easyrsa gen-dh
创建ta.key
为了提高OpenVPN
的安全性,可以创建ta.key
:openvpn --genkey --secret ta.key
,能够加强认证方式,防止攻击。
cd /etc/openvpn/server/easy-rsa
openvpn --genkey --secret ta.key
整理服务器端证书:
cd /etc/openvpn/server/easy-rsa
cp -a pki/ca.crt /etc/openvpn/server/
cp -a pki/private/server.key /etc/openvpn/server
cp -a pki/issued/server.crt /etc/openvpn/server
cp -a pki/dh.pem /etc/openvpn/server
cp -a ta.key /etc/openvpn/server
编辑配置文件
拷贝sample.conf到/etc/openvpn作为起始配置文件
cp /usr/share/doc/openvpn-*/sample/sample-config-files/server.conf /etc/openvpn/server
使用vi /etc/openvpn/server/server.conf命令编辑配置文件
将25行修改为:local 0.0.0.0
注释35行注释,修改效果:; proto tcp
取消注释36行,修改效果:proto udp
修改79行,设置ca.crt的路径:ca /etc/openvpn/server/ca.crt
修改80行,设置server.crt的路径:cert /etc/openvpn/server/server.crt
修改81行,设置server.key的路径:key /etc/openvpn/server/server.key
修改86行,设置dh的路径:dh /etc/openvpn/server/dh.pem
修改142行,设置vpc地址池:push "route 10.11.0.0 255.255.255.0"
修改245行:tls-auth /etc/openvpn/server/ta.key 0
取消257行注释,修改效果:compress lz4-v2
取消258行注释,修改效果:push "compress lz4-v2"
取消275行注释,修改效果: user nobody
取消2765行注释,修改效果: group nobody
添加SNAT访问内网
- 让
10.8.0.0/24
(openvpn客户端地址无需修改)访问10.11.0.0/16
(需要修改为vpc地址池)的时候做SNAT, {{OPENVPN_SERVER_IP}}改成OpenVPN服务器的内网地址。例如:10.11.1.1
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -d 10.11.0.0/16 -j SNAT --to-source {{OPENVPN_SERVER_IP}}
# iptables 规则持久化保存
iptables-save > /etc/sysconfig/iptables
# 启动加载iptables配置
cat > /etc/rc.local <<EOF
iptables-restore < /etc/sysconfig/iptables
EOF
chmod +x /etc/rc.d/rc.local
# 规则查看
iptables -nvL -t nat
Chain POSTROUTING (policy ACCEPT 10 packets, 620 bytes)
pkts bytes target prot opt in out source destination
7 448 SNAT all -- * * 10.8.0.0/24 10.11.0.0/16 to:{{OPENVPN_SERVER_IP}}
启动OpenVPN并配置开机启动
$ cp /usr/lib/systemd/system/openvpn-server\@.service /usr/lib/systemd/system/openvpn-server.service
$ sed -i 's/%i/server/g' /usr/lib/systemd/system/openvpn-server.service
# check
$ cat /usr/lib/systemd/system/openvpn-server.service
[Unit]
Description=OpenVPN service for %I
After=syslog.target network-online.target
Wants=network-online.target
Documentation=man:openvpn(8)
Documentation=https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
Documentation=https://community.openvpn.net/openvpn/wiki/HOWTO
[Service]
Type=notify
PrivateTmp=true
WorkingDirectory=/etc/openvpn/server
ExecStart=/usr/sbin/openvpn --status %t/openvpn-server/status-server.log --status-version 2 --suppress-timestamps --config server.conf
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_DAC_OVERRIDE CAP_AUDIT_WRITE
LimitNPROC=10
DeviceAllow=/dev/null rw
DeviceAllow=/dev/net/tun rw
ProtectSystem=true
ProtectHome=true
KillMode=process
RestartSec=5s
Restart=on-failure
[Install]
WantedBy=multi-user.target
$ systemctl daemon-reload
# 启动OpenVPN
$ systemctl start openvpn-server
# 配置OpenVPN开机启动
$ systemctl enable openvpn-server
Client端
为客户端创建证书
生成无密码的客户端证书:./easyrsa build-client-full client nopass
生成带密码的客户端证书:./easyrsa build-client-full sam,会提示让你输入密码,记住设置的密码,在连接OpenVPN服务端时会使用,可多次操作该步骤为多个用户创建证书
客户端配置
从/etc/openvpn/server/easy-rsa拷贝ta.key文件
从/etc/openvpn/server/easy-rsa/pki/private拷贝客户端的.key文件,例如:sam.key
从/etc/openvpn/server/easy-rsa/pki/issued拷贝客户端的.crt文件,例如:sam.crt
从/etc/openvpn/server/easy-rsa/pki拷贝客户端的ca.crt文件
Windows系统安装OpenVPN客户端后,打开配置文件夹(默认是:C:\Program Files\OpenVPN\config),新建文件夹(例如:client),拷贝前面4个文件到新建的文件夹
在第5步新建的文件夹中,创建client.ovpn文件(文件名和文件夹名称一致),配置内容如下,其中sam.crt、sam.key替换成对应的文件名
scp ec2-user@xxx.xxx.xxx.xxx:/etc/openvpn/server/easy-rsa/ta.key ./Documents/openvpn/
scp ec2-user@xxx.xxx.xxx.xxx:/etc/openvpn/server/easy-rsa/pki/private/sam.key ./Documents/openvpn/
scp ec2-user@xxx.xxx.xxx.xxx:/etc/openvpn/server/easy-rsa/pki/issued/sam.crt ./Documents/openvpn/
scp ec2-user@xxx.xxx.xxx.xxx:/etc/openvpn/server/easy-rsa/pki/ca.crt ./Documents/openvpn/
vim ./Documents/openvpn/nx.ovpn
client
dev tun
proto udp
remote xxx.xxx.xxx.xxx 1194
resolv-retry infinite
nobind
;user nobody
;group nobody
persist-key
persist-tun
ca ca.crt
cert sam.crt
key sam.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-CBC
compress lz4-v2
verb 3
;mute 20
用户管理
创建 open VPN 用户脚本
初始化客户端openvpn配置
vim /etc/openvpn/client/sample.ovpn
client
dev tun
proto udp
remote {{替换为openvpn服务器的外网IP地址}} 1194
resolv-retry infinite
nobind
;user nobody
;group nobody
persist-key
persist-tun
ca ca.crt
cert admin.crt
key admin.key
remote-cert-tls server
tls-auth ta.key 1
cipher AES-256-CBC
compress lz4-v2
verb 3
;mute 20
创建用户脚本
vim /etc/openvpn/server/create_vpn_user.sh
#!/bin/bash
# example sh create_vpn_user.sh test1
set -e
OVPN_USER_KEYS_DIR=/etc/openvpn/client/keys
EASY_RSA_DIR=/etc/openvpn/server/easy-rsa/
PKI_DIR=$EASY_RSA_DIR/pki
mkdir /etc/openvpn/client/keys -p
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
# 生成客户端 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/ta.key $OVPN_USER_KEYS_DIR/$user/ta.key # auth-tls 文件
cd $OVPN_USER_KEYS_DIR
zip -r $user.zip $user
chown 1000.1000 $user.zip
echo "create $user finish, /etc/openvpn/client/keys/$user.zip "
done
执行上面脚本创建一个用户:
sh /etc/openvpn/server/create_vpn_user.sh username
查看文件
cd /etc/openvpn/client/keys/username
.
├── ca.crt
├── username.crt
├── username.key
├── username.ovpn
└── ta.key
删除一个 OpenVPN 用户
上面介绍了如何添加一个用户,如果公司员工离职了或者其他原因,想删除对应用户 OpenVPN 的使用权,只要吊销对应用户的 SSL 证书即可。因为OpenVPN 的客户端和服务端的认证主要通过 SSL 证书进行双向认证。
编辑 OpenVPN 服务端配置 server.conf 添加如下配置:
注意: 增加此行后才可删除用户,次行配置放到配置文件第一行。
cd /etc/openvpn/server/easy-rsa/
# 变量控制多久过期,过期后所有用户将无法登入
EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
cp ./pki/crl.pem /etc/openvpn/server/crl.pem
chmod 666 /etc/openvpn/server/crl.pem
cat >> /etc/openvpn/server/server.conf <<EOF
crl-verify /etc/openvpn/server/crl.pem
EOF
systemctl restart openvpn-server
吊销用户证书
cd /etc/openvpn/server/easy-rsa/
./easyrsa revoke username
systemctl restart openvpn-server
重启 OpenVPN 服务端使其生效
systemctl restart openvpn-server
一键删除用户
vim /etc/openvpn/server/delete_vpn_user.sh
#!/bin/bash
# example sh delete_vpn_user.sh test1
set -e
OVPN_USER_KEYS_DIR=/etc/openvpn/client/keys
EASY_RSA_DIR=/etc/openvpn/server/easy-rsa/
for user in "$@"
do
cd ${EASY_RSA_DIR}
echo -e 'yes\n' | ./easyrsa revoke $user
EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
cp ./pki/crl.pem ../crl.pem
chmod 666 ../crl.pem
# 吊销掉证书后清理客户端相关文件
if [ -d "$OVPN_USER_KEYS_DIR/$user" ]; then
rm -rf $OVPN_USER_KEYS_DIR/${user}*
fi
systemctl restart openvpn-server
done
执行上面脚本删除一个用户:
sh /etc/openvpn/server/delete_vpn_user.sh username
上述配置完成了用户流量的分配,必要的地址都vpn,其余的走正常的自己的网络。不会全部走vpn。
参考资料
openvpn配置文件详解
# 监听地址
#local 0.0.0.0
# 监听端口
port 51194
# 通信协议
proto tcp
# TUN模式还是TAP模式
dev tap
# 证书
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/openvpn-server.crt
key /etc/openvpn/pki/openvpn-server.key
dh /etc/openvpn/pki/dh.pem
crl-verify /etc/openvpn/pki/crl.pem
# 禁用OpenVPN自定义缓冲区大小,由操作系统控制
sndbuf 0
rcvbuf 0
# TLS rules “client” | “server”
#remote-cert-tls "client"
# TLS认证
tls-auth /etc/openvpn/pki/ta.key
# TLS最小版本
#tls-version-min "1.2"
# 重新协商数据交换的key,默认3600
#reneg-sec 3600
# 在此文件中维护客户端与虚拟IP地址之间的关联记录
# 如果OpenVPN重启,重新连接的客户端可以被分配到先前分配的虚拟IP地址
ifconfig-pool-persist /etc/openvpn/ipp.txt
# 配置client配置文件
client-config-dir /etc/openvpn/client/config
# 该网段为 open VPN 虚拟网卡网段,不要和内网网段冲突即可。
server 10.8.0.0 255.255.255.0
# 配置网桥模式,需要在OpenVPN服务添加启动关闭脚本,将tap设备桥接到物理网口
# 假定内网地址为192.168.0.0/24,内网网关是192.168.0.1
# 分配192.168.0.200-250给VPN使用
#server-bridge 192.168.0.1 255.255.255.0 192.168.0.200 192.168.0.250
# 给客户端推送自定义路由
#push "route 192.168.0.0 255.255.255.0"
# 所有客户端的默认网关都将重定向到VPN
#push "redirect-gateway def1 bypass-dhcp"
# 向客户端推送DNS配置
#push "dhcp-option DNS 223.5.5.5"
#push "dhcp-option DNS 223.6.6.6"
# 允许客户端之间互相访问
client-to-client
# 限制最大客户端数量
#max-clients 10
# 客户端连接时运行脚本
#client-connect ovpns.script
# 客户端断开连接时运行脚本
#client-disconnect ovpns.script
# 保持连接时间
keepalive 20 120
# 开启vpn压缩
comp-lzo
# 允许多人使用同一个证书连接VPN,不建议使用,注释状态
#duplicate-cn
# 运行用户
user openvpn
#运行组
group openvpn
# 持久化选项可以尽量避免访问那些在重启之后由于用户权限降低而无法访问的某些资源
persist-key
persist-tun
# 显示当前的连接状态
status /var/log/openvpn/openvpn-status.log
# 日志路径,不指定文件路径时输出到控制台
# log代表每次启动时清空日志文件
#log /var/log/openvpn/openvpn.log
# log-append代表追加写入到日志文件
#log-append /var/log/openvpn/openvpn.log
# 日志级别
verb 4
# 忽略过多的重复信息,相同类别的信息只有前20条会输出到日志文件中
mute 20
查看哪些证书被吊销
cd /etc/openvpn/server/easy-rsa/pki/
openssl crl -in crl.pem -text -noout
Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: /CN=Easy-RSA CA
Last Update: Mar 28 05:30:57 2022 GMT
Next Update: Sep 24 05:30:57 2022 GMT
CRL extensions:
X509v3 Authority Key Identifier:
keyid:C2:6C:60:11:42:D2:91:B3:22:4E:44:FF:E9:31:FB:75:E9:00:AF:27
DirName:/CN=Easy-RSA CA
serial:E3:FD:F0:EF:25:BA:35:06
Revoked Certificates:
Serial Number: 519811768EE8EE7968FA2A5F31EA7DB0
Revocation Date: Mar 28 04:59:46 2022 GMT
Serial Number: 58F9DDFE1F73C82AD9D10F80CBAD90D4
Revocation Date: Mar 28 05:22:44 2022 GMT
Serial Number: A61A0F093E5C49A02129EF4F69655FA1
Revocation Date: Mar 28 05:28:31 2022 GMT
Serial Number: B03350B71C3D540A435D57C583AE0CB4
Revocation Date: Mar 28 04:39:06 2022 GMT
Signature Algorithm: sha256WithRSAEncryption
0c:f2:42:3e:66:88:bf:95:49:76:39:3c:18:7c:c0:d7:3d:9e:
47:0c:93:7b:4c:fa:72:21:35:1a:ef:43:68:eb:3e:e2:05:b8:
82:d6:1b:74:df:f7:50:63:d5:db:3e:8f:e4:8b:96:48:6a:6a:
fc:f5:d8:d6:3f:13:6f:c3:d8:09:48:1f:1d:c6:55:77:42:96:
1c:92:dd:73:a2:5a:61:d2:d1:b0:d0:0b:53:d5:48:d1:2f:b9:
02:68:9b:1c:d6:12:75:f0:b3:a0:b5:68:96:78:4b:3b:40:a8:
67:a3:b9:6f:e4:c8:a3:d7:3a:d2:f6:86:ce:71:5c:1e:ea:6a:
6e:08:9a:11:39:8b:6b:8e:59:75:94:04:27:e1:21:4a:a4:ab:
2f:a8:70:13:09:5f:1d:72:b9:91:85:9d:b3:de:d0:16:c6:68:
fa:c1:55:2b:d2:6a:cd:63:4e:35:05:de:59:02:bc:01:fb:82:
42:0a:cf:93:95:25:75:91:7c:2b:9e:bc:6f:7b:94:cb:bf:16:
47:92:ef:a2:dd:8f:77:5b:2b:c2:23:3a:a8:ea:9f:55:17:00:
26:ba:94:62:10:e9:c2:a8:81:c7:e2:18:54:fa:78:ca:ad:6c:
95:f3:8a:0c:c1:61:11:20:2f:4e:b1:08:78:64:a3:e1:cc:a3:
74:58:96:40
可理解为openvpn客户端的数据库
所有生成的openvpn客户端证书记录(可用、吊销)
文件中通过第一列标志识别是否为注销状态
V为可用
R为注销
cat index.txt
V 240627100023Z CD4088802AF18E10BECD74AA2E94231D unknown /CN=server
R 240630032853Z 220328043906Z B03350B71C3D540A435D57C583AE0CB4 unknown /CN=sam-bj
R 240630044040Z 220328045946Z 519811768EE8EE7968FA2A5F31EA7DB0 unknown /CN=sam-bj
R 240630052053Z 220328052244Z 58F9DDFE1F73C82AD9D10F80CBAD90D4 unknown /CN=sam-test1
R 240630052802Z 220328052831Z A61A0F093E5C49A02129EF4F69655FA1 unknown /CN=sam-test2