为什么 ASA 远程用户能到子网却到不了应用
路由只能证明隧道通,不能证明用户被允许打开应用。先读会话实际收到的过滤器,再分别测试一条被允许和一条被拒绝的连接。
你的用户连上了,也拿到了地址,还能 ping 通应用子网里的服务器,却始终打不开上面的服务。这种组合在 ASA 上很常见,因为 隧道建成和权限可用是由两套不同的设置决定的。拆分隧道列表只决定哪些目的地址进入隧道;VPN 过滤器和目的端自己的访问规则才决定解密后的请求能到哪一步。请按顺序检查这三个决定,而不是不断放宽路由列表直到出现变化。
三个容易混淆的决定
准入回答用户能不能建立隧道:凭据、证书以及任何第二因素。选路回答客户端把哪些目的地址送进隧道。授权回答解密后的请求能不能到达服务。只有第三个才会产生用户报告的错误。
快速区分它们的办法是问:一处改动会破坏什么。把某条路由从拆分列表里删掉,会停掉去往该子网的流量,但什么也不会放开;在 VPN 过滤器里加一条 ACE,只会放开一个目的地址,不会改变客户端走隧道的内容。
| Setting | What it decides | Symptom when it is wrong |
|---|---|---|
| Connection profile and authentication | Whether the tunnel is built | Login fails, no address assigned |
| Split-tunnel network list | Which destinations the client routes into the tunnel | Subnet unreachable from the client, everything else fine |
| VPN filter (ACL) | Which decrypted flows are permitted | Tunnel up, ping may work, TCP service refused or dropped |
读会话实际收到的过滤器
要从活动会话入手,而不是从你以为生效的配置入手。show vpn-sessiondb detail anyconnect 会输出该会话分配的组策略和所挂的过滤器名。如果该字段为空,就没有任何过滤器在生效,阻塞来自别处。
接着读拥有该值的策略,包括默认值,因为过滤器可能是继承来的,而不是写在你正在看的位置:
show run all group-policy <policy-name>
show run access-list <acl-name>
show run webvpn
把会话上的过滤器名和你刚改过的 ACL 对照。用户从未收到的同名 ACL 不可能改变该会话的资源策略,这正是看起来正确的改动毫无效果的最常见原因。
优先级解释了其余部分。对过滤器设置而言,DAP 记录高于用户名属性,用户名属性又高于组策略。当会话出现你没预料到的过滤器时,先去找与该用户匹配的 DAP 策略,再去改组配置。
拆分列表和过滤器是两个字段
在 ASA 9.x 上,组策略分别保存 split-tunnel-network-list 和 vpn-filter 这两项不同设置,9.22 的组策略指南正是为此把它们分开记录。网络列表只是给客户端的选路提示;过滤器才是施加在解密流量上的访问控制列表。
当用户只在一个子网里需要一项 HTTPS 服务时,这个区别很关键。把子网放进拆分列表让数据包进入隧道,然后在过滤器里只放行那一项服务。放宽路由列表不会授予任何权限,收紧路由列表也不是执行手段。
确认接口 ACL 是否真的在路径上
解密后的远程接入流量并不总像人们以为的那样经过 outside 接口的 ACL。在启用 sysopt connection permit-vpn 的地方,ASA 会对这类流量套用它有文档记载的 VPN 旁路,而适用的 VPN 过滤器之后仍然生效。要用 show run all sysopt 核对设置,而不是从拓扑图推断。
无论如何,目的主机自己的防火墙和应用的授权仍然在路径上。一条允许 TCP 443 的 ASA 规则,并不会让应用接受这个用户。
也要用一条被拒绝的连接来验收
只测一条放行的连接几乎证明不了什么,因为只要有隧道,不管有没有过滤器,第一个包都一样。先从客户端打开目标服务,再试一个应当保持关闭的目的地址,确认它是因为正确的原因失败。
关单时记下四件事:被准入的身份、会话实际收到的策略和过滤器、拆分列表中的目的地址,以及用户被允许访问的资源。这四项能说明流量在哪里受控,而不必把路由列表变成防火墙。
如果过滤器放行后服务仍然拒绝,就转到主机侧:监听地址、主机防火墙以及应用自己的用户映射。到这一步隧道已经完成了它的工作,再改 ASA 只会增加风险。