2017-02-27

Bogons - インチキネームサービス

Bogons (Bogus Name Service) は、家庭内などの小規模ネットワークで使用できる名前サーバです。zeroconfとか言われている類ものです。avahi-daemonに似ています。

概要

インターネットで名前解決といえばDNSがお馴染みですが、BogonsはDNSサーバ機能だけでなく、Windowsネットワークでよく利用されるWINSサーバ機能や、AppleのBonjourで使用されるmDNS(MulticastDNS)サーバ機能も提供します。いずれもごく簡易的な機能に止めており、問い合わせに対する応答しかできません。定義ファイル(/var/bogons/hosts)を書き換えれば、応答結果にすぐに反映されるというのが特徴です。

逆引き、ドメイン、ゾーン転送などといった、常識的なDNSサーバが備えている機能は搭載していません。高トラフィック環境での使用は想定しておらず、セキュリティ的に枯れていませんので、インターネットで公開するような、本格的な名前解決サーバとして使用するのには向きません。

用途

DNSサーバとして

UDP/53で問い合わせを待ち受けます。アドレス定義ファイル /var/bogons/hosts に登録されている名前なら、即座にそのアドレスを返答します。登録されていない名前なら、上位サーバに委譲して名前解決をすることができます。上位サーバが設定されていなければ、 no such name 応答を返します。アドレス定義ファイルは、参照する際に更新されていれば再読込されますので、シグナルを送ったり、プログラムを再起動したりして更新する必要はありません。

WINSサーバとして

UDP/137で問い合わせを待ち受けます。同様に /var/bogons/hosts を参照して名前解決を行います。DNSとは異なり、WINSは通常、ブロードキャストで使用されます。たとえば、192.168.0.0/24のネットワークなら、192.168.0.255を宛先としてブロードキャストし、ネットワークセグメント全体に問い合わせが行き渡ります。名前解決が可能なコンピュータが即座に応答します。Bogonsは、信頼できないコンピュータが存在するなど、他者によって重複や矛盾した応答が行われても関知しません。そのため、BogonsをWINSサーバとして使用するには、信頼できる小規模ネットワーク内だけで使わなければなりません。WINSモードで実行する場合には、解決できない問い合わせは、上位サーバに委譲することなく、ただ無視します。

DNSの場合、あらかじめ、誰に訊くべきか、つまり、問い合わせ先のDNSサーバのアドレスを知っておく必要がありますが、WINSの場合、ブロードキャストで問い合わせするため、事前登録などしないで、いきなりネットワークに接続しただけで、自分の名前を配信することができます。これは便利なこともありますが、トラフィックとセキュリティに関しては欠点ともなりえます。

小規模ネットワークで使用することを想定していますので、応答の有効期限(TTL)は60秒と短くしています。これは、設定で変更することができます。

mDNSサーバとして

UDP/5353で問い合わせを待ち受けます。それ以外の多くの点では、WINSに似ています。

LLMNRサーバとして

UDP/5355で問い合わせを待ち受けます。それ以外の多くの点では、mDNSに似ています。

使い方

コンパイル

ソースコード : https://github.com/soramimi/Bogons

Windows

Visual Studio 2008 でコンパイルしますが、それ以外のVisual Studioであっても、プロジェクトを新規作成して、3個の .cpp と2個の .h を登録するだけですので、難しくはないと思います。ビルドすると bogons.exe ができます。

設定ファイルは C:\var\bogons に置きます。常に固定です。設定で変更することはできませんので、違う場所にしたければ、ソースファイルを書き換えて再コンパイルする必要があります。

Linux、Mac OS X など

bogons/src に移動して、makeコマンドでビルドできます。bogonsを /usr/local/bin などにコピーします。DNSおよびWINSモードでは、well-knownポートにbindするため、実行する際はスーパーユーザでなければなりません。

設定ファイルは /var/bogons に置きます。

設定ファイル

設定ファイルは hosts と bogons.ini です。

/var/bogons/hosts

192.168.0.123 mypc mypc.local

この例では、1つのアドレスに2つの名前を定義しています。「mypc」または「mypc.local」で問い合わせが来たときに、「192.168.0.123」を返答します。

必ず複数の名前を定義する必要はなく、1対1の定義でもいいですし、ドメインサフィックスを付けずに、単一のホスト名だけでも構いません。

DHCPサーバから自分の所属するネットワークのドメイン名を取得して、自動的にサフィックスが付けられてしまう場合があります。DHCPサーバで、ドメインサフィックスが local と設定されていた場合、端末が mypc であっても、OSのリゾルバが自動的に mypc.local で問い合わせを行うことがありますので、単一ホスト名と共に、DHCPサーバで設定されたドメインサフィックス付きの名前を定義するといいでしょう。もちろん、端末側でドメインサフィックスを設定している場合は、それに合わせて定義ファイルに記述します。

/var/bogons/bogons.ini

masterserver=192.168.0.1
ttl=300

この例では、DNS用の上位サーバと、問い合わせ結果の有効時間を定義しています。どちらもオプションです。実際のところ、bogons.iniファイル自体が存在しなくても動作します。現バージョンでは masterserver と ttl 以外の設定項目はありません。

masterserver

DNS用上位サーバ

一つだけ定義できます。IPv4アドレス、または名前を指定します。この設定が無い場合、上位サーバへの委譲は行われません。DNSモード以外で実行する場合は、このオプションは使用されません。

ttl

問い合わせ結果の有効時間

単位は秒です。

このファイルは、変更しても自動読み込みされません。設定を有効にするには、bogonsを実行し直す必要があります。

コマンドラインオプション

-d, --dns

DNSモードで実行します。UDP/53でサービスを提供します。既定の動作ですので、このオプションを指定する必要はありません。

-w, --wins

WINSモードで実行します。UDP/137でサービスを提供します。主にWindowsのクライアントから名前解決に利用できます。

-m, --mdns

mDNSモードで実行します。UDP/5353でサービスを提供します。主にmacOSのクライアントから名前解決に利用できます。

-l, --llmnr

LLMNRモードで実行します。UDP/5355でサービスを提供します。Windows Vista以降で利用できます。

-s, --self

自己応答機能を有効にします。この時 /var/bogons/hosts に定義しなくても、自己のホスト名とIPアドレスを自動認識し、問い合わせに応答します。通常、WINSモードまたはMDNSモードで使用します。

-v, --verbose

実行中の動作状況を逐一表示します。bogons.iniやhostsを変更したとき、動作確認のために使用します。正常に動作することが確認できたら、このオプションを外して実行します。

DNS、WINS、MDNSの三つのモードは、どれか一つだけ指定することができます。複数指定すると、最後に指定したオプションのみが有効となり、他は無視されます。異なるモードで複数のプロセスを起動することは可能です。

使用例

Raspberry Pi で自動応答

Raspberry Pi で Bogons を WINS/self モードで実行すると、Windowsから名前でアクセスすることができます。この場合、bogons.iniもhostsも必要ありません。

/etc/rc.local

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

/usr/local/bin/bogons -w -s &

exit 0

LinuxからWINSで名前解決をする

Debian系Linuxでの設定例を挙げます。

winbind パッケージをインストール

# apt-get install winbind libnss-winbind

/etc/nsswitch.conf を編集

winsを追加

hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4 wins

トラブルシューティング

LinuxでmDNSやLLMNRモードでの起動が失敗する場合

/etc/rc.localに、以下のように書いたとします。

/usr/local/bin/bogons -w -s &
/usr/local/bin/bogons -m -s &

起動後、ps ax を実行して、プロセスを見てみると、前者のWINSモードは正常に起動し、後者のmDNSモードの起動が失敗することがあります。手入力で、 /usr/local/bin/bogons -m -s を実行すると、何事もなく成功します。起動ログをよく見てみると、

setsockopt : No such device

と表示されている場合が、本件に該当します。

systemdを利用してLinuxが起動する場合に、発生するようです。筆者が確認したのは、Raspberry Piに 2015-09-24-raspbian-jessie をインストールした場合です。

BogonsをmDNSやLLMNRモードで実行する場合、マルチキャストモードのソケットを使用するのですが、以下のようなコードで setsockopt が失敗します。

mreq.imr_interface.s_addr = INADDR_ANY;
mreq.imr_multiaddr.s_addr = inet_addr("224.0.0.251");
setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)); 

解決策としては、 224.0.0.0/29 のルーティング規則を定義します。具体的には、下記のように rc.local に記述します。

route add -net 224.0.0.0 netmask 224.0.0.0 eth0 
/usr/local/bin/bogons -m -s &