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つ目のパッチを当てると、検索結果に関する余分な情報が出力されなくなり、スクリプト等で使いやすくなると思います。