【Azure VNet入門③】NSGで通信を許可・拒否する|既定ルールと優先度

Azure

サブネットを用途別に切れたら、次は「どの通信を許可し、どの通信を拒否するか」を決める番です。これを担うのが NSG(Network Security Group/ネットワークセキュリティグループ) です。「DBサブネットにはアプリからの通信だけ許可して、インターネットからは遮断したい」——そんな要件を、NSGで具体的に形にしていきます。

NSGにルールをいっぱい足したのに、なぜか意図しない通信が通る(or 通らない)…優先度って何が効いてるの?

この記事では、NSGについて次の4つを順番に整理します。読み終えたときに、これらを自分の言葉で説明できるようになることをゴールにしています。

  • NSGが何か(サブネット / NIC に適用する許可・拒否ルール)を説明できる
  • インバウンド / アウトバウンドの既定ルールを理解している
  • 優先度(priority)とルールの評価順を理解している
  • NSGをサブネットに関連付けできる

NSGとは?(サブネット / NIC に適用する許可・拒否ルール)

NSG(ネットワークセキュリティグループ)とは、サブネットやNIC(ネットワークインターフェース)に適用して、通信を「許可(Allow)」または「拒否(Deny)」するルールの集まりです。いわばVNet内に置く”ファイアウォールの簡易版”です。

NSGは、ビルの各フロアの入口に立つ「警備員」のような存在です。「この送信元から・このポート宛の通信は通す/通さない」というルールブックを持っていて、やってくる通信を1件ずつチェックします。NSGのルールは、次の5つの要素で「どの通信か」を指定します。

  • 送信元(Source):どこから来た通信か(IP / サブネット / サービスタグ)
  • 宛先(Destination):どこ宛の通信か
  • ポート / プロトコル:例)TCP 443(HTTPS)、TCP 3389(RDP)
  • 方向:インバウンド(受信)かアウトバウンド(送信)か
  • アクション:許可(Allow)か拒否(Deny)か

NSGは「サブネット」にも「NIC(VM単位)」にも適用できます。基本はサブネットに当てて層ごとにまとめて制御し、特定のVMだけ例外を設けたいときにNICへ当てる、という使い分けが定石です(両方当たっている場合は、受信は「サブネット→NIC」の順、送信は「NIC→サブネット」の順で両方を通過する必要があります)。

【ここが説明できればOK①】
「NSGは、サブネットやNICに適用して通信を許可/拒否するルールの集まり(送信元・宛先・ポート・方向・アクションで指定)である」——これを言えれば、1つ目のチェックはクリアです。

インバウンド / アウトバウンドの既定ルール

ここはハマりどころです。NSGを新規作成すると、実は最初から「既定ルール」がいくつか入っています。これを知らないと「何も設定してないのにVNet内は通信できる」「拒否したつもりが通ってしまう」といった混乱が起きます。主要な既定ルールは次のとおりです。

■ インバウンド(受信)の既定ルール
  ・VNet内からの通信          → 許可(AllowVnetInBound)
  ・Azure Load Balancerから    → 許可
  ・上記以外すべて             → 拒否(DenyAllInBound)

■ アウトバウンド(送信)の既定ルール
  ・VNet内への通信            → 許可
  ・インターネットへの送信      → 許可(AllowInternetOutBound)
  ・上記以外すべて             → 拒否(DenyAllOutBound)

この既定ルールから読み取れる大事な性質は2つです。

  • VNet内の通信は既定で許可:同じVNetのリソース同士は、何もしなくても通信できる(=内線は自由)。
  • 外からの受信は既定で拒否・外への送信は既定で許可:インターネットから勝手に入っては来られないが、中から外へは出ていける。

つまり、自分が追加するルールは「この既定の上に乗せる例外」です。「インターネットからHTTPS(443)を受け付けたい」なら受信許可ルールを足す、「特定サブネット宛は拒否したい」ならより高い優先度の拒否ルールを足す、という具合です。既定を知らずにルールを足すと、意図と噛み合わずに悩むことになります。

「VNet内は許可・外からの受信は拒否」がデフォルト。自分のルールはこの土台への”例外の追加”だと考えると迷わないよ!

【ここが説明できればOK②】
「NSGには既定ルールがあり、VNet内通信は許可・インターネットからの受信は拒否・外への送信は許可。自分のルールはこの上に足す例外だ」——これを説明できれば、2つ目のチェックはクリアです。

優先度(priority)とルールの評価順

冒頭の「意図しない通信が通る/通らない」の正体が、この優先度(priority)です。NSGのルールには 100〜4096 の優先度番号が付き、次のルールで評価されます。

NSGのルールは、優先度(priority)の「数字が小さい順」に評価され、最初に一致したルールが適用されて、そこで評価は止まります。

言い換えると、「早い者勝ち」です。小さい番号(=優先度が高い)から順にチェックし、通信にマッチするルールが見つかった瞬間、その許可/拒否が確定して残りのルールは無視されます。例で見てみましょう。

受信ルール(優先度の小さい順に評価)
  priority 100  10.0.1.0/24 → 3389(RDP)  許可   ← app層からのRDPは通す
  priority 200  *           → 3389(RDP)  拒否   ← それ以外のRDPは全部止める
  priority 65500 既定 DenyAllInBound

【評価】インターネットから来たRDP(3389)は?
  100 にマッチしない(送信元がapp層でない)
   → 200 にマッチ → 「拒否」で確定・終了

ここで重要なのは、「拒否ルールと許可ルールの順番(優先度)で結果が変わる」ということです。もし上の例で拒否(200)を許可(100)より小さい番号にしてしまうと、app層からのRDPまで止まってしまいます。「より具体的な許可を小さい番号に、広い拒否を大きい番号に」置くのが基本のセオリーです。ルールが効かないと感じたら、まず優先度の並び順を疑いましょう。

【ここが説明できればOK③】
「NSGは優先度の数字が小さい順に評価され、最初に一致したルールで確定する(早い者勝ち)。だから許可と拒否の並び順で結果が変わる」——これを説明できれば、3つ目のチェックはクリアです。

NSGをサブネットに関連付ける

NSGは作っただけでは効きませんサブネット(またはNIC)に「関連付け(associate)」して初めて有効になります。ここを忘れて「ルールを書いたのに効かない」と悩むケースが非常に多いので、必ずセットで覚えましょう。

Azure CLI での例

# NSGを作成
az network nsg create -g rg-network -n nsg-app

# ルールを追加(HTTPS 443 を受信許可)
az network nsg rule create \
  -g rg-network --nsg-name nsg-app \
  -n allow-https --priority 100 \
  --direction Inbound --access Allow \
  --protocol Tcp --destination-port-ranges 443

# ★ サブネットに関連付け(これで初めて有効になる)
az network vnet subnet update \
  -g rg-network --vnet-name myVnet -n subnet-app \
  --network-security-group nsg-app

Terraform での例

resource "azurerm_network_security_group" "app" {
  name                = "nsg-app"
  location            = "japaneast"
  resource_group_name = azurerm_resource_group.net.name

  security_rule {
    name                       = "allow-https"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "443"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

# ★ サブネットへの関連付け
resource "azurerm_subnet_network_security_group_association" "app" {
  subnet_id                 = azurerm_subnet.app.id
  network_security_group_id = azurerm_network_security_group.app.id
}

Terraformでは、NSG本体(azurerm_network_security_group)とは別に、関連付け専用のリソース(azurerm_subnet_network_security_group_associationを書くのがポイントです。この行を忘れると、NSGは存在するのにどのサブネットにも当たっていない「宙に浮いたNSG」になってしまいます。

【ここが説明できればOK④】
「NSGは作成しただけでは効かず、サブネット(またはNIC)に関連付けて初めて有効になる」——これを説明でき、実際に関連付けまでできれば、4つ目のチェックはクリアです。

まとめ

  • NSG は、サブネット/NICに当てて通信を許可・拒否するルールの集まり
  • 既定ルール:VNet内は許可・外からの受信は拒否・外への送信は許可。自分のルールはこの上の例外
  • 優先度は数字が小さい順に評価し、最初に一致したルールで確定(早い者勝ち)
  • NSGはサブネット/NICに関連付けて初めて有効(作っただけでは効かない)

NSGで「誰と通信してよいか」を制御できたら、次は「通信がどの経路を通るか」を決めるルーティングです。既定の経路(システムルート)と、それを上書きするUDR(ユーザー定義ルート)を次の記事で扱います。「全通信をファイアウォールに通して検査する」設計も、このルーティングで実現します。

あわせて読みたい

タイトルとURLをコピーしました