Azure Virtual WANでSNAT/DNATを実現する

複数の拠点からAzure Virtual WANへS2S VPNで接続する環境があります。各拠点からAzureへ接続する際にはSNATとDNATを適用する要件があり、これまでは拠点側のルータ設定で実現していました。しかし、ルータの機種がバラバラでNATの設定を機種ごとに用意しなければならなかったため、Azure Virtual WANでSNAT/DNATが適用できるか調査、検証してみることにしました。

# Virtual WANでのNATの考え方、用語
なかなか独特です。独自の世界観をまず押さえる必要があります。

## 種類
動的か静的かを選択します。
### 動的（Dynamic）
いわゆるNAPTです。IPとポートの組み合わせを使って1対多の関係でNAT変換がおこなわれます。
「変換元のアドレスプールサイズ > 変換先のアドレスプールサイズ」の場合、動的を選択します。
例）変換元：192.168.0.0/24 -> 変換先：10.100.0.0/26

### 静的（Static）
1対1の変換をします。「変換元のアドレスプールサイズ = 変換先のアドレスプールサイズ」でなければなりません。DNATする場合は静的を選択することになります。

## IP構成ID
ここで指定するIDはVPNゲートウェイのインスタンスIDです。Virtual WANはVPNゲートウェイを作るとActive/Active構成で2インスタンスできます。（スケーリングユニットが20超えるとさらにインスタンスが増えます）動的NATの場合、このIDを指定する必要があります。静的NATではIP構成IDの選択はありません。

## モード
Azure Virtual WANでは「IngressSnat」、「EgressSnat」の2つのモードがあります。これがとても理解しづらいです。Azure側を起点にIngressとEgressを考えます。設定次第でDNATと同じことができるのですが、DNATという単語はどこにも出てきません。

### IngressSnat
* **拠点→Azure**の通信で**送信元IP**を変換する
Azureから見るとイングレス通信。その送信元のIPをNATしているのでSNAT。わかる。
* **Azure→拠点**の通信で**宛先IP**を変換する
Azureから見るとエグレス通信だが…？混乱。

### EgressSnat
* **Azure→拠点**の通信で**送信元IP**を変換する
Azureから見るとエグレス通信。その送信元のIPをNATしているのでSNAT。わかる。
* **拠点→Azure**の通信で**宛先IP**を変換する
混乱の極み。なぜIngressDnatといわないのか…

DNATを実現する設定もSNATの名を冠しているので訳が分からなくなるのですが、こういうものと割り切るしかありません。

この考え方を整理するうえでこちらの記事を参考にしました。わかりやすいです。
[Azure VPN Gateway で NAT を試す！](https://www.cloudou.net/vpn-gateway/vpn007/)

## マッピング
NAT変換するIPアドレスのマッピングです。内部マッピングと外部マッピングがあります。

### 内部マッピング
NAT変換前のIPアドレスです。
### 外部マッピング
NAT変換後のIPアドレスです。

# 要件に応じた設定の組み合わせ
整理すると以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/80b38d0b-4ef0-c302-327b-1c4c8d9b782a.png)

:::note warn
拠点→Azureについては検証してSNAT/DNATともに動作することを確認していますが、Azure→拠点方向のSNAT/DNATは未検証です。情報を整理すると上の表のようになるはずですが、机上での整理となります。
:::

# 動作検証
拠点→AzureのSNATとDNATを以下の構成で検証しました。BGPは無効です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/69634380-9e59-a5c1-8f40-96b36fa4d758.png)

オンプレミスのルータを用意できなかったので、拠点は以下で代替しています。
* Azure上に拠点を模したVnet作成
* 仮想ネットワークゲートウェイとローカルネットワークゲートウェイを用意して、Virtual WANとS2S VPNを確立
* 動作確認用にVMを1台作成

これらの設定手順やVirtual WANの基本セットアップは本題から外れるので詳細な手順は割愛します。

## NATの設定
NATの設定画面には仮想ハブの「VPN（サイトからサイトへ）」の画面から遷移できます。
![nat01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/fdccee19-b096-44b2-95fa-642fc06fb679.png)

SNATとDNATに対応する設定を下図のように入れます。
![nat-rule.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/1dcd3671-7142-e99c-79b4-b7a3bee70bf2.png)
* SNAT用の設定は動的としたので、IP構成IDの選択が必要。Instance0とInstance1用のルールをそれぞれ用意する。注意点としてInstance0とInstance1で重複する外部マッピングは指定できない。拠点1のサイトには「10.200.0.0/26」を割り当てているので、これを半分に割ってそれぞれ「10.200.0.0/27」、「10.200.32.0/27」を指定。
* 1個のIPアドレスを内部マッピング/外部マッピングで指定する際、「/32」をつけないとエラーになる
* 内部ポートマッピング、外部ポートマッピングは何も指定しない
* 「VPNリンク接続」で拠点1とのリンクを指定


## ローカルネットワークゲートウェイ側のアドレス空間指定
拠点側のローカルネットワークゲートウェイではアドレス空間にDNATの宛先として指定しているアドレスを入力します。ルータの実機で設定する場合、DNATの宛先をVPNトンネルに流すような設定をすることになると思います。
![lgw01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/b914ac3a-4d53-b53f-bfa3-0a76f2606442.png)

## 通信確認
拠点1上のVMからDNATで指定している宛先アドレスを指定してpingをうち、Azure上のVMと通信できていることが確認できました。

![vm-branch01-testresult.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/7065ff10-8ae7-55af-d1e0-ce5a4d1520b8.png)

以下の動作検証も行ってみましたが、問題なく動作しました。
* 拠点1と同じネットワークアドレスである拠点2に対しても同様の設定を行い、「拠点2→Azure上のVM」間でSNAT/DNATして通信
* AzureのVnetと同じネットワークアドレスである拠点3に対しても同様の設定を行い、「拠点3→Azure上のVM」間でSNAT/DNATして通信

## 補足事項
現状、NAT規則は100個までしか作れません。接続する拠点数が増えたり、NATする対象が増えるとこの上限に抵触する可能性があるので注意が必要です。

Virtual WANではなく、VPNゲートウェイ（仮想ネットワークゲートウェイ）でもNATは可能です。ただし、使えるSKUは「VpnGw2～5、および VpnGw2AZ～5AZ」となっているため、金額はお高めになります。

# まとめ
Microsoftの公式ドキュメントではDNATはできないように見えましたが、設定次第でDNATができることを確認できました。独特の概念で理解しづらく、なかなかクセが強いですが、Virtual WAN側のNATを使いこなせれば設計・設定の選択肢が増えます。ぜひ理解して活用していきましょう。