你粘贴了入门邮件里的地址,客户端连到网关,出现的登录表单却是通用门户,而不是运维人员说的合作伙伴门户。没有任何报错,正因如此才让人困惑:隧道甚至可能建立起来,只是落在错误的入口后面。那个 URL 里的路径本来在起作用,替换掉它的东西把这个作用丢掉了。

把工单里作为同一串字符出现的两件事分开:到达服务的地址,以及决定认证从哪里开始的输入。只修前者、忽略后者,就是主机名正确却仍然登录错误的原因。

在出现表单之前客户端发送了什么

对于 https://vpn.example.net/partners 这样的地址,客户端的第一个动作是向该路径而不是裸主机发出 HTTPS 请求。返回的通常是到登录端点的重定向,或者表单本身。只拿到 vpn.example.net 的客户端会从当时默认的落地页开始,那可能是另一个门户、另一份分组列表,或者一个期待完全不同协议的页面。在任何凭据被输入之前,差异就已经出现在响应头里了。

这就是为什么可用的浏览器标签页和失败的客户端配置可以指向同一个网关,却仍然对不上。浏览器跟着路径走了;配置里从来没有它。

两个看起来可以互换、其实不能的输入

OpenConnect 把初始 HTTPS 路径暴露为 --usergroup,而手册页面把携带该路径的完整 URL 当作同一请求的另一种写法。--authgroup 是另一个选项:它从网关在登录表单里展示的列表中选择一项。有些协议把这一项叫分组,有些叫域或网关,两个参数正是在这里被混淆的。

服务完全可能同时需要两者。路径可能把你带到正确的门户,而表单仍然要求你在其中选择分组。把门户名当作分组名传,或者反过来,会得到一个看起来被接受、随后却无法授权的登录,因为值在语法上有效、在语义上错误。

请运维人员把每个值分别写在单独一行:入口路径、表单选择,以及两者是否都需要。不要因为标签听起来相似就从一个推出另一个。

为什么截掉路径会改变结果

只接受主机和端口的客户端往往仍然能连上,所以症状很少是硬失败。取而代之的是错误的登录页、空的分组列表、不再与运维人员公布内容一致的证书名,或者在没有通往目标服务的路由时仍然建立的隧道。这些各自处在不同层次,没有一个能靠把更长的字符串粘进一个文档里写着主机名的字段来修好。其中两个从外部也无法区分,因为两者都表现为一个只是不再继续的登录表单。

用 IP 地址替换主机名是另一个常与之同行的错误。基于名称的服务选择和证书校验都依赖名称,所以数字地址可能把路径格式问题变成 TLS 错误。

浏览器地址还带有路径之外的东西。会话标识、重定向目标、语言前缀和临时登录参数都会出现在地址栏里,而它们都不该出现在保存的客户端配置里。

在改动其他任何东西之前先确认入口

读取所给路径的响应头。curl -sS -o /dev/null -D - https://vpn.example.net/partners 这样的请求会打印状态行和任何 Location 头,而不跟随重定向。指向具名登录端点的 302 说明路径存在,并显示它通往哪里;404 意味着运维人员给的地址已经过期。

然后在获准的客户端里复现同一个入口,例如 openconnect --usergroup=partners vpn.example.net,观察出现的是哪个表单。如果表单正确而隧道仍然失败,那路径从来不是问题,下一站是策略或路由。

把主机名、端口、协议、入口路径和表单选择作为五个独立字段记录在工单里。正是这份清单让下一位工程师能区分不可达服务器、TLS 拒绝、被拒绝的选择,以及在没有所需路由时建立的隧道。

相关文章