背景と目的
Hub & Spoke構成のAzure環境で、インターネットやオンプレ拠点との接続用にSASE製品を組み合わせる検証作業をやっていました。
以前はSASE製品の収容をVPN Gateway経由で行っており、BGPで受け取った経路はGateway伝達によりVNetに自動的に反映されていました。拠点増減時に設定変更する必要があるため、今回の構成検討と至ったものみられます(この構成検討は別チームで行っていたので自分はそこまで詳しくない)

トポロジ: SASE製品(GW) ↔ NVA ↔ Azure Route Server (ARS) ↔ Hub & Spoke。
この構成変更により、SASE製品とHubの間にNVAを挟むことになりました。NVAが学習したルートをVNetに反映する方法がないため、Azure Route Serverを使うこととなりました。Azure Route ServerはBGPのルートリフレクタとして振る舞い、実際のデータパケットについては扱わないようです。
HubにはAzure Route ServerやNVAの他に、Azure FirewallもありSpokeのすべての通信はAzure Firewallを通過させたい意図があります。Hubは通信の要所としています。HubとSpoke間はVNet Peeringしています。
遭遇した課題
Azure Route ServerとNVA間でBGPはEstablishedになっておりオンプレ拠点のPrefixも受信していましたが、非対称ルーティングが発生し、実際の通信がAzure Firewall等にブロックされる事象が発生しました。調査のためにユーザー定義ルート(以後UDRと表記)をNVAのAzure Firewall接続サブネットに作成し、Spoke宛はAzure Firewallを通るよう指定すると通信ができました。
下記の記事にあるような非対称ルーティングです。オンプレ拠点発、Spoke行きの通信がHubに到達後VNet Peeringを辿ってSpokeに到達するが、オンプレ拠点に戻ろうとする際にAzure Firewallを通ることで非対称ルーティングとなります。
実際の通信がAzure Firewall等にブロックされる事象というのは具体的に、SpokeのWebサーバからオンプレ拠点に対して、TCPのハンドシェイクは成功しますがHTTPの通信が成功しないという状況でした。nc -z コマンドは成功しますが、curlコマンドの応答がありませんでした。パケットキャプチャを見ると、Azure基盤(Arista)からRSTが返ってきている状況でした。行きと帰りで出現するMACアドレスが違ったため、非対称ルーティングかな?と疑うきっかけとなりました。
Azureのルーティング優先順位
Azureでは下記のルート選択優先順位があります。これはプレフィックス長が同じ場合に適用されます。
複数のルートに同じアドレス プレフィックスが含まれている場合は、次の優先順位に基づいてルートの種類が選択されます。 ユーザー定義のルート BGP のルート システム ルート
BGP がより具体的なプレフィックスをアドバタイズする場合でも、ピアリングされた仮想ネットワークのシステム ルートは BGP で学習されたルートよりも優先されます。
これらの仕様を踏まえたうえで、実際に起きたことを見ていきましょう。HubとSpoke間でVNetピアリングを張ると、自動的にSpoke VNetアドレス空間の具体的なシステムルートが生成されます。これに対し、UDRで「172.16.0.0/12(RFC1918)」のような広い範囲を指定しても、LPM(より具体的なルートを優先する原則)によりシステムルートに負けてしまいます。UDRがないと、Spokeのすべての通信はAzure Firewallを通過させたい意図を満たすことができません。
参考: LPMについて
BGPでSpoke VNetアドレス空間の具体的なルートがAzure Route Serverによって広報されたら問題なく通信できると思ったのですが、実は違いました。「BGP がより具体的なプレフィックスをアドバタイズする場合でも、ピアリングされた仮想ネットワークのシステム ルートは BGP で学習されたルートよりも優先され」てしまうのです。この挙動を回避するにはUDRでオーバーライドするしか無いようです。
BGP運用であっても、バイパスを防ぐためには Spokeサブネットと同じサイズ(/24など)のUDRを「行き」の経路にピンポイントで書く必要があります。
これではBGPを使っている意味が無いというか限定的になってしまいます。Azure Route Serverが経路を広報する際にNextHopをAzure FirewallのIPアドレスに変更するroute-mapのような機能があれば解決されると思われます。
Tips
Azure Route Serverが受け取ったルーティングを確認する方法はありますが、Azure Firewallに伝わっているかを確認する方法がありません。あるけどPreview版でうまく動きませんでした。
仮想マシンを立ち上げていたらAzure Portal上でEffective Routesを確認できますが、数が多いとCLIで見るかCSVダウンロードして見るしかないなど微妙な不便さがあります。Hub側とSpoke側両方で見たい場合も両方で仮想マシンを立ち上げる必要があり料金が発生してしまい不便ですね。