【ネットワーク+ポリシー入門編】Azure DNS(パブリック)にプライベートIPを登録できないようにする!
2025-12-15
azblob://2025/12/15/eyecatch/2025-12-15-azure-dns-not-register-rfc1918-policy-000.png

はじめに

こんにちは、業務ルータを購入したのに未だ家庭のネットワークはクラスC(192.168.0.0/23)な海野です。

今回はAzure PolicyでプライベートIPアドレス(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)をAzure DNS(パブリック)を登録させないようにするポリシーを作成したので記事にしてみました。

プライベートIPアドレスについておさらい

さて、本題に入る前にプライベートIPアドレス範囲についておさらいしましょう。

プライベートIPアドレス範囲を定義したインターネット標準規格として RFC 1918 があります。

以下にRFC 1918で定義されるプライベートIPアドレス範囲を載せておきます。

RFC 1918で定義されるプライベートIPアドレス範囲 

  • クラスA相当: 10.0.0.010.255.255.255 (10.0.0.0/8)
  • クラスB相当: 172.16.0.0172.31.255.255 (172.16.0.0/12)
  • クラスC相当: 192.168.0.0192.168.255.255 (192.168.0.0/16) 

なぜ実装したか?

簡潔に説明すると「プライベートIPアドレス」を追加するメリットが無いからです。

Azure DNS(パブリック)でプライベートIPアドレスを登録すると、普通に名前解決は出来ます。

以下はプライベートIPアドレスを登録したパターンの名前解決の一例です。

nslookup hogehogetest.com

権限のない回答:
名前:  hogehogetest.com
Addresses: 10.0.0.2

例えば、同じネットワーク内で10.0.0.2にWebサーバがあれば「hogehogetest.com」にアクセスすればホームページが見られるでしょう。

しかし、実際に他のネットワークに繋がっている人が「hogehogetest.com」に接続すると、その人が属しているネットワークの10.0.0.2のIPアドレスへのアクセスを試行します。

もちろん10.0.0.2のIPアドレスが割当たっているサーバは無ければ当然ホームページにはアクセスできません。

まるで「ホームページ作りました!アドレスはfile:\\C:\users\hogehoge\homepage\index.html」みたいですね。

例えば、ネットワーク内部で名前解決をしたい場合は「Azure Private DNS」というサービスがあるのでそちらを使いましょう。

Azure Policyについて

さて、本題に入っていきましょう。

Azure Policyは、Azure 上にあるリソースが「組織が決めたルール(ガバナンス)」を守っているかどうかを自動的にチェックし、違反していれば是正(修復)まで行えるサービスです。
「Azure のリソースに対する社内ルールの自動監査+強制」と覚えるとイメージしやすいと思います。

Azure Policyの必要性

クラウド(Microsoft Azure等)は簡単にリソースを作れるため、次の課題が発生しがちです。

・勝手に高価なサイズの VM が作られた
・命名規則やタグがバラバラ
・日本リージョンだけ使うはずが海外にリソースができていた
・セキュリティ要件(暗号化・パブリック IP 禁止など)を満たしていない

そこでAzure Policy を使うと、これらを「作成前にブロック」「作成後に自動修復」「定期監査」のいずれか(または組み合わせ)で統制できます。

基本用語集

  • Policy Definition(ポリシー定義)
     チェックしたい条件と、条件に合致しなかった場合のアクション(Effect)を JSON で記述したもの。
     例: 「location が japan-east または japan-west 以外なら deny する」
  • Policy Assignment(ポリシー割り当て)
     どの範囲(管理グループ / サブスクリプション / リソース グループ)に定義を適用するかを指定。
  • Initiative(イニシアティブ)
     複数の Policy Definition を束ねたセット。セキュリティ ベースラインなどをまとめて適用できる。
     (別名: Policy Set)
  • Effect(効果)
     条件にマッチしたときに何をするか。代表的なもの:
    • Deny       : 作成・更新を拒否
    • Audit      : 違反を記録(作成は許可)
    • AuditIfNotExists : 満たさなければ違反とする(リソースの補助リソースも確認)
    • Modify  : タグ自動付与・設定変更などを書き換え
    •  DeployIfNotExists : 条件を満たさない場合、テンプレートを自動デプロイ(暗号化有効化など)

Compliance(コンプライアンス)
 ポリシーに準拠している割合がポータルや API で確認できる。違反リソース一覧も取得可能。

代表的なユースケース

  1. コスト管理
    • VM SKU が D シリーズ以下でなければ Deny
    • リソースに CostCenter タグが無ければ自動付与
  2. セキュリティ・コンプライアンス
    • ストレージアカウントは HTTPS を必須 (Deny)
    • SQL Server は TLS1.2 を有効化 (DeployIfNotExists)
    • Public IP を持つ VM がないか Audit
  3. リージョン/可用性
    • 東日本・西日本リージョン以外へのデプロイを禁止
    • 可用性ゾーン を強制
  4. ガバナンス基盤
    • 社内命名規則を JSON 式でチェック
    • 複数ポリシーをまとめた「社内クラウド基準」イニシアティブの作成

ポリシーを作る

要件定義

  • 「Aレコード(IPv4)が RFC 1918以外であること」を定義。
  • サービス CIDR (eg. 169.254.0.0/16) や 100.64.0.0/10 (Carrier-grade NAT) は除外対象。

ポリシー定義作成・割り当て

はじめにポリシー定義を作ります。


次に、ポリシーを今回はサブスクリプションに割り当てます。

動作確認

ではさっそくAzure DNS(パブリック)にRFC 1918のプライベートIPを追加してみましょう。


[追加]をクリックしたところ、こんな感じのエラーが出ました。

どうやら「リソースはポリシーによって許可されていません。」と出ているのでポリシーの効果が出ていそうです。


では次にRFC 1918の範囲ではない普通のパブリックIPアドレスを追加してみましょう。

今回はテストでGoogle Public DNSのIPアドレス(8.8.8.8)を追加します。


問題なく追加することができました。

まとめ

今回はAzure Policyで RFC 1918の範囲をAzure DNSにAレコードとして登録させなくするポリシーを作ってみました。

本記事を参考に、Azure Policyを活かして自社にあったポリシーを作成してみてください。

付録

今回作成したポリシー定義JSON

{
  "mode": "All",
  "policyRule": {
    "if": {
      "allOf": [
        {
          "field": "type",
          "equals": "Microsoft.Network/dnszones/A"
        },
        {
          "anyOf": [
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "10.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "192.168.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.16.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.17.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.18.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.19.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.20.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.21.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.22.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.23.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.24.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.25.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.26.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.27.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.28.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.29.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.30.*"
            },
            {
              "field": "Microsoft.Network/dnszones/A/ARecords[*].ipv4Address",
              "like": "172.31.*"
            }
          ]
        }
      ]
    },
    "then": {
      "effect": "deny"
    }
  },
  "parameters": {}
}