Ubuntu 22.04 安装 OpenConnect 指南

Ubuntu 22.04 安装 OpenConnect 全流程实测:ocserv 服务端(开箱 PAM 验证、certtool 自签证书、plain 认证、高位端口、systemd 管理)与 openconnect 客户端双线安装连接,apt 与源码编译(ocserv 1.6.0 / openconnect v9.21)双方案对比,实测日期 2026-10-20。

OpenConnectOpenConnectVPN网络配置Ubuntu2026/10/20

Ubuntu 22.04 安装 OpenConnect 指南

目标:在 Ubuntu 22.04 服务器上完成 OpenConnect 生态的完整安装与验证——服务端 ocserv(含开箱验证、证书、认证切换、高位端口、systemd 管理)与客户端 openconnect(含连接实测),覆盖 apt 在线安装与源码编译两条路线。全部步骤与回显均在实测环境真实执行(见第一章),执行日期 2026-10-20。

一、环境信息

  • 操作系统:Ubuntu 22.04.4 LTS (jammy),x86_64,内核 6.8.0-138-generic,root 权限
  • 软件源版本:ocserv 1.1.3-1、openconnect 8.20-1(jammy/universe,apt 实查)
  • 上游最新稳定版(2026-10-20 官方 releases 实查):ocserv 1.6.0(2026-10-16 发布)、openconnect v9.21(2026-06-16 发布)——方案 B 编译实测即用此版本
  • 实测网络形态:服务端与客户端同机部署(客户端连 127.0.0.1 或本机网卡 IP 192.168.146.128),生产部署时客户端在外网、步骤完全一致
  • 实验端口:服务监听高位端口 15001(TCP/UDP),避开默认 443 及本机其他服务占用(8144/8145/8148/8888)
  • 关联组件:GnuTLS 3.7.3(两端的 TLS/DTLS 底座)、vpnc-scripts(客户端默认网络脚本)

二、前置条件

  • root 或 sudo 权限;apt 已联网可用(apt-get update 通过)。
  • 明确监听端口:默认 443 若已被占用(ss -ltn | grep :443)则改用高位端口,本文统一用 15001。
  • 防火墙策略知晓:放行所选端口的 TCP+UDP(第七章 7.4 有 ufw 命令;本实测机 ufw 处于 Status: inactive,未启用状态不影响验证)。
  • 若需外网访问:云服务器在安全组放行端口(TCP+UDP 双协议都要,DTLS 数据通道走 UDP)。

三、版本选型说明

OpenConnect 生态是「一个协议、两个组件」:服务端 ocserv 与客户端 openconnect 是独立软件包、独立版本、独立发布。Ubuntu 22.04 apt 可装版本与上游最新版差距明显,选择路线前先对齐版本预期:

组件Ubuntu 22.04 apt(本篇方案 A 实测)上游最新稳定版(2026-10-20 实查,本篇方案 B 实测)差距说明
ocserv 服务端1.1.3-11.6.0(2026-10-16)跨 1.1→1.6 共 5 个次版本
openconnect 客户端8.20-1v9.21(2026-06-16)跨 8.x→9.x 主版本

结论:追求稳定省事选方案 A(apt),版本旧但补丁由 Ubuntu 跟进;要最新版特性和上游版本对齐选方案 B(源码编译)。两条路线的产物互相独立、可并存(编译版建议放 /usr/local 或独立目录,避免覆盖 apt 版二进制)。配置文件参数两版命名一致,《OpenConnect 配置参数详解》以 1.1.3 实测、对 1.6.0 同样适用。

四、方案 A:apt 在线安装(推荐)

4.1 服务端 ocserv:安装与开箱自检

安装(一条命令,实测输出节选):

apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y ocserv

实测输出(节选):

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  gnutls-bin iproute2 ocserv-common
Suggested packages:
  ocserv-gssapi ocserv-radius ocserv-oath ocserv-seccomp
The following NEW packages will be installed:
  gnutls-bin ocserv ocserv-common
Setting up ocserv (1.1.3-1) ...
Created symlink /etc/systemd/system/multi-user.target.wants/ocserv.service → /lib/systemd/system/ocserv.service.

要点:依赖自动带上 gnutls-bin(证书工具 certtool 所在)、ocserv-common(配置文件包);安装即注册并启动 systemd 服务,无需手动 enable。

立即自检(实测输出):

systemctl status ocserv.service --no-pager
● ocserv.service - OpenConnect SSL VPN server
     Loaded: loaded (/lib/systemd/system/ocserv.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2026-10-20 20:44:01 CST; 5s ago
   Main PID: 1616991 (ocserv)
      Tasks: 3 (limit: 38344)
     Memory: 2.6M
        CPU: 10ms
     CGroup: /system.slice/ocserv.service
             ├─1616991 ocserv-main
             └─1616993 ocserv-sm
ss -ltnp | grep ocserv
ss -lunp | grep ocserv
LISTEN 0    1024   0.0.0.0:443   0.0.0.0:*   users:(("ocserv-main",pid=1616991,fd=3))
LISTEN 0    1024      [::]:443      [::]:*    users:(("ocserv-main",pid=1616991,fd=7))
UNCONN 0    0      0.0.0.0:443   0.0.0.0:*   users:(("ocserv-main",pid=1616991,fd=8))
UNCONN 0    0         [::]:443      [::]:*    users:(("ocserv-main",pid=1616991,fd=9))

进程形态是 ocserv-main(主进程)+ ocserv-sm(sec-mod 安全进程),TCP/UDP 双栈同时监听 443。此时是「开箱可用」状态:默认配置使用 PAM 系统账号认证 + snakeoil 自签证书。用真实系统账号实测开箱路径(先建一个普通系统用户):

useradd -m vpnadmin
echo 'vpnadmin:q1w2e3r4' | chpasswd

客户端连接(openconnect 先按 4.4 节装好;snakeoil 证书指纹用 pin 方式接受):

openconnect --servercert=pin-sha256:DT4gU9T9ZkLr5ONVx3gVjhXXUB+QuK0CU0t4IeX3Cgw= --user=vpnadmin 127.0.0.1:443

实测输出(节选,openconnect 输出为本地化中英混合原文):

POST https://127.0.0.1/
正在尝试连接到服务器 127.0.0.1:443
已连接到 127.0.0.1:443
SSL 与 127.0.0.1 协商
服务器证书验证失败:未找到签署者
Connected to HTTPS on 127.0.0.1 with ciphersuite (TLS1.3)-(ECDHE-SECP256R1)-(RSA-PSS-RSAE-SHA256)-(AES-256-GCM)
XML POST 已启用
Please enter your username.
Please enter your password.
Password:
得到了 CONNECT 响应:HTTP/1.1 200 CONNECTED
X-CSTP-Server-Name: ocserv 1.1.3
X-CSTP-Hostname: ops
X-CSTP-DPD: 60
X-CSTP-Address: 192.168.1.135
X-CSTP-Netmask: 255.255.255.0
X-CSTP-Keepalive: 300
X-CSTP-Idle-Timeout: 1200
X-CSTP-Base-MTU: 1500
X-CSTP-MTU: 1434
X-CSTP-Content-Encoding: oc-lz4
已建立 DTLS 连接(使用 GnuTLS)。密码套件 (DTLS1.2)-(PSK)-(AES-256-GCM)。
DTLS 连接压缩正使用 LZ4。
Configured as 192.168.1.135, with SSL + LZ4 connected and DTLS + LZ4 connected
在后台继续;pid 1712027

服务端确认在线(实测):

occtl show users
      id     user    vhost             ip         vpn-ip device   since    dtls-cipher    status
 1793454 vpnadmin  default      127.0.0.1  192.168.1.135  vpns0     0s  (AES-256-GCM) connected

结论:Ubuntu 22.04 上 ocserv 开箱即用,PAM 认证 + 默认 443 端口直接可跑通。但生产不建议长期用系统账号+snakeoil 证书,继续往下做证书与认证收敛。

4.2 生成服务器证书(certtool)

自签证书四步(CA 私钥 → 自签 CA → 服务器私钥 → CA 签发服务器证书),模板先准备好:

cat > /etc/ocserv/ca.tmpl <<'EOF'
cn = "quzuo-demo-ca"
organization = "quzuo"
serial = 1
expiration_days = 3650
ca
signing_key
cert_signing_key
crl_signing_key
EOF

cat > /etc/ocserv/server.tmpl <<'EOF'
cn = "vpn.example.com"
organization = "quzuo"
expiration_days = 3650
signing_key
encryption_key
tls_www_server
EOF

实测生成(输出节选):

certtool --generate-privkey --outfile /etc/ocserv/ca-key.pem
certtool --generate-self-signed --load-privkey /etc/ocserv/ca-key.pem --template /etc/ocserv/ca.tmpl --outfile /etc/ocserv/ca.pem
certtool --generate-privkey --outfile /etc/ocserv/server-key.pem
certtool --generate-certificate --load-privkey /etc/ocserv/server-key.pem --load-ca-certificate /etc/ocserv/ca.pem --load-ca-privkey /etc/ocserv/ca-key.pem --template /etc/ocserv/server.tmpl --outfile /etc/ocserv/server-cert.pem
Generating a 3072 bit RSA private key...
Generating a self signed certificate...
X.509 Certificate Information:
        Version: 3
        Serial Number (hex): 01
        Validity:
                Not Before: Tue Oct 20 13:24:23 UTC 2026
Generating a 3072 bit RSA private key...
Generating a signed certificate...
X.509 Certificate Information:
        Version: 3
        Serial Number (hex): 43afeaf80d2e0df5f9b5d4a56cf2bb3617950279
openssl x509 -in /etc/ocserv/server-cert.pem -noout -subject -dates
subject=O = quzuo, CN = vpn.example.com
notBefore=Oct 20 13:24:23 2026 GMT
notAfter=Oct 17 13:24:23 2036 GMT

⚠️ 注意:生成服务器证书必须带 --load-ca-privkey(CA 私钥),实测缺它直接报错 missing --load-ca-privkey。模板里 tls_www_server 与 encryption_key 两个扩展不能少,否则 TLS 服务器角色校验不通过。

4.3 认证收敛:plain 口令 + ocpasswd + 高位端口

创建 plain 认证账号(交互输入两次口令,这里用 q1w2e3r4):

printf 'q1w2e3r4\nq1w2e3r4\n' | ocpasswd -c /etc/ocserv/ocpasswd admin
cat /etc/ocserv/ocpasswd
admin:*:$5$9i1c.Z750LjoyTex$oyz.Qi.2NUKoeBUxie5uqAbzO.w4U6cD0aqvHJdpA75

修改 /etc/ocserv/ocserv.conf 关键四项(完整参数解释见《OpenConnect 配置参数详解》):

auth = "plain[passwd=/etc/ocserv/ocpasswd]"     # 原 auth = "pam[gid-min=1000]" 改这里
tcp-port = 15001                                 # 原 443
udp-port = 15001                                 # 原 443
server-cert = /etc/ocserv/server-cert.pem        # 原 snakeoil 路径
server-key = /etc/ocserv/server-key.pem
ca-cert = /etc/ocserv/ca.pem
ipv4-network = 10.10.10.0                        # 原 192.168.1.0,避开常见家用网段

改完先校验再重启:

ocserv -t -c /etc/ocserv/ocserv.conf
systemctl restart ocserv.service
ss -ltnp | grep 15001
note: vhost:default: setting 'plain' as primary authentication method
note: setting 'file' as supplemental config option
LISTEN 0    1024   0.0.0.0:15001   0.0.0.0:*   users:(("ocserv-main",pid=1613260,fd=3))

⚠️ 注意:改认证方式后必须重启(restart),occtl reload 对 auth/端口类改动不保证生效。若配置里同时存在 auth 与 enable-auth 两行同类口令认证,重启会失败并报 error: vhost:default: you cannot mix multiple password authentication methods(排障见第八章 FAQ)。

4.4 客户端 openconnect:安装

DEBIAN_FRONTEND=noninteractive apt-get install -y openconnect

实测输出(节选):

The following additional packages will be installed:
  libopenconnect5 vpnc-scripts
Suggested packages:
  vpnc network-manager-openconnect-gnome
The following NEW packages will be installed:
  libopenconnect5 openconnect vpnc-scripts
Setting up openconnect (8.20-1) ...

版本与能力自检(实测输出):

openconnect --version
OpenConnect version v8.20-1
Using GnuTLS 3.7.3
Features present: TPMv2, PKCS#11, RSA software token, HOTP software token, TOTP software token, Yubikey OATH, System keys, DTLS, ESP
Supported protocols: anyconnect (default), nc, gp, pulse, f5, fortinet, array
Default vpnc-script: /usr/share/vpnc-scripts/vpnc-script

4.5 连接实测(服务端 + 客户端全链路)

用 admin 账号连本机 15001 端口(首次连接需接受自签证书,把指纹用 pin-sha256: 传给 --servercert;口令经标准输入传入,实测可用):

printf 'q1w2e3r4\n' | openconnect -b --servercert=pin-sha256:7ginaG3nWN8ZbISIdJoGE4YFrrlf6ujtXeYtRSlCfis= --user=admin 127.0.0.1:15001

实测输出(完整握手,节选;客户端输出为本地化中英混合原文):

POST https://127.0.0.1:15001/
正在尝试连接到服务器 127.0.0.1:15001
已连接到 127.0.0.1:15001
SSL 与 127.0.0.1 协商
服务器证书验证失败:未找到签署者
Connected to HTTPS on 127.0.0.1 with ciphersuite (TLS1.3)-(ECDHE-SECP256R1)-(RSA-PSS-RSAE-SHA256)-(AES-256-GCM)
XML POST 已启用
Please enter your username.
Please enter your password.
Password:
得到了 CONNECT 响应:HTTP/1.1 200 CONNECTED
X-CSTP-Version: 1
X-CSTP-Server-Name: ocserv 1.1.3
X-CSTP-DPD: 60
X-CSTP-Address: 10.10.10.165
X-CSTP-Netmask: 255.255.255.0
X-CSTP-Split-Include: 10.10.20.0/255.255.255.0
X-CSTP-Keepalive: 300
X-CSTP-Idle-Timeout: 1200
X-CSTP-Rekey-Method: ssl
X-DTLS-DPD: 60
X-DTLS-Port: 15001
X-DTLS-Keepalive: 300
X-CSTP-Base-MTU: 1500
X-CSTP-MTU: 1434
X-DTLS-Content-Encoding: oc-lz4
X-CSTP-Content-Encoding: oc-lz4
CSTP 已连接。DPD 60,持久连接(Keepalive)300
已建立 DTLS 连接(使用 GnuTLS)。密码套件 (DTLS1.2)-(PSK)-(AES-256-GCM)。
DTLS 连接压缩正使用 LZ4。
Configured as 10.10.10.165, with SSL + LZ4 connected and DTLS + LZ4 connected
在后台继续;pid 1624711

要点解读:

  • X-CSTP-Address: 10.10.10.165:客户端从 ipv4-network 池里拿到的地址(predictable-ips 语义下由用户名哈希偏移)。
  • (DTLS1.2)-(PSK)-(AES-256-GCM) + DTLS 连接压缩正使用 LZ4:数据通道 DTLS + 压缩生效。
  • -b 使连接认证成功后转入后台(在后台继续;pid 1624711)。

隧道连通性验证(实测):

ip addr show tun0
ping -c 3 10.10.10.1
ip route show | grep '10\.10\.'
999: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1434 qdisc fq_codel state UNKNOWN group default qlen 500
    link/none
    inet 10.10.10.165/32 scope global tun0
       valid_lft forever preferred_lft forever
998: vpns0: <POINTOPOINT,UP,LOWER_UP> mtu 1434 qdisc fq_codel state UNKNOWN group default qlen 500
    link/none
    inet 10.10.10.1 peer 10.10.10.165/32 scope global vpns0
       valid_lft forever preferred_lft forever
3 packets transmitted, 3 received, 0% packet loss, time 2087ms
rtt min/avg/max/mdev = 0.040/0.044/0.050/0.004 ms
10.10.10.0/24 dev tun0 scope link
10.10.10.165 dev vpns0 proto kernel scope link src 10.10.10.1
10.10.20.0/24 dev tun0 scope link

服务端观测与断开(实测):

occtl show users        # 查看 admin 会话行
occtl disconnect user admin
      id     user    vhost             ip         vpn-ip device   since    dtls-cipher    status
 1790602    admin  default      127.0.0.1   10.10.10.165  vpns0     3s  (AES-256-GCM) connected
user 'admin' was disconnected

💡 说明:客户端断开或被踢后,tun0 网卡与 10.10.x 路由会自动消失(实测 ip route show | grep 10.10. 已为空、pgrep openconnect 无进程)。生产客户端在外网时,把 127.0.0.1:15001 换成服务器公网地址即可,其余步骤一致。

4.6 systemd 服务管理速查

systemctl status ocserv        # 运行状态(active (running)、PID、内存)
systemctl restart ocserv       # 重启(改 auth/端口/证书后必做)
systemctl stop ocserv          # 停止
systemctl is-enabled ocserv    # 开机自启确认 → enabled
journalctl -u ocserv -f        # 实时日志
journalctl -u ocserv -n 20     # 最近 20 行

五、方案 B:源码编译安装

5.1 编译安装 ocserv 1.6.0(实测通过)

编译依赖(README Required 一节 + meson 配置实测需要):

apt-get install -y build-essential meson ninja-build pkg-config \
  libgnutls28-dev libev-dev libreadline-dev libtasn1-bin \
  protobuf-c-compiler libprotobuf-c-dev libtalloc-dev

下载(官方 GitLab 归档;注意 tag 名无 v 前缀):

curl -sSL -o ocserv-1.6.0.tar.gz "https://gitlab.com/openconnect/ocserv/-/archive/1.6.0/ocserv-1.6.0.tar.gz"
tar xzf ocserv-1.6.0.tar.gz && cd ocserv-1.6.0

配置与编译(meson + ninja,实测耗时约 1 分钟):

meson setup build
ninja -C build

实测输出(节选):

The Meson build system
Version: 0.61.2
Project name: ocserv
Project version: 1.6.0
C compiler for the host machine: cc (gcc 11.4.0 "cc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0")
Build targets in project: 32

ninja: Entering directory `build'
[221/222] Compiling C object tests/config-inherit.p/config-inherit.c.o
[222/222] Linking target tests/config-inherit

验证编译产物(实测输出):

./build/src/ocserv --version
OpenConnect VPN Server 1.6.0

Compiled with: seccomp, oath, radius, gssapi, PKCS#11, AnyConnect
GnuTLS version: 3.7.3

安装与运行(两种方式任选其一,均实测):

# 方式一:直接运行编译产物(不落系统目录,便于并存/回退)
./build/src/ocserv --version

# 方式二:安装到系统(生产默认前缀 /usr/local:ocserv→/usr/local/sbin,occtl/ocpasswd→/usr/local/bin)
ninja -C build install

实测输出(编译产物版本回显):

OpenConnect VPN Server 1.6.0

安装产物路径(默认前缀 /usr/local,经重定向安装实测同构):ocserv/ocserv-worker → /usr/local/sbin/,occtl/ocpasswd → /usr/local/bin/,防火墙辅助脚本 ocserv-fw → /usr/local/libexec/。无法直写 /usr/local 的受限环境用 meson install -C build --destdir <自定义目录> 验证,产物落 <自定义目录>/usr/local/... 同构路径(本机实测即此形态)。

再用 1.6.0 二进制校验 apt 版(1.1.3)的旧配置(实测通过,退出码 0,但给出两处版本差异提示):

note: 'min-reauth-time' was replaced by 'ban-time'
note: vhost:default: setting 'plain' as primary authentication method
note: the cisco-client-compat option implies select-group-by-url = true; enabling
note: setting 'file' as supplemental config option

💡 说明:这组 note 是 1.1.3 → 1.6.0 升级的真实兼容性情报——min-reauth-time 在 1.6 中更名为 ban-time(旧名仍被接受并提示);cisco-client-compat 会隐式启用 select-group-by-url。旧配置可直接沿用,但升级后建议按提示改名。

⚠️ 注意:编译版与 apt 版不要同时跑(端口/配置冲突)。切编译版时先 systemctl disable --now ocserv,再用编译版二进制指向同一配置启动;或给编译版单独建 systemd 单元(ExecStart=/usr/local/sbin/ocserv --foreground --config /etc/ocserv/ocserv.conf)。

5.2 编译安装 openconnect v9.21(实测通过)

客户端 9.21 官方发布 tarball 用 autotools 构建(注意:GitLab 归档里没有预生成 configure,直接用官网 tarball):

apt-get install -y build-essential pkg-config libgnutls28-dev libxml2-dev zlib1g-dev gettext
curl -sSL -o openconnect-9.21.tar.gz "https://www.infradead.org/openconnect/download/openconnect-9.21.tar.gz"
tar xzf openconnect-9.21.tar.gz && cd openconnect-9.21
./configure --prefix=/usr/local
make -j$(nproc)
make install && ldconfig
/usr/local/sbin/openconnect --version | head -3

实测输出(节选,二进制随系统 locale 输出中文):

OpenConnect 版本 v9.21
正使用 GnuTLS 3.7.3。当前功能: PKCS#11, HOTP software token, TOTP software token, System keys, DTLS, ESP
支持的协议: anyconnect(默认), nc, gp, pulse, f5, fortinet, array
默认 vpnc-script(使用 --script 覆盖): /usr/share/vpnc-scripts/vpnc-script

⚠️ 注意(实测踩坑):①make install 默认前缀 /usr/local,二进制落在 /usr/local/sbin/openconnect(sbin 不是 bin);②新装的 v9.21 链接 /usr/local/lib 下的 libopenconnect.so.5,若不执行 ldconfig(或显式 LD_LIBRARY_PATH=/usr/local/lib)会与系统 8.20 的旧库冲突而报 libopenconnect.so.5: version 'OPENCONNECT_5_9' not found;③本次最小依赖编译出的 9.21 功能集(PKCS#11/HOTP/TOTP/System keys/DTLS/ESP)比 apt 版 8.20 少了 TPMv2 与 RSA token 项——那是可选依赖(libtss2-dev、libstoken-dev 等)未装所致,需要时补装后重新 configure 编译即可。

六、方案对比与选择建议

维度方案 A:apt 在线方案 B:源码编译
版本ocserv 1.1.3 / openconnect 8.20(jammy 冻结版)ocserv 1.6.0 / openconnect v9.21(2026-10 上游最新)
耗时分钟级依赖下载+编译实测约 5 分钟
升级维护apt upgrade 自动手动重编译
配置兼容同参数命名一致,配置文件可直接复用(实测 1.6.0 二进制 -t 通过 1.1.3 配置)
适用稳定优先、无人值守维护需要新版特性(如 1.6 的 OIDC 认证)、版本对齐要求

建议:无特殊版本诉求一律方案 A;编译版作为长期运行方案时,把编译安装纳入版本管理(记录 commit/tag 与编译参数)。

七、配置说明(安装后要点)

7.1 文件与路径清单(方案 A 实测)

文件说明
/etc/ocserv/ocserv.conf主配置(667 行,注释详尽)
/etc/ocserv/ocpasswdplain 认证口令文件(ocpasswd 维护)
/etc/ocserv/server-cert.pem、server-key.pem、ca.pem自签服务器证书三件套(4.2 生成)
/lib/systemd/system/ocserv.servicesystemd 单元(enabled,ExecStart=/usr/sbin/ocserv --foreground --pid-file /run/ocserv.pid --config /etc/ocserv/ocserv.conf)
/usr/sbin/ocserv、/usr/bin/occtl、/usr/bin/ocpasswd服务端三件套
/usr/bin/openconnect、/usr/share/vpnc-scripts/vpnc-script客户端与网络脚本

7.2 端口与协议

  • TCP 端口:TLS 控制通道(CSTP/HTTPS);UDP 端口:DTLS 数据通道,两者默认同号、可分开配。
  • 云服务器安全组与防火墙都要放行「TCP+UDP 双协议同一端口」;只放 TCP 时客户端会回落 TLS/TCP(能通但性能差,实测 -b 连接日志出现「DTLS 已禁用」)。

7.3 开机自启与多实例

  • apt 安装默认已 enable(systemctl is-enabled ocserv → enabled)。
  • 多实例:复制 systemd 单元改 --config 与端口/socket 文件路径即可;socket-file、pid-file、tcp-port、udp-port 四项必须实例间错开。

7.4 防火墙(ufw)

ufw allow 15001/tcp
ufw allow 15001/udp
ufw status

⚠️ 注意:本实测机 ufw 为未启用状态(Status: inactive),以上规则为启用 ufw 时的标准写法;在启用 ufw 的机器上执行前先确认 ufw allow 22/tcp(SSH 放行),否则会自锁远程会话。

7.5 升级与版本管理

apt-get update && apt-get upgrade ocserv      # 方案 A 升级(jammy 内只推安全补丁,版本号不变)
apt-cache madison ocserv                       # 查软件源全部可装版本
apt-get install ocserv=1.1.3-1                 # 版本回退/固定(实测 jammy 源仅此一版)

⚠️ 注意:Ubuntu 22.04 生命周期内 apt 不会把 ocserv 升到 1.6.x;需要新版本走方案 B 并自行跟踪上游 releases(https://gitlab.com/openconnect/ocserv/-/releases.atom)。

八、常见问题(FAQ)

Q1:重启失败,日志报 error: vhost:default: you cannot mix multiple password authentication methods? 配置同时写了 auth 与 enable-auth 两行同类口令认证(本文实测踩过)。保留一行 auth = "plain[...]",删掉 enable-auth 行。

Q2:客户端报 SSL 连接失败:Error in the pull function.? 服务端日志若出现 The futex facility returned an unexpected error code.(实测出现在受限制内核环境),把 isolate-workers = true 改为 false 并重启服务。正常独立服务器保持 true。

Q3:首连时客户端打印一大段证书指纹提示? 自签证书未受信时 openconnect 会提示接受与否并打印指纹;用 --servercert=pin-sha256:<指纹> 跳过。注意该指纹是证书**公钥(SPKI)**的 SHA256,不是整证书文件指纹——直接照抄客户端提示里给出的 pin 值最稳。

Q4:443 被占用怎么办? ss -ltnp | grep :443 找到占用方(常见为 web 服务器),或者直接把 tcp-port/udp-port 改成高位端口(本文 15001),重启即可;客户端地址后缀端口 https://server:15001。

Q5:openconnect 连上了但断网/不通? ① 服务端地址池与客户端本地网段撞段(改 ipv4-network);② 分流路由 route 未包含目标网段;③ 云平台未放行 UDP 导致只有 TCP 回落通道。逐项用 ip route show、occtl show status、连接日志实测核对。

Q6:错误口令试错被记分后 IP 会封吗? 计分与封禁列表真实生效(occtl show ip ban points / show ip bans / unban ip),但 1.1.3 实测中超过阈值后正确口付认证仍可成功(多轮复测),不要把它当唯一防线;叠加 fail2ban 监控认证失败日志。

九、卸载与清理

systemctl disable --now ocserv    # 停服务并取消自启
apt-get purge -y ocserv ocserv-common openconnect libopenconnect5 vpnc-scripts gnutls-bin
rm -f /etc/ocserv/ocpasswd /etc/ocserv/server-cert.pem /etc/ocserv/server-key.pem /etc/ocserv/ca.pem \
      /etc/ocserv/ca-key.pem /etc/ocserv/ca.tmpl /etc/ocserv/server.tmpl
rm -rf /etc/systemd/system/ocserv.service.d /usr/local/sbin/ocserv /usr/local/sbin/openconnect \
      /usr/local/lib/libopenconnect* /usr/local/libexec/openconnect
userdel -r vpnadmin 2>/dev/null   # 删除开箱验证用的系统账号
ss -ltnp | grep -E ':(443|15001)\b'; pgrep -a ocserv; pgrep -a openconnect

💡 说明:purge 会连带删除 conffile(/etc/ocserv/ocserv.conf);最后一行实测应无任何输出(无监听、无进程)才算清理干净。自建证书文件不在包管理范围内,需手动删除(rm 命令已含)。

十、参考链接