Azure Load Balancer の SNAT (Outbound 通信) がわからん

この記事では、Azure Load Balancer の配下にある[^haika] VM から、インターネットと通信したい時の話を取りあげます。
具体的には、いわゆる SNAT と呼ばれる仕組みで、Outbound 通信ができるパターンが LB の構成に依存していくつか存在するので、それを紹介します。

ただ、実の所このドキュメントに全部書いてあります。・・・・が、長い・・・[^long-doc]。

**Azure の Outbound connections - Azure Load Balancer | Microsoft Docs**
https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-outbound-connections

本稿は、上の内容を「**概要をぱっと速く掴みたい人**」向けにざっくりまとめたものです。

[^long-doc]: 細かいところを網羅しなければならないという、ドキュメントに課せられた要請上、仕方がない点です。

# 背景

本筋の前に、簡単に LB と VM の関係や、LB の SKU について確認しておきます。

* Load Balancer には **内部/パブリック** という種類がある[^lb-types]。
    * **パブリック ロードバランサー (Public Load Balancer)** は、すべてのフロントエンドが「パブリック IP アドレスのグローバル IP アドレス」で構成されている LB のことです。歴史的経緯から「外部 LB」と呼ぶこともあり、名称が短いという単純な理由で本稿では「外部 LB」と呼ぶことにします。
    * **内部ロードバランサー (Internal Load Balancer; ILB)** は、すべてのフロントエンドが「仮想ネットワーク内のプライベート IP アドレス」で構成されている LB のこと。
* Load Balancer の SKU には **Basic/Standard** がある[^lb-standard]。
    * 種類とは独立した概念です
    * 例) Basic SKU の内部 LB、Basic SKU の外部 LB
* VM は次のいずれかのパターンで LB に組み込める
    * 一つの内部 LB にだけ所属
    * 一つの外部 LB にだけ所属
    * 一つの内部 LB と一つの外部 LB の両方に所属 ※この時、両 LB の SKU が揃っている必要があります[^double-lb]。
    
[^lb-standard]: [Azure Standard Load Balancer とは - Azure Load Balancer | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-standard-overview#what-is-standard-load-balancer)
[^lb-types]: [Azure Load Balancer の概要 - Azure Load Balancer | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-overview#load-balancer-types) 
[^haika]: ある VM が LB の「配下にある」とは、その LB のあるバックエンド プールに属していることを意味しています。
[^double-lb]: [Azure ロードバランサー利用時の注意点 – Japan Azure IaaS Support Blog](https://blogs.technet.microsoft.com/jpaztech/2019/01/29/azurelb-tips/#cannot-add-vm)

# 1. パブリック IP アドレスがある VM の場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127839/312074e5-7463-aa1a-1a7f-859ca7cb529f.png)

**VM に関連付けられたパブリック IP アドレス (PIP) が存在する場合、LB の構成に関わらず、必ず PIP を利用して SNAT します。**

[上記ドキュメント](https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-outbound-connections)では[「シナリオ 1」](https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-outbound-connections#ilpip)に該当する構成パターンです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127839/0ed97cea-b198-7b81-2ac7-314aa5c53c6a.png)

以下で登場する他の構成パターンと異なり、**パブリック IP のすべてのエフェメラル ポートを使用できる**というメリットがあります。
ただ、デメリットとして PIP による金銭的コストの増加や、ファイアウォールの管理コストの増加等の影響があるので注意してください。

参考: [各 VM にパブリック IP を割り当てる | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-outbound-connections#assignilpip)

# 2. パブリック IP アドレスがない VM の場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127839/10498ab8-a4d0-67f9-db06-d595e105fd35.png)

パターンは 4 つですね。

- Azure 既定の SNAT
- 送信不可
- 外部 LB の SNAT
- 外部 LB の SNAT + 送信規則

## Azure 既定の SNAT

[上記ドキュメントの「シナリオ 3」](https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-outbound-connections#defaultsnat)に相当する状況。
VM のデプロイされた **Azure リージョンで使われる "任意のグローバル IP アドレス"[^azure-pip] を利用して SNAT** されます。

[^azure-pip]: なお、グローバル IP アドレスの一覧は、以下のページからダウンロード出来ます。

  Download Azure IP Ranges and Service Tags – Public Cloud from Official Microsoft Download Center
  https://www.microsoft.com/en-us/download/details.aspx?id=56519

	
注意事項としては、**送信フロー毎に利用される IP アドレスが変わる**こと。
例えばファイアウォールなどでホワイトリストしたり、サーバー側でクライアントの IP アドレスを利用するシナリオ等で注意が必要です。

## 送信不可

(パブリック IP アドレスもなく、外部 LB の配下にもいない VM が) **Standard SKU の内部 LB の配下にいる場合は、外部と通信できません**[^vm-within-ilb-cant-connect]。

[^vm-within-ilb-cant-connect]: [Azure ロードバランサー利用時の注意点 – Japan Azure IaaS Support Blog](https://blogs.technet.microsoft.com/jpaztech/2019/01/29/azurelb-tips/#outbound-cannot-connect)

## 外部 LB の SNAT

[上記ドキュメントの「シナリオ 2」](https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-outbound-connections#lb)に相当する状況。

**外部 Load Balancer のフロントエンドに付与したパブリック IP アドレスを利用して SNAT される**。そのため、SNAT で利用する IP アドレスが (一般に複数ではあるものの) 固定されているのが特徴。

このシナリオには、結構引っかかりやすい落とし穴がいくつかあるので要注意。

### 注意 1: 負荷分散規則を作って初めて SNAT 出来るようになる

Basic SKU の場合、TCP/UDP のどちらの負荷分散規則でも良いので、SNAT したい ipconfig に対する負荷分散規則を作成している必要がある。
    
■ Azure の Outbound connections - Azure Load Balancer | Microsoft Docs
https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-outbound-connections#preallocatedports

> Basic SKU の SNAT では、負荷分散規則で指定されたトランスポート プロトコルに関係なく、常に両方の IP トランスポート プロトコルに対して SNAT がプログラムされます。

### 注意 2: ipconfig ごとに任意のエフェメラル ポートが使える訳ではない
以下の公式ドキュメントに定義されているように、ipconfig ごとが利用できる SNAT ポート数 (i.e. 同時に張れる Outbound TCP コネクション数) は予め決まっている。
    
■ Azure の Outbound connections - Azure Load Balancer | Microsoft Docs
https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-outbound-connections#preallocatedports

> 次の表は、バックエンド プール サイズのレベルに対する SNAT ポートの事前割り当てを示しています。
> (表略)

## 外部 LB の SNAT + 送信規則

これも[ドキュメントの「シナリオ 2」](https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-outbound-connections#lb)に相当する状況で、基本は「外部 LB の SNAT」と同じだけど、**さらに送信規則によって SNAT をコントロール出来る**パターン。

"基本は" と述べたのは、**「外部 LB の SNAT」とは 注意 1 についての仕様が少し違う**から。具体的には次の通り。

- 負荷分散規則を構成して初めて SNAT 出来る点は、Basic も Standard も変わらない
- Standard SKU の場合は、TCP の SNAT なら TCP の負荷分散規則が、UDP の SNAT なら UDP の負荷分散規則が、といった風に**プロトコル毎の規則作成が必要**となる。

■ Azure の Outbound connections - Azure Load Balancer | Microsoft Docs
https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-outbound-connections#preallocatedports
> 重要
> Standard SKU の SNAT プログラミングは、IP トランスポート プロトコルに従い、負荷分散規則から派生します。 TCP 負荷分散規則だけが存在する場合、SNAT は TCP でのみ使用できます。 TCP 負荷分散規則しかないときに、UDP の送信 SNAT が必要な場合は、同じフロントエンドから同じバックエンド プールへの UDP 負荷分散規則を作成します。 これにより、UDP の SNAT プログラミングがトリガーされます。 動作規則や正常性プローブは不要です。

### 送信規則

この構成パターンの最大の特徴は、**送信規則 (outbound rule)** と呼ばれる、Standard 外部 LB 特有の機能が利用できること。
送信規則は、**Basic SKU での [注意 2] の制限を緩和する**目的で利用され、その概要や構成方法については以下の公式ドキュメントで詳細に記述されている。 

■ アウトバウンド規則 - Azure Load Balancer | Microsoft Docs
https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-outbound-rules-overview

# まとめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127839/312074e5-7463-aa1a-1a7f-859ca7cb529f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127839/10498ab8-a4d0-67f9-db06-d595e105fd35.png)

# 宣伝

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127839/6993cdbe-8509-e5a7-702c-6acf1db1f26a.png)

SNAT の裏の仕組みについての記事も書いてるので、ぜひ！！！

**Ananta: Azure を支えるステートフル L4 ロードバランサー - Qiita**
https://qiita.com/OpenJNY/items/6c5e6614868c732dff3b