在 Cloud VPN 隧道上始终到不了 Established 的 BGP 会话,通常不是路由问题。这是接线问题:两个必须互为镜像的地址被写反了,或者第一条隧道的地址对被挪到了第二条上。隧道本身可以完全健康,会话却停在 Waiting for peer,因为 IPsec 和 BGP 是同一对端点之间的两场独立协商。重建任何东西之前,先判断这两者中到底哪一个坏了。

一个问题就能定下大多数情况:对端设备究竟能不能看到 Cloud Router 的地址?

隧道状态和会话状态是两项不同的检查

IKE 和 ESP 在先。如果隧道没有建立,里面的东西都不重要,讨论 BGP 地址为时过早。先读隧道状态和详细信息,再读同一隧道的路由器 BGP 对端状态。

隧道已建立、BGP 对端却已断开,故障就缩小到会话本身:对端地址、ASN,或者进到内层地址的 TCP 179。隧道已建立、会话已建立,却在 VPC 里仍然看不到任何路由,这是第三种情况。改地址对这个没用,因为会话已经在工作,只是前缀没有被宣告或没有被优先选择。把这三者区分开,就是这活儿的大半。

每条隧道都要有自己的 /30,两端都要填

每条 HA VPN 隧道从 169.254.0.0/16 里分到一个 link-local /30,一个地址落在 Cloud Router 接口上,另一个落在你的对端。对端字段必须写远端,绝不能写路由器自己的地址。

两条隧道意味着 Cloud Router 上两个接口,各自一个不同的 /30。把隧道 0 的地址对挪到隧道 1 上,这个错误在汇总表里看着很整齐,却死在 OPEN 报文里。

TunnelRouter interfacePeer addressWhat a swap produces
tunnel 0169.254.1.1/30169.254.1.2OPEN sent to itself or to nothing; session waits
tunnel 1169.254.1.5/30169.254.1.6same failure on the second session
bothone pair reusedone address reusedone session up, the other never leaves waiting

从路由器资源里读这一对地址,不要读控制台的汇总。汇总把对端地址放在一列里,很容易看错;接口的 ipRange 加上对端的 peerIpAddress,必须描述同一个 /30 的两端。

地址写反通常发生在重建的时候

恰恰是重建隧道的时候,地址对会串。旧隧道的对端地址被抄进新隧道的接口字段,或者新会话指向上一条会话的对端。无论哪种,Cloud Router 发出的 OPEN 报文都发往一个如今等于自己的地址,或者发往背后根本没有隧道的地址。

打开控制台之前先把这几对写下来:隧道名、接口、路由器地址、对端地址、对端 ASN。然后一次把两条隧道都建出来,免得第二条用第一条的剩料填成。

会话卡住的另外三个原因

第一是对端 ASN:两边都要配成对方的 ASN,不一致时能到达对端却永远建立不起来。第二是对端自己的防火墙,必须在隧道接口上放行 TCP 179,IKE 或 ESP 的规则覆盖不到。第三是对端从一个不同于邻居配置的源地址回包。

对端自己的日志才是判据。如果它的 BGP 汇总里没有该地址的邻居,说明报文没到,地址对或路径是错的。如果邻居停在 Active 或 Connect,说明报文到了,是会话参数对不上。

按报文行走的顺序逐层核对

从外往里查:先隧道状态,再路由器 BGP 对端状态,再对端 BGP 汇总,最后看路由。前两项健康就别再改 Cloud VPN 这一侧,去动对端设备。如果路由器报对端已断开,而你的设备上根本没有邻居,那就是地址对写错了,或者 BGP 端口被过滤。在对端隧道接口上抓一次包就能一眼定案,因为 OPEN 报文要么到得了那里,要么永远到不了。

gcloud compute routers get-status ROUTER --region=REGION 会把对端状态打在它正在使用的地址旁边,那正是你要比对的那一对。

会话建立之后,确认学到的前缀出现在 VPC 路由表里,并且两侧各有一台主机能应答。然后把最终的地址对写在隧道名旁边,下次重建就从一张验证过的表出发,而不是从控制台的汇总出发。

相关文章