Cisco ASA 到 Azure VPN:流量选择器的前缀对
把 ASA 到 Azure VPN 的连接写成一份契约:连接模型、精确前缀对、选择器验证,然后回滚。一份与版本匹配的运行手册。
隧道起来了,IKE 看起来健康,却没有任何流量通过。这是 ASA 到 Azure 选择器问题的常见形态,也是我在碰任何一台控制台之前先写契约的原因。契约是四件事:标识每个对端的对象、连接模型、精确的前缀对,以及证明每一对的验证。这些弄错了,之后每条命令都在调试一份你本不该搭建的配置。这份运行手册就是我使用的顺序,并附上能指出哪个对象真正出错的命令。
配置之前先写下四个对象
从 ASA 版本与平台、公网端点、Azure VPN 网关的类型与 SKU,以及代表你这一侧的本地网络网关开始。这四个名字是后续一切的词汇表,出问题时它们各有不同的负责人。
如果其中两个还只是猜测,就停下来。本地网络网关上前缀列表写错,不是调优问题。
选定一种连接模型,停止混用模板
crypto map 设计与 tunnel interface 设计是两种不同的配置,改一下对端地址并不会让其中一种的模板对另一种生效。粘贴任何内容之前,先记录你在搭哪一种,因为不匹配后来会以选择器问题的形式出现,而不是配置错误。微软的 ASA 互操作指南 覆盖了这两种模式,并说明各自假定哪种 Azure 网关模型。如果你的笔记没有写出模型,你就还没有设计。
带基于策略的流量选择器的基于路由的 Azure 网关是一个有明确文档的选项,不是默认值。如果你的设计依赖它,设计就必须写明,因为默认的基于路由的选择器模型在 Azure 一侧行为不同。
版本限制也属于契约。一份关于加密域上限的旧现场报告,只是关于特定版本的数据点,而不是每台 ASA 的永久属性。
枚举前缀对,而不是聚合
把矩阵写出来。本地 A、B 到 Azure X、Y 是四对,每一对要么需要覆盖,要么需要明确的排除。把 A 和 B 合并成一个聚合,也会把它们之间的东西一并包含进去,设计就是这样悄悄长出一个洞。
检查对端协商了什么,而不是你保存了什么。ASA 上的本地与远端网络列表是意图;CHILD SA 才是结果。
某一对缺失时,修复通常是一行 access-list 或一个选择器条目,而不是新建隧道。
用点名对象的命令来验证
在 ASA 上先确认 IKE 会话,再确认 IPsec SA,最后确认选择器对。每条命令回答不同的问题,只跑第一条,正是「隧道起来了」变成错误结论的原因。要读你实际配置的那个对端的输出,而不是列表里恰好排第一的 SA。Azure 一侧也从自己的视角回答同样三个问题。
show crypto ikev2 sa detailed
show crypto ipsec sa peer 203.0.113.10
show run access-list AZURE-SELECTORS
packet-tracer input inside icmp 10.1.10.10 8 0 10.2.20.20 detailed
然后用 az network vpn-connection show --name <connection> --query connectionStatus 向 Azure 查询连接状态。显示已连接、数据路径却是零字节,这是选择器问题,不是路由问题。
每一对测一条被允许的流,检查对端看到的源地址,再试一个本应被拒绝的资源。只有最后这项测试才能证明边界仍然存在。
把加密范围与访问权限分开
选择器宽不等于授权。如果受支持的布局比应用策略更宽,就把窄服务留在防火墙规则里,让加密范围待在它必须在的地方。
Azure 工作负载路由与本地回程路由分别评审。BGP 通告、静态网络范围和用户定义路由必须描述同一条路径,且任何一项都不得递归捕获对端传输。
回滚,以及它确实生效的证明
改动选择器之前,保留之前的运行配置,并知道那条能把它放回去的命令。在 ASA 上,这意味着保存的副本和对应的恢复路径,而不是凭记忆回想你改了什么。趁变更还是假设的时候,就把恢复命令写进变更工单。然后重跑同样的三项检查:IKE 状态、IPsec SA 对、每对一条被允许的流。
如果恢复之后某一对仍然失败,那变更就不是原因,你刚刚替自己省下了第二次中断。