Azure Network Security Group(NSG)についておさらい(2019年版)

目次

はじめに

Azureで主にIaaSを使って仮想マシンを構成する場合、仮想ネットワークを作成すると思いますが、仮想ネットワークのサブネット間、仮想マシン間のネットワークトラヒックを制御するためにNetwork Securyty Group(NSG)は大変重要なものですよね。

NSGの大まかな説明や、詳細な説明については本家MSのサイトを参考にするのが良いのですが、もともと物理サーバのインフラエンジニアをやっていた筆者が最近NSGで気になったトピックをまとめてみました。

NSG

詳しくはセキュリティ グループあたりに書かれています。

適用できるリソース

NSGは仮想ネットワークのサブネット、もしくはNetwork Interface Card(NIC)に適用できるのはご存知の通りです。
一つのNSGを複数のサブネットに割り当てたり、複数のNICに割り当てることもできます。

下図の例では仮想ネットワークの「サブネット1」「サブネット2」それぞれに「NSG-1」「NSG-2」が適用されており、仮想マシン「VM-3」には(実際にはNICにですが)「NSG-VM3」が適用されている状態です。

img

ここで、VM-1からVM-3に対して通信を行う際にはどういったルールでNSGが判定されるというと以下の通りですよね。

img

  1. NSG-1の送信ルール
  2. NSG-2の受信ルール
  3. NSG-VM3の受信ルール

これはサブネット間のトラヒックになるため、特に引っかかることなく理解できます。元インフラエンジニアも納得です。

続いて、VM-1から同じセグメントにあるVM-2に対して通信を行う場合はどうでしょう。

img

この場合は
1. NSG-1の送信ルール
2. NSG-1の受信ルール

が評価されます。
同じサブネット内であれば、隣(?)のサーバにはフリーで繋がるわけではないのでご注意ください。
次の章のNSG既定ルールでも書きますが、デフォルトルールで仮想ネットワーク間の通信は全ポート送受信ともに「許可」設定になっているため自在に接続ができているように見えているだけなのです。

念のため、VM-4からVM-3の通信の場合はこんな感じです。

img

  1. NSG-2の送信ルール
  2. NSG-2の受信ルール
  3. NSG-VM3の受信ルール

受信規則、送信規則と既定のルール

以下の表はNSG作成時に無条件に定義される既定ルールです。

【受信の既定ルール】

Name 優先順位 発信元 IP 発信元ポート 宛先 IP 宛先ポート プロトコル Access (アクセス)
AllowVnetInBound 65000 VirtualNetwork * VirtualNetwork * * ALLOW
AllowAzureLoadBalancerInBound 65001 AzureLoadBalancer * * * * ALLOW
DenyAllInBound 65500 * * * * * DENY

【送信の既定ルール】

Name 優先順位 発信元 IP 発信元ポート 宛先 IP 宛先ポート プロトコル Access (アクセス)
AllowVnetOutBound 65000 VirtualNetwork * VirtualNetwork * * ALLOW
AllowInternetOutBound 65001 * * Internet * * ALLOW
DenyAllOutBound 65500 * * * * * DENY

ポータル上からもNSGリソースの「受信セキュリティ規則」もしくは「送信セキュリティ規則」のメニューから「既定の規則」をクリックすると確認することができます。

img

既定のルールは「インターネットからのアクセスには厳しく、しかし仮想ネットワーク内の通信はゆるゆる。おまけにインターネットへのアクセスはなんでもおk」という設定になっています。

数台の仮想マシンを一つのサブネットで立ち上げて小規模なサービスを提供する場合には既定のルールに追加でインターネットからの受信ルールとして、TCP/443とTCP/80だけを空ける等で問題なさそうですね。

少し規模が大きくなって、サブネット毎にサーバ用途を分ける場合、既定のルールが有効なままだとDMZセグメントのサーバを踏み台にして、プライベートセグメントのDBサーバに侵入されてしまうケースもあり得ます。

img

なので、NSGの受信ルールには既定ルールの手前にVirtualNetowrk間の受信も制限を入れて、それよりも優先度の値の小さい場所に必要な受信ルールを個々に設定するとよいと思います。

img

【受信規則の優先度4090を追加】

Name 優先順位 発信元 IP 発信元ポート 宛先 IP 宛先ポート プロトコル Access (アクセス)
DenyVnetInbound 4090 VirtualNetwork * VirtualNetwork * * DENY

タグの説明

NSGで指定可能なタグは各種ありますが、そのなかで代表的なものについて説明します。

「VirtualNetwork」

以下の全てが「VirtualNetwork」の範囲内になります。

  • 仮想ネットワーク内の同一サブネット(当然ですね)
  • 仮想ネットワーク内の別サブネット
  • 仮想ネットワークピアリングで接続された別仮想ネットワーク
  • Site to Site接続された別の仮想ネットワーク(Azure、オンプレ)
  • Point to Site接続されたクライアント側PC
  • Express Routeによって接続されたオンプレ側ネットワーク

……結局のところ、インターネット以外すべてですね。
なので、安易にVirtualNetworkタグを使って受信規則をフルオープンにしてしまうと、社内の誰からも、どこからもアクセスできてしまうのでご注意ということです。

「AzureLoadBalancer」

「AzureデータセンターIPに変換されます」と記載がありますが、たぶん「168.63.129.16」に変換されます。
このIPアドレス自身はグローバルIPアドレスなのですが、必ずAzureデータセンター内にある仮想IPアドレスであるため、ロードバランサー(Internal,External問わず)設定する際には許可してあげる必要があります。

既定のルールでは優先度65001で、AzureLoadBalancerからの受信はすべて許可となっていますが、こちらを無効化した場合は「ロードバランサーにProbeされるすべての仮想マシンの必要ポート」を空けます。

img

※なぞのAzureLoadBalancerがVM-2とVM-3の死活確認用ポートにアクセスする(例えばTCP/80)

「Internet」

「VirtualNetwork」以外のアドレス空間は(多分)全てこちらの「Internet」になります。
通常は受信規則で「特定のWebサーバのTCP/443だけを空ける」などの場合に指定しますよね。

Name 優先順位 発信元 IP 発信元ポート 宛先 IP 宛先ポート プロトコル Access (アクセス)
AllowInternetHTTPInbound 200 Internet * 10.0.0.4 443 TCP ALLOW

MSの資料にもあるとおり、こちらのInternetタグはAzure内の他のPaaSサービス等で使われるIPアドレスも含まれています。

特に受信規則ではAzureのPaaSサービスを起点として仮想ネットワーク内の仮想マシンにアクセスされるケースは少ないので問題になりづらいのですが、送信規則でInternet向けの通信を遮断した場合、色々面倒な事がおきます。
具体的には以下のルールを送信規則に設定した場合です。

【送信規則の優先度4090を追加】

Name 優先順位 発信元 IP 発信元ポート 宛先 IP 宛先ポート プロトコル Access (アクセス)
DenyInternetOutbound 4090 VirtualNetwork * INTERNET * * DENY

無論仮想マシン上のIE等のブラウザからgoogle検索などは行えなくなります。
他に私が知る限り以下の不都合が発生します。

  • 仮想マシンに拡張機能(BGInfoなど)の追加操作をしてもデプロイが正常終了しない
  • 仮想マシンの診断機能(Diagnostics)を有効にしてもストレージアカウントに結果が出力されない
  • LogAnalyticsが有効なのに一向にログが転送されてこない
  • 仮想マシンのバックアップが正常に完了しない

これらは全て仮想マシンのOS内からAzureのPaaSサービス(ストレージアカウント含む)への接続が行えないため発生します。

対処方法としては、LogAnalyticsはコントロールパネルの設定でproxyサーバが指定できるので回避可能かもしれませんが、他はやはりNSGの送信規則は絞らない方向で調整するのが宜しいかと思います。

「AzureTrafficManager」

Azure Traffic Managerからの着信だけを受けたいなどの場合にこちらを受信規則に指定します。

「Storage」

MSドキュメントに記載の通りなのですが、Azureストレージアカウントに対して禁止・許可をすることができるタグです。
「Storage」の後に「.リージョン名」が記載できて、特定のリージョンだけを指定することもできます。
以下の送信規則を適用すると、「基本インターネット向け(Azureサービス含む)のOutboundは拒否だけど、ストレージアカウント(東日本)だけは繋げてよいよ」といったルールになります。

Name 優先順位 発信元 IP 発信元ポート 宛先 IP 宛先ポート プロトコル Access (アクセス)
AllowStorageOutbound 4080 VirtualNetwork * Storage.japaneast * * Allow
DenyInternetOutbound 4090 VirtualNetwork * INTERNET * * DENY

「Sql」

先の「Storage」を同じですが、Azure SQL DBに対して禁止・許可をすることができるタグです。
「Sql」の後に「.リージョン名」が記載できて、特定のリージョンだけを指定することもできます。

以下の送信規則を適用すると、「基本インターネット向け(Azureサービス含む)のOutboundは拒否だけど、SQL DB(西日本)だけは繋げてよいよ」といったルールになります。

Name 優先順位 発信元 IP 発信元ポート 宛先 IP 宛先ポート プロトコル Access (アクセス)
AllowSqlOutbound 4080 VirtualNetwork * Sql.japanwest * * Allow
DenyInternetOutbound 4090 VirtualNetwork * INTERNET * * DENY

2018年に入ってGAした「仮想ネットワーク サービスのエンドポイント」は、StorageとSQL DBを特定のVNET内Subnetからのみ限定的に接続するサービスですが、こちらのサービスタグを併用して必要に応じて送信規則を空けておく必要があります。

Application Security Group(ASG)

ASGも2018年3月末にGAしたのですが、本記事執筆時点では特にAzureポータル上から簡単に使える感じではなさそうです。
以前書いたプレビューの時の記事をとりあえず参考にしてください。

Azure Application Security Group(ASG)がPublic Previewになったので使ってみた

こちらの公式ドキュメントもご参考にどうぞ。

Filter network traffic with a network security group using PowerShell

ソースIPアドレスと宛先IPアドレスの複数記述

2018年1月から、NSGのソースIPアドレスと宛先IPアドレスが1ルール内に複数個書くことができるようになりました。
複数の特定IPアドレスからのsshを許可する場合、今までは複数行受信規則を書かなければいけなかったのですが、これが1ルールで記述可能になっています。

【今まで】

Name 優先順位 発信元 IP 発信元ポート 宛先 IP 宛先ポート プロトコル Access (アクセス)
AllowSshInbound1 4080 xxx.xxx.xxx.1/32 * * 22 TCP Allow
AllowSshInbound2 4081 xxx.xxx.yyy.2/32 * * 22 TCP Allow
AllowSshInbound3 4082 xxx.xxx.zzz.3/32 * * 22 TCP Allow

【これからは!】

Name 優先順位 発信元 IP 発信元ポート 宛先 IP 宛先ポート プロトコル Access (アクセス)
AllowSshInbound 4080 xxx.xxx.xxx.1/32, xxx.xxx.yyy.2/32, xxx.xxx.zzz.3/32 * * 22 TCP Allow

1つのルールに記述可能なIPアドレス(CIDR)は標準で2,000個、MSサポートにお願いすると最大4,000個記述可能になります。
(参考:ネットワークの制限 - Azure Resource Manager)

無条件に通るパケット

実はNSGの送信規則でInternet側を絞っても、例外的に通過するルールが存在します。
MS宇田さんの「IP アドレス 168.63.129.16 について」を参照して頂きたいのですが、仮想マシンの起動や名前解決に欠かせないDNS、DHCPについては168.63.129.16宛に常に空いているようです。

このへんのOutbound通信に関する公式ドキュメントとしては、以下が参考になると思います。

img

https://docs.microsoft.com/ja-jp/azure/virtual-network/security-overview#azure-platform-considerations

ロードバランサーに適用する場合

ロードバランサの種類としてはPublic IP Addressを持った"External Load Balancer"と仮想ネットワーク内からのアクセスのみ許容する"Internal Load Balancer"の二種類がありますね。

ロードバランサー経由の受信規則をNSGに書く場合、「発信元」「宛先」に何を指定するのかを説明します。

下図のようにVM-1(10.0.0.4)からVM-2(10.0.1.5)とVM-3(10.0.1.6)のTCP/443にだけアクセスさせたい場合。

img

Name 優先順位 発信元 IP 発信元ポート 宛先 IP 宛先ポート プロトコル Access (アクセス)
AllowLbHttpsInbound1 200 10.0.0.4/32 * 10.0.1.5/32 443 TCP ALLOW
AllowLbHttpsInbound2 201 10.0.0.4/32 * 10.0.1.6/32 443 TCP ALLOW

このように、個々の仮想マシン毎にVM-1(10.0.0.4)からのアクセス許可を追加します。
(ロードバランサー(10.0.1.4)は受信規則の中に登場しません)

Public IP Addressを持つExternal Load Balancerでも本ルールは変わりません。

(ひとりごと)VM-1からLBを経由しないでダイレクトにVM-2、VM-3に繋げられてしまうけど、これの抑止はどうするんだろう

ping(icmp)について

既定の受信ルールが有効の場合はVirtualNetwork→VirtualNetworkのトラヒックは全てのプロトコルが許可されているため、ping(icmp)は通ります。

2019年7月末にNSGのプロトコル指定に「*」「TCP」「UDP」の他に「ICMP」が追加になりました。
(Azure CLIやAzure PowerShellからは他に「ESP」も指定できますが、まあ通常は使いません)

https://azure.microsoft.com/ja-jp/updates/network-security-group-improvements-now-available/

今までは以下のようなルールが必要だったのですが、今後はpingを通したい発信元、宛先に対してプロトコルにICMPを許可してあげればOKです。特にインターネット越しにping監視を行っている場合等には有効かと思います。

(従来の無理やりICMPを通すルール例)【受信ルールでVirtualNetwork間の通信はICMPのみ】

Name 優先順位 発信元 IP 発信元ポート 宛先 IP 宛先ポート プロトコル Access (アクセス)
AllowICMPInbound1 4090 VirtualNetwork * VirtualNetwork * TCP DENY
AllowICMPInbound2 4091 VirtualNetwork * VirtualNetwork * UDP DENY
AllowICMPInbound3 4092 VirtualNetwork * VirtualNetwork * * ALLOW

TCPとUDPは拒否するけど、その他は許可ということで、ICMPだけが通過するようになります。

おわりに

こちらでまとめた内容は既に既知の情報ではありますが、NSGの受信、送信ルールを設計していく上で意外と引っかかりがちな部分をピックアップしました。

本内容は執筆時点(2019/08)の情報となっており、その後Azureの機能改善、機能アップが行われ次第不定期に更新予定です。