OpenConnect 常用 CLI 命令详解
把 OpenConnect 服务端三件套 ocserv/occtl/ocpasswd 与客户端 openconnect 逐条梳理为带真实回显的运维手册,覆盖启停、踢线、封禁、改配置、口令管理与连接参数。
OpenConnect 常用 CLI 命令详解
目标:把 OpenConnect 生态的命令行工具梳理成一张可日常翻查的运维手册——服务端三件套
ocserv/occtl/ocpasswd与客户端openconnect,逐条给出真实回显(全部来自同一台 Ubuntu 22.04 服务器的实测记录,执行日期 2026-10-20),并给出可直接复用的运维组合。
一、环境信息
- 操作系统:Ubuntu 22.04.4 LTS (jammy),x86_64,内核 6.8.0-138-generic,root 权限
- 服务端:ocserv 1.1.3-1(apt 安装,systemd 单元
/lib/systemd/system/ocserv.service托管,--foreground方式运行);上游最新稳定版 ocserv 1.6.0(2026-10-20 官方 releases 实查,源码编译产物在本文 4.2 节实测) - 客户端:同机安装两版——apt 版 openconnect 8.20-1(
/usr/bin/openconnect)与源码编译版 v9.21(/usr/local/sbin/openconnect,PATH 优先生效);本文连接实测的客户端为 v9.21(服务端会话详情中 User-Agent 可证),两版 CLI 参数兼容 - 服务形态:测试配置监听高位端口 15001(TCP+UDP),plain 认证(口令文件
/etc/ocserv/ocpasswd,账号 admin,口令 q1w2e3r4),地址池 10.10.10.0/24,推送路由 10.10.20.0/24 - 命令回显说明:服务端日志类输出为英文原文;openconnect 客户端输出随系统 locale 为中英混合原文,均未加工
二、前置条件
- 已按《Ubuntu 22.04 安装 OpenConnect 指南》完成服务端安装、认证配置与客户端安装(本篇不重复安装)。
- 服务在运行中:
systemctl is-active ocserv为 active;ss -ltnp | grep ocserv能看到监听端口。 - occtl 依赖服务端管理 socket(配置
use-occtl = true且socket-file = /run/ocserv.socket),服务未运行时所有 show 类命令都会失败(见第九章 FAQ)。 - 至少一个可用的 plain 认证账号(本文用 admin)。
三、命令与工具总览
| 命令 | 归属 | 作用 |
|---|---|---|
| ocserv | 服务端主程序 | 启动服务(-c 配置、-t 校验、-f 前台、-d 调试);日常由 systemd 托管 |
| occtl | 服务端管理工具 | 状态/会话/统计查询、踢线、解封、配置热重载、停服 |
| ocpasswd | 服务端口令工具 | plain 认证口令文件维护(建号/改密/建组/锁定/解锁/删除) |
| openconnect | 客户端 | 连接任意兼容网关(--protocol 支持 7 种协议)、后台化、证书固定 |
| vpnc-script | 客户端辅助 | 连接建立/拆除时配置 tun 网卡、路由、DNS(由 openconnect 自动调用,一般不手工执行) |
systemd 单元实测(cat /lib/systemd/system/ocserv.service):
[Service]
ExecStart=/usr/sbin/ocserv --foreground --pid-file /run/ocserv.pid --config /etc/ocserv/ocserv.conf
ExecReload=/bin/kill -HUP $MAINPID
RuntimeDirectory=ocserv
💡 说明:systemd 是日常运行形态,
ocserv --foreground(前台模式)+--pid-file+--config正是该单元使用的三个参数;手工前台调试的写法与单元一致(见 4.3 节)。
四、服务端命令:ocserv
4.1 版本与帮助
ocserv --version 实测输出:
OpenConnect VPN Server 1.1.3
Compiled with: seccomp, tcp-wrappers, oath, radius, gssapi, PAM, PKCS#11, AnyConnect
GnuTLS version: 3.7.3
Compiled with: 一行是排障金矿——编译特性决定配置可用性(如没有 PAM 就用不了 auth = "pam[...]",没有 radius 就用不了 RADIUS 认证)。
ocserv --help 实测输出(完整):
ocserv - OpenConnect VPN server
Usage: ocserv [ -<flag> [<val>] | --<name>[{=| }<val>] ]...
-f, --foreground Do not fork into background
-d, --debug=num Enable verbose network debugging information
- it must be in the range:
0 to 9
-c, --config=file Configuration file for the server
- file must exist
-t, --test-config Test the provided configuration file
--no-chdir Do not perform a chdir on daemonize
-p, --pid-file=file Specify pid file for the server
-v, --version output version information and exit
-x, --traceable Allow processes tracing
- use for debugging purposes only
-h, --help display extended usage information and exit
Openconnect VPN server (ocserv) is a VPN server compatible with the
openconnect VPN client. It follows the TLS and DTLS-based AnyConnect VPN
protocol which is used by several CISCO routers.
Please send bug reports to: openconnect-devel@lists.infradead.org
4.2 配置校验:ocserv -t
改配置后先校验再重启是标准动作,三种路径实测(详见《OpenConnect 配置参数详解》第三章):
ocserv -t -c /etc/ocserv/ocserv.conf # 合法 → 两条 note,退出码 0
ocserv -t -c /etc/ocserv/broken.conf # 非法值 → error,退出码 1
ocserv -t -c /nonexistent.conf # 文件不存在 → error,退出码 1
实测回显:
note: vhost:default: setting 'plain' as primary authentication method
note: setting 'file' as supplemental config option
warning: skipping unknown option 'bogus-option'
error: the tcp-port option is mandatory!
error: cannot access config file: /nonexistent.conf
💡 说明:不认识的选项名只给 warning 并跳过(不阻断),值非法才 error。校验能通过的配置仍可能有语义问题(如端口被占用),最终以启动日志为准。
4.3 版本升级差异校验(1.6.0 二进制实测)
用源码编译的 1.6.0 二进制(编译目录内 ./build/src/ocserv,即安装指南方案 B 的产物)校验 1.1.3 的旧配置文件,可提前发现版本间参数变化(实测):
./build/src/ocserv -t -c /etc/ocserv/ocserv.conf
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
4.4 手工前台运行(排障形态)
官方排障姿势是不进 systemd、前台跑:
systemctl stop ocserv
ocserv -f -c /etc/ocserv/ocserv.conf -p /var/run/ocserv-fg.pid
-f/--foreground 正式 systemd 单元同款参数;-d 0~9 逐级加大调试量(-d 1 即可看到 listening/auth 细节)。前台运行时 Ctrl+C 即停服,排障完 systemctl start ocserv 恢复托管形态。
⚠️ 注意:手工前台运行要留意
pid-file与 socket 文件路径的写权限;若日志出现could not chown socket ...: Permission denied,优先检查当前身份与socket-file所在目录权限。生产排障建议保持 systemd 托管、用journalctl -u ocserv -f看实时日志,减少手工形态带来的路径差异。
五、服务端管理命令:occtl
5.1 帮助(命令树总览)
occtl --help 实测输出(完整):
occtl: [OPTIONS...] {COMMAND}
-s --socket-file Specify the server's occtl socket file
-h --help Show this help
--debug Enable more verbose information in some commands
-v --version Show the program's version
-j --json Use JSON formatting for output
Available Commands
disconnect user [NAME] Disconnect the specified user
disconnect id [ID] Disconnect the specified ID
unban ip [IP] Unban the specified IP
reload Reloads the server configuration
show status Prints the status and statistics of the server
show users Prints the connected users
show ip bans Prints the banned IP addresses
show ip ban points Prints all the known IP addresses which have points
show iroutes Prints the routes provided by users of the server
show sessions all Prints all the session IDs
show sessions valid Prints all the valid for reconnection sessions
show session [SID] Prints information on the specified session
show user [NAME] Prints information on the specified user
show id [ID] Prints information on the specified ID
show events Provides information about connecting users
stop now Terminates the server
全局选项三个常用:-j/--json(机器可读输出)、-s(指定 socket,多实例部署时用)、--debug(更详细输出,show events 必开,见 5.8)。
5.2 show status:服务器状态与统计
occtl show status 实测输出(有一活跃会话时):
Note: the printed statistics are not real-time; session time
as well as RX and TX data are updated on user disconnect
General info:
Status: online
Server PID: 1793572
Sec-mod PID: 1793575
Sec-mod instance count: 1
Up since: 2026-10-20 21:29 (10m:23s)
Active sessions: 1
Total sessions: 1
Total authentication failures: 0
IPs in ban list: 0
Median latency: <1ms
STDEV latency: <1ms
Current stats period:
Last stats reset: 2026-10-20 21:29 (10m:23s)
Sessions handled: 1
Timed out sessions: 0
Timed out (idle) sessions: 0
Closed due to error sessions: 0
Authentication failures: 0
Average auth time: 0s
Max auth time: 0s
Average session time: 0s
Max session time: 0s
Min MTU: 1434
Max MTU: 1434
RX: 0 bytes
TX: 0 bytes
💡 说明:输出开头的 Note 很关键——统计非实时,会话时长与 RX/TX 在用户断开时才结算。巡检脚本若要拉实时流量,用 show user <name> 的 RX/TX(同为断开结算口径)或部署侧 netflow。
JSON 模式(occtl -j show status,脚本解析友好)实测节选:
{
"Status": "online",
"Server PID": 1717690,
"Sec-mod PID": 1717692,
"Sec-mod instance count": 1,
"Up since": "2026-10-20 21:10",
"_Up since": " 2s",
"raw_up_since": 1792501846,
"uptime": 2,
"Active sessions": 0,
"Total sessions": 0,
"Total authentication failures": 0,
"IPs in ban list": 0,
"Median latency": "<1ms",
"raw_median_latency": 0,
... ...
"RX": "0 bytes",
"raw_rx": 0,
"TX": "0 bytes",
"raw_tx": 0
}
(严格 JSON——jq 可直接解析,如 occtl -j show status | jq -r '.Status' 实测返回 online。字段名是人类可读口径(含空格、首字母大写),并伴随 raw_* 原始数值字段,机器取数按需选择。)
5.3 show users:在线用户列表
occtl show users 实测输出:
id user vhost ip vpn-ip device since dtls-cipher status
1836337 admin default 127.0.0.1 10.10.10.165 vpns0 1s (AES-256-GCM) connected
5.4 show user / show id:单会话详情
occtl show user admin 实测输出(完整):
ID: 1836337
Username: admin Groupname: (none)
State: connected
vhost: default
Device: vpns0 MTU: 1434
Remote IP: 127.0.0.1 Location: unknown
Local Device IP: 127.0.0.1
IPv4: 10.10.10.165 P-t-P IPv4: 10.10.10.1
User-Agent: AnyConnect-compatible OpenConnect VPN Agent v9.21
RX: 48 (48 bytes) TX: 352 (352 bytes)
Average bandwidth RX: 48 bytes/sec TX: 352 bytes/sec
DPD: 60 KeepAlive: 300
Hostname: ops
Connected at: 2026-10-20 21:39 ( 1s)
Session: RdaN9p
TLS ciphersuite: (TLS1.3)-(ECDHE-SECP256R1)-(RSA-PSS-RSAE-SHA256)-(AES-256-GCM)
DTLS cipher: (DTLS1.2)-(PSK)-(AES-256-GCM)
CSTP compression: oc-lz4 DTLS compression: oc-lz4
Routes: 10.10.20.0/255.255.255.0
Restricted to routes: False
occtl show id 1836337 输出与 show user 相同(同一会话的两种寻址方式);occtl show session RdaN9p 用会话 ID 查询,格式同。排障价值:User-Agent 看客户端软件与版本、ciphersuite 看加密协商、Routes 看实际推送。
5.5 show sessions all / valid:会话 ID 列表
session user vhost ip user agent created status
RdaN9p admin default 127.0.0.1 AnyConnect-compatible Op 1s authenticated
show sessions all:全部会话(含已失效待回收的)。show sessions valid:仍可用于断线重连的会话。本例两者一致(活跃会话)。
5.6 show iroutes:用户宣告路由
occtl show iroutes 实测输出(无用户宣告 iroute 时仅表头):
id user vhost device vpn-ip iroute
iroute 是「某个在线用户把它身后的子网宣告给 VPN」的机制,配合客户端路由传播实现站点接入。
5.7 封禁观测:show ip bans / show ip ban points / unban ip
错误口令连续触发计分后(每错一次 +10,默认 ban-points-wrong-password = 10):
occtl show ip ban points
IP score
127.0.0.1 30
达到 max-ban-score(默认 80)后进入封禁列表(带过期时间):
occtl show ip bans
IP score expires
127.0.0.1 80 2026-10-20 21:03 ( 4m:30s)
手工解封:
occtl unban ip 127.0.0.1
IP '127.0.0.1' was unbanned
⚠️ 注意:封禁到期时间按
min-reauth-time(默认 300s)计算;计分按ban-reset-time(300s)周期整体归零。1.1.3 实测中超过阈值的 IP 用正确口令仍可完成认证(多轮复测),封禁列表更多是观测手段,硬拦截建议叠加 fail2ban(详见《OpenConnect 配置参数详解》5.2 节实测结论)。
5.8 show events:连接事件流(配合 --debug)
occtl --debug show events 是常驻流式输出,跟随打印连接/断开事件(实测回显):
Press 'q' or CTRL+C to quit
default: connected user 'admin' (1645449) from 127.0.0.1 with IP 10.10.10.165
default: disconnect user 'admin' (1645449) from 127.0.0.1 with IP 10.10.10.165 (reason: server disconnected, time: 5s)
⚠️ 注意:实测不带
--debug直接occtl show events无任何输出(既无提示也无事件);用--debug形式稳定可用。适合临时盯现场;长期审计用 journalctl。
5.9 disconnect:踢用户(两种寻址)
occtl disconnect user admin # 按用户名踢(该用户全部会话)
occtl disconnect id 1836337 # 按会话 ID 踢(精准单会话)
实测回显:
connection ID '1836337' was disconnected
目标不存在时(实测):
could not disconnect user 'admin'
5.10 reload:配置热重载
occtl reload
Server scheduled to reload
reload 只调度、不等于已生效——超时/并发/路由类参数重连后生效(实测改 dpd=60→90 后重连收到 X-CSTP-DPD: 90);认证方式/端口/证书类必须 systemctl restart ocserv。
5.11 stop now:命令行停服
occtl stop now
Server scheduled to stop
实测后 systemctl is-active ocserv 变为 inactive(main 进程退出);恢复用 systemctl start ocserv。这是不登 systemd 主机(仅 ssh 转发 occtl socket)时也能停服的通道。与 reload 的 Server scheduled to reload 同为「调度」语义——命令返回即表示已受理。
六、服务端口令管理:ocpasswd
6.1 帮助与文件格式
ocpasswd --help 实测输出(完整):
ocpasswd - OpenConnect server password utility
Usage: ocpasswd [ -<flag> [<val>] | --<name>[{=| }<val>] ]... [username]
-c, --passwd=file Password file
-g, --groupname=str User's group name
-d, --delete Delete user
-l, --lock Lock user
-u, --unlock Unlock user
-v, --version output version information and exit
-h, --help display extended usage information and exit
Options are specified by doubled hyphens and their name or by a single
hyphen and the flag character.
This program is openconnect password (ocpasswd) utility. It allows the
generation and handling of a 'plain' password file used by ocserv.
Please send bug reports to: openconnect-devel@lists.infradead.org
口令文件格式(实测 cat /etc/ocserv/ocpasswd):
admin:*:$5$9i1c.Z750LjoyTex$oyz.Qi.2NUKoeBUxie5uqAbzO.w4U6cD0aqvHJdpA75
demo:contractors:$5$VjefTgCXux1nWUTD$63YqBebYAppg/2vrcWhOnrQ0mNc.e10eJSyRYoMdkUA
三段式 用户名:组名:哈希;哈希为 SHA512-crypt($5$ 前缀);组名为空即无组(detail 里 Groupname: (none))。
6.2 创建与改密(-c 必带)
printf 'q1w2e3r4\nq1w2e3r4\n' | ocpasswd -c /etc/ocserv/ocpasswd admin # 口令经 stdin 传入(两行:输入+确认)
实测要点:不带 -c 直接 ocpasswd /etc/ocserv/ocpasswd admin 会打印完整 usage 帮助并退出(-c 是必选项而非可选)。
6.3 建组与换组(-g)
printf 'q1w2e3r4\nq1w2e3r4\n' | ocpasswd -c /etc/ocserv/ocpasswd -g vpnusers demo # 建号同时入组
printf 'q1w2e3r4\nq1w2e3r4\n' | ocpasswd -c /etc/ocserv/ocpasswd -g contractors demo # 改组(重新输入口令,生成新盐值哈希)
实测错误:-g 写两次会拒绝——
-g option cannot be specified multiple time
用户入第二个组的办法:手工编辑口令文件把组段写成逗号分隔(demo:group1,group2:哈希),ocpasswd 本身一次只写一个组。
6.4 锁定 / 解锁 / 删除(-l / -u / -d)
printf 'q1w2e3r4\nq1w2e3r4\n' | ocpasswd -c /etc/ocserv/ocpasswd bob # 先建一个测试账号
ocpasswd -c /etc/ocserv/ocpasswd -l bob # 锁定
grep '^bob:' /etc/ocserv/ocpasswd # 看锁定效果
ocpasswd -c /etc/ocserv/ocpasswd -u bob # 解锁
grep '^bob:' /etc/ocserv/ocpasswd
ocpasswd -c /etc/ocserv/ocpasswd -d bob # 删除
grep '^bob:' /etc/ocserv/ocpasswd; echo "exit=$?"
实测输出(-l / -u / -d 本身均无任何回显、静默成功,操作结果靠 grep 口令文件确认):
bob:*:!$5$wxD3GgZ0Z6F5Kvlo$jpD0D9pnFN.At/MmxwCXCxGSsxG1rmteJN0F9qZBkCA ← 锁定后:哈希前插入 '!'
bob:*:$5$wxD3GgZ0Z6F5Kvlo$jpD0D9pnFN.At/MmxwCXCxGSsxG1rmteJN0F9qZBkCA ← 解锁后:'!' 被移除
exit=1 ← 删除后:整行消失
锁定/解锁就是往哈希前插/移除 !,删除直接移除整行——三条命令都没有确认提示、也没有成功消息,操作结果要靠 grep 口令文件确认,误删需重建。
七、客户端命令:openconnect
7.1 版本与帮助
openconnect --version(apt 版 8.20-1)实测输出:
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
openconnect --help(107 行完整帮助,节选高频项,原文):
用法: openconnect [选项...] <服务器>
--protocol=PROTO 更新所有 URL 的安全协议
可选值: anyconnect|nc|gp|pulse|f5|fortinet|array
-b, --background 继续在后台运行
-p, --key-password=PASS 密钥或令牌的解锁口令
--external-auth=MODE 使用外部认证工具 (浏览器)
-q, --quiet 少打印信息
-v, --verbose 多打印信息
-u, --user=NAME 登录身份
-s, --script=SCRIPT vpnc-script 脚本以配置网络
--servercert=HASH 只接受与 HASH 匹配的服务器证书
--no-dtls 禁用 DTLS 和 ESP
-C, --cookie=COOKIE 认证时使用 cookie
--authenticate 从服务器获取认证 cookie,然后退出
--cookieonly 从服务器获取认证 cookie,然后退出(不连接)
--pid-file=PIDFILE pidfile
--timestamp 输出时间戳作为部分输出前缀
--token-mode=MODE 软件令牌类型: rsa, totp, hotp, oidc 或系统默认
(完整清单以 openconnect --help 为准;其余低频选项不逐条展开。)
7.2 连接(前台交互)
openconnect --servercert=pin-sha256:7ginaG3nWN8ZbISIdJoGE4YFrrlf6ujtXeYtRSlCfis= --user=admin 127.0.0.1:15001
实测输出(节选,v9.21 客户端 + ocserv 1.1.3 服务端):
POST https://127.0.0.1:15001/
已连接到 127.0.0.1:15001
SSL 与 127.0.0.1 协商
服务器证书验证失败:未找到签署者
已使用加密套件 (TLS1.3)-(ECDHE-SECP256R1)-(RSA-PSS-RSAE-SHA256)-(AES-256-GCM) 连接到 127.0.0.1 上的 HTTPS
XML POST 已启用
Please enter your username.
POST https://127.0.0.1:15001/auth
Please enter your password.
Password:
POST https://127.0.0.1:15001/auth
得到了 CONNECT 响应:HTTP/1.1 200 CONNECTED
CSTP 已连接。DPD 60,持久连接(Keepalive)300
已建立 DTLS 连接(使用 GnuTLS)。密码套件 (DTLS1.2)-(PSK)-(AES-256-GCM)。
DTLS 连接压缩正使用 LZ4。
已配置为 10.10.10.165,使用 SSL + LZ4 已连接 和 DTLS + LZ4 已连接
使用 vhost-net 进行 tun 加速,环大小 32
--servercert 的 pin-sha256: 值是服务器证书**公钥(SPKI)**的 SHA256 base64,不是整证书文件指纹。首连不带该参数时,客户端会在证书确认提示里直接给出可抄的 pin(实测原文):
来自 VPN 服务器 "127.0.0.1" 的证书验证失败。
原因:未找到签署者
要在将来信任此服务器,可以添加这个到你的命令行:
--servercert pin-sha256:7ginaG3nWN8ZbISIdJoGE4YFrrlf6ujtXeYtRSlCfis=
输入 "yes" 以接受,"no" 以中止;其他任意键以查看:X.509 Certificate Information:
完整提示里还有 Public Key PIN: pin-sha256:7ginaG3nWN8ZbISIdJoGE4YFrrlf6ujtXeYtRSlCfis= 一行,把它抄进 --servercert 即完成固定。口令可在 Password: 处交互输入;脚本化时 printf '口令\n' | openconnect ... 经 stdin 传入(实测可用)。注意管道输入时上面的证书确认提示同样从 stdin 读,所以首连固定 pin 的动作建议在交互终端完成。
7.3 后台化与进程管理(-b / --pid-file / --timestamp)
printf 'q1w2e3r4\n' | openconnect -b --servercert=pin-sha256:7ginaG3nWN8ZbISIdJoGE4YFrrlf6ujtXeYtRSlCfis= \
--user=admin --pid-file=/var/run/openconnect.pid --timestamp 127.0.0.1:15001
实测输出(节选):
[2026-10-20 21:58:31] 已配置为 10.10.10.165,使用 SSL + LZ4 已连接 和 DTLS + LZ4 已连接
[2026-10-20 21:58:31] 在后台继续;pid 1910112
-b:认证成功后转入后台并打印主进程 PID(在后台继续;pid NNN)。--pid-file:把同一个 PID 落盘;实测cat /var/run/openconnect.pid返回的数字与pgrep -a openconnect看到的守护进程号一致。- 退出:
kill $(cat /var/run/openconnect.pid);实测 kill 后pgrep openconnect无进程、tun 网卡与隧道路由随进程退出自动清理(见 7.6)。 --timestamp:每行日志加[yyyy-mm-dd hh:mm:ss]前缀(实测如上),脚本日志审计友好。
7.4 TCP 回落模式(--no-dtls)
printf 'q1w2e3r4\n' | openconnect -b --no-dtls --servercert=pin-sha256:7ginaG3nWN8ZbISIdJoGE4YFrrlf6ujtXeYtRSlCfis= \
--user=admin --pid-file=/var/run/openconnect-nd.pid --timestamp 127.0.0.1:15001
实测输出(节选):
[2026-10-20 21:58:36] CSTP 已连接。DPD 60,持久连接(Keepalive)300
[2026-10-20 21:58:36] 已配置为 10.10.10.165,使用 SSL + LZ4 已连接 和 DTLS 已禁用
[2026-10-20 21:58:36] 在后台继续;pid 1910375
服务端视角(occtl show users,与另一条 DTLS 会话并列时实测):
id user vhost ip vpn-ip device since dtls-cipher status
1925521 admin default 127.0.0.1 10.10.10.187 vpns1 4s (no-dtls) connected
1925042 admin default 127.0.0.1 10.10.10.165 vpns0 8s (AES-256-GCM) connected
no-dtls 会话的 dtls-cipher 列显示 (no-dtls)。适用于 UDP 被策略性封禁、只放行 TCP 的网络。日常 UDP 可用时不要加(DTLS 吞吐显著更好)。
7.5 认证失败与被拒行为(实测)
错误口令(stdin 传错值)实测输出:
Please enter your username.
Please enter your password.
Password:
Login failed.
Please enter your password.
Password:
fgets (标准输入): Inappropriate ioctl for device
服务端同号计分 +10(见 5.7);脚本传错口令后 stdin 耗尽即报 Inappropriate ioctl for device 退出(这不是故障,是交互重试与管道输入的固有冲突)。
同账号超过 max-same-clients 上限被拒(实测 max-same-clients=1 时第二个连接):
得到了不正确的 HTTP CONNECT 响应:HTTP/1.1 401 Cookie is not acceptable
创建 SSL 连接失败
Cookie was rejected by server; exiting.
7.6 断开清理
客户端退出(kill/被踢)后自动清理 tun 网卡与路由(实测断开后 ip addr show tun0 报 Device does not exist、ip route 无隧道路由、pgrep openconnect 无进程)。服务端踢线见 5.9。
八、典型运维组合(SOP)
SOP-1 日常巡检(状态、在线、异常认证):
occtl show status | grep -E 'Status|Active sessions|Total authentication failures|IPs in ban list'
occtl show users
SOP-2 踢指定用户下线:
occtl disconnect user admin # 或先 occtl show users 拿 id 再 disconnect id <id>
SOP-3 认证失败排查(谁在试、试了几次):
occtl show status | grep authentication failures
occtl show ip ban points
journalctl -u ocserv --since '-10min' | grep -E 'failed|invalid'
SOP-4 改配置上线(校验 → 分级生效 → 验证):
ocserv -t -c /etc/ocserv/ocserv.conf && occtl reload # 运行参数
systemctl restart ocserv # 认证/端口/证书类
occtl show status && printf 'q1w2e3r4\n' | openconnect -b --servercert=pin-sha256:... --user=admin 127.0.0.1:15001 # 回归验证
SOP-5 新增/停用账号(plain 认证):
printf '新口令\n新口令\n' | ocpasswd -c /etc/ocserv/ocpasswd -g vpnusers alice # 新增
ocpasswd -c /etc/ocserv/ocpasswd -l alice # 临时停用(可逆)
ocpasswd -c /etc/ocserv/ocpasswd -d alice # 注销
九、常见问题(FAQ)
Q1:occtl 全部命令报 error connecting to ocserv socket '/var/run/occtl.socket'?
服务没在跑(或管理 socket 未开)。先 systemctl is-active ocserv、ss -lx | grep ocserv 确认 socket 存在;多实例或自定义 socket-file 时用 occtl -s <socket路径> 显式指定。
Q2:脚本管道传口令报 Inappropriate ioctl for device? 管道输入只有一行口令,客户端认证失败后想再次交互重试但没有 tty(见 7.5 实测);属预期行为。修正口令或改交互终端执行。
Q3:disconnect 报 could not disconnect user 'xxx'?
该用户名当前没有在线会话(或拼写不同)。用 occtl show users 拿到真实 id 再 disconnect id <id>。
Q4:show events 没有输出?
加 --debug:occtl --debug show events(实测稳定输出连接/断开事件流);不带 --debug 在 1.1.3 上无输出。
Q5:occtl show status 的 RX/TX 与用户实际流量对不上?
统计在断开时结算(输出首行 Note 明示),活跃会话的量不实时累计;看单用户详情用 occtl show user <name>(同为断开结算口径)。
十、参考链接
- ocserv 手册页:
man ocserv、man occtl、man ocpasswd(随 ocserv 1.1.3-1 软件包安装) - openconnect 客户端帮助与官网文档:https://www.infradead.org/openconnect/manual.html(2026-10-20 查询)
- ocserv 官方仓库:https://gitlab.com/openconnect/ocserv(2026-10-20 查询)
- 站内同系列:《Ubuntu 22.04 安装 OpenConnect 指南》《OpenConnect 配置参数详解》《OpenConnect 介绍与选型指南》