OpenConnect 用同一个短时效的值把两段彼此独立的交互串起来:Web 登录和 VPN 隧道。第一段是普通的 HTTPS:凭据、一次 SAML 往返或一个令牌被送到网关,响应里带回一个认证 Cookie。第二段把这个 Cookie 交给同一个网关,作为 Web 阶段已经完成的凭证,直到这时隧道才建立起来。

登录过程中并没有协商隧道的任何参数。这正是值得理解的地方,因为大多数脚本错误都以为 Cookie 是应当保存的密码,或是保护流量的密钥,而它实际上只是针对某个特定网关会话的持有式门票。

客户端与网关按顺序交换什么

认证阶段看起来就像一个普通的受保护网站。OpenConnect 发送用户凭据,或者跟随网关的重定向前往身份提供方,网关则返回一份内嵌认证 Cookie 的文档。在 AnyConnect 协议中,这个值会在后续请求的 Cookie 头里传输,通常使用 webvpn 这样的名字,手册把它当作延续会话的凭据。

第二阶段是带着该 Cookie 向网关的 VPN 端点发出 CONNECT 请求。网关检查它、分配地址,客户端在 TLS 之上启动 CSTP,会话建立后 DTLS 成为可选的更快数据通路。隧道参数、路由、DNS 设置和会话的流量密钥都只在这个时刻才确定。Cookie 只是让客户端进了门,它没有加密任何东西。

这个顺序解释了 openconnect --authenticate 为什么存在。运行它,它会完成 Web 阶段,打印一小段 shell 变量,如 COOKIE、HOST、CONNECT_URL 和 FINGERPRINT,然后在建立任何隧道之前退出。之后包装脚本可以用这些值启动真正的连接,而无头或双容器部署需要的正是这种拆分。

Cookie 是会话持有凭证,而不是密钥

对待这个值要像对待 Web 应用里的会话 ID 一样。在它的有效期内持有它的人,可以向网关索取该会话有权获得的隧道,因此它的保密性很重要。但复制它并不会泄露流量,因为隧道的机密性来自 TLS 握手和派生密钥,而不是 Cookie 字符串本身。

它也不是永久授权。会话能活多久由网关和身份提供方决定,而仍然显示已登录页面的浏览器,并不能说明隧道会话是否还有效。过期后重新连接意味着重做 Web 阶段并生成新的 Cookie,这正是重新认证的意义,而不是要用工程手段绕开的麻烦。

不要把 Cookie 当作其他凭据的通用替代品。SAML 断言、浏览器密码和由另一项服务签发的 Cookie 是面向不同对象的不同东西,把一个塞进另一个的字段,通常会在网关处失败,或者更糟,会在错误的信任边界上取得成功。

传递 Cookie 而不留下副本

Linux 上最安全的机械式交接是标准输入。--cookie-on-stdin 从 stdin 读取该值,因此 Cookie 永远不会出现在进程参数列表里,那里任何本地用户都可以用 ps 读到它。在一个进程里认证、在另一个进程里喂给隧道的管道,会把值留在管道中,而不是文件或环境变量里。

命令行参数和环境变量各有各的弱点。参数在客户端整个生命周期内都可见于进程表,而且常常落进 shell 历史。环境变量会被子进程继承,而在单元文件里设置它的 systemd 单元,会把秘密存进可读的配置。如果确实需要文件,就把它限制在服务账号下,并在会话结束时删除。

特权边界也要有意维持。与身份提供方对话、可能还要打开浏览器的进程,应当以拥有该登录的用户身份运行。配置路由、DNS 和隧道设备的进程可能需要更多特权。为了让 Cookie 供 root 所有的隧道使用而把整个浏览器都以 root 运行,是错误的取舍,而现代 OpenConnect 配置可以显式地把这个值跨过该边界传递。

日志同样值得怀疑。详尽的客户端输出、辅助脚本和网关诊断都可能复述请求材料,而且并非每个日志级别都会对 Cookie 做脱敏。只记录你需要的最小错误信息,把它挡在共享渠道之外,并在附到工单之前检查一份脱敏样本。

第二阶段的校验与过期

第二阶段仍然要校验服务器。--authenticate 打印的 FINGERPRINT 是 pin-sha256: 形式的证书固定值,用 --servercert 把它传给隧道调用,可以把校验锚定在你所认证的那台网关上。为了让脚本更简单而关掉证书校验,等于丢掉了 Cookie 被交给预期主机的唯一证据。

当网关拒绝这个 Cookie 时,解决办法是重新走一轮认证,而不是延长缓存。只在连接存续期间保存 Cookie,退出时删除临时文件,并在会话暴露或设备丢失时,使用身份提供方或网关的会话移除流程。被缓存的 Cookie 不是 MFA 的豁免。

在自动化之前,请确认四件事:隧道以正确的账号运行,Cookie 通过 stdin 到达,证书指纹已被固定,并且隧道关闭时会丢弃会话。缺任何一项,自动化就只是扩大了对 Cookie 的信任,而没有复现手工流程。

相关文章