FreeBSD: DHCPで割り当てられたIPアドレスとホスト名を一致させる

前々から気にはなっているものの、放置してきた問題。

我が家のネットワークとサーバーでは named と DHCPd が動いていて、ネットワークデバイスをネットワークに接続すると、自動的にネットワークに接続できるようになっています。いまどき当然のこと。我が家の場合、家庭用ルーター内蔵のDHCP機能ではなく、サーバーで、dhcpd と named を動かしています。

DHCPd と named は独立して動いているため、DHCPdが割り当てたIPアドレスは、あらかじめ機械的に指定してあるIPアドレスプールになっています。(例: pc1, pc2, …. pc10, ….pc20,…..pc100 )
FreeBSD 設定ファイルの中でホスト名を指定しても、FreeBSD → named 方向のデータアップデートはないため、適当にFreeBSDホスト名指定すると、named に登録してあるホスト名と、テストマシンに指定するホスト名が食い違ったまま利用することになります。
仮に、BINDに登録してあるホスト名に一致させて登録しても、時間が経つうちにDHCPdから別のIPアドレスが割り当てられてしまい、再びホスト名が一致しないことも起きます。
このしくみは、接続操作を行う毎に異なるIPアドレスが割り当てられる ISPのダイナミックIPアドレス割り当て方式と同じです。

これはこれで仕方がないのですが、ホスト名とIPアドレスが一致している必要がある Apache などをテストしようとするとワーニングメッセージが出力されたりして不便を感じることがあります。
手作業で毎回IPアドレスとホスト名が一致するよう作業すればいいのですけど、最近VMを使う機会が増え、FreeBSD の VMを立ち上げるごとに設定を行うのは面倒なので、自動的に「dhcpd が割り当てた IPアドレスから、named に登録されているホスト名を設定する」ことが出来ないものかと考えていました。

それで、ちょっとしたスクリプトを書いてみました。

#!/bin/sh

current_ip=`ifconfig | grep netmask | head -1 | awk '{print $2}'`
current_host=`host $current_ip | awk '{print $5}' | sed -e 's/\.$//'`
if [ "$current_host" !=  "$HOST" ]; then
	echo "hostname=\"$current_host\"" > /etc/rc.conf.new
	grep -v "hostname=" /etc/rc.conf >> /etc/rc.conf.new
	mv /etc/rc.conf /etc/rc.conf.old
	mv /etc/rc.conf.new /etc/rc.conf
fi

ifconfig コマンドで表示されるインタフェース名から netmask を含む行を取り出し、コマンド出力 一番上のインタフェースに割り当てられているIPアドレスからホスト名を決定し、/etc/rc.conf の中の hostname 行と置き換えます。(ネットワークインタフェースが2つ以上ある場合は、ifconfig コマンドで一番上に表示されるNICに割り当てられるIPアドレスをホスト名として登録します。)PPPoE接続用インタフェースのIPアドレスをホスト名として使用したいケースでは、スクリプトの修正が必要になるでしょう。

動作条件

  • FreeBSD 9.3, 11.0 (で動作確認しました)であること。多分、FreeBSD10.x でも動くでしょう。
  • DHCP と named 動作環境であること。
  • nslookup や dig で IPアドレス→ホスト名検索が正常に動作する環境であること。

保存場所

/etc/rc.shutdown

-rw-r--r--  1 root  wheel  375 Nov 29 01:30 /etc/rc.shutdown

上記ファイルを /etc/rc.shutdown として保存すれば、シャットダウン中にホスト名のIPアドレスの整合性を確認します。リブート一発すれば、ホスト名が自動設定されるってこと。

都合がよい名前に変更して保存して、手動で実行してもOK。

動作確認

FreeBSD を実マシンじゃなく VM で実行するための素の状態の FreeBSD11 VBOXイメージ が FreeBSDダウンロードサイトに置いてありますが、これを簡単に使うために準備したスクリプトです。インストール作業が必要なOSでは動作確認していません。

コメントを残す