runmdn
概要
runmdn は BIND-4 あるいは BIND-8 をベースとした リゾルバライブラリを持つクライアントを、 再コンパイルなしに多言語ドメイン名を扱えるようにするためのコマンドです。
起動
% runmdn コマンド [引数...]
例えば telnet コマンドで多言語ドメイン名を扱うためには次のようにします。
% runmdn telnet ログイン.どこかの会社.jp
実装
runmdn は共有ライブラリのプリロード機構を用いて、 標準のリゾルバライブラリに含まれる関数の一部を、 多言語ドメイン名の処理機能を持つ別のバージョンに動的に置換えることで、 クライアントでの多言語ドメイン名の処理を実現します。
多くのシステムでは共有ライブラリのプリロードは環境変数 LD_PRELOAD を用いて実現されています。 この環境変数にプリロードしたい共有ライブラリファイルのパス名を指定すると、 クライアントの実行時に、 アプリケーションに標準の共有ライブラリがリンクされる前に指定したライブラリがリンクされます。 これによって標準のライブラリ関数を置換えることができます。
したがって、runmdn の実体は、この環境変数を設定し、 引数で指定されたコマンドを起動するだけのシェルスクリプトであり、 実際に多言語ドメイン名の処理を行うのはアプリケーションにリンクされる共有ライブラリ libmdnresolv です。
libmdnresolv をリンクすることにより、 BIND4 あるいは BIND8 ベースのリゾルバライブラリで用いられている次の関数が置き換わります。
dn_comp dn_expand res_hnok res_ownok res_mailok res_dnok
それぞれの変更点を簡単に記述します。
- dn_comp
- 指定されたドメイン名を DNS プロトコルで用いられるドメインデータに変換する前に、 ローカルコードセットから DNS プロトコル上で用いられるエンコーディングへの変換および正規化、(必要ならば) ZLDの付加を行います。
- dn_expand
- DNS プロトコルで用いられるドメインデータをドメイン名文字列に変換した後、 (必要なら) ZLD を削除し、 ローカルコードセットへの変換を行います。 また通常この関数はドメイン名に含まれる ASCII 以外の文字をバックスラッシュエスケープする処理をしますが、これを抑制します。
- res_hnok
- どんな文字でも正当な文字であると判断するようにします。
- res_ownok
- どんな文字でも正当な文字であると判断するようにします。
- res_mailok
- どんな文字でも正当な文字であると判断するようにします。
- res_dnok
- どんな文字でも正当な文字であると判断するようにします。
エンコーディング変換や正規化、ZLD の処理等はすべて MDN ライブラリ (libmdn) の res モジュールを使用しています。
現在の実装では libmdnresolv は MDN ライブラリ (libmdn) を呼び出すのではなく、 libmdn 自体を内部に抱え込むような形態になっていますが、 これは単なる実装上の都合からそうなっているだけで、 論理的には MDN ライブラリの機能を呼び出しているといってよいでしょう。
また使用するエンコーディングや正規化の設定は クライアント設定ファイルの設定を利用します。
制限
runmdn にはいくつかの制限があり、 どんなシステムでも使えるわけではありません。
- runmdn は共有ライブラリの動的リンク機構を用いているので、共有ライブラリが使用できるシステムでなければなりません。
- また環境変数 LD_PRELOAD または類似の機構によるライブラリのプリロード機能を持つシステムでなければなりません。
- runmdn の対象となるコマンドはリゾルバライブラリをスタティックリンクしていてはなりません。
- システムのライブラリが iconv() 関数を提供していない場合、外部のライブラリを用いることになりますが、そのライブラリも共有ライブラリでなければなりません。
- システムのリゾルバライブラリは BIND4 あるいは BIND8 ベースのものでなければなりません。
- セキュリティ上の理由から一般に setuid されたコマンドはプリロード機能が使えないようになっているので、setuid されたコマンドであってはなりません。