DSAS環境でのDNS活用法2 〜tinydns-get活用術〜
KLab Advent Calendar 2011 「DSAS for Social を支える技術」 の13日目です。
先週に引き続き、DSAS 環境での DNS 活用法を紹介します。
スクリプト中でのゾーン参照方法
DSAS で使用している各種スクリプト内で、DNS の情報を参照する際に使ってるコードを紹介します。
# 設定情報用のゾーン(.dsas)を検索
mzone ()
{
R="$1";
( cd $INTERNALZONE 2> /dev/null;
_zone TXT $R.dsas )
}
# 名前解決を行う
# tinydnsのゾーンファイルのコピーがあればtinydns-getを使用
# ゾーンファイルがなければDNS問い合わせを行う
_zone ()
{
if [ -r data.cdb ]; then
DNSCMD="_zonedjb";
else
DNSCMD="_zonedig";
fi;
if [ -z "$2" ]; then
Q="A";
R="$1";
else
Q="$1";
R="$2";
fi;
$DNSCMD $Q $R
}
_zonedig ()
{
dig +short $1 $2 | sed 's/^\"\(.*\)\"$/\1/'
}
# tinydns-getを使い、カレントディレクトリのdata.cdbを検索
_zonedjb ()
{
tinydns-get $1 $2
}
mzone() と呼んでいる関数では、前回紹介した TXT レコードによる設定データを参照します。
この他に、通常の内部ホスト名の名前解決を行う pzone() や、そのグローバル版の gzone() 等を定義しています。
各サーバでは、起動スクリプト中でこれらの関数等を使い、設定ファイルを生成しています。
下記に抜粋したコードでは、この関数を使い、keepalived.conf の VRRP に関する設定を生成しています。
lan=$(mzone net.private)
lan=$(pzone lvs)/${lan#*/}
wan=$(mzone net.link)
wan=$(mzone lvs.link)/${wan#*/}
cat <<EOF
vrrp_instance VI {
state BACKUP
interface bond0
garp_master_delay 5
virtual_router_id $(mzone lvs.vrid)
priority ${PRIO}
nopreempt y
advert_int 1
authentication {
auth_type PASS
auth_pass ********
}
virtual_ipaddress {
${lan} dev bond0
${wan} dev bond0
}
}
EOF
パラメータ部分を DNS に逃すことで、生成スクリプトの環境依存部分を極力減らせるほか、複数のスクリプトから参照している設定情報を1箇所で管理することができるようになります。
オフライン時の内部ゾーン参照
DSAS 環境では、多くの設定ファイルを同様の方法で起動時に生成しています。
ネットワークインタフェースはもちろん、resolv.confや、全サーバのローカルで動いているDNSキャッシュサーバの設定ファイルも起動時に生成しているため、これらの生成スクリプトは、ネットワークが使えない状態でも動作出来る必要があります。
ネットワーク設定の生成にネットワークアクセス(DNS参照)が必要という矛盾した状況ですが、とても単純な方法で解決しています。
そもそも DNS 上の情報は、それほど頻繁に更新されるものではないため、サーバの起動時にゾーンファイルを転送してローカルで検索を行い、起動が完了したら DNS の参照に切り替えてやればいいのです。
先ほど紹介した、検索用の関数でも、ローカルにゾーンファイルの一時コピー(data.cdb)が存在するかをキーに動作が切り替わるようになっています。
この方法では、ゾーンファイルの一時コピーを消し忘れると、いつまでも古い情報を参照してしまう恐れがあるので、起動処理の一番最後で必ずゾーンファイルを削除するようにします。
tinydns-getの使い方
tinydns-get はカレントディレクトリの data.cdb をゾーンファイルとして読み込むため、ゾーンファイルの置かれてるディレクトリに移動して、下記のように実行します。
$ tinydns-get A www.klab.jp 1 www.klab.jp: 189 bytes, 1+1+4+4 records, response, authoritative, noerror query: 1 www.klab.jp answer: www.klab.jp 86400 A 211.13.209.202 authority: klab.jp 259200 NS ns1.klab.org authority: klab.jp 259200 NS ns2.klab.org authority: klab.jp 259200 NS ns8.klab.org authority: klab.jp 259200 NS ns9.klab.org additional: ns1.klab.org 14400 A 61.195.64.249 additional: ns2.klab.org 14400 A 61.195.64.247 additional: ns8.klab.org 86400 A 211.13.207.96 additional: ns9.klab.org 86400 A 211.13.207.97
「answer:」の行がクエリの結果です。
tinydns-get では、dig のような「+short」オプションがなく、自分で出力を加工する必要がある上に、TXT レコードの処理に問題があります。
'test.dsas.jp:TEST
answer: test.dsas.jp 86400 16 \004TEST
'test.dsas.jp:TEST5678901234567890123456789TEST
answer: test.dsas.jp 86400 16 !TEST5678901234567890123456789TEST
'test.dsas.jp:TEST5678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890
123456789012345678901234567TEST
answer: test.dsas.jp 86400 16 \177TEST56789012345678901234567890
1234567890123456789012345678901234
5678901234567890123456789012345678
90123456789012345678901234567\004T
EST
上記は、上段がバイナリ変換前のゾーンファイルでのレコード、下段が tinydns-get コマンドを使って検索した結果を示します。
各レコードは、1桁目がレコードの種類(TXTレコードは「'」)、続いてコロン区切りでFQDNとレコードの値が続きます。
answer行の各カラムは、検索したFQDN、TTL、レコードのタイプ値(TXTは16)、レコードの値となっています。
ご覧のとおり、レコードの値に「\004」、「!」など、元のゾーンにない文字列が混ざってしまっています。
なんと tinydns-get は、TXT レコードに対応しておらず、data.cdb ファイルに格納されている 「1バイトの文字列長 + 最大127バイトのデータ値」の繰り返しによるデータ列をそのまま表示してしまっているのです。
データにより、「\xxx」や「!」など、表示され方に差があるのは、出力時に ASCII Printable であればそのまま、制御コードなどであれば8進数表記に変換して表示しているためです。
tinydns-get-suppress-msgs.patch
上記のパッチを当てると、tinydns-get が TXT レコードに対応し、余分な文字列を出力しなくなります。
また、少々手荒に書いたパッチですが、2つ目のパッチを当てると、検索結果に関する余分な情報が出力されなくなり、スクリプト等で使いやすくなると思います。
