しばやん雑記

Azure Serverless とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure App Service のネットワーク関連アップデート (NAT Gateway / NSG / Access Restriction)

ASE ではないマルチテナントの App Service では Outbound IP は同じ Stamp に乗っている他の App Service と共有されていて、外部連携などで IP を使ったアクセス制限が必要な場合には若干の問題がありましたが、NAT Gateway を使うことで任意の IP に固定できるようになりました。

少し前から検証用の環境で NAT Gateway を使った Outbound IP の固定が行えるようになっていることは確認していましたが、正式にアナウンスがあったので安心して使うことが出来ます。

アナウンスでは NAT Gateway にのみ触れられていますが、ついでに色々確認したところ NSG での Service Tag を使ったフィルタリングも正しく動作するようになっていたので、それについても書いています。

あまり関係ないですが Access Restriction でも Service Tag が使えるようになっていたので一緒に書きます。

NAT Gateway サポート

もはや説明は不要な気もしますが、App Service は Stamp や Scale unit と呼ばれる VM の集合体の単位でホストされているため、Outbound IP は 1 つではなく 2~8 ぐらいが割り当てられています。

ドキュメントにもあるように、この Outbound IP は App Service Plan の Tier 変更によって変化します。

最近では Regional VNET Integration や Service Endpoint / Private Endpoint によって Azure 内では IP アドレスを使った制限は必要なくなってきましたが、外部連携などで Outbound IP を固定したいこともあります。

このようなケースでは NAT Gateway を用意するのが定石ですが、Regional VNET Integration が GA した時には動きませんでした。しかし今回のアップデートでその辺りが正しく動作するようになったので、また 1 つ App Service の制約が取り払われました。

NAT Gateway を利用するためには App Service で Regional VNET Integration と WEBSITE_VNET_ROUTE_ALL を有効にする必要があります。要するに Private Endpoint を使う時と同じです。

これから実際に試すわけですが、NAT Gateway を追加する前に Outbound IP を確認しておきます。

f:id:shiba-yan:20201117235834p:plain

NAT Gateway は適当にパブリック IP を作成して、App Service や VNET と同じ場所にデプロイしておきます。IP Prefixes も動作すると思いますが、今回は 1 つの IP を割り当てました。

f:id:shiba-yan:20201117234134p:plain

このパブリック IP アドレスが App Service の Outbound IP として使われるようになります。

デプロイが完了すれば、後は App Service を参加させている Subnet へ NAT Gateway を割り当てます。試した限りでは反映されるまで少しかかるようでしたので、焦らずに待ちます。

f:id:shiba-yan:20201117234144p:plain

実際の Outbound IP を確認するにはアプリに組み込む方法もありますが、自分は手軽に済ませたいので Kudu から curl を使って IP を返す API を適当に呼んでいます。

f:id:shiba-yan:20201117234406p:plain

返ってきた IP は NAT Gateway に割り当てたパブリック IP と同じであることが確認できます。設定と動作としてはこれだけですが、これまで色々と言われていた部分なので解消されたのは喜ばしいです。

アナウンスでは Outbound IP の固定化だけではなく、専用の NAT Gateway を使うことで SNAT ポート周りの制約も大きく緩和されたとありました。個人的にはあまり困ったことは無いのですが、SNAT でのポート枯渇で苦しんでいた場合には有効でしょう。

NSG での Service Tag サポート

Regional VNET Integration の GA 時に NSG のサポートも同時に行われましたが、以前に自分が試した時は NSG の Service Tag を使ったフィルタリングは正しく動作していませんでした。

詳細は以下のエントリに書いていますが、全てが Any として扱われているようでした。

これが何時からか分かりませんが、気が付いたら正しく動作するようになっていました。NAT Gateway のサポート時に修正が行われたのかもしれません。

例えば以下のように Japan East の App Service へのアクセスをブロックするルールを追加してみます。これまでは全ての Outbound 通信がブロックされてしまいました。

f:id:shiba-yan:20201117234654p:plain

しかし今は Japan East の App Service への通信だけがブロックされるようになりました。それ以外のリージョンにデプロイされている App Service への通信は問題なく行えます。

f:id:shiba-yan:20201117235111p:plain

冷静に考えると特定サービスへのアクセスだけ許可・拒否する NSG ルールを追加するより、全てを Private Endpoint 経由にしてインターネットへのアクセスをブロックした方がシンプルな気がしますが、何かしらのユースケースに合うかもしれません。

Access Restriction での Service Tag サポート

あまり前の 2 つとは直接は関係ないのですが、App Service の Access Restriction で Service Tag を条件に指定出来るようになっていました。これまでは IP アドレスと VNET が指定可能でした。

ARM REST API 的には Service Tag が追加されていたのは知っていましたが、Azure Portal から設定出来るようになりました。アナウンスされるのかは微妙です。

f:id:shiba-yan:20201117233808p:plain

VM の場合は Network Interface に NSG を追加出来るので、アクセス元をサービス単位で細かく制限可能でしたが、これで App Service でも同じようなアクセス制限を実現可能です。

Azure Portal から選択できる Service Tag は全体の一部で、Event Grid や Logic Apps といった App Service / Azure Functions 上の API を実際に利用するサービスが用意されていました。

f:id:shiba-yan:20201117233827p:plain

特に便利だと思うのは Front Door Backend の Service Tag だと思います。これまでは IP の範囲を追加していましたが、変更される可能性はあるとドキュメントに明記されていました。しかし Service Tag で指定すると IP 範囲の変更の影響を受けません。

今回のアップデートで App Service のネットワーク周りでイマイチだと思っていた部分が一気に解消されました。これまでなら ASE が必要なことが多かったのですが、マルチテナントの App Service で実現できるアーキテクチャが増えたので本当に嬉しいです。