部署OpenConnect VPN Server
前言-配置说明
- 基础系统为ubuntu 24.04环境;
- OpenConnect使用1.2.4版本;
- GnuTLS version: 3.8.3;
1.服务器基础环境部署及升级
1.1. 配置登录用户及证书登录
sudo useradd alan
sudo mkdir /home/alan
sudo chown alan:alan /home/alan
sudo usermod -s /bin/bash alan
adduser alan sudo
echo "alan ALL=NOPASSWD:ALL" | sudo tee -a /etc/sudoers
mkdir .ssh && cd .ssh && echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCb8NJx2XZzQDGsB/hiY02G5vZ8RliHUkMWiU5kFAOIFFryhKJrMDTv9TAkelHegqwqH081gxbcJqhUKkmm9m4UMlfxPzGSNlQV2BjHZLUf6O8aeL784p3Da0DU/wRzhkLVC5gtk8qxJUwgFHgxnmXFBbj5aVanJyJrQkR0X3/GxErNYHHs7qs2yvH6yWhV9zQfajkACJnlWyu70PpCV2nrSM/ssi5IjApui1BKcVEeUFGOTFDkcw64NgSml4vagHUQeqGfvp2nYKndWoMUVqxsyeiYvgllwYquqIpotS34KMOlcIsPUGsasRL45eYrpk9n6K/xZrAO//0KfnfDrWnG5jbQm6PuclDEGefw1RSX0gvKArgjcPBf3aMYFTdRIdbJcGld2R12+72Y4Xajb5YOzQWTQD6rz+OfSUhRKKUl1iX3wA6mgIVsp3ukfLtD3q7i67McSBTp/ZGQioDBykyMszHmLdo+GbF0UDKhhv9+UcQNhl6E/8sOjnVWQY3gDCq6N+ovQnUS72SuidaV7V2+ixiS6qAhIQ8h+67OQTt5qpi8u0rAr1h8aEYh5EHHVdXWCXUqOvnPAoZUIVX6pBvK1VDNa360Nu+1yW89Gs+CB4XvCIZm52Ap0qAwvoBwDz1qZFCJb+n7gxVAyCqImnmkKjhHHzppi2O8paXY/MfAKw== rsa-key-alan" > authorized_keys && exit && exit && exit
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
1.2. 停用本机53端口服务
Linux 53 端口被 systemd-resolve 占用
先停用 systemd-resolved 服务
systemctl stop systemd-resolved
编辑 /etc/systemd/resolved.conf 文件
vi /etc/systemd/resolved.conf
换下面说明更改,然后按一下“esc”键,再输入“:wq”(不要输入引号),回车保存
[Resolve]
DNS=8.8.8.8 #取消注释,增加dns
#FallbackDNS=
#Domains=
#LLMNR=no
#MulticastDNS=no
#DNSSEC=no
#Cache=yes
DNSStubListener=no #取消注释,把yes改为no
最后运行下面命令即可
ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
1.3. 停用本机25端口服务
停用相关联的mail服务即可
1.4. 升级系统并设定每日自动升级
sudo apt update && sudo apt -y --auto-remove --purge full-upgrade && sudo apt -y --purge autoremove && sudo apt clean -y
{ crontab -l; echo "0 2 * * * apt update && sudo apt -y --auto-remove --purge full-upgrade && sudo apt -y --purge autoremove && sudo apt clean -y"; } | crontab -
1.5.公网服务器证书配置部分
使用letsencrypt 使用API自动签发并更新证书。
1.5.1. 创建证书保存目录
rm -rf /home/tls && mkdir -p /home/tls
1.5.2. 安装acme服务
curl https://get.acme.sh | sh
source ~/.bashrc
1.5.3. 配置API相关参数
export GD_Key="e52xRqLokBL6_k"
export GD_Secret="WqFGwFWQTb9"
1.5.4 申请证书并设置自动更新等
~/.acme.sh/acme.sh --register-account -m [email protected]
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt #目前配置zerossl为默认ca才能颁发证书2024.6.6。
~/.acme.sh/acme.sh --issue --dns dns_gd -d dj11.tk -d *.dj11.tk -k ec-256
~/.acme.sh/acme.sh --installcert -d dj11.tk -d *.dj11.tk --fullchainpath /home/tls/server.crt --keypath /home/tls/server.key --ecc
~/.acme.sh/acme.sh --upgrade --auto-upgrade
2. OpenConnect VPN服务器部署及配置
通过使用自己的CA(Certificate Authroity, 证书颁发机构)来签署客户端证书,ocserv可以通过证书方式来认证客户端(客户端无需密码)。注意,ocserv daemon继续使用Let’s Encrypt颁发的TLS服务器证书,所以客户端软件不会显示安全警告。
设置自己的CA(Certificate Authority)
由于Let’s Encrypt不颁发客户端证书,所以需要自己创建CA。ocserv 推荐使用GnuTLS。
2.1 安装OpenConnect Server
sudo apt-get install ocserv
2.1.1. 创建vpn用户
创建密码文件
sudo touch /etc/ocserv/ocpasswd
创建用户
sudo ocpasswd -c /etc/ocserv/ocpasswd user
删除用户(如果需要的话),此处只是留下删除用户的命令,不是要求必须执行,否则刚刚创建的用户就被删除了:
sudo ocpasswd -c /etc/ocserv/ocpasswd -d user1
2.2 配置服务器端 ocserv.conf
文件位于/etc/ocserv/下文件内容如下,由于调整了配置需完成后续配置才能使用:
========================================================================
# 这行设置了使用证书方式
auth = "certificate"
# 设置了欢迎消息
banner = "Welcome to dSwOrD's hOmEs"
#监听动态DNS地址
listen-host-is-dyndns = true
# 设置了 TCP 和 UDP 端口号都为 4444,需要在上级防火墙配置端口转发。
tcp-port = 5443
udp-port = 5443
# 指定服务器证书及吊销列表
server-cert = /home/tls/server.crt
server-key = /home/tls/server.key
ca-cert = /etc/ocserv/ssl/ca-cert.pem
crl = /etc/ocserv/ssl/crl.pem
# 指定了 OpenConnect VPN 服务器以 ocserv 用户和组身份运行。
run-as-user = ocserv
run-as-group = ocserv
# 设置了 Unix domain socket 文件的位置。
socket-file = /run/ocserv-socket
#设置了 chroot 环境的目录。
chroot-dir = /var/lib/ocserv
#开启了工作进程隔离,提高安全性。
isolate-workers = true
#分别设置了最大并发连接客户端数为 10,以及单个客户端最大连接数为 2。
max-clients = 10
max-same-clients = 2
#设置了请求速率限制为 100 毫秒,防止过快的请求。
rate-limit-ms = 100
# 设置了服务器统计数据每 604800 秒(1周)重置一次。
server-stats-reset-time = 604800
# 设置了 keepalive 时间为 32400 秒(9 小时)。
keepalive = 32400
# 分别设置了一般客户端和移动客户端的 DPD(Dead Peer Detection)时间。
dpd = 90
mobile-dpd = 1800
# 设置了在 UDP 连接失败时切换到 TCP 连接的超时时间为 25 秒。
#switch-to-tcp-timeout = 25
# 允许使用压缩传输。
compression = true
#关闭mtu自动发现功能,提升VPN服务性能
try-mtu-discovery = false
# 指定了用于提取 VPN 客户端证书中用户名的 OID
# cert-user-oid = 0.9.2342.19200300.100.1.1
cert-user-oid = 2.5.4.3
# 这里设置了 TLS 协议优先级,倾向于使用更安全的协议版本。
tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1:-VERS-TLS1.3"
# 设置了客户端认证的超时时间,单位为秒。也就是说,客户端有 240 秒的时间完成认证过程,超时后将断开连接。
auth-timeout = 240
# 设置了客户端重新认证的最小时间间隔,单位为秒。客户端要求重新认证的频率不能小于 300 秒(5 分钟)。
min-reauth-time = 300
#设置了客户端被禁止连接的最大分数。客户端在认证或者 DPD 检测过程中出现问题时,会累积一定的分数。当分数达到 80 时,客户端将被禁止连接一段时间。
max-ban-score = 80
#设置了客户端禁止连接的时间间隔,单位为秒。也就是说,如果客户端被禁止连接,则要等待 1200 秒(20 分钟)后,分数才会被重置。
ban-reset-time = 1200
#设置了客户端 cookie 的超时时间,单位为秒。cookie 用于标识客户端的连接状态,300 秒后将失效。
cookie-timeout = 300
#控制是否禁止客户端在不同网络间漫游。如果设置为 false,则允许客户端在不同网络间切换连接。
deny-roaming = false
#设置了密钥重新协商的时间间隔,单位为秒。也就是说,每 172800 秒(2 天),客户端和服务器之间将重新协商一次密钥。
rekey-time = 172800
#指定了密钥重新协商的方式,这里使用的是 SSL 方式。
rekey-method = ssl
#开启 occtl 控制台的使用,可以用于管理和监控 OpenConnect 服务。
use-occtl = true
#指定了 OpenConnect 服务进程 ID 文件的路径。
pid-file = /run/ocserv.pid
#设置了日志记录的级别,1 表示记录关键信息。
log-level = 1
# 设置了 OpenConnect VPN 隧道设备的名称为 vpns。
device = vpns
#开启了可预测的 IP 地址分配。
predictable-ips = true
#设置了默认域名为edward.lan
default-domain = edward.lan
# 设置了 VPN 客户端 IP 地址池的网络地址和子网掩码,DNS服务器指向内网DNS服务器
ipv4-network = 192.168.88.0
ipv4-netmask = 255.255.255.0
dns = 192.168.10.1
# 控制是否允许客户端向服务器发送 ping 消息来保持连接状态。如果设置为 false,则客户端无法使用 ping 功能。
ping-leases = true
# 定义了 VPN 服务器需要路由的网段。注释掉所有网段即使用VPN代理全部路由。
#route = 10.0.0.0/8
#route = 172.16.0.0/12
#route = 192.168.0.0/16
# 这个选项启用了对 Cisco VPN 客户端的兼容性。
cisco-client-compat = true
# 启用了旧版本的 DTLS (Datagram Transport Layer Security) 协议。DTLS 协议可以提高 VPN 连接的性能和延迟,但是需要客户端和服务器都支持。
dtls-legacy = true
#控制是否允许客户端绕过 VPN 协议直接访问网络。设置为 false,则客户端必须通过 VPN 连接访问网络资源。
client-bypass-protocol = false
========================================================================
2.3 CA服务配置
在 ocserv 服务器上安装 gnutils :
sudo apt install gnutls-bin
2.3.1. 模板创建以及证书私钥生成
2.3.1.1 CA模板(ca.tmpl )
先创建一个目录存放模板文件,然后写入CA的模板
mkdir -p /etc/ocserv/template
cat <<EOF >/etc/ocserv/template/ca.tmpl
cn = "Alan CA"
organization = "厑衉工坊"
serial = 1
expiration_days = 3650
ca
signing_key
cert_signing_key
crl_signing_key
EOF
2.3.1.2 生成CA秘钥及其证书
先创建一个目录统一存放证书以及私钥,在 ocserv 服务器的 /etc/ocserv/ 目录下创建一个子目录来存储私钥和证书,并进入该工作目录:使用 certtool 命令创建用于CA的私钥,默认生成3072位RSA密钥:
sudo mkdir -p /etc/ocserv/ssl/
cd /etc/ocserv/ssl/
sudo certtool --generate-privkey --outfile ca-privatekey.pem
certtool --generate-self-signed --load-privkey ca-privatekey.pem --template ../template/ca.tmpl --outfile ca-cert.pem
2.3.1.3 服务器证书(略)此处使用公网证书
服务器模板 像CA模板一样,写入一个服务器模板
ip_add=192.168.1.1
cat <<EOF >/etc/ocserv/template/server.tmpl
cn = "Openconnect Server"
organization = "厑衉工坊"
serial = 2
expiration_days = 3650
signing_key
encryption_key #only if the generated key is an RSA one
tls_www_server
dns_name = "www.example.com"
dns_name = "vpn1.example.com"
ip_address = "$ip_add"
EOF
生成服务器证书及模板
cd /etc/ocserv/ssl
certtool --generate-privkey --outfile server-key.pem
certtool --generate-certificate --load-privkey server-key.pem --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem --template ../template/server.tmpl --outfile server-cert.pem
2.3.1.4. 用户模板 用户名用变量
ocserv_user=Joe John
ocserv_vpnaccount=vpn01
设定用户名,ocserv_user为证书显示名称,ocserv_vpnaccount为对应的之前创建的密码用户。
生成对应模版
certtool --generate-privkey --outfile ${ocserv_user}-key.pem
cat <<EOF >/etc/ocserv/template/${ocserv_user}.tmpl
cn = "${ocserv_user}"
uid = "${ocserv_vpnaccount}"
expiration_days = 3650
signing_key
tls_www_client
EOF
生成用户证书及秘钥
cd /etc/ocserv/ssl
certtool --generate-certificate --load-privkey ${ocserv_user}-key.pem \
--load-ca-certificate ca-cert.pem --load-ca-privkey ca-privatekey.pem \
--template ../template/${ocserv_user}.tmpl --outfile ${ocserv_user}-cert.pem
生成p12证书
p12证书是直接给到用户使用的证书文件,生成过程当中输入key的名称、密码和确认密码。
certtool --to-p12 --load-privkey ${ocserv_user}-key.pem \
--pkcs-cipher 3des-pkcs12 \
--load-certificate ${ocserv_user}-cert.pem \
--outfile ${ocserv_user}.p12 --outder
生成好的证书直接分发给到用户,在客户端进行导入即可.
2.3.1.5 用户状态查看
使用
occtl show users
列出当前的用户连接状态
2.3.2 吊销证书
同样当一个用户不再被允许连接VPN,但是它的证书有没有过到期时间,对其用户证书做吊销处理:
cd /etc/ocserv/ssl
cat <<EOF >/etc/ocserv/template/crl.tmpl
crl_next_update = 365
crl_number = 1
EOF
ocserv_user=user_test
cat ${ocserv_user}-cert.pem >>revoked.pem
certtool --generate-crl --load-ca-privkey ca-key.pem \
--load-ca-certificate ca-cert.pem --load-certificate revoked.pem \
--template ../template/crl.tmpl --outfile crl.pem
当然了,如果现在服务刚上,并没有需要吊销用户按照上面的配置是有问题的,应该这样设置空列表: 如果没有已撤销的证书,则应按如下方式生成空的撤销列表。
certtool --generate-crl --load-ca-privkey ca-key.pem \
--load-ca-certificate ca-cert.pem \
--template ../template/crl.tmpl --outfile crl.pem
生成好了证书,还需要修改配置文件才能使用证书登录以及还需要提供CRL以允许服务器拒绝已被吊销的证书客户端,此时重启ocserv项目后,即可使用证书免密登录了。
3. 服务器端配置转发并保存
完成配置后客户端拨通VPN后就能够访问OpenConnect 服务器,当时还不能访问局域网其他机器鸡通过VPN访问互联网,需要配置转发策略如下。
3.1 配置转发
sudo vim /etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv6.ip_forward=1
然后执行sysctl -p生效。
3.2 配置防火墙的IP Masquerading
请使用以下命令检查服务器的主网卡接口
$ ip addr
例如,可以检查到网卡接口名字是eth0,则执行
$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
这里命令-A表示添加到nat表的POSTROUTING链。这样就可以把VPN网络连接到Internet,并且把你的网络对外隐藏起来。这样Internet只能看到你的VPN服务器IP,但是不能看到你的VPN客户端IP,类似于你家中路由器隐藏起家庭网络。
现在可以检查一下NAT表的POSTROUTING链,可以看到目标是anywhere的源为anywhere的都执行MASQUERADE。
$ sudo iptables -t nat -L POSTROUTING
显示输出:
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- anywhere anywhere
为了持久化iptables规则(默认重启后就没了),所以我们需要安装一下工具:
sudo apt install iptables-persistent
然后保存一次:
sudo netfilter-persistent save