🌎

Azure Private DNS Zonesの名前解決をオンプレミスからCoreDNSで実現する

2022/05/09に公開

はじめに

タイトルが長いですね。

Azureとオンプレミスと各種方法(ExpressRoute、Site to Site VPNなど)で接続する場合、ひとつ課題になるのが仮想マシンなどの名前解決です。

Azure側では「Private DNS Zone」という便利な機能があり、Azure Virtual Networkにリンクしておくと自由にDNSレコードの登録ができます。

また「自動登録」を設定しておくことでAzure側に新たに仮想マシンなどが追加になっても勝手にAレコードが登録されていきます。

Azure プライベート DNS とは

Azure Virtual NetworkはデフォルトでDNSサーバとして「168.63.129.16」が割り当てられて、こちらを参照するだけでPrivate DNS Zonesの名前解決も行えます。

ただし残念なことに、こちらの「168.63.129.16」はAzure内でのみ利用できるアドレスとなっているため、閉域接続されているオンプレミスからでも参照できません(DNSによる名前解決ができません)

IP アドレス 168.63.129.16 とは

Azure Virtual Network内で、VMの名前解決しか必要でなければ、特にPrivate DNS Zonesを作成しなくとも、標準のAzure DNSサーバが良しなにやってくれます。

しかしハイブリッド構成で相互に名前解決させるには以下のアプローチが必要です。

Azure を使用してハイブリッド ドメイン ネーム システム ソリューションを設計する

これは正直本気度MAXで業務向け案件ですね。

オンプレとAzure双方にDNSサーバを立ち上げて相互にフォワードし合う構成ですね。

無論私も、お仕事であればやりますが、推し事ではここまではやりません。

(前置きも長かった)

CoreDNSとは

誤解を恐れずに、ざっくり説明すると。

  • GoLangで書かれた超軽量DNSサーバ
  • Kubernetesにもv1.12以降は標準で組み込まれている
  • 各種プラグインが充実している

すみません、ほんとざっくりで。

今回はこのCoreDNSのAzureプラグインを使って、オンプレミスからAzure Virtual Network内の名前解決を行えるような設定を試してみました。

ネットワーク構成

超概略図ですが、自宅の環境です。

img

外向けのルータ(NURO用HG8045Q)の他に、DHCPサーバ件ローカルルータとしてYAMAHA RTX810があります。

今回はDocker上でCoreDNSを動作させたいので、手元にあったSynology DS220+のNAS上でDockerを動かします。

Azureとの接続にはWireGuardを使って閉域接続をしています。

ちなみに、WireGuardの接続については、以下記事を参照ください。

WireGuardでAzure、オンプレミス、iPhoneを閉域接続しまくる

既に自宅ネットワーク(192.168.1.0/24)とAzureネットワーク(192.168.2.0/24)は疎通している状態です。

192.168.1.35から実行
C:\>ping 192.168.2.4
192.168.2.4 に ping を送信しています 32 バイトのデータ:
192.168.2.4 からの応答: バイト数 =32 時間 =4ms TTL=63
192.168.2.4 からの応答: バイト数 =32 時間 =4ms TTL=63
(snip)

CoreDNSで実現させたい機能

今回は自身が持っているドメイン「nya-n.net」のルートドメインによる名前解決以下のような感じで実現させます。

  1. プライベートIPアドレスを返したいFQDNはhostsに定義
  2. それで見つからない場合はAzure Private DNS Zonesを参照
  3. それでも見つからない場合はGoogle DNS(8.8.8.8)に問い合わせ
  4. nya-n.net以外のドメインについては、先にhosts参照後、Google DNSに問い合わせ

これにより、自宅から外部に公開しているサーバについても、自宅から接続ではローカルネットワーク内で繋がるようになるでしょう。

(いちいちInternet向けルータを経由しないで済む)

設定

Azure側の確認

以下のPrivate DNS Zoneリソースが準備されています。

img

私のドメイン「nya-n.net」Zoneに、先に書いたWireGuardサーバのVMである「wgvm」が自動登録されています。

今回はこの名前解決をオンプレミスからCoreDNSの機能を使って実現させます。

(1件だけだったら、ローカルのhostsに書けという突っ込みは拒否します)

CoreDNSからAzureのリソースにアクセスさせるためには、専用のアプリケーションIDを準備する必要がありますが、このアプリケーションIDのアクセス権をPrivate DNS Zoneのみに限定させるために、リソースIDを控えておきます。

img

アプリケーションIDの作成

以下の条件で作成します。

  • 有効期限は5年(メンテが面倒なので少し長めに)
  • ロールは閲覧者(Reader)
  • スコープはPrivate DNS Zoneリソースのみ

ポータルからの操作は手順が多いので、az ad sp create-for-rbacコマンドでさくっと作成します。

こちらのコマンドの詳細は以下を参照してください。

Azure CLI で Azure サービス プリンシパルを作成する

az ad sp create-for-rbac \
    --name test-coredns-20220509 \
    --role Reader \
    --scopes /subscriptions/XXXXXXXXXXXXXXXX/resourceGroups/method-rg/providers/Microsoft.Network/privateDnsZones/nya-n.net \
    --years 5

{
  "appId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  "displayName": "test-coredns-20220509",
  "password": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "tenant": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}

あと、AzureのサブスクリプションIDも必要なので確認しておきましょう。

az account show --query id
"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"

hostsファイルの準備

プライベートIPアドレスを返したい一覧をhosts形式で作成します。

とりあえず適当な場所で作成しておきます。

以下は例です。別にプライベートIPアドレスや、リンクローカルアドレスが漏洩しても問題ないので実際のものを。

hosts.txt
192.168.1.1     nuro nuro.nya-n.net
192.168.1.220   fs2 fs2.nya-n.net
192.168.1.254   rtx rtx.nya-n.net

fe80::6eeb:b6ff:fec8:9eaf   nuro nuro.nya-n.net
fe80::211:32ff:fecf:7269    fs2 fs2.nya-n.net
fe80::2a0:deff:fe83:6dfc    rtx rtx.nya-n.net

CoreFileの準備

CoreDNSが使用するconfigファイルは以下のように設定しました。

CoreFile
nya-n.net:53 {
    hosts /data/hosts.txt {
        reload 1s
        fallthrough
    }
    azure method-rg:nya-n.net {
        tenant XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
        client XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
        subscription XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
        secret XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        access private
        fallthrough
    }
    forward . 8.8.8.8:53
    log
}

.:53 {
    hosts /data/hosts.txt {
        reload 1s
        fallthrough
    }
    forward . 8.8.8.8:53
    log
}

「azure method-rg:nya-n.net…」の部分を解説します。

「method-rg」の部分は自分のAzure Private DNS Zonesが格納されているリソースグループ名を指定します。

「nya-n.net」の部分も正しいAzure Private DNS Zones名(リソース名)に変更します。

各種ID系は以下の値を設定します。

property value
tenant az ad sp create-for-rbacコマンドで実行した結果のtenantの値
client az ad sp create-for-rbacコマンドで実行した結果のappIdの値
subscription az account showの実行結果のID
secret az ad sp create-for-rbacコマンドで実行した結果のpasswordの値

Dockerコンテナの起動

今回はSynology NASのDockerを使います。

先に適当なディレクトリをDSMのファイルマネージャにて作成しておき、そこに作成したhosts.txtとCoreFileを格納しておきます。

img

イメージの取得でDockerHub上の公式イメージ「coredns/coredns:latest」を取得してきます。

img

取得したコンテナイメージから「起動」を押して先に進みます。ネットワーク設定ではブリッジネットワークは使わずに、ホストネットワークを選択します。

img

全般設定では一応リソース制限と、自動再起動を有効にしたのち「詳細設定」を押します。

img

詳細設定の「実行コマンド」にて、コマンド(となっているけど実際はパラメータ)に「-conf /data/CoreFile」を指定します。

img

ボリューム設定にて先にファイルマネージャで保存したhosts.txtとCoreFileのあるディレクトリを「/data」にマッピングします。読み取り専用にもチェックを付けます。

img

設定完了後、コンテナを起動させて完了です。ログにも正常に起動(エラーが出ていない)事が確認できます。

img

DHCPサーバの設定変更

こちらは利用環境によって設定や操作は異なりますが、参考情報として。

自宅のDHCPサーバはYAMAHA RTX810上で動作していますが、TELNETにて以下のコマンドでDHCPサーバが広報するDNSサーバのIPアドレスを変更しました。

# dhcp scope option 1 dns=192.168.1.220
# save
Saving ... CONFIG0 Done .

他に、NUROの貸与ルータであるHG8045QではIPv4のDHCPサーバ機能は無効にしていたのですが、IPv6 DHCPサーバが有効のままだったのでOFFにしました。

具体的には「IPv6>LANアドレス設定」を以下の通りにします。

  • DHCPv6サーバを有効にする:チェックOFF
  • その他の種類の割り当て方法:SLAAC

でOKでした。

img

動作確認

一度クライアントのWindows PCを再起動します(ipconfig /renewでもOK)。

ipconfig /allで確認すると、ちゃんとDNSサーバがCoreDNSのIPアドレスになっていますね。

C:\>ipconfig /all
(snip)
イーサネット アダプター CalDigit Giga Ether:

   接続固有の DNS サフィックス . . . . .:
   説明. . . . . . . . . . . . . . . . .: Cypress GX3 SuperSpeed to Gigabit Ethernet Bridge Controller
(snip)
   DHCP サーバー . . . . . . . . . . . .: 192.168.1.254
(snip)
   DNS サーバー. . . . . . . . . . . . .: 192.168.1.220
   NetBIOS over TCP/IP . . . . . . . . .: 有効

ドメイン指定なしても、Azure Private DNS Zonesのものでも、外部DNSのものでも自在に名前解決ができるようになりましたね。

C:\>nslookup fs2
サーバー:  fs2
Address:  192.168.1.220

名前:    fs2
Addresses:  fe80::211:32ff:fecf:7269
          192.168.1.220


C:\>nslookup fs2.nya-n.net
サーバー:  fs2
Address:  192.168.1.220

名前:    fs2.nya-n.net
Addresses:  fe80::211:32ff:fecf:7269
          192.168.1.220


C:\>nslookup wgvm.nya-n.net
サーバー:  fs2
Address:  192.168.1.220

名前:    wgvm.nya-n.net
Address:  192.168.2.4


C:\>nslookup zakki.nya-n.net
サーバー:  fs2
Address:  192.168.1.220

権限のない回答:
名前:    zakki.nya-n.net
Address:  40.79.195.1


C:\>nslookup www.google.com
サーバー:  fs2
Address:  192.168.1.220

権限のない回答:
名前:    www.google.com
Addresses:  2404:6800:4004:820::2004
          142.250.207.4

ちゃんとオンプレからもFQDN指定でssh接続もできるようになりました。

C:\>ssh yotan@wgvm.nya-n.net
yotan@wgvm.nya-n.net's password:
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.13.0-1022-azure x86_64)
(snip)
Last login: Mon May  9 02:31:16 2022 from 192.168.1.35
yotan@wgvm:~$

おわりに

CoreDNSについて特に詳しいわけではないので軽く使っただけでの記事執筆でとても恐縮ですが、Azureプラグインの使い方についてはうまく説明できたのではないかなと。

実際に自宅の環境構成でCoreDNSを導入したら便利になったので、共有します。

Discussion