Azure NATゲートウェイ

スポンサーリンク

Azure NATゲートウェイの使い方を説明します。仮想マシンをデフォルトの設定で作成する場合、パブリックIPアドレスが付与されます(正確に言えば、プライベートIPアドレスとパブリックIPアドレスが1:1でNATされる暗黙的な設定が作成されます)。この場合は何も意識する事なくインターネットへ接続できますが、パブリックIPアドレスを付与しない場合は「NATゲートウェイ」などを作成しない限り、インターネットへ接続する事ができません。

前提

公式ドキュメント

参考になる公式ドキュメントを以下に示します。

事前設定

以下、リソースグループを作成します。

az group create --name MyResourceGroup --location japaneast

仮想ネットワークとサブネットを作成します。

az network vnet create \
  --resource-group MyResourceGroup \
  --name Vnet01 \
  --address-prefix 172.16.0.0/16

az network vnet subnet create \
  --resource-group MyResourceGroup \
  --name Subnet01 \
  --vnet-name Vnet01 \
  --address-prefixes 172.16.1.0/24

費用削減のため、Azure Bastionサービスではなく、同等機能を提供する仮想マシンを作成します。

az network vnet subnet create \
  --resource-group MyResourceGroup \
  --name MyBastionSubnet \
  --vnet-name Vnet01 \
  --address-prefixes 172.16.0.0/24

az vm create \
  --resource-group MyResourceGroup \
  --name bastion250 \
  --image UbuntuLTS \
  --size Standard_B1s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/authorized_keys \
  --vnet-name Vnet01 \
  --subnet MyBastionSubnet \
  --private-ip-address 172.16.0.250

構成図

+---------------------------------------------+
|                                             |
| +-----------------------------------------+ |
| |                                         | |
| |  +---------------+   +---------------+  | |
| |  |linux010       |   |linux020       |  | |
| |  |172.16.1.10    |   |172.16.1.20    |  | |
| |  +---------------+   +---------------+  | |
| |                                         | |
| | Subnet01                                | |
| | 172.16.1.0/24                           | |
| +-----------------------------------------+ |
|                                             |
| +-----------------------------------------+ |
| |                                         | |
| |  +---------------+                      | |
| |  |bastion250     |                      | |
| |  |172.16.0.250   |                      | |
| |  +---------------+                      | |
| |                                         | |
| | MyBastionSubnet                         | |
| | 172.16.0.0/24                           | |
| +-----------------------------------------+ |
|                                             |
| Vnet01                                      |
| 172.16.0.0/16                               |
+---------------------------------------------+

疎通確認用 仮想マシンの作成

パブリックIPアドレスを持たない仮想マシンの作成

パブリックIPアドレスが付与されない仮想マシンを作成します。

az vm create \
  --resource-group MyResourceGroup \
  --name linux010 \
  --image UbuntuLTS \
  --size Standard_B1s \
  --admin-username azureuser \
  --admin-password P@ssw0rd1234 \
  --vnet-name Vnet01 \
  --subnet Subnet01 \
  --private-ip-address 172.16.1.10 \
  --public-ip-address ''

az vm create \
  --resource-group MyResourceGroup \
  --name linux020 \
  --image UbuntuLTS \
  --size Standard_B1s \
  --admin-username azureuser \
  --admin-password P@ssw0rd1234 \
  --vnet-name Vnet01 \
  --subnet Subnet01 \
  --private-ip-address 172.16.1.20 \
  --public-ip-address ''

仮想マシンへのログイン

仮想マシンはパブリックIPアドレスを持たないため、直接SSHなどでログインする事はできません。このシナリオでは、Azure Bastionサービスは使用せずに、Bastion相当の仮想マシンを構築していますので、Bastion相当の仮想マシンを経由してログインします。

Bastion相当の仮想マシンに付与されたパブリックIPアドレスを調査します。

$ az network public-ip show \
  --resource-group MyResourceGroup \
  --name bastion250PublicIP \
  --query ipAddress
"20.222.2.140"

Bastion相当の仮想マシン(bastion250)へログインします。

admin@mac19 ~ % ssh azureuser@20.222.2.140
The authenticity of host '20.222.2.140 (20.222.2.140)' can't be established.
ED25519 key fingerprint is SHA256:QYPbZYAwwdC+B+KpyA8WUpkDAqsCIsJir7cFAZb1+VI.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

  <omitted>

azureuser@bastion250:~$ 

Bastion相当の仮想マシン(bastion250)から、linux010(172.16.1.10)やlinux020(172.16.1.20)へログインします。

azureuser@bastion250:~$ ssh 172.16.1.10
The authenticity of host '172.16.1.10 (172.16.1.10)' can't be established.
ECDSA key fingerprint is SHA256:S9qC8QylHQ/nYmNy1uDLCV6I1sOVH4KvdCLaGBrH77A.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.16.1.10' (ECDSA) to the list of known hosts.
azureuser@172.16.1.10's password: 

 <omitted>

azureuser@linux010:~$ 

仮想マシンからインターネットへの疎通確認

インターネットへの疎通を確認します。仮想マシンに、パブリックIPアドレスもNATゲートウェイも設定されていませんが、一応は疎通可能です。

通信経路を把握するために、「https://whatsmyip.com」や「確認くん」などのWebサイトを利用します。これらWebサイトは送信元IPアドレスを表示してくれる便利なWebサイトです。「確認くん」は以下のように表示されます。

確認くん

「確認くん」で表示される送信元となるパブリックIPアドレスをgrepすると以下のようになります。

azureuser@linux010:~$ curl -s https://www.ugtop.com/spill.shtml | grep -i IPv4 -A 1
  <th>あなたのIPアドレス(IPv4)</th>
  <td><font size=+2 color=blue>20.222.209.217</font></td>
azureuser@linux010:~$ 

身に覚えがないパブリックIPアドレス「20.222.209.217」からインターネットに疎通可能な事が分かります。これは「既定の送信アクセス IP」と呼ばれるIPアドレスで、マイクロソフトが管理するIPアドレスです。マイクロソフトは「既定の送信アクセス IP」を実稼働ワークロードでの使用を推奨していません。

NATゲートウェイ

NATゲートウェイの作成

インターネットに接続するための「NATゲートウェイ」を作成します。「NATゲートウェイ」は単一のIPアドレスと紐づけるならば、az network public-ip createコマンドで「パブリックIPアドレス」を作成します。

もし、SNAT枯渇が心配されるようならば、「NATゲートウェイ」は複数のIPアドレスと紐づける事もできます。複数のIPアドレスを使用する場合は、az network public-ip prefix create「パブリックIPプレフィック」を作成します。

az network public-ip create \
  --resource-group MyResourceGroup \
  --name MyPublicIp \
  --sku Standard

az network nat gateway create \
  --resource-group MyResourceGroup \
  --name MyNatGateway01 \
  --public-ip-addresses MyPublicIp \
  --idle-timeout 4

az network vnet subnet update \
  --resource-group MyResourceGroup \
  --vnet-name Vnet01 \
  --name Subnet01 \
  --nat-gateway MyNatGateway01

仮想マシンからインターネットへの疎通確認

疎通確認の前に、「NATゲートウェイ」に割り当てたパブリックIPアドレスを確認します。

$ az network public-ip show \
  --resource-group MyResourceGroup \
  --name MyPublicIp \
  --query "ipAddress"
"52.140.213.186"

「確認くん」で表示される送信元となるパブリックIPアドレスを見ると、確かに「NATゲートウェイ」に割り当てたパブリックIPアドレスに変わった事が分かります。

Azure Virtual Network NAT 接続のトラブルシューティング」によると、NATゲートウェイはTCPとUDPをサポートし、ICMPはサポートされません。そのため、2022年4月時点の仕様では、pingによる疎通確認はできない事に注意ください。pingはNATゲートウェイを設定しても疎通不能です。

azureuser@linux010:~$ curl -s https://www.ugtop.com/spill.shtml | grep -i IPv4 -A 1
  <th>あなたのIPアドレス(IPv4)</th>
  <td><font size=+2 color=blue>52.140.213.186</font></td>
azureuser@linux010:~$ 

補足

ルートテーブル

Azureの仮想マシンはデフォルトゲートウェイまでパケットが到達した後は、ルートテーブルなどの設定に基づいてパケットがフォワードされます。どのようにフォワードされるかは仮想NICの設定画面から確認できます。まずは、「すべてのサービス」から「コンピューティング」「Virtual Machines」「仮想マシン名(linux010)」「ネットワーク」「NIC名(linux010VMNic)」の順に画面遷移します。

ルートテーブルの確認 01

「有効なルート」を押下すると、デフォルトゲートウェイに到達してからどのようにフォワードされるかを確認できます。「0.0.0.0/0」がインターネットになっていますので、インターネットへの接続が可能な事が分かります。

ルートテーブルの確認 02

なお、前述の「有効なルート」はazコマンドでも確認可能です。azコマンドで確認する場合は、az network nic show-effective-route-tableを使用します。操作例は以下の通りです。

az network nic show-effective-route-table \
  --resource-group MyResourceGroup \
  --name linux010VMNic

SNAT枯渇の問題

概要

Azureに限らない話ですが、NATはパブリックIPアドレスとプライベートIPアドレスのマッピングを記録するNATテーブルと呼ばれる情報を保持します。ポート番号は65535までしか使用できませんので、NATによる同時接続には上限があります。

Azure Virtual Network NAT 接続のトラブルシューティング」によると、Azureの「NATゲートウェイ」は1つのパブリックIPアドレスあたり、64,000個のSNATポートを提供します。

アイドル タイムアウト タイマー

アイドル タイムアウト タイマーを長くすればするほど、SNATポートを解放するまでの時間が長くなりますので、SNAT枯渇を誘発しやすくなります。デフォルト設定は「4分」で、可能ならばデフォルト設定の「4分」を使用しましょう。設定変更操作は以下の通りです。

az network nat gateway update \
  --resource-group MyResourceGroup \
  --name MyNatGateway01 \
  --idle-timeout <アイドル タイムアウト(分)>

アイドルタイムアウトは短いに越した事はないですが、アプリケーションの要件によっては、アイドルタイムアウトに長い値を設定せざるを得ない状況もあるかもしれません。このような場合は、「NATゲートウェイ」に複数のIPアドレスを割り当てます。

パブリックIPプレフィックス

「NATゲートウェイ」に複数のIPアドレスを割り当てるには、まず「パブリックIPプレフィックス」を作成します。引数lengthはサブネット長です。31ならば2個のパブリックIPアドレスが作成されます。

az network public-ip prefix create \
  --resource-group MyResourceGroup \
  --name MyPublicIpPrefix \
  --length 31

「NATゲートウェイ」と「パブリックIPプレフィックス」を紐づけます。

az network nat gateway create \
  --resource-group MyResourceGroup \
  --name MyNatGateway02 \
  --public-ip-prefixes MyPublicIpPrefix \
  --idle-timeout 4

az network vnet subnet update \
  --resource-group MyResourceGroup \
  --vnet-name Vnet01 \
  --name Subnet01 \
  --nat-gateway MyNatGateway02

「確認くん」などで疎通確認をすると、複数のパブリックIPアドレスで負荷分散しつつのインターネットへの疎通を実現できる事を確認します。

azureuser@linux010:~$ curl -s https://www.ugtop.com/spill.shtml | grep -i IPv4 -A 1
  <th>あなたのIPアドレス(IPv4)</th>
  <td><font size=+2 color=blue>20.222.38.20</font></td>
azureuser@linux010:~$ curl -s https://www.ugtop.com/spill.shtml | grep -i IPv4 -A 1
  <th>あなたのIPアドレス(IPv4)</th>
  <td><font size=+2 color=blue>20.222.38.21</font></td>
azureuser@linux010:~$ curl -s https://www.ugtop.com/spill.shtml | grep -i IPv4 -A 1
  <th>あなたのIPアドレス(IPv4)</th>
  <td><font size=+2 color=blue>20.222.38.21</font></td>
azureuser@linux010:~$ curl -s https://www.ugtop.com/spill.shtml | grep -i IPv4 -A 1
  <th>あなたのIPアドレス(IPv4)</th>
  <td><font size=+2 color=blue>20.222.38.20</font></td>
azureuser@linux010:~$ 
タイトルとURLをコピーしました