我在 Windows 笔记本电脑上连接 Azure VPN 客户端,打开一个回显地址的页面,看到的仍是家里路由器分配的那个公网地址。与此同时,10.20.0.4 上的跳板机可以应答,私有终结点名称也能解析,说明隧道并没有坏。点到站点网关只是照着它默认的配置在工作:承载私有前缀,把其余流量全部留在本地链路上。要拿到一个属于 Azure 的出口地址,这是路由设计的改动,而不是一次修复。

网关默认通告什么

网关会推送虚拟网络地址空间的路由,以及允许网关传输的对等网络和通过站点到站点连接或 BGP 学到的本地前缀。这个集合里没有 0.0.0.0/0。你的操作系统把默认路由留在 Wi-Fi 或以太网上,所以发往公网 API 的数据包根本不会进入隧道。

客户端在隧道内拿到的地址,是点到站点地址池分配的私有租约。它用于向 VNet 内的资源标识客户端;它不是互联网能看到的地址,也永远不会作为发往 SaaS API 的出站请求源出现。围绕这个租约去配置允许列表是不可能生效的,无论你等多久让它在服务商日志里出现。

拆分隧道与强制隧道并列对比

Split tunnel, the defaultForced tunneling
Internet traffic exits throughlocal ISP or office routerfirewall or appliance inside Azure
Source address the API seesyour home or office IPthe firewall public IP
Inspection and logging in Azurenonepolicy rules plus flow logs
Ongoing costgateway onlygateway, firewall hours, data processing
What usually breaksnothing on the egress pathDNS, on-premises routes, overlapping local ranges

只有第二行会改变远端服务看到的地址。那张表里其余的东西,都是当出口必须在 Azure 内被检查或转换时你要承担的成本和运维面。如果有人要求你让公网 IP 改变,他要的是整个右列,而不是对客户端做一点小调整。

在重建任何东西之前,有一个中间方案值得先说明。在 VNet 内放一台代理或网关虚拟机,可以为那些能被指向它的应用提供一个可控的源地址,而不必移动客户端的默认路由。这样常规浏览仍留在本地,同时又能满足只需要一次 API 调用从 Azure 发出的合作方。当需求实际上是关于全部流量时,这个方案会失败,因为任何忽略代理设置的东西依旧从本地出去。

让隧道承载默认路由

在虚拟网络网关上,把客户端所有互联网流量导入隧道的受支持做法,是往点到站点配置里加入自定义路由。两个半边覆盖整个 IPv4 空间,而且都比本地默认路由更具体,所以客户端无需删除任何东西就会优先选择它们:

Set-AzVirtualNetworkGateway -VirtualNetworkGateway GWOBJ -CustomRoute 0.0.0.0/1,128.0.0.0/1

那一行只是示意,不是可以照抄的完整命令:先用 Get-AzVirtualNetworkGateway 取到网关对象并替换掉 GWOBJ,运行前再确认 SKU 和部署模型接受自定义路由。同样的前缀也出现在门户的点到站点配置页面上;如果你还没有用脚本管理网关,在那里设置更稳妥。

改动这些前缀会让客户端包失效。要重新下载 VPN 客户端包并重装,因为路由是随配置文件一起下发的。用旧配置文件重连的客户端会保留旧路由集,你可能白花一小时去排查一个根本没到达它的改动。

在受保护的虚拟 WAN 中心里,等价做法是在与点到站点网关关联的中心路由表中加一条默认路由,由中心里的 Azure Firewall 接管流量。防火墙会把去往互联网的连接转换成它自己的公网 IP 地址,新的出口地址就来自这次转换。当一台防火墙有多个公网 IP 时,其中任何一个都可能成为源地址,所以允许列表必须把它们全部列上。

上面两种设计都是 IPv4。两个 /1 前缀对 IPv6 毫无作用,而点到站点的 IPv6 支持范围很窄,在承诺对等之前应该先测试这种组合。

先查路由,再查出口

重装客户端包并重新连接后,确认客户端确实装上了两个半边。在 Windows 上,Get-NetRoute -DestinationPrefix 0.0.0.0/1 以及对 128.0.0.0/1 的同一查询应当指向隧道接口,route print 会把两者都显示在你原有默认路由旁边。在 Linux 上,ip route show 必须列出这两个前缀;如果没有,说明配置文件从未带上它们。

随后从客户端再次检查公网地址,并读取同一条连接的防火墙日志。源地址应当是防火墙的公网 IP,端口已做过转换。如果两条路由都在、客户端却仍从本地出去,说明数据包到了 Azure 又从别的路径离开:网关子网上的用户自定义路由、自身被强制隧道回本地网络的防火墙,或者在转换之前就把流量丢弃的策略。

在同一会话里再测一个私有目标。改动之后跳板机突然不应答,是常见的信号:新前缀挤掉了某些东西,要么是先前通告过的更具体的本地路由,要么是现在指向一个没有为你的私有区域配置转发器的解析器。

什么时候该保留拆分隧道

如果目标只是访问一个私有 API、一个私有终结点或一个内部管理页面,默认行为更省钱也更安静。强制隧道会增加防火墙时长和数据处理费用、更长的路径,以及又一个所有客户端流量都可能失败的地方。它抓取的流量也远多于你真正关心的那一个目的地。

当需求是以出口来表述的时候才用它:合作方必须看到一个固定的 Azure 地址,安全团队要求连接被记录和检查,或者数据必须经由一个受控点离开。即使如此,这种设计给每个用户的都是共享出口,所以按用户追责必须来自应用层的身份,而不是源地址。

在结束改动之前,确认四件事:安装的客户端包是新的、两个 /1 路由落在隧道接口上、私有目标仍能应答,以及远端服务的日志里出现防火墙地址。

相关文章