以下のテキストは、執筆時当時の情報を元に書いたものであり、 現在の情勢にそぐわないことを含む場合があるので注意されたい。 また、テキストは最終提出原稿で校正を経る前のものなので、実際にUNIXUSER 本誌に記載されたものとは異なる。誤字脱字等そのままである。
致命的な誤り以外は加筆修正等は行なわないので情報の鮮度に気をつけつつ 利用して欲しい。
→目次
========================================================================== 大特集 DJB ツールで固める堅牢サーバ ========================================================================== ---------------------------------------------------------------------- D. J. Bernstein 氏(DJB)によるqmailは、設定ファイルの驚くまでのシンプルさ と、ユーザに与える利便性の高さ、そしてなによりも徹底した高セキュリティ性 で一躍有名になった。誰もがネットワークサーバが立てられるようになった現在 は同時に誰もが外部からのアタックを受け続ける時代でもある。今回はDJBツー ルを利用して、ネットワークサービスを固める方法をたっぷりと解説しよう。 ---------------------------------------------------------------------- 【Part 1 DJBツールに流れる哲学】 DJBツールを代表するqmailは、安全で高性能という評判が瞬く間に広がり、今で は商用サービスのMTAとしても採用されるに至った。qmail公表当時のsendmailの 配送性能が極端に良くなかったことから、qmailの「並列配送」が余計際だつこ とになった。これにより「配送効率の高さ」がqmailの第一の特徴として捉えら れるようになった。 しかしDJBツールの真髄は、動作時の効率よりもむしろその設計ポリシーにある と言って良い。DJBが、各ツールの仕様をどのような根拠で決定しているかを知 ることは、今後それらツールを理解し、付き合っていく上で重要なことだろう。 Part1ではDJBツール全体に流れるプログラミング哲学について考えてみよう。 ■ ■ プログラムの安全性 ■ qmailがそうであるように、DJBツールはどれも安全と言われている。では実際の ところどの程度「安全」なのだろうか。これに関して、筆者自身が数年DJBツー ルを使って来て肌で感じたことを交えながら、DJB作のプログラムの持つ信頼性 の高さについて考えるところを述べてみたい。 ●Unixらしさ Unixのもつ「シェル環境」のすばらしさを表現するための例として、次のような コマンドラインが例示されることがある。 % cat foo.txt | tr A-Z a-z | tr -s ' ' '\012' \ | sort | uniq -c | sort -nr これは、foo.txt が英文テキストだとして、その中に含まれる各英単語の登場す る回数を数えて、回数の多い順に並べ換えて回数と単語自身を表示するものであ る【註 い】。この例は、それぞれが独立していてひとつの種類の処理をするプ ログラム同士でも、それらを組み合わせることにより全体として問題解決に効果 的な「ツール」に変身させられることを示している。 ---[註 い]------------------------------------------------------------ 実用に値するものにするにはアルファベット以外の処理などが必要で もっと複雑なコマンドラインになるが、それはこの例の目的ではない。 ---------------------------------------------------------------------- Unixのツールは、ひとつの機能に特化したもので、その入出力を標準入出力とし たものが多い。こうすることで上記のような「パイプライン」の一部として働か すことが可能となる。複数の機能をひとつのアプリケーションソフトウェアに詰 めこむのではなく、機能を分割することによるメリットは数多い。 A 機能を絞ることはソフトウェアの複雑性軽減に繋がり信頼度の高いも のを作りやすい B データの入出力を標準入出力にすることで、データ構造の単純化、プ ログラムの可換性が得られる C 「パイプライン」処理であればユーザ自身がフィルタを書くことで 処理の拡張が簡単に行なえる などが考えられるが、DJBの代表作、qmailでは(A)のメリットを存分に活かし、 qmailシステム全体の信頼度向上を獲得している。 ●バグは作るもの 人間である以上かならずミスを犯してしまう。同様に、プログラムにバグは付き 物だ。筆者自身も自作のプログラムを公開して、多数の人に使ってもらうという 経験を重ねて十年以上になる。色々な機能を足そうとコードを書き、その副作用 として色々なバグを生み出し、それを修正してきた。そのような経験をくり返す うちに、直感的にではあるが新しく書き加えたコードのうち、不具合が出るかも しれない場所、そうでない場所がだんだん予想がつくようになってきた。たいて いの場合、新しく機能を追加した部分、効率化などのためにアルゴリズムを変え た部分、仕様を変更した部分、システム環境に依存した情報を取り扱う部分など である。さらに、ユーザが新機能を利用するために新たな個人設定を書き足す必 要がある場合、それが分かりづらいものだとたいてい誤動作の引き金となる妙な 値を設定するものである。 多くのフリーソフトウェアは、新しい機能をまずは「実験的」に実装し、利用者 にベータバージョンとして配布して全員で検証している。この流れがあるからこ そ現在までの進歩がある。これは非常に価値のあることで非難すべき点など全く ないのだが、ことDJBのネットワークツールに関してはさらにそれよりも厳しい 姿勢が貫かれている。なぜならネットワークサービスデーモンとなるプログラム は、常に外界からのアタックに晒されるものだからだ。ユーザがコマンドライン から使うようなアプリケーションプログラムでちょっと不具合が出るのとは訳が 違う。ネットワークサービスデーモンは少しでも隙があれば、システム全体の危 機につながってしまう。それゆえ、プログラムに求められる安定度は必然的に高 いものとなり、妥協を排除したプログラミングが必要となって来る。では、その ためにはどんな点に注意すれば良いか代表的なものを考察してみよう。 ・プログラミングの落し穴 プログラミングは楽しい。一利用者として、新しいソフトウェアを使い始める のが楽しいとしたら、プログラマにとって自分の作ったものが狙った通りに動 く樣を見るのは嬉しいし、さらにそれを自分が利用者として使うのも楽しい。 つまり、作者は利用者の最低でも2倍は楽しいのである。それゆえ、世の中に は数多くのフリーソフトウェア作者が存在し続ける。 プログラマにとって、新しく考えた機能を作り込んで、それが実現できるのは 楽しい。楽しいからこそ、新機能はどんどん追加したくなる誘惑がやってくる。 その反面、異常データが入力された場合の処理だとか、例外処理だとか、古く なったコメント文の修正だとかはちっとも楽しくない。できればやりたくない が、そうも言っていられないので努力して作業に当たる。 もし、安定こそが全て、というプログラムを作るとしたらどうなるだろう。新 しいアイデアのものはいっさい使わず、基本機能だけを簡潔に実装し、その代 わり異常値検査、例外処理のような地味なものだけを入れる。おそらく、つら い修業になるだろう。しかし、このようなプログラムがDJBツールなのだ。ユー ザからの要望、拡張したい誘惑を断ち切って「KISSの法則(※ろ)」を遵守して いる。これを守るのは簡単なようで、実は一番難しい。 ---[註 ろ]------------------------------------------------------------ Keep it simple, stupid. ---------------------------------------------------------------------- ・仕様の囲い込み 多くの優れたソフトウェア(の作者)は「拡張性」というものを大事にする。ユー ザが設定ファイルに書く内容によって処理の幅を拡げたり、将来新たな機能を 追加する場合に便利な「ノリシロ」を残したりする。「より便利」なものを 「より効率的」に作るためには重要な要素だ。しかし、DJBツールでは「ここ までできれば十分」という一線を引いてそれ以上の拡張性は切り落としている。 このように書くと、qmailを「非常に便利だ」と感じているユーザは意外に思 うかもしれないが、実際のところ qmail では管理者用の設定ファイルも、ユー ザ用の dot-qmail ファイルも、ifなどの制御構造、マクロ展開はおろか、正 規表現すらも使えない。言い換えるならば、設定ファイルに動的記述はまった く認めていない。これはdjbdnsでも同様である。動的記述はユーザ自身の拡張 のためには欠かせない要素だが、その反面プログラムが格段に複雑になる。現 在では一般的な正規表現も、その解析器だけでかなり大きくなるし、ユーザが 間違った正規表現を書いた場合の対処も大きくなる。 DJBツールの設定ファイルでは、そのほとんどが「1行1エントリ」、「区切り はコロン」、「クォート不可」というきわめて単純な書式しか許されていない。 にもかかわらず使い勝手がいいのは、DJBの「必要十分な仕様」を見切る判断 力が高いせいだろう。たとえば、qmail の virtualdomain などは、もはや無 しでは考えられないくらいに便利である。しかし良く考えると virtualdomains ファイルに書くのは、単純な文字列置き換えルールでしかな く、プログラマも利用者も間違いようのない、確実性この上ない機構である。 大きな利益を着実なコードで実現する仕様策定は見事といえよう。 ・責任の取れるコード 全てのDJBツールでは、strcmp, strcpy といった標準C関数ですら利用せず、 それに代わるものを自前で用意している。さすがにstrcmpにバグのあるシステ ムはないだろう、と思うところだが、「localeを考慮して異なる挙動をするシ ステムが将来出てくるか」、などを考え始めるとだんだん「絶対大丈夫」とは 言えなくなってくる。それよりも、既に書いたバグのない「枯れた」コードを 自前で用意することで環境依存のない「保証できる」プログラムとなる。 ・間違う可能性の排除 上記二項目に関連するが、DJBツールでは最初から人間が間違う可能性を徹底 的に排除している。たとえば、「パース(Parse; 構文解析)しない」姿勢を貫 いている。パースというと、プログラミング言語のような高水準なものを思い 浮かべるだろうが、実際はシェルのコマンドラインのような身近なところでも 処理されている。まず第一に、パーサ(構文解析器)を作ること自体が難しい。 gccなどのコンパイラが正常に処理できるのは「入力ソースに文法的な誤りが ない」場合に限った話であり、構文エラーがあった場合には本当に適切なエラー 発生箇所を示すことすら不可能に近い。プログラミング経験のある読者なら分 かるだろうが、セミコロンやダブルクォーテーションを忘れただけなのに、表 示されるエラーメッセージからはそれを知ることが困難だ、ということは良く あるケースである。シェルやコンパイラの場合、入力に文法的誤りがあった場 合エラー終了して済ませられるが、ネットワークサービスデーモンはそうは行 かない。むしろ、クラッカーたちは意図的に構文解析器を暴走させるような文 字列を送りつけて来るだろう。 第二に、どんな単純な文法でも、ユーザがそれに忠実に従って書くのは難しい という点がある。閉じ括弧忘れ、セミコロン忘れ、クォート忘れなど単純なも のもあるし、正規表現のように利用者が自分で把握できなくなるほど複雑なも のが書けたりするものもある。 一般的なツールの多くが、その設定ファイルに「簡易プログラミング言語」の ような文法規則を持たせているのとは対象的に、qmailを始めとするDJBツール では、設定ファイルをできるだけ「パースしない」方針を取っている。ユーザ の立場からすれば、設定作業をするにあたり新たに文法規則を覚える必要がな いことになる。「パースしない」ことがもたらす結果として、プログラムの誤 りの可能性も、ユーザの設定誤りの可能性も低く保つことができる。 ●セキュリティギャランティ DJBは、qmail, djbdns にセキュリティギャランティ【註 と】を掛けている。こ のような「挑戦」は一般のプログラマなどには全く手の届かない世界の話で、異 常なまでに高いプログラミング技術を持った人にしかできないことと考えていた。 しかし、最近それは少し違っていると感じ始めた。確かに「プログラミング技術」 は大切で、ある一定の線を越えなければ書くコードすべてにバグの入る可能性が 残る。しかし、ある程度熟練すると過去に自分が入れてしまったバグの記憶が経 験として蓄積され、よほど凝った部分でない限り、ミスはしなくなる。さらにそ の上のレベルで、本当にバグのないプログラムを作るために必要なのは、プログ ラミング技術よりもむしろ「バグの入り込みそうな仕様を避ける」ための設計技 術、むやみに機能を足さないという覚悟、あとで機能を足さなくて済むようにす るための事前の「見切り」だろう。これらを冷徹に見極め、「決められた範囲内」 でのみ動くようなプログラムを作ることができれば、それはDJBツールに匹敵す る安定度となるのではないだろうか。 ---[註 と]------------------------------------------------------------ djbdns, qmail それ自身にセキュリティホールを発見した場合には賞金として $500 が与えられると言うもの。条件に関する詳細は http://cr.yp.to/djbdns/guarantee.html http://cr.yp.to/qmail/guarantee.html を確認のこと。 ---------------------------------------------------------------------- もし、安全性においてDJBツールに匹敵すると言われているツールがあったら、 ソースアーカイブ中にある ChangeLog や HISTORY ファイルを眺めてみて欲しい。 たいていの場合、"fix"(修正) という単語がたくさん出現しているはずだ。そし てその多くは、パーサの解析ミスなどの不具合、拡張性を持たせた部分の不具合、 少し前に足した機能の不具合などに集中しているだろう【註 ち】。そのような ソフトウェアの作者(陣)は根本的にDJBとは設計に臨む覚悟が違うことが分かる だろう。 ---[註 ち]------------------------------------------------------------ ちなみに、筆者自身の公開しているプログラムは "fix" だらけである。 申し訳ない(__)。 ---------------------------------------------------------------------- ここで、念のためもう一度強調しておく。「機能追加」→「バグの修正」の繰り 返し、という開発モデルが悪いということでは全くない。実際のところ、現在便 利に利用しているソフトウェアのほぼ全てはそのサイクルを経て進化している。 とても素晴らしいことだ。しかし、ネットワークデーモンのように ・外部からのアタックに常に晒され ・決められたプロトコル内でのみ動作すれば良い プログラムであれば、絶大な安定性を手に入れるために機能拡張を放棄するとい う決断も重要な選択となる。このことを考慮すると、セキュリティギャランティ を掛けているのは、それだけの裏付けがあってのことだと納得できる。 ■ ■ 本特集のねらい ■ 本誌では、これまで何度かDJBツールについてとりあげて来た。本特集は、それ らの集大成となることを目標に置いた。この一冊が手元にあれば、DJBツールの 導入と日常的な運用の助けとなることを目指したい。DJBツールは、qmailに詳し いオンラインマニュアルがついて来るほかは、ほとんどドキュメントがない。一 次情報先として http://cr.yp.to/ のDJBのWebページを参照することが推奨され ている。これは、より新しいバージョンが発表された場合、手元に残る古いドキュ メントが混乱を来すのを避けるためだろう。しかし、その心配とは裏腹に、DJB ツールはその優れた設計のおかげで、一度リリースされたものが2〜3年では陳腐 化しないという特徴を持っている。実際、筆者が管理するメイルサーバでは、 qmail-1.03 に2〜3のパッチを当てた1998年のコンパイルディレクトリを変える ことなく使い続けている。さらには、過去に本誌に書いたdaemontoolsの説明を 引っ張り出しては良く利用している。それなら、2002年7月号時点の記事も、お そらく2〜3年以上の価値はあるのだと願って今回の特集とした。 なお、今回解説する内容についていくつか注意する点を述べておく。 代表的なDJBツール複数をとりあげるので、スペースの都合上DJBツール以外との 連系の設定などは、それが一般的なものでも解説を省略せざるを得なかった。た とえば、MTA管理で "POP before SMTP" のような動的リレー制限を実現するため の設定などは現状では必須のものだが、今回は見送った。 また、筆者自身DJBツール自体の設計と仕様には共感するものの、ファイルシス テムレイアウト論など、運用に関する点はあまり共感できない部分がある。その ため、最近のDJBツールで求めている "/package hierarchy" (Part2のコラム参 照)とは違うインストールポリシーでの導入例を紹介している。実際のところ、 これから新たにDJBツールを採用するかどうか試したい、という場合にはいきな り重要なディレクトリに入れるのではなく、実験的なディレクトリ(たとえば /work/tmp など)にインストールしてしばらく試したいだろう。そのような事情 をふまえて、インストールパスをデフォルトとは違う場所に変更する方法にもで きるだけ触れるようにした。たとえテンポラリディレクトリへのインストールで も良いので、これまで手を出さなかった人もできるだけ実際に確かめていただき たい。
yuuji@ Fingerprint16 = FF F9 FF CC E0 FE 5C F7 19 97 28 24 EC 5D 39 BA