wide-dhcpv6-clientでIPv6アドレスを取得
最近IPv6での通信を始めたのですが、Windowsでは自動配布でDNSサーバーのアドレスまで取得できるのに、Linux(Debian)では取得できていないみたいです。/etc/resolv.confにエントリーを追加すれば稼働するようにはなるのですが、なんとなくスマートではないので自動取得できないものか調べてみました。
RAによるDNSサーバーのアドレス取得
追記
以前までRAではDNSサーバーのアドレスを取得できないという旨の記述をしていましたが、メッセージいただきまして、RAでDNSサーバーの情報は取得できるようです。ご指摘ありがとうございました。
また、JPNIC「 RA 」によれば、 RFC6106にRAのオプションとしてDNSの設定が定義されているとの事です。
筆者の環境ではIPv6のルーター広告(RA)からDNSサーバーの情報を取得できませんせんでしたので、DNSサーバーのアドレスを受信するためにIPv6のDHCPを利用することにしました。
wide-dhcpv6-clientのインストール
APTでDHCPをキーワードに探してみたら、wide-dhcpv6-clientというものが見つかりました。これを利用してみます。
...
# apt update
...
# apt install wide-dhcpv6-client
...
インストール中に設定を反映させるインターフェース名を聞いてくるので、入力します。
設定ファイルは、/etc/wide-dhcpv6/にありますが、特に設定の必要はありませんでした。詳しくは「man dhcp6c.conf」を確認してください。
もしインストール時にインターフェース名を間違えた場合は/etc/default/wide-dhcpv6-clientファイルで修正します。
ファイアウォールの設定
筆者はファイアウォール(iptable-persistent)を利用している為その修正をします。/etc/iptables/rules.v6に次の行を加えて、DHCPとDNS解決時のパケットを通過させる設定をします。ちなみに筆者の環境では、OUTPUTはポリシーをACCEPTとしているので、ここでは設定していません。
-A INPUT -p udp --dport 546 -j ACCEPT
DNSは送信ポート基準でUDP53番、DHCPv6Clientは受信ポート基準で546番の通過を許可しました。
ちなみにIPv4で使用するDHCPのポート番号はサーバー宛てが67番、クライアント宛てが68番です。IPv6の場合はサーバー宛てが547番、クライアント宛てが546番と、クライアント宛の方が若いポート番号になっています。
「UDPの状態は判定可能?」というページでUDPもESTABLISHEDステータスになるという話を聞いて、ためしに「-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT」を入れてみましたが、この用途ではうまくいきませんでした。
設定を終えたらサービスを再起動します。「systemctl restart wide-dhcpv6-client」で行います。
再起動後、resolv.confにIPv6用のDNSサーバーのアドレスが追記されているのを確認します。
search flets-west.jp. iptvf.jp.
nameserver 2001:a7ff:5f01::a
nameserver 2001:a7ff:5f01:1::a
nameserver 8.8.8.8
心配していたクライアントのIPv6アドレスですが、DHCPクライアントの使用の前後で変化はありませんでした。
最後にドメイン名でpingを実行して応答があったら設定完了です
...
...64 bytes from...
...
wide-dhcpv6-clientのバグ?
wide-dhcpv6-clientを稼働させてからしばらく数日後/etc/resolv.confを見てみたら、何行も同じsearchエントリーが入っていました。
調べてみると、wide-dhcpv6-clientサービスが再起動されるたびに1行増えていくようです。
search行が不要なら/etc/wide-dhcpv6/dhcpv6c.confに記述されているエントリーを消してしまえばいいです。
profile default { information-only; request domain-name-servers; #↓コメントアウト #request domain-name; script "/etc/wide-dhcpv6/dhcp6c-script"; };
search行も欲しい場合は/etc/wide-dhcpv6/dhcp6c-scriptを修正します。ファイルの最初の方にあるif [ -n "$new_domain_name" ]のif~fiまでを次のようにします。
if [ -n "$new_domain_name" ]; then new_domain_name_trim=$(echo search $new_domain_name) res=$(grep "$new_domain_name_trim" $old_resolv_conf) if [ -z "$res" ]; then echo search $new_domain_name >> $new_resolv_conf fi fi
元のスクリプトは$new_domain_nameには新しいドメイン名しか入ってこない前提のような記述ですが、筆者の環境では必ず入ってきてしまうため、旧設定ファイル内をチェックし、同じ記述がない場合のみ追加ファイルに出力するようにしています。
echo search $new_domain_nameという形でファイルに追加されているので、$new_domain_name内部の文字列の前後に空白があったり、途中に2文字以上の空白があったりすると除去されて保存されます。その処理による不一致をなくすためにいったんechoで検索文字を整形しています。