在Arch Linux上部署OpenConnect VPN¶
OpenConnect VPN Server,也称为 ocserv
,采用OpenConnect SSL VPN协议,并且和Cisco AnyConnect SSL VPN协议的客户端兼容。目前不仅加密安全性好,而且客户端可以跨平台,主流操作系统以及手机操作系统都可以使用。
选择OpenConnect VPN Server( ocserv
)的主要原因如下:
SSL VPN协议安全性较好,被GFW干扰的可能性较低(GFW不太可能完全屏蔽SSL流量,毕竟HTTPS是现代互联网的主流)
跨平台通用客户端,这样我可以在Linux,macOS,Windows以及Android,iOS平台使用
备注
由于我将VPS服务器从 Ubuntu Linux 更改到 Arch Linux ,所以重新部署Ocserv服务(OpenConnect VPN)
我力求在 OpenConnect VPN 基础上整合近期的部署改进,以实现完善的个人VPN部署 越过长城
准备工作¶
需要购买一台海外VPS
需要一个域名,在注册域名中添加一条记录指向新购买VPS的IP地址(
vpn.example.com
解析到将要部署的服务器IP地址)
备注
使用Let’s Encrypt签发的证书是针对域名的:
使用
certbot
生成证书时候,Let's Encrypt会通过你签发证书的域名访问该域名对应IP的80端口进行验证,所以必须准备好部署服务器的域名解析如果暂时无法准备好域名解析,那么可以自己手工签发一个证书临时使用
安装ocserv¶
Arch Linux 发行版只包括了 openconnect
客户端,但是没有直接提供 ocserv
服务端。在 Arch Linux上安装 ocserv
是通过 Arch Linux AUR 部署的。
首先完成 Arch Linux AUR 管理工具
yay
安装:
pacman -S --needed git base-devel
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si
使用
yay
安装ocserv
:
yay -S ocserv
Let's Encrpyt Certbot生成证书(推荐)¶
Arch linux官方提供了Let's Encrypt客户端Certbot,所以安装非常简单:
pacman -S certbot
确保80端口没有使用中,然后从Let’s Encrypt获取一个TLS证书:
sudo certbot certonly --standalone --preferred-challenges http --agree-tos --email admin@example.com -d vpn.exapmle.com
备注
在执行上述 certbot
命令获取证书前,需要暂停80端口的nginx服务,因为 certbot
会监听该端口来迎接Let's Encrypt验证域名 vpn.example.com
(也就是你执行生成证书的服务器): --preferred-challenges http ... -d vpn.exapmle.com
否则会报错:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Cert is due for renewal, auto-renewing...
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for vpn.example.com
Cleaning up challenges
Problem binding to port 80: Could not bind to IPv4 or IPv6.
一切正常的话,会收到如下正确获得并存储证书的信息:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Cert is due for renewal, auto-renewing...
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for vpn.example.com
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/vpn.example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/vpn.example.com/privkey.pem
Your cert will expire on 2023-04-14. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
警告
Let's Encrypt提供的证书有效期3个月,所以每3个月需要使用上述命令重新生成一次证书。建议 使用cron定时更新letsencrypt证书
手工生成临时使用自签名证书(可选)¶
由于我暂时没有搞定域名注册,所以我也临时使用了以下命令生成证书(正式使用还是要采用上文Let's Encrypt证书):
openssl req -x509 -nodes -newkey rsa:4096 -keyout /etc/ocserv/ocserv.key -out /etc/ocserv/ocserv.cert -days 3650 -subj "/CN=ocserv"
配置ocserv¶
Arch Linux AUR 提供的 ocserv
软件包提供了配置文件 /etc/ocserv.conf
和 /etc/ocserv-passwd
,但是我发现实际上没有使用( systemctl start ocserv
显示使用 /etc/ocserv/ocserv.conf
)
mkdir /etc/ocserv
mv /etc/ocserv.config /etc/ocserv/
rm /etc/ocserv-passwd
修订ocserv配置文件 /etc/ocserv/ocserv.config
如果使用自签名证书,配置如下:
# 以下行注释关闭使用系统账号登陆
# auth = "pam[gid-min=1000]"
# 添加以下行表示独立密码文件认证
auth = "plain[passwd=/etc/ocserv/ocpasswd]"
# 只开启TCP端口,关闭UDP端口,以便使用BBR加速
tcp-port = 443
# udp-port = 443
# 修改证书,注释前两行,添加后两行,表示使用Let's Encrypt服务器证书
# server-cert = /etc/ssl/certs/ssl-cert-snakeoil.pem
# server-key = /etc/ssl/private/ssl-cert-snakeoil.key
server-cert = /etc/letsencrypt/live/vpn.example.com/fullchain.pem
server-key = /etc/letsencrypt/live/vpn.example.com/privkey.pem
# 设置客户端最大连接数量,默认是16
max-clients = 16
# 每个用户并发设备数量
max-same-clients = 2
# 启用MTU discovery以提高性能
#try-mtu-discovery = false
try-mtu-discovery = true
# 设置默认域名为vpn.example.com
default-domain = vpn.example.com
# 修改IPv4网段配置,注意不要和本地的IP网段重合
ipv4-network = 10.10.10.0
# 将所有DNS查询都通过VPN(防止受到DNS污染)
tunnel-all-dns = true
# 设置使用Google的公共DNS
dns = 8.8.8.8
# 注释掉所有路由参数
# route = 10.10.10.0/255.255.255.0
# route = 192.168.0.0/255.255.0.0
# route = fef4:db8:1000:1001::/64
# no-route = 192.168.5.0/255.255.255.0
创建VPN账号:
启动ocserv¶
启动ocserv:
systemctl start ocserv
systemctl enable ocserv
IP转发和MASQUERADE¶
激活IP Forwarding (重要步骤)
修改 /etc/sysctl.conf
添加配置并激活:
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
配置防火墙的IP Masquerading (这里假设网卡接口是
ens3
)以及允许端口访问,配置好以后保存配置(以便后续通过 Systemd进程管理器 启动恢复 :
# MASQUERADE
iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
# 在防火墙上开启端口443
iptables -I INPUT -p tcp --dport 443 -j ACCEPT
iptables -I INPUT -p udp --dport 443 -j ACCEPT
# 保存防火墙配置
iptables-save > /etc/iptables.rules
创建一个systemd服务来启动时恢复iptables规则,编辑
/etc/systemd/system/iptables-restore.service
:
[Unit]
Description=Packet Filtering Framework
Before=network-pre.target
Wants=network-pre.target
[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore /etc/iptables.rules
ExecReload=/sbin/iptables-restore /etc/iptables.rules
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
激活
iptables-restore
服务:
systemctl daemon-reload
systemctl enable iptables-restore
错误排查¶
客户端连接错误排查¶
使用Cisco Secure Client连接认证后失败,检查日志:
journalctl -u ocserv
日志显示找不到 tun 设备:
Apr 24 22:07:05 serv-arch ocserv[577235]: NLM query failed No such file or directory
Apr 24 22:07:05 serv-arch ocserv[577235]: main: delaying accepts for 100 ms
Apr 24 22:07:09 serv-arch ocserv[577237]: sec-mod: sec-mod instance 0 issue cookie
Apr 24 22:07:09 serv-arch ocserv[577237]: sec-mod: using 'plain' authentication to authenticate user (session: /bxaa+)
Apr 24 22:07:20 serv-arch ocserv[577235]: NLM query failed No such file or directory
Apr 24 22:07:20 serv-arch ocserv[577235]: main: delaying accepts for 100 ms
Apr 24 22:07:22 serv-arch ocserv[577235]: NLM query failed No such file or directory
Apr 24 22:07:22 serv-arch ocserv[577235]: main: delaying accepts for 100 ms
Apr 24 22:07:23 serv-arch ocserv[577235]: NLM query failed No such file or directory
Apr 24 22:07:23 serv-arch ocserv[577235]: main: delaying accepts for 100 ms
Apr 24 22:07:24 serv-arch ocserv[577235]: main[huatai]:1.80.209.3:5790 new user session
Apr 24 22:07:24 serv-arch ocserv[577237]: sec-mod: initiating session for user 'huatai' (session: /bxaa+)
Apr 24 22:07:24 serv-arch ocserv[577235]: main: tun.c:654: Can't open /dev/net/tun: No such device
Apr 24 22:07:24 serv-arch ocserv[577235]: main: tun.c:729: Can't open tun device: No such device
Apr 24 22:07:24 serv-arch ocserv[577235]: main[huatai]:1.80.209.3:5790 failed authentication attempt for user 'huatai'
Apr 24 22:07:24 serv-arch ocserv[577487]: worker: 1.80.209.3 failed cookie authentication attempt
Apr 24 22:07:24 serv-arch ocserv[577237]: sec-mod: temporarily closing session for huatai (session: /bxaa+)
但是实际上 /dev/net/tun
设备文件存在,我参考 OpenVPN 2.3.1 - ERROR: Cannot open TUN/TAP dev /dev/net/tun ,看起来是我最近做了一次系统升级,但是升级后没有重启系统导致的。重启系统之后,该问题消失
客户端连接后无法访问internet¶
我使用Cisco Secure Client连接VPN之后,发现无法访问Internet
已经确认服务器开启了
net.ipv4.ip_forward = 1
乌龙了 忘记配置防火墙IP Masquerading,执行以下命令开启(上文步骤已经补充):
iptables -t nat -A POSTROUTING -o enp1s0 -j MASQUERADE
备注
实际需要参考上文,通过 Systemd进程管理器 自动回复防火墙IP Masquerading