デスクトップLinuxとして使っているUbuntu18.04で、ドメインごとに問い合わせるDNSサーバを変更したい場面が出てきた。 具体的には、VPNを接続してその接続先のドメインだけはDNSサーバを変更したいみたいな。
Ubuntu18.04ではDNSリゾルバとして、systemd-resolvedを使っている。 こいつでは、やりたいことは出来ないようなのでdnsmasqに変更することにした。
なぜdnsmasqなのか?
すでにインストールされていて*1、そしてNetworkManagerが対応している。 Ubuntu18.04ではネットワーク関連の設定をNetworkManagerが管理しているので、とても都合がよい。 そんなこんなでdnsmasqを使うことにした。
systemd-resolvedを止める
止める手順としてはまず、/etc/systemd/resolved.conf
の Resolve
セクションに DNSStubListner=no
を設定する。
[Resolve] DNSStubListener=no
設定を行ったら systemd-resolved
を再起動する。
$ sudo systemctl restart systemd-resolved
再起動した後、digっても何も返ってこないはず。
NetworkManagerの設定をする
この状態でdnsmasqを起動してもいいのだが、NetworkManagerと連携させないとDHCPで降ってくるDNSサーバの情報を反映させることができないため、連携設定を行う。
連携設定は /etc/NetworkManager/NetworkManager.conf
のmain
セクションに dns=dnsmasq
を設定する。
[main] dns=dnsmasq
次に、NetworkManagerを再起動したいのだが、実はまだdnsmasqとの連携設定が出来ていない。
というのも /etc/resolv.conf
が systemd-resolvedが生成するresolv.confへのシンボリックリンクになっている場合、NetworkManagerは自動的にsystemd-resolvedと連携するようになる。
なので、 このシンボリックリンクを削除する。
$ ls -lah /etc/resolv.conf lrwxrwxrwx 1 root root 39 8月 10 17:32 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf $ sudo unlink /etc/resolv.conf
/etc/resolv.conf
は作らなくてもNetworkManagerを再起動すれば作成されるので問題ない。
ということで、NetworkManagerを再起動する。
$ sudo systemctl restart NetworkManager
dnsmasqの設定を変える
ここまでの設定でdnsmasqがDNSリゾルバになっているはず。
しかし、まだ当初やりたかった 特定ドメインだけDNSサーバを変える
を達成していない。
NetworkManagerで起動するdnsmasqは /etc/NetworkManager/dnsmasq.d
配下にあるファイルを読み込むのでこのディレクトリ配下に設定ファイルを作成する。
ファイル名は何でも良いのだが、なんとなく default.conf
にした。
$ cat /etc/NetworkManager/dnsmasq.d/default.conf server=/example.com/192.0.2.0
設定ファイルを作成後、NetworkManagerを再起動すると反映される*2。
digれない!
dnsmasqを使うようになってからdigを打ったら何も取得できない!!!
$ dig ; <<>> DiG 9.11.3-1ubuntu1.2-Ubuntu <<>> ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: FORMERR, id: 57447 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ; COOKIE: b9472f88fb4991ce (echoed) ;; QUESTION SECTION: ;. IN NS ;; Query time: 3 msec ;; SERVER: 127.0.1.1#53(127.0.1.1) ;; WHEN: Fri Oct 12 19:46:35 JST 2018 ;; MSG SIZE rcvd: 40
結論からいうと、私の環境が悪かった。
dnsmasqが問い合わせに行く上位のDNSサーバ(つまりDHCPで設定されたDNSサーバ)が、DNS cookieを受け付けていなかったのであった。
よって、+nocookie
オプションをつければ問題は解決された。
$ dig +nocookie ; <<>> DiG 9.11.3-1ubuntu1.2-Ubuntu <<>> +nocookie ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28281 ;; flags: qr rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 3 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4000 ;; QUESTION SECTION: ;. IN NS ;; ANSWER SECTION: . 77519 IN NS j.root-servers.net. . 77519 IN NS k.root-servers.net. . 77519 IN NS m.root-servers.net. . 77519 IN NS h.root-servers.net. . 77519 IN NS b.root-servers.net. . 77519 IN NS l.root-servers.net. . 77519 IN NS a.root-servers.net. . 77519 IN NS e.root-servers.net. . 77519 IN NS c.root-servers.net. . 77519 IN NS d.root-servers.net. . 77519 IN NS i.root-servers.net. . 77519 IN NS g.root-servers.net. . 77519 IN NS f.root-servers.net. ;; ADDITIONAL SECTION: j.root-servers.net. 86400 IN A 192.58.128.30 a.root-servers.net. 26879 IN A 198.41.0.4 ;; Query time: 8 msec ;; SERVER: 127.0.1.1#53(127.0.1.1) ;; WHEN: Fri Oct 12 19:49:53 JST 2018 ;; MSG SIZE rcvd: 284
ちなみにこの問題はsystemd-resolvedのときは起こらなかった。 systemd-resolvedは上位のDNSサーバに問い合わせるときには、どうやらDNS cookieをつけていないようだった。 dnsmasqでも同じ設定ができるのかどうかは調査中…。
Tips: 現在設定されている問い合わせ先DNSサーバを知る
通常、問い合わせ先のDNSサーバは /etc/resolv.conf
を見ればわかるんのだが、今回の設定によりローカルをみるようになっている。
しかし、nmcliから確認することができる。
$ nmcli d sh | grep DNS
ちなみに、systemd-resolvedでは systemd-resolv
というコマンドがありこちらで確認できる。