▼BIND namedで network unreachable resolving '...' を抑制する▼

DNSサーバの BIND 9.x系 named をアップデートすると
Jun 13 15:02:32 ns named[2344]: network unreachable resolving 'ns2.value-domain.com/A/IN': 2001:7fd::1#53
Jun 13 15:02:32 ns named[2344]: network unreachable resolving 'ns1.value-domain.com/A/IN': 2001:7fd::1#53
Jun 13 15:02:32 ns named[2344]: network unreachable resolving 'ns3.value-domain.com/A/IN': 2001:7fd::1#53
のようなエラーが /var/log/messages に出てきて、 ログファイルがやたら太ることがあります。 (上の 2001:7fd::1k.root-servers.netの IPv6アドレス)

$Keywords: named bind squelch disable suppress "network unreachable resolving" UDP/IPv6 log message $
$Id: bind-unreach.html,v 1.8 2013-03-12 16:53:15+09 kabe Exp $


原因

と、外部へのDNS問い合わせ先にたまたま IPv6 の外部サーバ(NS)を索き当てると、 IPv6 で問い合わせしようとして失敗します。 (再試行でIPv4のサーバにあたれば、結果的には問題なく索けます)

options { forwarder { ...; }; }; を指定していても、 IPv6は直で訊きにいってしまうようです

ええと、もちろん、正規のDNSサーバが落ちていて索けない、 IPv4ですら通信できない、場合も似たようなエラーは出ます。


対策(1): IPv4専用モード

named-4オプション (IPv4専用モード) で起動するようにします。

Red Hat/CentOS系であれば、/etc/sysconfig/namedに 以下を追加します。 起動スクリプトの /etc/rc.d/init.d/named が拾ってくれます。

	# OPTIONS="whatever"	 --  These additional options will be passed to named
	#			     at startup. Don't add -t here, use ROOTDIR instead.
	OPTIONS="-4"

-4はblogなど 色々なところ で紹介されていますね

対策(2): IPv6ポート使用禁止

update: bind のバグ [#24173] のため、 以下をDNSスレーブに適用すると マスタからのゾーン転送が止まってしまいます! bind 9.8.0 でも問題残存。(なんだそりゃ…)

外部へのIPv6は使えないが、内部では使いたい、::1 くらいは有効にしたい、 という場合は -4は使いたくないので、

やや姑息ですが UDPv6 の問い合わせ用ポートを全部使用禁止にします。

named.conf:
	options
	{ 
		...
		listen-on-v6 { any; }; // default none!
		// disable outgoing IPv6 query (forwarders{} not enough?)
		// avoid-v6-udp-ports { range 0 65535; };
		use-v6-udp-ports { };
		...
	};

デフォルト値は range 1024 65535; です。 named を再起動し、

Jun 14 19:32:24 ns named[21668]: using default UDP/IPv6 port range: [1024, 65535]
という行が出ていなければ設定成功です。 IPv6で外部への問い合わせをしなくなるだけで、 IPv6の問い合わせ自体には応答できます。

なお、デフォルトでは IPv6 には応答できない! ([::]:53にbindしない)ので、 内部用などでIPv6で応答したい場合は陽に listen-on-v6 { any; }; を 追加する必要があります。

対策(3): IPv6サーバをブラックリスト化

BIND 9.5.0a1 以降 でないとこの文法は使えません。

BINDのFAQ (I don't have an external IPv6 connection) には

	// N.B: Needs BIND 9.5.0a1 and above for "server ip_prefix"
	server ::1		{ bogus no; };	// localhost6
	server fe80::/16	{ bogus no; };	// link-local
	server ::ffff:0:0/96	{ bogus no; };	// v6-mapped-v4
	server ::/0		{ bogus yes; };	// omni
的な方法が示されていて、使えるならこちらのほうがキレイです。

対策(4): ログ出力抑制

手っ取り早く、ログだけ出なければいいやという場合は、

named.confの category lame-servers でログ出力を制御できます。

	logging
	{
		//category default { default_syslog; default_debug; };
		...
		category lame-servers { null; };
	};

"resolving" 系のエラーは、良く見かける以下のような "lame server" のエラーと同じログ分類になっており、 同時に抑制されます。
Jun 15 10:52:09 ns named[23252]: lame server resolving 'lb2.iws.mofa.go.jp' (in 'lb2.iws.mofa.go.jp'?): 61.213.187.189#53
Jun 15 10:52:09 ns named[23252]: lame server resolving 'lb1.iws.mofa.go.jp' (in 'lb1.iws.mofa.go.jp'?): 210.160.15.253#53

もっともログを抑制しているだけなので、 実際に内部ではIPv6処理は行われています。 (「なんかDNS遅いんだけど?」の調査の手がかりが減ってしまう)

参考: namedソースコードでの出力箇所
lib/dns/resolver.c:add_bad()
	isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS,
		DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
		"%s %s%s%sresolving '%s/%s/%s': %s",
		dns_result_totext(reason), sep1, code, sep2,
		namebuf, typebuf, classbuf, addrbuf);

reason == ISC_R_NETUNREACH == 8
isc_result_totext(ISC_R_NETUNREACH)=="network unreachable"

付録:logwatchでのログ抑制

Red Hat/CentOS系で動いている logwatch(8) の出力に

 --------------------- Named Begin ------------------------

 **Unmatched Entries**
    network unreachable resolving 'ns1.value-domain.com/A/IN': 2001:7fd::1#53: 1 Time(s)
    network unreachable resolving 'ns2.value-domain.com/A/IN': 2001:7fd::1#53: 1 Time(s)
    ....
が大量に出てくるので抑制したい、がログ自体は取っておきたい、場合は、

以下のような内容の /etc/logwatch/conf/services/named.confを新しく作っておくと、 egrep -iv フィルタが挟まって除去できます。

	# /etc/logwatch/conf/services/named.conf
	# invoke scripts/shared/remove
	*remove = (network unreachable resolving )
なお "lame server resolving"については、解析プログラム本体 (/usr/share/logwatch/scripts/services/named) にて無視されています。

なお引数に "'などのクオートやシェル特殊文字を入れると 動かないことが多いので避けます。 内部的には open("| $perl $script") + system("egrep -iv \"@ARGV\"") のように 多段でシェル呼び出しをしているため、どう展開されるか予想しにくい。


かべ@sra-tohoku.co.jp