Linux サーバで Active Directy ドメインに参加しようとしたらできなかったのでその時の対応メモです。なお、この事象は Ubuntu 16.04 LTS 以上であれば起こり得るのですが、私の場合 Ubuntu 20.04 LTS で発覚しました。
事象
realm join
で Active Directory に加入しようとすると realm: No such realm found
というエラーが出てしまいました。realm discover
でドメインを探そうとしますが同じエラーになってしまいました。ドメインは example.local
としています。
% realm join -v example.local * Resolving: example.local * No results: example.local realm: No such realm found
% realm discover example.local -v * Resolving: example.local * No results: example.local realm: No such realm found: example.local
調査
example.local
の名前解決ができないのが原因のようです。IP アドレスが正引きできるかを確かめるとたしかに引けないことがわかります。ここで SERVER: 127.0.0.53#53(127.0.0.53)
が気になります。というのも DHCP オプションセットで AmazonProvidedDNS を有効にしているため、DNS サーバの IP アドレスは VPC IPv4 CIDR にプラス 2 したものになるはずだからです(10.0.0.0/16
なら 10.0.0.2
)。
DHCP オプションセット - Amazon Virtual Private Cloud
% dig example.local ; <<>> DiG 9.16.1-Ubuntu <<>> example.local ;; global options: +cmd ;; Got answer: ;; WARNING: .local is reserved for Multicast DNS ;; You are currently testing what happens when an mDNS query is leaked to DNS ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 7884 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 65494 ;; QUESTION SECTION: ;example.local. IN A ;; Query time: 0 msec ;; SERVER: 127.0.0.53#53(127.0.0.53) ;; WHEN: Fri Jun 05 20:32:19 JST 2020 ;; MSG SIZE rcvd: 39
resolv.conf
を見ると DNS サーバが 127.0.0.53
になっていて、This file is managed by man:systemd-resolved(8). Do not edit.
と書かれています。
% cat /etc/resolv.conf # This file is managed by man:systemd-resolved(8). Do not edit. # # This is a dynamic resolv.conf file for connecting local clients to the # internal DNS stub resolver of systemd-resolved. This file lists all # configured search domains. # # Run "resolvectl status" to see details about the uplink DNS servers # currently in use. # # Third party programs must not access this file directly, but only through the # symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way, # replace this symlink by a static file or a different symlink. # # See man:systemd-resolved.service(8) for details about the supported modes of # operation for /etc/resolv.conf. nameserver 127.0.0.53 options edns0 search example.com
systemd-resolved とは
systemd-resolved は動的な DNS リゾルバです。Ubuntu 16.04 LTS から採用されています。 /etc/resolv.conf
は systemd-resolved によって生成されたファイル(/run/systemd/resolve/stub-resolv.conf
)のシンボリックリンクになっています。
$ ls -l /etc/resolv.conf lrwxrwxrwx 1 root root 39 May 30 06:49 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
DNS の設定を変更するには、/etc/systemd/resolved.conf
を編集するか、/etc/systemd/resolved.conf.d/
以下に <適当なファイル名>.conf
を設置して systemd-resolved を再起動します。
スタブリゾルバ
DNS サーバが 127.0.0.53
となっていますが、これはスタブリゾルバと呼ばれ、外部 DNS サービスに問い合わせをする仲介役となっています。スタブリゾルバは DNS サーバの応答をキャッシュするなどの役割を果たします。
なぜ 「.local」 で名前解決ができないのか
ここで resolvectl status
を実行してみると、DNS Servers: 10.0.0.2
とあり、AmazonProvidedDNS に向いています。
% resolvectl status Global LLMNR setting: no MulticastDNS setting: no DNSOverTLS setting: no DNSSEC setting: no DNSSEC supported: no DNSSEC NTA: 10.in-addr.arpa ...(省略).... Link 2 (ens5) Current Scopes: DNS DefaultRoute setting: yes LLMNR setting: yes MulticastDNS setting: no DNSOverTLS setting: no DNSSEC setting: no DNSSEC supported: no Current DNS Server: 10.0.0.2 DNS Servers: 10.0.0.2 DNS Domain: example.com
example.local
以外のドメインでは名前解決はできていました。
% dig test.example.com ; <<>> DiG 9.16.1-Ubuntu <<>> test.example.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58839 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 65494 ;; QUESTION SECTION: ;test.example.com. IN A ;; ANSWER SECTION: test.example.com. 299 IN A xxx.xxx.xxx.xxx ;; Query time: 0 msec ;; SERVER: 127.0.0.53#53(127.0.0.53) ;; WHEN: Fri Jun 05 20:43:55 JST 2020 ;; MSG SIZE rcvd: 90
また、AmazonProvidedDNS を直接指定すると example.local
も IP アドレスの正引きができることも確認できました。
% dig example.local @10.0.0.2 ; <<>> DiG 9.16.1-Ubuntu <<>> example.local @10.0.0.2 ;; global options: +cmd ;; Got answer: ;; WARNING: .local is reserved for Multicast DNS ;; You are currently testing what happens when an mDNS query is leaked to DNS ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4439 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;example.local. IN A ;; ANSWER SECTION: example.local. 300 IN A 10.0.10.10 example.local. 300 IN A 10.0.11.20 ;; Query time: 3 msec ;; SERVER: 10.0.0.2#53(10.0.0.2) ;; WHEN: Fri Jun 05 20:57:59 JST 2020 ;; MSG SIZE rcvd: 60
ではなぜ example.local
の名前解決ができないのでしょうか。man を見ると下のように書いてあり、つまりは example.local
はスタブリゾルバ(127.0.0.53
)から DNS フォワードされないため名前解決ができないのが原因のようです(多分)。
Other multi-label names are routed to all local interfaces that have a DNS server configured, plus the globally configured DNS servers if there are any. Note that by default, lookups for domains with the ".local" suffix are not routed to DNS servers, unless the domain is specified explicitly as routing or search domain for the DNS server and interface.
その他のマルチラベル名は、DNSサーバーが設定されているすべてのローカルインターフェースにルーティングされ、さらにグローバルに設定されたDNSサーバーがある場合は、グローバルに設定されたDNSサーバーにルーティングされます。デフォルトでは、「.local」サフィックスを持つドメインの検索は、そのドメインがDNSサーバーとインターフェースのルーティングまたは検索ドメインとして明示的に指定されていない限り、DNSサーバーにルーティングされないことに注意してください。(DeepL による翻訳)
This means that on networks where the ".local" domain is defined in a site-specific DNS server, explicit search or routing domains need to be configured to make lookups within this DNS domain work. Note that these days, it's generally recommended to avoid defining ".local" in a DNS server, as RFC6762[2] reserves this domain for exclusive MulticastDNS use.
つまり、「.local」ドメインがサイト固有のDNSサーバーで定義されているネットワークでは、このDNSドメイン内での検索を動作させるために、明示的な検索またはルーティングドメインを設定する必要があるということです。最近では、RFC6762[2]がこのドメインをMulticastDNSの排他的な使用のために予約しているため、DNSサーバーで「.local」を定義しないことが一般的に推奨されていることに注意してください。(DeepL による翻訳)
https://www.man7.org/linux/man-pages/man8/systemd-resolved.service.8.html
解決策
解決策は2つあります。
- systemd-resolved をやめて
/etc/resolv.conf
に直書き - systemd-resolved でスタブリゾルバ(
127.0.0.53
)を使わないようにする
1 はVPCネットワーク(VPC IPv4 CIDR)が変わると、毎回 DNS サーバの IP アドレスを変更しなければなりません。AmazonProvidedDNS によって動的に DNS サーバを設定しているため、直書きするようなことは極力控えたいです。
2 については再び man を見ると次のように書いてありました。
systemd-resolved maintains the /run/systemd/resolve/resolv.conf file for compatibility with traditional Linux programs. This file may be symlinked from /etc/resolv.conf and is always kept up-to-date, containing information about all known DNS servers. Note the file format's limitations: it does not know a concept of per-interface DNS servers and hence only contains system-wide DNS server definitions. Note that /run/systemd/resolve/resolv.conf should not be used directly by applications, but only through a symlink from /etc/resolv.conf. If this mode of operation is used local clients that bypass any local DNS API will also bypass systemd-resolved and will talk directly to the known DNS servers.
systemd-resolved は、従来の Linux プログラムとの互換性を保つために /run/systemd/resolve/resolv.conf ファイルを管理しています。このファイルは /etc/resolv.conf からシンボリックリンクされており、常に最新の状態に保たれており、すべての既知の DNS サーバに関する情報を含んでいます。このファイル形式には制限があることに注意してください: このファイルはインターフェイスごとの DNS サーバの概念を知らないので、システム全体の DNS サーバの定義しか含まれていません。/run/systemd/resolve/resolv.conf はアプリケーションによって直接使用されるべきではなく、/etc/resolv.conf からのシンボリックリンクを介してのみ使用されるべきであることに注意してください。この操作モードが使用されている場合、ローカル DNS API をバイパスするローカルクライアントは systemd-resolve もバイパスし、既知の DNS サーバーと直接通信することになります。(DeepL による翻訳)
https://www.man7.org/linux/man-pages/man8/systemd-resolved.service.8.html
ここで /run/systemd/resolve/resolv.conf
というファイルが出てきます。この中身を見ると、DNS サーバが 外部 DNS サーバ(AmazonProvidedDNS)が指定されていました。
% cat /run/systemd/resolve/resolv.conf # This file is managed by man:systemd-resolved(8). Do not edit. # # This is a dynamic resolv.conf file for connecting local clients directly to # all known uplink DNS servers. This file lists all configured search domains. # # Third party programs must not access this file directly, but only through the # symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way, # replace this symlink by a static file or a different symlink. # # See man:systemd-resolved.service(8) for details about the supported modes of # operation for /etc/resolv.conf. nameserver 10.0.0.2 search example.com
つまり、/run/systemd/resolve/stub-resolv.conf
はスタブリゾルバを利用するための設定ファイルで、/run/systemd/resolve/resolv.conf
外部 DNS サーバを利用するための設定ファイルであるようです。
systemd-resolved でスタブリゾルバを使わないようにする
Ubuntu 18.04 の systemd-resolved で local DNS stub listener の利用をやめる - Qiita に書いてあるとおりにやれば良いです。
# スタブリゾルバを使用しない % sed -i"" -e "s/.*DNSStubListener=yes/DNSStubListener=no/" /etc/systemd/resolved.conf # リゾルバファイルのシンボリックリンク先を変更 % cd /etc % ln -sf ../run/systemd/resolve/resolv.conf resolv.conf # 再起動して反映 % systemctl restart systemd-resolved.service
これで example.local
への名前解決ができるようになりました。
% dig example.local ; <<>> DiG 9.16.1-Ubuntu <<>> example.local ;; global options: +cmd ;; Got answer: ;; WARNING: .local is reserved for Multicast DNS ;; You are currently testing what happens when an mDNS query is leaked to DNS ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4439 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;example.local. IN A ;; ANSWER SECTION: example.local. 300 IN A 10.0.10.10 example.local. 300 IN A 10.0.11.20 ;; Query time: 3 msec ;; SERVER: 10.0.0.2#53(10.0.0.2) ;; WHEN: Fri Jun 05 20:57:59 JST 2020 ;; MSG SIZE rcvd: 60
まとめ
Ubuntu 16.04 LTS から採用された systemd-resolved によって「.local」の名前解決ができない問題について調査し対応しました。
そもそもとして「.local」を使ってはいけないという情報もあるので、ドメイン名が悪いのはたしかなのですが、気軽のドメイン名を変えるのが難しいので systemd-resolved の設定変更で対応することにしました。