Ubuntu 16.04: libvirtのNATが名前解決できないケース

libvirtのNATで名前解決できない特殊なケースについて記載します。

1 /etc/resolv.confの種類

2種類の/etc/resolv.confについて記載します。この記事では後者について取り扱います。

なお、/etc/resolv.confの内容はDCHPサーバが責任を持つべきです。ラップトップを別のネットワークアドレスで使う場合に、いちいち/etc/resolv.confの設定を変更する必要があるのはDHCPサーバに問題があります。

1.1 バックアップとして複数のnameserverを使う

Primary DNSサーバが動作しない場合に、Secondary DNSサーバを使います。

$ cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 8.8.8.8
nameserver 8.8.4.4
  • nameserver 8.8.8.8はPrimary DNSサーバで、再帰的に名前解決します。
  • nameserver 8.8.4.4はSecondary DNSでサーバ、nameserver 8.8.8.8が落ちていて、問い合わせを返さない場合に使われます。nameserver 8.8.8.8が落ちているかは問い合わせ時間のタイムアウトで判断します。

1.2 専用ドメインの名前解決に複数のnameserverを使う

これは特定のドメインの名前解決に特定のDNSサーバを使います。

$ cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 192.168.11.2
nameserver 192.168.11.1
search hiroom2.com
  • nameserver 192.168.11.2はドメインhiroom2.com向けのDNSサーバです。ドメインhiroom2.comにあるホスト名以外は名前解決せず、再帰問い合わせは実行しません。
  • nameserver 192.168.11.2で解決できないホスト名はnameserver 192.168.11.1で解決するようにします。つまり、ホストマシンで反復問い合わせを実行することを期待しています。

2 VirtualBoxのNATは名前解決できる

VirtualBoxのNATはIPアドレスだけでなく、アドレスとホストマシンの/etc/resolv.confを元にDNSサーバを配布します。仮想マシンでDHCPを利用していれば、ゲストマシンの/etc/resolv.confはホストマシンと同じ内容になります。

仮想マシンの名前解決を実現するには、仮想マシンの名前をDNSサーバに登録し、ホストマシンの/etc/resolv.confにそのDNSサーバを記載する必要があります。

これは扱いやすい実装です。

3 libvirtのNATで名前解決できない

libvirtによりホストマシンでdnsmasqが動作し、DHCPサーバとDNSサーバを実現しています。ゲストマシンへホストマシンの仮想ネットワークインターフェースのIPアドレスがDNSサーバとして配布されます。

ゲストマシンでDHCPを利用した場合、以下の/etc/resolv.confが自動的に生成されます。

$ cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 192.168.122.1

libvirtのdnsmasqはホストマシンの/etc/hostsの内容と/etc/resolv.confを元に名前解決を実現します。

問題となるのはホストマシンの/etc/resolv.confに複数のnameserverが記載されている場合、ひとつ目のnameserverで名前解決ができない場合(REFUSEDを返す場合)、それ以上の名前解決を実行しない点です(タイムアウトの場合は2つ目のnameserverに問い合わせるようです)。

"専用ドメインの名前解決に複数のnameserverを使うケース"では期待した動作になりません。

dnsmasqは"専用ドメインの名前解決に複数のnameserverを使うケース"向けに複数のnameserverを問い合わせる設定が可能なようですが、少なくともUbuntu 16.04のlibvirtはそのように設定することはできません。

複数のforwarderを設定できるこのコミットで解決する見込みです。