qmail logo

qmail のある暮らし

Dave Sill
30 November 2007
やまぐちたかのり(訳)
[訳注] Life with qmail の全訳。訳者はどちらかというと qmail が嫌いであり積極的に使うことはないので(まったく使ってないわけではないんだけど)、誤訳や的外れの訳注コメントがあるかもしれないが、そういうのを見つけたら連絡してほしい


目次

1. はじめに
1.1. 対象とする読者
1.2. qmail とは?
1.3. なぜ qmail を使うのか
1.4. 歴史
1.5. 特徴
1.6. 関連パッケージ
1.7. 構造
1.8. ライセンス
1.9. 他の MTA との比較
1.10. 文書
1.11. サポート
2. 導入
2.1. インストールの際に考慮すること
2.2. 準備
2.3. システム要件
2.4. ソースの取得
2.5. ソースを組み立てる
2.6. ucspi-tcp のインストール
2.7. daemontools のインストール
2.8. qmail の起動
2.9. インストール後の確認
3. 設定
3.1. 設定ファイル
3.2. 中継
3.3. 複数ホスト名
3.4. 仮想ドメイン
3.5. エイリアス
3.6. qmail-users
3.7. spam 制御
3.8. ウィルススキャン
4. 使い方
4.1. .qmail ファイル
4.2. メッセージの送信
4.3. 環境変数
5. 進んだ話題
5.1. procmail
5.2. POP と IMAP サーバ
5.3. POP と IMAP クライアント
5.4. 相乗り配送と個別配送
5.5. VERP
5.6. トラブルシューティング
5.7. 大規模サーバ
5.8. Sendmail から qmail への移行
5.9. メーリングリストマネージャ
5.10. パッチ
5.11. QMTP
5.12. SMTP セッション中での無効な受信者の拒否
5.13. TLS と STARTTLS
A. 謝辞
B. 関連パッケージ
B.1. dot-forward
B.2. fastforward
B.3. ucspi-tcp
B.4. daemontools
B.5. qmailanalog
B.6. rblsmtpd
B.7. serialmail
B.8. mess822
B.9. ezmlm
B.10. safecat
B.11. djbdns
B.12. maildrop
B.13. syncdir
C. インターネットのメールのしくみ
C.1. A 地点から B 地点にメッセージはどのように届くか
C.2. さらなる情報
D. 構造
D.1. 機能分割システム構造
D.2. ファイル構造
D.3. キュー構造
D.4. 図版
E. たまにある質問とその答
E.1. 遅延メッセージはどれぐらいの頻度で再送されるのか?
E.2. 多数の MX を持つ大きなサイトに送れないのはなぜか?
E.3. QUEUE_EXTRA とは何か?
F. エラーメッセージ
G. Gotchas
G.1. qmail がスーパーユーザにメールを配送しない
G.2. qmail がホームディレクトリのないユーザにメールを配送しない
G.3. qmail が名前に大文字を含むユーザにメールを配送しない
G.4. qmail が拡張アドレスのピリオド(.)をコロン(:)に置換する
G.5. qmail が拡張アドレスの大文字を小文字に変換する
G.6. qmail/etc/hosts を使わない
G.7. qmail が SMTP の活動をログに記録しない
G.8. qmail が遅延通知をしない
G.9. /var/qmail/queue/lock/trigger がない/権限がおかしい/通常ファイルのとき qmail が遅い
G.10. DNS や IDENT の問い合わせで SMTP が遅くなる
G.11. 復帰改行 (CRLF) がおかしい
G.12. ログが詰まると qmail-sendtcpserver が止まる
G.13. qmail-smtpd がアドレスのローカル部の有効性を検証しない
G.14. ファイアウォールが SMTP/POP3/IMAP サーバへのリモートアクセスをブロックする
G.15. USERLOGNAME がセットされていないと qmail-injectFrom フィールドを anonymous にする
G.16. qmail-send を kill してもただち に終了しないことがある
G.17. /dev/null に配送してもメッセージを捨てられない
G.18. qmail-send の動作中にキューを修正するのは危険
H. Life with qmail に関するよくある質問と答
H.1. Life with qmail のバージョンは?
H.2. Life with qmail は誰のもの?
H.3. Life with qmail のライセンスは?
H.4. LWQ の新版リリースはどうやって知ればいいの?
H.5. LWQ に貢献した人やファンはどこで話してるの?
H.6. Life with qmailXXX 語への翻訳ってある?
H.7. HTML 以外に Life with qmail の PostScript や PDF やべたテキストやその他の形式はあるの?
H.8. Life with qmail を使ったらシステムがぶっこわれた/ディスクがトンだ/我が愛しき暮らしがメチャクチャになった/犬が死んだ/とかなんとか
H.9. どうしたら LWQ に貢献できる?
H.10. LWQ のこの版の変更点は?

1. はじめに

1.1. 対象とする読者

qmail のある暮らし は予備の PC に Linux をインストールしたばかりの初心者(newbie)から熟達したシステム管理者ないしはメール管理者まで、qmail を動かすことに興味を持つ人すべてに向けて書かれている。もし足りない部分やはっきりしない部分があれば知らせてほしい。コメントは lwq@sill.org まで。

qmailに関する豊富な情報はさまざまなところから得られる。newbie を対象としたものもあれば、もっと経験を積んだ読者を想定したものもある。qmail のある暮らし はすきまを埋める「接着剤」となってこの情報を1ヶ所に集積しようとするものであり、読者は

といった基本的なスキルを持っていると想定する。

[訳注] 初心者も対象であり、qmail に関する事前知識は特に必要はないが、qmail 以前の電子メール配送の基本的な仕組みに関する知識ぐらいは必要である(付録 C)。
[訳注] 翻訳に関する指摘は原著者ではなく訳者へ。

1.2. qmail とは何か

qmail は UNIX-like な OS 上の Internet Mail Transfer Agent (MTA) である。 UNIX OS で用意されている Sendmail システムに対する手軽な置き換えである。qmail は他のシステムの MTA とメッセージをやりとりするために Simple Mail Transfer Protocol (SMTP) を用いる。

Note: 名前は "qmail" であって "Qmail" ではない。

1.3. なぜ qmail を使うのか

あなたが使っている OS には MTA、おそらくは PostfixSendmail が入っているだろうから、このドキュメントを読んでいるのはなにか別のものを探してのことではないかと思う。ベンダが用意した MTA に対する qmail の利点には以下のようなものがある。

1.3.1. セキュリティ

qmail は高いセキュリティを持つよう設計されている。Sendmail は重大なセキュリティ問題の長い歴史を持っている。Sendmail が書かれたとき、ネットははるかに友好的な場所だった。誰もが他の誰かを知っていて、高いセキュリティに関する設計やコードはほとんど必要なかった。現在のインターネットはネットワークサーバにとってもっとずっと敵対的な環境である。Sendmail の作者 Eric Allman と現在保守している Claus Assman はプログラムをひきしめるいい仕事をしたが、再設計が足りておらず、のセキュリティを達成できていない。

1.3.2. 性能

qmail はメール配送を並列化し、デフォルトでは同時20配送までおこなう。

[訳注] 並列配送は qmail だけの特長というわけではなく、Postfix などでもサポートされているし、Sendmail でも SMTPfeed のような外部配送エージェントを利用することで可能になる。

1.3.3. 信頼性

qmail はいったんメッセージを受け付けると、それを失わないことを保証する。qmail はまた NFS 上でさえ確実に使える新しいメールボックス形式をサポートする。

[訳注] Qmail bugs and wishlist というページでは、クラッシュの際にバウンスメールが壊れたり不達になったり、MUA によっては Maildir のファイル名が衝突する可能性が指摘されている。また、Maildir は qmail の専売特許ではなく、Postfix や、設定しだいでは Sendmail でも使うことができる。

1.3.4. 単純

qmail は他の同等の機能を持つ MTA よりも小さい。

Note: 公式 qmail Web ページ(http://cr.yp.to/qmail.html) は qmail の利点をもっと詳細に述べている。

1.4. 歴史

qmail は現在イリノイ州立大学シカゴ校の数学教授である Dan Bernstein (DJB) (http://en.wikipedia.org/wiki/Daniel_J._Bernstein) によって書かれた。Bernstein 博士はまた暗号学の分野における業績や暗号化ソースコードの出版に関するアメリカ政府に対する訴訟でも知られている。訴訟に関しては http://en.wikipedia.org/wiki/Bernstein_v._United_Stateshttp://cr.yp.to/export.html を参照のこと。

最初に公にされたリリースはベータ版の 0.70 で、1996年1月24日のことだった。最初のガンマ版は 0.90 で1996年8月1日である。

最初の一般的なリリースであるバージョン 1.0 は1997年2月20日にアナウンスされた。現在のバージョンは 1.03 で1998年6月15日にリリースされたものである。

次のリリースは 2.0 の評価版であると予想されている。バージョン 2 であらわれるであろうことは http://cr.yp.to/qmail/future.html で触れられている。

1.5. 特徴

qmail の Web ページ(http://cr.yp.to/qmail.html) には qmail の機能の広範囲なリストがある。この節はそのリストに多くを拠っている。

1.5.1. セットアップ

1.5.2. セキュリティ

1.5.3. メッセージの生成

1.5.4. SMTP サービス

1.5.5. キュー管理

1.5.6. バウンス

[訳注] QSBMF: The qmail-send Bounce Message Format、HCMSSC: The Hash Convention For Mail System Status Codes
[訳注] QSBMF の問題点ダブルバウンスの問題点

1.5.7. ドメインによるルーティング

1.5.8. SMTP 配送

[訳注] 8bit クリーンではあるが、8bit なメールも EMSTP 8BITMIME 拡張を使わず素の SMTP で送ってしまう。明白な RFC 違反であり、受け手が 8bit クリーンでない場合には問題が生じる可能性がある。

1.5.9. 転送とメーリングリスト

1.5.10. ローカル配送

1.5.11. POP3 サービス

qmail は、それぞれのツールは単一でよく定義された機能を実行するべきであり、複雑な機能は単純なツールの「パイプライン」結合でおこなうべきであるという古典的な UNIX 哲学に従う。もうひとつの手段はより単純なツールのたくさんの機能を再発明するずっと複雑なツールを作ることである。

qmail 自身ですべてのことをやらないのは驚くことではないし、そうしてほしいなどと誰も願ってないだろう。そこで、qmail 用に作られたよりポピュラーなアドオンがある。もちろん、多くの標準的な UNIX ユーティリティも qmail と組み合わせることができる。

1.7. 構造

付録 Dqmail の機能と物理的構造について解説する。ひとことでいえば、qmail は異なる仕事をする一連のプログラム(モジュール)で構成される。

1.8. ライセンス

As of 2007-11-30, qmail 1.03 is in the public domain. See http://cr.yp.to/qmail/dist.html. This means that there are no legal limits to what you can do with it: you can copy it, give it away, sell it, modify it, rename it, or use pieces of it in copy-protected works, without any restrictions.

Other packages by Dan Bernstein, such as daemontools and ucspi-tcp, are copyrighted by the author, and are not distributed with a statement of user's rights. In http://cr.yp.to/softwarelaw.html, he outlines what he thinks your rights are under U.S. copyright law. See also http://en.wikipedia.org/wiki/License-free_software.

2007/11/30 に qmail 1.03 はパブリックドメインになった。http://cr.yp.to/qmail/dist.html を参照。これは、qmail に対して何をおこなっても法的な制限を受けないことを意味する: 複製することも、無料で配ることも、売ることも、修正することも、改名することも、コピープロテクトされた製品内で一部を流用することも、一切の制約なしに可能である。

daemontoolsucspi-tcp といった Dan Bernstein による他のパッケージは作者に著作権が帰属し、利用者の権利の声明とともに配布されるものではない。http://cr.yp.to/softwarelaw.html において、彼は利用者の権利が米国著作権法のもとにあるという考えを概説している。http://en.wikipedia.org/wiki/License-free_software も参照のこと。

[訳注] 原文公開時にパブリックドメイン化が明文化されていたのは qmail だけであり、それ以外のものは(すべてパブリックドメイン化するという意向は伝えられていたものの)従来のライセンスのままだったため、上のような記述になっている。その後、2007/12/28 に daemontoolsucspi-tcp もパブリックドメインにすることが宣言された。その他、djb の代表的なソフトウェアの多くがすでにパブリックドメインになっているが、すべてがそうなっているわけではないので利用の際は注意のこと。

1.9. 他の MTA との比較

この話題に関して本が1冊書けそうだが、読むのは退屈だろう。ここでは他の一般的な UNIX MTA のいくつかと qmail との比較をざっと挙げてみる。

MTA 完成度 セキュリティ 特徴 性能 Sendmail 風 機能分割
qmail アドオン
Sendmail - ×
Postfix
exim ×
Courier オプション

Sendmail 風 とは Sendmail から別の MTA に移行する際、.forward ファイルの利用や /etc/aliases/var/spool/mail への配送といったものがユーザに違いを意識させず、その MTA が Sendmail のような動作をするという意味。

Jonathan de Boyne Pollard は http://homepages.tesco.net/~J.deBoynePollard/Reviews/UnixMTSes/ で多くの UNIX MTA をレビューしている。別の詳細な比較が http://www.geocities.com/mailsoftware42/ で見ることができる。

[訳注] これは qmail について書かれたドキュメントなので qmail びいきな内容になるのはしかたないとは思うのだが、だからといって qmail が Features: high となってるのは誇大広告に過ぎるような。ESMTP の各種拡張機能とかぜんぜん足りてないと思うんだけど……。事実、挙げられている URL のうちの後者の方では Features: low とされている。前者の URL もだいぶ評価に偏りがあるように感じるなぁ。なお、これ以外には MTA を性能面から比較したものとして WIDE プロジェクトによる MTA 性能比較Postfix Stuff 内の Benchmarks などがある。ただし、どちらもかなり古い記事であり、現在のバージョンで測定すればかなり違う結果になるだろうことに注意(qmail だけは現行と同じバージョンだけど)。

1.10. 文書

1.10.1. man ページ

qmail は完全な man ページとともに配布されている。インストール後、それらは /var/qmail/man に置かれる。おそらく MANPATH 環境変数にそのディレクトリを追加する必要があるだろう。

シェル コマンド
Bourne (/bin/sh) MANPATH=$MANPATH:/var/qmail/man; export MANPATH
bash, Korn export MANPATH=$MANPATH:/var/qmail/man
C Shell setenv MANPATH $MANPATH:/var/qmail/man

この時点で "man manページの名前" というコマンドで適切な man ページが表示される。

この man ページはオンラインで HTML 形式でも入手可能である。

Note: qmail の man ページにはたくさんの情報があるが、とても密度が高く技術的に書かれているので、読むには注意を要する。一式を印刷して何がどこにあるのか知るためにひととおり目を通しておきたくなるだろう。複数のページで繰り返し書かれている情報はほとんどないので、どこに書かれているのかわからなければ見つけるのは難しい。

1.10.2. Docs

qmail の配布物は /var/qmail/doc 以下にインストールされる一連の文書を含む。

これらの文書もオンラインで入手できる。

1.10.3. FAQ

ふたつの公式 FAQ (よくある質問とその答)がある。

Web 版の方が完全である。

1.10.4. 書籍

1.10.4.1. The qmail Handbook

Dave Sill, the author of Life with qmail, has written a qmail book for Apress (http://www.apress.com/). This book, The qmail Handbook, covers everything in this guide, but goes into much more detail and also covers a lot of new ground.

For more information, see http://www.apress.com/catalog/book/1893115402/. To order this book from my bookstore, in association with Amazon.com, see http://www.amazon.com/exec/obidos/ASIN/1893115402/davesill.

1.10.4.2. Qmail Quickstarter: Install, Set Up and Run your own Email Server

Kyle Wheeler has written a qmail book for Packt (http://www.packtpub.com/). As the title suggests, this book is designed to help people new to qmail to set up a mail server.

To order this book from my bookstore, in association with Amazon.com, see http://www.amazon.com/exec/obidos/ASIN/1847191150/davesill.

1.10.4.3. qmail

John Levine has written a qmail book for O'Reilly & Associates (http://www.oreilly.com/). See http://qmail.gurus.com/ for more info including the Table of Contents and a sample chapter.

To order this book from my bookstore, in association with Amazon.com, see http://www.amazon.com/exec/obidos/ASIN/1565926285/davesill.

1.10.4.4. Running qmail

Richard Blum has written Running qmail, which is published by Sams. This book has received mixed reviews on the qmail mailing list.

For more information or to order this book, see http://www.amazon.com/exec/obidos/ASIN/0672319454/davesill.

[訳注] 邦訳 qmail メールサーバの構築

1.10.4.5. qmail: Yuksek Performansli E-Posta Sunucu

Ismail Yenigul, et al, have written a Turkish-language qmail book. See http://www.acikakademi.com/catalog/qmail/.

1.10.5. メーリングリストの過去ログ

Dan Bernsterin が保守している qmail のメーリングリストは価値ある情報源である。ML の Web アーカイブは

にある。qmail に関するほとんどの質問はまずアーカイブを検索すると答が見つかるだろう。

1.10.6. その他の Web サイト

1.11. サポート

1.11.1. メーリングリスト

以下のメーリングリストは list.cr.yp.to にある。spammer によるメールアドレスの収集を避けるため、完全で有効なアドレスや "mailto:" URL では表記しない。

これらのメーリングリストはアドレスごとに異なる処理をする ezmlm で運用されている。

登録/脱退するアドレス(仮に joe@example.com とする)を指定するには、メッセージを

に送る。

[訳注] このほか、qmail.jp などに日本語のメーリングリストもあるようだけど、訳者はそのどれにも入ってないのでよく知らん。入るつもりもない。

1.11.1.1. qmail

qmail のメインのメーリングリスト。qmail に関するほとんどのこと(専用の ML があるものは除く)についての議論と質問/回答用。投稿する前に、Charles Cazabon の "12 Steps to qmail List Bliss" (http://pyropus.ca/personal/writings/12-steps-to-qmail-list-bliss.html) を読むべし。また、質問の前に FAQ を調べ、過去ログを検索すること。質問するときには他人が回答できるよう十分な情報を含めること。

Note: qmail メーリングリストでは投稿されたメッセージが spam でないことを確認するのに qsecretary というユーティリティを使っている。投稿されたメッセージごとに qsecretary からメールで承認依頼が届く。承認するためにはそのメッセージを読んで指示に従うこと(通常はただ返信するだけでよい)。Charles Cazabon の pymsgauth (http://pyropus.ca/software/pymsgauth/) のような自動返信ツールを使ってこのプロセスを自動化している常連投稿者も多い。pymsgauthqmail メーリングリストに送られたメッセージがほんとうにあなたが送ったものなのか確認するので、名前を騙って送られたメッセージには自動承認することはない。

1.11.1.2. qmailannounce

qmail の告知メーリングリスト。新版のリリースはここでアナウンスされる。投稿アドレスはない。講読のみである。

1.11.1.3. serialmail

serialmail パッケージについての議論。

1.11.1.4. ezmlm

ezmlm ML マネージャについての議論。

1.11.2. コンサルタント

http://www.qmail.org/top.html#paidsup に商用サポート事業者のリストがある。

1.11.3. FAQTS Knowledgebase

qmail 関連の質問と回答のデータベースが http://qmail.faqts.com/ にある。もし FAQ にない質問があれば、このナレッジベースで調べてみるとよい。「どうやればいいのか」という質問に特に強い。


2. 導入

この章では qmail のインストールについて解説する。経験を積んだシステム管理者ならばソース配布物にある INSTALL にある手順に従って qmail をインストールできるだろう。INSTALL に書いてあるのは、公式のインストール手順である。これは qmail のある暮らし の手順より複雑であり、読者は経験を積んだシステム管理者、メール管理者であると想定している。また、これは時代遅れであり、Bernstein が現在推奨しているやりかたを反映していない。

Note: もし次の手順を使ってインストールすることを選択するのならば、最初から最後までの過程に慣れておくためにこの章全体を読むべきである。

2.1. インストールの際に考慮すること

2.1.1. バイナリかソースコードか

2007/11/30 までの qmail のライセンスは事前構築済みパッケージの配布に関して制限があり、通常ソースコードからインストールされていた。daemontoolsucspi-tcp がパブリックドメインになれば、将来このやりかたは変わるだろう。けれども qmail では当面はソースコードが好まれる配布方法である。

[訳注] 2007/12/28 に daemontoolsucspi-tcp もパブリックドメインになった。

もしソースコードとバイナリの区別がよくわからなければ、宅配ピザの注文を想像してみよう。「バイナリ」のピザはすぐ食べられる状態で到着する。「ソース」のピザは小麦粉、イースト、チーズ、ソース、トッピング、調理手順の入った材料セットとして届けられる。ソースコードからのインストールはちょっと作業は増えるが、注意して手順に従えば、同じかもっと美味いものができあがる。自分で焼いたピザの方がアツアツで、自分好みのトッピングにできて、ピザについて、そして中がどうなっているかもっと多くのことを知ることができるだろう。

インターネットに接続するネットワークサービスを安全に動かすのは簡単ではない。適切に設定しなければホストが攻撃を受ける危険性があるし、他のサイトを攻撃する踏台に使われる -- 管理者が法的責任にさらされる可能性がある。ネットワークサービスがどのように動くかについて知るほど、適切に設定し安全なものにしようとするだろう。

2.1.2. tar 玉と OS 固有のパッケージ

いくつかの OS ではソースコードからのインストールを自動化する機構を備えている。ピザのたとえに戻ると、ボタンを押すだけでピザが焼き上がるような材料と手順をパッケージしているようなものだ。

そりゃすごくないかい?

実際には、それはそんなによい考えではないだろう。これらのパッケージを組み上げることはかなり難しく、思いどおりにはいかないかもしれない。それらはソフトウェアであり、他のソフトウェアのようにバグ入りのこともある。しかし、バグがなかったとしても、それらパッケージから得られる利点は欠点にもなる。自分で焼いたピザの利点 -- 自分好みのトッピングにしたり、ピザがどのように作られて中がどうなっているのかといった知識 -- がほとんど得られない。

もし qmail がピザなら、自動でビルドするというのはそれでもいいやりかただろう。しかしそうではない。スムーズに動くよう維持するためにインストールする人/メンテナンスする人が深く理解する必要があるというのはかなり困難なシステムである。自動インストールの qmail はユーザがインストールするよりも簡単だが、ユーザがインストールした方が設定や問題の対処が容易だ。qmail をインストールするのは一度だけだが、再設定する機会はきっと何度かあるだろうし、なぜメールが思ったとおりに流れていかないのか解決をはかることもあるだろう。

この理由により、わたしは qmail を RedHat の RPM や他の自動インストールセットではなく、ソースコードの tar 玉を使ってゼロからインストールすることを提案する。

[訳注] 以下の説明では「なぜそうするのか」「そうすることによって何が起きるか」を記さずに天下り的に「こうしなさい」と述べているところが多いので、この文書を読んでもこの著者が言うメリットを十分に得られるわけではないと思う。ゼロではないけど。

2.2. 準備

システムに qmail をインストールする前に、特にこれが初めての qmail インストールならば、いくつか考えておく必要がある。

2.3. システム要件

qmail はほとんどの UNIX および UNIX 風システムでインストールして動くだろうが、いくつか必要事項がある。

Note: qmailbin ディレクトリは setuid() された実行ファイルが使えるファイルシステムになければならない。いくつかの OS では /var ディレクトリが自動で nosuidnoexec オプションが有効になってマウントされる。このようなシステムではこのオプションを無効にするか、/var/qmail/bin ディレクトリをこれらのオプションが無効になっている別のファイルシステムに置くべきである。ディレクトリ作成 の節ではシンボリックリンクを使って後者を実現する方法を説明する。/varnosuid でマウントされていた場合、qmail-send のログに以下のようなエラーメッセージが見つかるだろう。
delivery : deferral: Sorry,_message_has_wrong_owner._(#4.3.5)
Note: qmail は Apple の OS X では以下にある手順や INSTALL ファイルにある手順では適切にインストールできないだろう。Eben Pratt が http://netdevice.com/qmail/#osx で OS X にインストールする方法を書いている。

2.4. ソースの取得

OK、それじゃ qmail をインストールする条件を満たしたシステムを手に入れたわけだ。最初にするのは qmail およびその他アドオンのソースコードの取得だ。もちろん、qmail は必要だ。たぶん ucspi-tcpdaemontools も入手しておくべきだろう。

これらのファイルを Web ブラウザや wget のような Web クライアント、FTP クライアントを使って拾ってこよう。

Note: もしいずれかのリンクがおかしければ、おそらくパッケージがアップデートされたのだろう。その場合、http://cr.yp.to/software.html に行って現行バージョンをダウンロードするリンクをたどってほしい。アップグレード版は以降の説明と一致しない可能性があるので、"Upgrading from previous versions..." 節にあるリリースノートを忘れず読んでおくこと。
Note: ここで解説する導入手順では qmail 1.03 の公式な tar 玉にいくつかのバグ、欠陥、非互換性を解消するパッチを適用した netqmail という配布物を使う。詳しくは http://www.qmail.org/netqmail/ および netqmailCHANGES ファイルを参照のこと。

2.5. ソースを組み立てる

2.5.1. ビルド環境の確認

まず最初にするのはプログラムをコンパイルするにに必要なツールが揃っているか確認することだ。これはどんな種類の UNIX を使っているかに依存して決まる。保証できないけどいちばん簡単な方法は、とにかくやっちゃえ

Note: これらのテストのどれかひとつでもパスしたらそこでやめて次の節に進むこと。
$ cc
cc: No input files specified
$

この節では qmail のコンパイルを実際にやってみる。カットアンドペーストは役に立つだろうが、ほんとうに必要なわけではない。

[訳注] 本節ではコンパイラの有無だけを問題にしているが、実際にはそれ以外にも必要なものがあり、この節のチェックが通っても後でうまくいかないことがあるかもしれない。が、その程度は自力で解決してほしい。

2.5.2. 配布物の展開

ここまできたら動作する C コンパイラと tar 玉を持っていることになる。次に、tar 玉を作業ディレクトリにコピーあるいは移動する。qmailucspi-tcp には /usr/local/src がよい選択であり、daemontools/package 以下で構築すべきである。

[訳注] daemontools も /usr/local/src 以下において問題ない。特に、パーティションを / だけでなく /usr、/var、/home など細かく区切るような運用をしている場合、/ パーティションの容量は比較的小さめに取ってあるだろうから、むしろ /package などには置かない方がいいだろう。もっとも、/package に展開しなくてもできあがったものは標準的には /command にインストールされるわけなので大した違いはないが(避けることも可能)。いちおう以下では原文どおり /package を使う。

まだ root になっていなければここで root になっておこう。

[訳注] 作業ディレクトリへの書き込み権限があれば root である必要はない。
su
umask 022
mkdir -p /usr/local/src
mv netqmail-1.06.tar.gz ucspi-tcp-0.88.tar.gz /usr/local/src
mkdir -p /package
mv daemontools-0.76.tar.gz /package
chmod 1755 /package

ここでパッケージを展開する。

cd /usr/local/src
gunzip netqmail-1.06.tar.gz
tar xpf netqmail-1.06.targunzip ucspi-tcp-0.88.tar.gz
tar xpf ucspi-tcp-0.88.tar
rm *.tar      # 容量に余裕があればやらなくてもよい
cd /package
gunzip daemontools-0.76.tar.gz
tar xpf daemontools-0.76.tar
rm *.tar      # 同上

これで /usr/local/src/netqmail-1.06/usr/local/src/ucspi-tcp-0.88/package/admin/daemontools-0.76 というディレクトリが作成される。

[訳注] 必要があればここで各種パッチを適用する。最近では DNS パッチが必要ない環境はまずありえないので、必ず適用すること。

2.5.3. ディレクトリの作成

qmail のインストールプログラムは自分が必要とするサブディレクトリを作成するので、qmail の「ホーム」ディレクトリだけ作成してやればよい。

mkdir /var/qmail

それでは次の節に進もう。

Note: /var 以外のどこかに qmail のファイルの一部ないしはすべてを置きたいのならば、他の場所を指すように /var/qmail の下でシンボリックリンクを張ることで可能になる。

たとえばqmail の設定ファイルを /etc/qmail に置きたいのなら以下のようにする。

mkdir /etc/qmail
ln -s /etc/qmail /var/qmail/control

2.5.4. ユーザとグループの作成

必要なユーザとグループを作成するもっとも簡単な方法はそれをするための小さなスクリプトを作成することだ。ソースディレクトリに INSTALL.ids というファイルが見つかるだろう。このファイルには多くのプラットフォームでのコマンドラインが含まれているのでこのファイルを別の名前でコピーして編集するのが手っ取り早くて簡単だ。

cd /usr/local/src/netqmail-1.06
cp INSTALL.ids IDS

そして、お好きなエディタを使っていらない行をすべて削除する。たとえば、FreeBSD では IDS は編集後このようになるだろう。

pw groupadd nofiles
pw useradd qmaild -g nofiles -d /var/qmail -s /nonexistent
pw useradd alias -g nofiles -d /var/qmail/alias -s /nonexistent
pw useradd qmaill -g nofiles -d /var/qmail -s /nonexistent
pw useradd qmailp -g nofiles -d /var/qmail -s /nonexistent
pw groupadd qmail
pw useradd qmailq -g qmail -d /var/qmail -s /nonexistent
pw useradd qmailr -g qmail -d /var/qmail -s /nonexistent
pw useradd qmails -g qmail -d /var/qmail -s /nonexistent
[訳注] FreeBSD の ports では nofiles ではなく qnofiles になる。vpopmail などの ports も qnofiles が存在していることが前提になっているので、そういう ports を使う予定があるならばそちらに合わせておいてもいいかもしれない(もちろん ports の方を修正してもいいし、ports なんか使わないという選択肢もある)。

それでは実行しよう。chmod を使って実行可能にするか、sh とともに実行する。

前者の方法:

chmod 700 IDS
./IDS

後者の方法:

/bin/sh IDS

スクリプトが終了するとすべてのユーザとグループが作成される。次の節に進もう。

しかし、INSTALL.ids に挙げられていないシステムを使っている場合はどうしたらいいだろう? 手で作らなければならない。お好きなエディタを起動して /etc/group を編集する。ファイル末尾に次の2行が必要だ。

qmail:*:2107:
nofiles:*:2108:
Note: 2107 と 2108 がすでに使われていないことを確認しておこう。使われていれば、空いている数字をふたつ選びなさい。

次に、vipw(たいていのシステムにはあるが、なければ今度はエディタで /etc/passwd を編集する)を使って末尾に以下の行を追加する。

alias:*:7790:2108::/var/qmail/alias:/bin/true
qmaild:*:7791:2108::/var/qmail:/bin/true
qmaill:*:7792:2108::/var/qmail:/bin/true
qmailp:*:7793:2108::/var/qmail:/bin/true
qmailq:*:7794:2107::/var/qmail:/bin/true
qmailr:*:7795:2107::/var/qmail:/bin/true
qmails:*:7796:2107::/var/qmail:/bin/true
Note: 7790-7796 がすでに使われていないこと、および 2107 と 2108 が上で使ったのと同じグループであることを確認すること。もしこれの UID のどれかがすでに使われていれば、空いてる数字を選ぶこと。
[訳注] システムによっては /bin/true ではなく /usr/bin/true かもしれない。

必ずしもファイルの末尾に追加する必要があるわけではないが、その方が説明するのが簡単なのだ。

それでは次節に進む準備ができた。

2.5.5. ビルドする

それでは qmail の構築をはじめられる。/usr/local/src/netqmail-1.06 ディレクトリに移ったらはじめよう。

cd /usr/local/src/netqmail-1.06

ビルド環境の確認の節で C コンパイラの場所を探した。もし cc という名前でなかったり、PATH 環境変数に含まれていなかったりした場合は conf-ccconf-ld を編集する必要がある。コンパイラが gcc であり、PATH に含まれていたとすると、conf-ccconf-ld を単純に "cc" から "gcc" に置き替えるだけでいい。

[訳注] FreeBSD の ports のように qnofiles グループを使う場合には conf-groupsnofiles の行を qnofiles に変更しておく。

以下のように入力しよう。

make setup check
[訳注] djb は root でプログラムを動かすのを嫌うわりには root でコンパイルすることについては何とも思わないらしい。root で上記のコマンドを実行する前に、まず root 以外のユーザで
make it man
を実行してコンパイルだけ済ませておいた方がいいだろう(作業ディレクトリへの書き込み権限が必要)。

ビルドが完了した後でインストール後の設定が必要だ。この作業を簡単にするためにふたつのスクリプトが用意されている。

DNS が適切に設定されていれば、この時点で必要なことはこのスクリプトがすべてやってくれる。

./config

もしなんらかの理由で config が DNS からホスト名を見つけられないときには、config-fast を実行しなければならない。

./config-fast the.full.hostname

たとえば、example.com というドメインでホスト名が dolphin ならば、config-fast は次のようになる。

./config-fast dolphin.example.com
Note: 小さなローカル LAN では ".local" のような擬似ドメインを使いたいと思うかもしれない。たとえばホスト名が "mash" なら ./config-fast mash.local とする。もしこうした場合、忘れずに返送先アドレス有効なインターネットドメイン名を使うよう qmail を設定しておくこと(3章設定を参照)。

これで qmail がインストールされ、稼働できる状態になった。次節は qmail の起動と試験の案内である。

2.6. ucspi-tcp のインストール

先だって qmailucspi-tcpdaemontools の tar 玉を展開しておいた。次に ucspi-tcp ディレクトリに移ろう。

cd /usr/local/src/ucspi-tcp-0.88

もしビルドするの節で conf-ccconf-ld を修正した場合は、このディレクトリでも同じ変更が必要である。

次に以下を実行する。

patch < /usr/local/src/netqmail-1.06/other-patches/ucspi-tcp-0.88.errno.patch
make
make setup check

これだけだ。ucspi-tcp がインストールされた。

[訳注] "make" までは一般ユーザで可能。"make setup check" だけ root で実行すればよい。

2.7. daemontools のインストール

daemontools の作業ディレクトリに移ろう。

cd /package/admin/daemontools-0.76

繰り返しになるが、qmailucspi-tcp のビルドで conf-cc and conf-ld を修正していれば src ディレクトリで同じ変更が必要になる。

以下を実行。

cd src
patch < /usr/local/src/netqmail-1.06/other-patches/daemontools-0.76.errno.patch
cd ..
package/install

/etc/inittab がない)BSD システムでは svscan(マスターサービス制御デーモン)を起動するためにここでリブートする必要がある。

"ps -ef | grep svscan" または "ps waux | grep svscan" を使って svscan が動いているか確認すること。

Note: Solaris では /etc/inittab の svscan の起動エントリを
SV:123456:respawn:/command/svscanboot

から

SV:123456:respawn:/command/svscanboot </dev/null >/var/log/svscan 2>&1

あるいは

SV:123456:respawn:/command/svscanboot </dev/null >/dev/msglog 2>&1

のように書き換える必要がある。どちらにするかは、svscan が起動するときのエラーメッセージをログファイルに書くかシステムコンソールに出力するかのどちらがいいかによる。なぜこうする必要があるかは、以下を参照のこと。

http://marc.theaimsgroup.com/?l=log&m=100327801309834&w=2

Note: Slackware では /etc/inittabSV というエントリは x1 のエントリの前にもってくるか、svscan をブート時には起動しないようにする必要があるとの報告がある。
[訳注] ソースを /package ではなく /usr/local/src 以下に展開した場合や、root 権限でやる作業を減らしたいときの作業手順。
cd /usr/local/src/admin/daemontools-0.76
patch -p1 < /usr/local/src/netqmail-1.05/other-patches/daemontools-0.76.errno.patch
package/compile
su		# ここで root になる
mkdir /command
cp command/* /command
chown -R 0:0 /command
cat package/commands | sed 's;.*;ln -sf /command/& /usr/local/bin/&;' | sh
mkdir /service
package/run
ここでは /command にインストールして /usr/local/bin にリンクを張って /service を作成しているが、/usr/local/bin だけに入れたり /var/service などとしてもよい。その場合、以降のスクリプト例は適宜書き換える必要がある。また、後述の inst_check でエラーが出る(意味がわかっていれば無視してかまわない)。
[訳注] /etc/inittab がないシステムで package/install(package/run) を使うと、起動スクリプトが /etc/rc.local に追加されるが、これは最近の *BSD の多くではあまり推奨されていない方法である。package/install のかわりに package/compilepackage/upgrade を使い、起動スクリプトの書き換えについては rc(8) のマニュアルに従って各 OS ごとに適切なものを手で書いた方がいいだろう。
[訳注] inittab を使うシステムではランレベル 1-6 のすべてで svscan が起動するように設定されるが、たいていこれは好ましくない。どのランレベルがどういう意味を持つかはシステムによって異なる(Linux でもディストリビューションが違えば同じとは限らない)ので詳しくは各 OS のドキュメントを参照してほしいが、たとえば Solaris ならば 2-4、RedHat なら 2-5 だけで十分だろう。package/install の実行後 /etc/inittab を書き換えるか、package/compilepackage/upgrade を実行した後で package/boot.inittab の内容を参考に /etc/inittab に追記してやればよい。いずれもその後でリブートか kill -HUP 1 を実行する必要あり。

2.8. qmail の起動

2.8.1. /var/qmail/rc

/var/qmail/boot ディレクトリにはさまざまな設定 -- /var/spool/mail$HOME/Mailbox か、procmail を使うか dot-forward を使うか、そしてこれらのいろんな組み合わせ -- での qmail の起動スクリプトの例が置かれる。これらは自由に試してもいいが、このインストールでは以下のスクリプトを使う。

#!/bin/sh

# Using stdout for logging
# Using control/defaultdelivery from qmail-local to deliver messages by default

exec env - PATH="/var/qmail/bin:$PATH" \
qmail-start "`cat /var/qmail/control/defaultdelivery`"
Note: このスクリプトはバッククォート(`)を使っている。シングルクォート(')ではない。いちばんいいのは、自分で打ち込むのではなく、このガイドのスクリプトをコピー & ペーストすることだ。

エディタで上の /var/qmail/rc を作成したら、以下のコマンドを実行しよう。

chmod 755 /var/qmail/rc
mkdir /var/log/qmail

ここで、.qmail ファイルで配送されないメッセージのデフォルトの配送モードを決める必要がある。よくある選択肢のあらましを次表で述べる。

メールボックス形式 名前 場所 defaultdelivery 備考
mbox Mailbox $HOME ./Mailbox もっとも一般的でほとんどの MUA で動く
maildir Maildir $HOME ./Maildir/ より信頼できるが、サポートしている MUA は少ない
mbox username /var/spool/mail INSTALL.vsm を参照 伝統的な UNIX メールボックス

詳しくは INSTALL.mboxINSTALL.maildirINSTALL.vsm を参照のこと。

デフォルトのメールボックス形式を決めたら、表の defaultdelivery の値を /var/qmail/control/defaultdelivery ファイルに入れる。たとえば、標準的な qmail Mailbox に配送することにしたのならば、

echo ./Mailbox >/var/qmail/control/defaultdelivery

とする。

Note: defaultdeliveryqmail の標準的な 制御ファイルではない。上の /var/qmail/rc ファイルの機能である。qmail-startdefaultdelivery 引数は .qmail が見つからなかったときにどうやって配送するかを指示する .qmail ファイルの中身である。この指示を別の制御ファイルに置くことで配送指示に含まれるシェルのメタキャラクタをクォートしなくてもよくなり、きたない複数行にわたる引数を避けられる。
[訳注] Gentoo Linux では maildir の標準は ~/Maildir ではなく ~/.maildir である。portage でインストールされる他のツールとの整合を取るためには、defaultdelivery として ./.maildir/ を指定しておく必要がある。もちろん、portage の方を修正してもよい。

2.8.2. システム起動ファイル

2.8.2.1. qmailctl スクリプト

もし /var/qmail/rc スクリプトを手で実行したら、qmail一部 だけ起動するだろう。しかし、qmail がシステム起動時に毎回自動でスタートてほしいし、システム停止時にはきれいに止まってほしい。

これは以下のような起動/停止スクリプトを /var/qmail/bin/qmailctl に作ってやればよい。

#!/bin/sh

# description: the qmail MTA

PATH=/var/qmail/bin:/bin:/usr/bin:/usr/local/bin:/usr/local/sbin
export PATH

QMAILDUID=`id -u qmaild`
NOFILESGID=`id -g qmaild`

case "$1" in
  start)
    echo "Starting qmail"
    if svok /service/qmail-send ; then
      svc -u /service/qmail-send /service/qmail-send/log
    else
      echo "qmail-send supervise not running"
    fi
    if svok /service/qmail-smtpd ; then
      svc -u /service/qmail-smtpd /service/qmail-smtpd/log
    else
      echo "qmail-smtpd supervise not running"
    fi
    if [ -d /var/lock/subsys ]; then
      touch /var/lock/subsys/qmail
    fi
    ;;
  stop)
    echo "Stopping qmail..."
    echo "  qmail-smtpd"
    svc -d /service/qmail-smtpd /service/qmail-smtpd/log
    echo "  qmail-send"
    svc -d /service/qmail-send /service/qmail-send/log
    if [ -f /var/lock/subsys/qmail ]; then
      rm /var/lock/subsys/qmail
    fi
    ;;
  stat)
    svstat /service/qmail-send
    svstat /service/qmail-send/log
    svstat /service/qmail-smtpd
    svstat /service/qmail-smtpd/log
    qmail-qstat
    ;;
  doqueue|alrm|flush)
    echo "Flushing timeout table and sending ALRM signal to qmail-send."
    /var/qmail/bin/qmail-tcpok
    svc -a /service/qmail-send
    ;;
  queue)
    qmail-qstat
    qmail-qread
    ;;
  reload|hup)
    echo "Sending HUP signal to qmail-send."
    svc -h /service/qmail-send
    ;;
  pause)
    echo "Pausing qmail-send"
    svc -p /service/qmail-send
    echo "Pausing qmail-smtpd"
    svc -p /service/qmail-smtpd
    ;;
  cont)
    echo "Continuing qmail-send"
    svc -c /service/qmail-send
    echo "Continuing qmail-smtpd"
    svc -c /service/qmail-smtpd
    ;;
  restart)
    echo "Restarting qmail:"
    echo "* Stopping qmail-smtpd."
    svc -d /service/qmail-smtpd /service/qmail-smtpd/log
    echo "* Sending qmail-send SIGTERM and restarting."
    svc -t /service/qmail-send /service/qmail-send/log
    echo "* Restarting qmail-smtpd."
    svc -u /service/qmail-smtpd /service/qmail-smtpd/log
    ;;
  cdb)
    tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp
    chmod 644 /etc/tcp.smtp.cdb
    echo "Reloaded /etc/tcp.smtp."
    ;;
  help)
    cat <<HELP
   stop -- stops mail service (smtp connections refused, nothing goes out)
  start -- starts mail service (smtp connection accepted, mail can go out)
  pause -- temporarily stops mail service (connections accepted, nothing leaves)
   cont -- continues paused mail service
   stat -- displays status of mail service
    cdb -- rebuild the tcpserver cdb file for smtp
restart -- stops and restarts smtp, sends qmail-send a TERM & restarts it
doqueue -- schedules queued messages for immediate delivery
 reload -- sends qmail-send HUP, rereading locals and virtualdomains
  queue -- shows status of queue
   alrm -- same as doqueue
  flush -- same as doqueue
    hup -- same as reload
HELP
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|doqueue|flush|reload|stat|pause|cont|cdb|queue|help}"
    exit 1
    ;;
esac

exit 0

このスクリプトは http://lifewithqmail.org/qmailctl-script-dt70 からも入手可能である。

エディタを使うか Web ブラウザでダウンロードするか(推奨)してスクリプトを作成すること。

qmailctl スクリプトを実行可能にし、パスのとおっているディレクトリにリンクを張っておこう。

chmod 755 /var/qmail/bin/qmailctl
ln -s /var/qmail/bin/qmailctl /usr/bin
[訳注] なんでもかんでも /usr/bin に放りこむのは Linux の悪習だと思う。訳者ならば /usr/local/sbin あたりにする(その場合、後述の inst_check でエラーが出るが無視してかまわない)。また、著者がピザのたとえで挙げていたメリットを額面どおりに受け取るのならば、内部をブラックボックス化するこのようなお便利スクリプトは参考程度に留めておいたほうがいいだろう。少なくとも、このスクリプトが内部で何をやっているのかは理解しておくべきである。

2.8.2.2. supervise スクリプト

qmail サービスのために supervise ディレクトリを作成しよう。

mkdir -p /var/qmail/supervise/qmail-send/log
mkdir -p /var/qmail/supervise/qmail-smtpd/log

/var/qmail/supervise/qmail-send/run ファイルを作成する。

#!/bin/sh
exec /var/qmail/rc

/var/qmail/supervise/qmail-send/log/run ファイルを作成する。

#!/bin/sh
exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/qmail

/var/qmail/supervise/qmail-smtpd/run ファイルを作成する。

#!/bin/sh

QMAILDUID=`id -u qmaild`
NOFILESGID=`id -g qmaild`
MAXSMTPD=`cat /var/qmail/control/concurrencyincoming`
LOCAL=`head -1 /var/qmail/control/me`

if [ -z "$QMAILDUID" -o -z "$NOFILESGID" -o -z "$MAXSMTPD" -o -z "$LOCAL" ]; then
    echo QMAILDUID, NOFILESGID, MAXSMTPD, or LOCAL is unset in
    echo /var/qmail/supervise/qmail-smtpd/run
    exit 1
fi

if [ ! -f /var/qmail/control/rcpthosts ]; then
    echo "No /var/qmail/control/rcpthosts!"
    echo "Refusing to start SMTP listener because it'll create an open relay"
    exit 1
fi

exec /usr/local/bin/softlimit -m 2000000 \
    /usr/local/bin/tcpserver -v -R -l "$LOCAL" -x /etc/tcp.smtp.cdb -c "$MAXSMTPD" \
        -u "$QMAILDUID" -g "$NOFILESGID" 0 smtp /var/qmail/bin/qmail-smtpd 2>&1
Note: concurrencyincoming は標準的な qmail の制御ファイルではない。上のスクリプトの機能である。また、 LOCAL の行は -1 (ハイフン、いち)であり、tcpserver の行は -l (ハイフン、エル)である。
Note: Solaris では通常の id プログラムではこのスクリプトはうまく動かない。id のかわりに /usr/xpg4/bin/id を使う。例:
QMAILDUID=`/usr/xpg4/bin/id -u qmaild`
NOFILESGID=`/usr/xpg4/bin/id -g qmaild`
Note: softlimit コマンドで指定されたメモリ制限は OS やハードウェアによっては値を大きくする必要があるかもしれない。25番ポートへの接続が失敗したりリモートシステムがこちらにメールを送れなかったり、あるいは
/usr/local/bin/tcpserver: error while loading shared libraries:
libc.so.6: failed to map segment from shared object: Cannot
allocate memory

というようなメッセージを目にしたりしたら、この値を 3000000 か 4000000 ぐらいまで上げてみよう。

concurrencyincoming 制御ファイルを作成する。

echo 20 > /var/qmail/control/concurrencyincoming
chmod 644 /var/qmail/control/concurrencyincoming

/var/qmail/supervise/qmail-smtpd/log/run ファイルを作成する。

#!/bin/sh
exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/qmail/smtpd

run ファイルを実行できるようにする。

chmod 755 /var/qmail/supervise/qmail-send/run
chmod 755 /var/qmail/supervise/qmail-send/log/run
chmod 755 /var/qmail/supervise/qmail-smtpd/run
chmod 755 /var/qmail/supervise/qmail-smtpd/log/run

続いてログディレクトリを準備する。

mkdir -p /var/log/qmail/smtpd
chown qmaill /var/log/qmail /var/log/qmail/smtpd

最後に supervise ディレクトリを /service にリンクする。

ln -s /var/qmail/supervise/qmail-send /var/qmail/supervise/qmail-smtpd /service

/service ディレクトリは daemontools をインストールしたときに作成される。

Note: qmail システムはこのリンクを張った後すぐに自動的に起動する。まだそうなってほしくなければ以下を実行する。
qmailctl stop
[訳注] 起動してから止めるぐらいなら最初から起動しないようにしておくべきだろう。supervise の管理しているディレクトリに down というファイルを置いておけば自動起動しなくなるので、/service にシンボリックリンクを張る前に、以下を実行しておく。
touch /var/qmail/supervise/qmail-send/down
touch /var/qmail/supervise/qmail-send/log/down
touch /var/qmail/supervise/qmail-smtpd/down
touch /var/qmail/supervise/qmail-smtpd/log/down

2.8.2.3. SMTP アクセス制御

ローカルホストが SMTP でメールを送信できるようにする。

echo '127.:allow,RELAYCLIENT=""' >>/etc/tcp.smtp
qmailctl cdb

2.8.3. インストール済み MTA の停止と無効化

qmail とすでに存在している MTA (おそらく Sendmail)を同時に動かすことも可能であるが、自分が何をしようとしているのか理解しているのでなければそうすることは推奨しない。そして失礼ながら、これを読んでいるならば、あなたはおそらく自分が何をしようとしているのか理解していない:-)。

もしすでに入っている MTA が Sendmail ならば、init.d スクリプトを stop 引数つきで実行することで停止できる。たとえば、以下のうちのひとつが動くだろう。

/etc/init.d/sendmail stop
/sbin/init.d/sendmail stop
/etc/rc.d/init.d/sendmail stop
[訳注] FreeBSD 4.x では /etc/rc.sendmail、FreeBSD 5.x、NetBSD では /etc/rc.d/sendmail になる。

もし init.d/sendmail スクリプトが見つからなければ、"ps -ef|grep sendmail" または ps waux|grep sendmail" を使って sendmail の PID を見つけ、以下のように停止する。

kill sendmailのPID

もし MTA が Sendmail でなければ、正しい停止手順をドキュメントで確認すること。

システムから古い MTA を完全に削除することも考えるべきだ。少なくとも、システムがリブートしたときにふたたび起動してこないように init.d スクリプトを無効化しておこう。

RedHat Linux では、Sendmail は以下のようにして削除できる。

rpm -e --nodeps sendmail
Note: もし、RedHat のような RPM ベースの Linux ディストリビューションを使っていれば、MTA パッケージの削除はうまくいかないかもしれない。システムをアップデートするユーティリティが Sendmail を再インストールしようとしたり、MTA がないからと MUA パッケージがインストールできないかもしれない。Mate Wierdl はこの問題を解決するための "fake_mta" という代替パッケージを用意している。ftp://ftp.csi.hu/mw/fake_mta-1-10memphis.noarch.rpm にある RPM をインストールすればよい。
[訳注] 削除ではなく、ブート時に起動しないよう無効化する方法は OS によって異なる。以下、訳者が確認できたものを挙げる。

SMTP ポート(25) を開いているものが何もないことを確認する。古い MTA や inetdxinetd などにその可能性がある。次のコマンドで何も出力されなければよい(qmail-smtpd サービスが動いていなければ)。

netstat -a | grep smtp

もし何か動いていれば、それが qmail でないことを確かめよう。

qmailctl stop

再度 netstat で確認する。

netstat -a | grep smtp

これでもまだ出力されるなら、qmail の SMTP サービスを動かす前に犯人を突き止めて修正しなければならない。

最後に、今ある /usr/lib/sendmailqmail 版に置き替える。

mv /usr/lib/sendmail /usr/lib/sendmail.old                  # エラーが出ても無視
mv /usr/sbin/sendmail /usr/sbin/sendmail.old                # エラーが出ても無視
chmod 0 /usr/lib/sendmail.old /usr/sbin/sendmail.old        # エラーが出ても無視
ln -s /var/qmail/bin/sendmail /usr/lib
ln -s /var/qmail/bin/sendmail /usr/sbin
Note: 前に使っていた MTA が何であれ、sendmail へのリンクを作成するのは重要である。メールを送信するのに多くのアプリケーションから sendmail コマンドが使われる。
[訳注] mailwrapper を採用している OS(NetBSD、FreeBSD など)では sendmail のバイナリを置きかえるのではなく、/etc/mail/mailer.conf を書き換える。詳細は mailwrapper(8)、mailer.conf(5) を参照のこと。また、シンボリックリンクの作成は、もともと /usr/lib/usr/sbin のどちらかにしか存在していなければ、その片方だけでよい(その場合、後述の inst_check でエラーが出るが無視してかまわない)。

最後にシステムエイリアスをいくつか作成する。

2.8.4. システムエイリアスの作成

どんな qmail インストールでも3つのシステムエイリアス(別名)を作成するべきである。

エイリアス 目的
postmaster RFC2821 で要求。メール管理者(あなた)を指す。
mailer-daemon いくつかのバウンスを受信するアドレスの事実上の標準。
root 特権アカウントからシステム管理者へメールを向け直す。
abuse abuse 申告を受信するアドレスの事実上の標準。

これらのエイリアスを作成するためには、それぞれがどこに転送されるべきか(ローカルユーザなのか外部アドレスなのか)を決めて、適切な .qmail ファイルを作成して登録しなければならない。たとえば、dave というローカルユーザがシステムとメールの両方の管理者だとすると、

echo dave > /var/qmail/alias/.qmail-root
echo dave > /var/qmail/alias/.qmail-postmaster
ln -s .qmail-postmaster /var/qmail/alias/.qmail-mailer-daemon
ln -s .qmail-postmaster /var/qmail/alias/.qmail-abuse
chmod 644 /var/qmail/alias/.qmail-root /var/qmail/alias/.qmail-postmaster

のようにする。詳しくは INSTALL.alias を参照のこと。

2.8.5. qmail 起動

もし /service にリンクを張った後に qmail を停止していたら、今再起動しておく。

qmailctl start
[訳注] down を作成して起動しないようにしておいた場合、そのままだとリブートしたときにも qmail が起動しなくなる。削除しておくこと。
rm /var/qmail/supervise/qmail-*/down /var/qmail/supervise/qmail-*/log/down

2.9. インストール後の確認

もう qmail が動いているはずだ。まずサービスが起動して動いているか確認するために qmailctl stat を実行してみよう。

# qmailctl stat
/service/qmail-send: up (pid 30303) 187 seconds
/service/qmail-send/log: up (pid 30304) 187 seconds
/service/qmail-smtpd: up (pid 30305) 187 seconds
/service/qmail-smtpd/log: up (pid 30308) 187 seconds
messages in queue: 0
messages in queue but not yet preprocessed: 0

4つのサービスすべてが1秒以上 "up" になっているはずだ。そうでなければ run スクリプトにミスタイプがあったり、必要なファイルやディレクトリやリンクを作成するステップをひとつかそれ以上すっとばしたのだろう。インストールの過程を一歩ずつ振り返って自分のした作業を二重チェックしよう。また、inst_check スクリプトを http://lifewithqmail.org/inst_check からダウンロードして実行してもいい。例:

# sh inst_check
! /var/log/qmail has wrong owner, should be qmaill
...try: chown qmaill /var/log/qmail
#

もしinst_check が問題を見つけたら、修正してもう一度実行しよう。すべてうまくいっていれば、inst_check

Congratulations, your LWQ installation looks good!

と報告する。

[訳注] 先の訳注にあるように、qmailctl/usr/bin ではなく /usr/local/sbin に置いたり、/var/qmail/bin/sendmail へのリンクを /usr/lib/usr/sbin のどちらかひとつにしか作成しなかった場合も警告が出るが、意味がわかっているのならば無視しても問題ない。

readproctitle プログラムは svscan で管理されているサービスで生成されたエラーメッセージのログを保持している。このメッセージを見るには、ps その他のプロセス参照コマンドを使う。たとえばこのように見えるだろう。

# ps -efl | grep "service errors" | grep -v grep
000 S root      1006  1001  0  76   0    -   334 pipe_w Mar31 ?        00:00:00
readproctitle service errors: ...unable to start qmail-smtpd/run: exec format error
#

この場合、問題は /service/qmail-smtpd/run スクリプトの最初の行にエラーがあるということである。もっともありがちな原因は、ファイルが DOS 形式になっている(改行が UNIX の LF ではなく CR-LF になっている)ことだ。

設定の問題を発見するために、サービスを手動で実行してみるのが助けになることがある。qmail-smtpd サービスが動いていないなら、こうしてみよう。

cd /service/qmail-smtpd/log
svc -d .
./run
エラーがなければ、何か1行入力して ENTER を押す
それでもエラーがなければ、CTRL-D (end-of-file) を押す

これで何がいけなかったのかがわかって修正できるはずだ。終わったら必要に応じてサービスのディレクトリに戻って、以下を実行。

svc -u .

サービスがすべて1秒以上動いていれば、TEST.deliverTEST.receive の説明にしたがって正しく動作しているか確認しよう。この文書の説明にしたがった場合、/var/log/maillog のようなファイルに splogger でログが記録されるのではなく、/var/log/qmailmultilog で記録されることに注意すること。

Note: もしデフォルトの配送方法として maildir メールボックス形式を選んだら、この説明を試す前に自分のホームディレクトリと alias のホームディレクトリに Maildir ディレクトリを作成しておく必要がある。このディレクトリを適切に作成する方法は maildir 節を参照のこと。

3. 設定

オススメのソース tar 玉から、あるいは自動コンパイルパッケージないしは var-qmail パッケージを使って qmail のインストールが完了した。この章では qmail を思いどおりに動かすために必要な情報について述べる。

3.1. 設定ファイル

~alias に置かれる .qmail 以外のすべての qmail のシステム設定ファイルは /var/qmail/control に置かれる。qmail-control の man ページには以下のような表が含まれる。

制御ファイル デフォルト 使用するプログラム 目的
badmailfrom なし qmail-smtpd 送信者アドレスのブラックリスト
bouncefrom MAILER-DAEMON qmail-send バウンス送信者のローカル部
bouncehost me qmail-send バウンス送信者のドメイン部
concurrencyincoming なし /service/qmail-smtpd/run 最大同時 SMTP 接続受け付け数
concurrencylocal 10 qmail-send 内部配送の最大同時並列度
concurrencyremote 20 qmail-send 外部配送の最大同時並列度
defaultdelivery なし /var/qmail/rc デフォルトの .qmail ファイル
defaultdomain me qmail-inject デフォルトドメイン名
defaulthost me qmail-inject デフォルトホスト名
databytes 0 qmail-smtpd メッセージの最大バイト数 (0=無制限)
doublebouncehost me qmail-send ダブルバウンス送信者のドメインパート
doublebounceto postmaster qmail-send ダブルバウンス受信者
envnoathost me qmail-send "@" がないときにアドレスに付加するドメイン名のデフォルト
helohost me qmail-remote SMTP HELO コマンドで使われるホスト名
idhost me qmail-inject Message-ID で使われるホスト名
localiphost me qmail-smtpd ローカル IP アドレスに対応するホスト名
locals me qmail-send ローカル配送するドメイン
me システムの FQDN さまざま いろんな制御ファイルのデフォルト
morercpthosts なし qmail-smtpd rcpthosts データベースその2
percenthack なし qmail-send "%" 形式の中継を許可するドメイン
plusdomain me qmail-inject 末尾の "+" で補完するドメイン名
qmqpservers なし qmail-qmqpc QMQP サーバの IP アドレス
queuelifetime 604800 qmail-send メッセージがキューに残留できる秒数
rcpthosts なし qmail-smtpd メールを受け取るドメイン名
smtpgreeting me qmail-smtpd SMTP グリーティングメッセージ
smtproutes なし qmail-remote 静的 SMTP 配送経路
timeoutconnect 60 qmail-remote SMTP 接続待ち時間(秒)
timeoutremote 1200 qmail-remote SMTP 応答待ち時間(秒)
timeoutsmtpd 1200 qmail-smtpd SMTP 受け付け待ち時間(秒)
virtualdomains なし qmail-send 仮想ドメインとユーザ名

個々の制御ファイルについての詳細は「使用するプログラム」の欄のモジュールの man ページを参照のこと。

[訳注] 一部を除いて、制御ファイルにはコメントなどを含めることはできないので注意。現在どのような設定になっているかは /var/qmail/bin/qmail-showctl を実行することで確認できる。

3.2. 中継(リレー)

3.2.1. はじめに

中継(リレー) とは何か? これは MTA がローカルアドレスでもローカル送信者でもないメッセージを SMTP で受けつけたときに起きる。

spam がはびこる以前、オープンリレー、すなわち誰からのメールも誰宛へのメールも受けつけるしっちゃかめっちゃかなサーバが MTA のふつうの設定だった。

現在ほとんどの MTA は中継を完全に無効にしてあるか、信頼できる特定のユーザないしはシステムにのみ中継させるように設定される。

Chris Johnson はこの件について qmail ユーザのためにとてもよい文書を書いている。http://www.palomine.net/qmail/relaying.html を一読することをお勧めする。

3.2.2. 中継を無効にする

もし qmail を公式な指示にしたがってインストールしていれば、デフォルトで中継しないようになっている。中継は localsvirtualdomains(内部ホスト)に列挙された完全修飾ドメイン名(FQDN)を var/qmail/control/rcpthosts に記述することで実現される。rcpthosts という制御ファイル名は SMTP の RCPT (recipient) コマンドに由来する。SMTP セッションではメッセージの受信者アドレスを指定するのに RCPT が使われる。そこで、rcpthosts には RCPT アドレスにあらわれてもよい有効なホスト名を列挙する。

3.2.3. 選択的な中継の許可

ユーザひとりで小さなワークグループサーバのほとんどは中継を完全に無効にできる。しかし、ひろがりのあるユーザコミュニティをサポートしなければならなければ、ユーザに、ユーザだけに、中継させるためにシステムを使わせる方法が必要になるだろう。これは tcpserverRELAYCLIENT 環境変数をセットすることで実現される。これは qmail-smtpdrcpthosts ファイルの設定を上書きするよう指示する。

このドキュメントの説明にしたがってインストールしたなら、選択的中継はデフォルトで可能になっている。クライアントに中継させるには、/etc/tcp.smtp に以下のようなエントリを追加してやればよい。

クライアントの IP アドレス:allow,RELAYCLIENT=""

そして SMTP アクセスデータベースを再構築してやる。

qmailctl cdb

あるいは

tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp
chmod 644 /etc/tcp.smtp*

公式のインストール手順にしたがったのならば、Chris Johnson が qmail で中継するホストを選択的に許可する設定方法について別のよいドキュメントを書いている。http://www.palomine.net/qmail/selectiverelay.html を参照してほしい。

3.2.4. スマートホストへの中継

典型的な家庭用ブロードバンドサービスでメールサーバを構築する人にとっては、あなたの IP アドレスが SORBS (http://www.dnsbl.sorbs.net/lookup.shtml) のような spam ブロックに尽力している組織のブラックリストに載せられる可能性は十分にある。ほとんどの ISP は、契約者からのすべてのメールを中継する SMTP サーバを用意していて、このようなサーバはふつうブラックリストに載らない。たとえば、 オハイオ州シンシナティの Road Runner サービスの契約者は smtp-server.cinci.rr.com が使える。すべての外向き SMTP トラフィックをそのサーバに向けるよう qmail に指示するには、以下のようにすればよい。

echo ":smtp-server.cinci.rr.com" > /var/qmail/control/smtproutes

smtproutes ファイルはこれ以外にもさらに多くのルーティングを実現できる機能がある。くわしくは qmail-remote の man ページを参照のこと。

[訳注] ISP のメールサーバがブラックリストに載らないというのは幻想である。リストを保守している組織のポリシーにもよるが、spam を中継していれば ISP のサーバだろうが気にせずリストに登録するところは少なくない。とはいえ、Outbound Port 25 Blocking が一般的になりつつあり、ブラックリストうんぬんとは別の理由で ISP のサーバへの中継が必要な場合もあるだろう。ISP によってはそのまま中継しても送れず、SMTP AUTH での認証が必須となることもあるが、その場合はたとえば ここにあるようなパッチを適用した qmail が必要になる(qmail-smtpd ではなく qmail-remote に対するパッチであることに注意)。

3.3. 複数ホスト名

もしシステムに複数の名前があれば、たとえば、user@host1.example.com の形のアドレスすべてが user@example.comuser@mail.example.com とも表わされるなら、それがローカル配送すべきアドレスでリモートから受け付けるべきメッセージであることが qmail にわかるよう教えてやる必要がある。

このためにはその名前すべてをふたつの制御ファイルに追加する。

追加したら locals を読み直すよう HUP シグナルを qmail-send に送る。qmailctl があれば以下のようにする。

qmailctl reload

3.4. 仮想ドメイン

仮想ドメインは前節で説明した複数ホスト名に似ているが、いくつか重要な違いがある。まず、example.net が仮想ドメイン virtual.example.com を収容しているとしたら、ふつう joe@example.net に送られたメッセージが最終的に joe@virtual.example.com に送られたメッセージと同じメールボックスに入るとは限らない。仮想ドメインそれぞれの名前空間は区別される。

qmail では仮想ドメインは virtualdomains ファイルに以下の形式でひとつ以上書くことで設定できる。

user@domain:prepend

qmailuser@domainprepend-user@domain の形式に変換して、結果として domain がローカルのものであるかのように扱う。user@ の部分はなくてもよい。なければそのエントリは すべての @domain アドレスにマッチする。

上の例の場合に戻ると、example.net のメール管理者がユーザ john の管理下で仮想ドメイン virtual.example.com を欲しければ、virtualdomains に以下のエントリを追加すればいい。

virtual.example.com:john

joe@virtual.example.com 宛に届いたメッセージは john-joe@virtual.example.com に書き換えられて内部配送される。john が自分の仮想ドメインをどのように管理するのかについては .qmail の節と拡張アドレスの節を参照してほしい。

複数ホスト名のときと同じように、届いたメッセージを qmail-smtpd が受け取るようすべての仮想ドメインを rcpthosts に列挙しなければならない。しかし、複数ホスト名のときとは違って仮想ドメインでは locals に追加してはいけない

virtualdomains を変更したら、ファイルを読み直させるために qmail-sendHUP シグナルを送る。qmailctl を使っていれば以下を実行する。

qmailctl reload

仮想ドメインを rcpthosts にも追加するのを忘れないこと。

Note: 適切なメールサーバに仮想ドメイン宛メッセージを届けるためには DNS の MX レコードを設定しなければならない。これはネームサーバ管理者の仕事であり、このガイドの範囲を越える。

3.5. エイリアス

qmail の標準的なエイリアス機構は qmail のローカル配送機構の自然な副産物である。qmail-locallocalpart@host 宛のメッセージを localpart というローカルユーザに配送しようとする。マッチするユーザがいなければ、メッセージはすべての qmail システムの擬似ユーザである alias ユーザに配送される。alias のホームディレクトリは通常 /var/qmail/alias である。

たとえば、ユーザ tom にメッセージを転送する info@example.com というエイリアスを作るとしよう。example.comroot ユーザになって以下を実行する。

echo \&tom > /var/qmail/alias/.qmail-info

.qmail の節と拡張アドレスの節では、存在するエイリアスを指定する .qmail ファイルをどうやって作成するか、送られたメッセージをどう扱うかについて解説している。

付録 Gotchas ではエイリアスの使い方に関していくつかトリッキーなケース -- 大文字とピリオド('.')を含むエイリアス -- に触れている。また、man dot-qmail.qmail ファイルの使い方についての完全なドキュメントが読める。

qmail におけるエイリアスの実装方法のために、エイリアスは有効なユーザの配送を決して上書きできないことに留意しておこう。たとえば、rachel が一般ユーザならば、~alias/.qmail-rachel は使われることはない。

fastforward パッケージは Sendmail のエイリアスデータベースと互換な単一ファイルで複数エイリアスを使う別のエイリアス機構を提供している。

次節 qmail-users ではエイリアスの実装に使われるもうひとつのしくみについて説明する。

3.6. qmail-users

qmail-users はユーザにアドレスを割り当てるシステムである。一連の設定ファイルは /var/qmail/users 以下に置かれる。assign ファイルが割り当て表になる。単純割り当てとワイルドカードの二種類の割り当て方法がある。

Note: assign は1行にひとつずつ割り当てを列挙し、単一のドット(.)だけからなる行で終わる。assign を手で作成したらドット行を忘れずに。

3.6.1. 単純割り当て

単純割り当ては以下のようになる。

=address:user:uid:gid:directory:dash:extension:

これは address 宛に届いたメッセージは uidgid のユーザ user として配送され、どうやって配送するかを directory/.qmaildashextension というファイルで指定するという意味になる。

3.6.2. ワイルドカード割り当て

ワイルドカード割り当ては以下のようになる。

+prefix:user:uid:gid:directory:dash:prepend:

これは prefixrest という形式のアドレスに届いたメッセージは uidgid のユーザ user として配送され、どうやって配送するかを directory/.qmaildashprependrest というファイルで指定するという意味になる。

3.6.3. qmail-user プログラム群

qmail-user には qmail-newuqmail-pw2uというふたつの補助プログラムがある。

qmail-newuassign ファイルを処理して /var/qmail/userscdb という constatnt database (CDB) 形式のファイルを 生成する。CDB は数千の割り当てがあったとしても qmail-lspwan が高速にアクセスできるようなバイナリ形式である。

qmail-pw2u はシステムのユーザデータベースである /etc/passwdassign の割り当て形式に変換する。以下のファイルが存在しているとそれに応じて qmail-pw2u は変換ルールを変更する。

Note: qmail-pw2u を使うのならば、ユーザを追加したり削除したり UID や GID が変わるたびに忘れずに qmail-pw2uqmail-newu を再実行すること。典型的な手順はこうなる。
qmail-pw2u </etc/passwd >/var/qmail/users/assign
qmail-newu

3.7. spam 制御

Chris Hardie がすぐれた qmail Anti-Spam HOWTO を書いている。http://www.summersault.com/chris/techno/qmail/qmail-antispam.html から入手できる。

3.8. ウィルススキャン

Jason Haar は qmail 用コンテンツ走査ツールである Qmail-Scanner を作成している。詳しくは http://qmail-scanner.sourceforge.net/ を参照のこと。

Qmail-Scanner には単純な「ポリシーブロッキング」コンポーネント(たとえば *.scr や "Subject: Yellow!" のブロック)が含まれており、また ClamAV Antivirus (http://www.ClamAV.net) などたくさんのアンチウィルス「プラグイン」をサポートしている。


4. 使い方

この章では一般ユーザでの qmail の使い方について述べる。qmail システムでメールの読み書きをしているのなら、qmail でどうやるかについてはここで見つかるだろう。

4.1. .qmail ファイル

ユーザのメールの配送はふつうひとつかそれ以上の ".qmail"(どっときゅーめーると発音する)ファイルで制御される。このファイルは .qmail ではじまる名前でユーザのホームディレクトリに置かれる。.qmail ファイルの使い方については dot-qmail man ページで説明されている。

.qmail ファイルは1行にひとつずつ配送指示を列挙したものである。各行の先頭文字でどのような種類の配送をするか決まる。

文字 配送タイプ
# 何もしない (コメント) 無視される
| プログラム シェルに実行させるコマンド
/ または . mbox (最終文字が / 以外) mbox のパス(/ や . も含む)
/ または . maildir (最終文字が /) maildir のパス(/ や . も含む)
& 転送 メッセージを転送するアドレス
文字または数字 転送 メッセージを転送するアドレス (先頭文字も含む)

4.1.1. プログラムへの配送

プログラムへの配送指示があれば、qmail はコマンドを実行するためにシェル(/bin/sh)を起動し、標準入力に受信メッセージの写しを流しこむ。qmail-command の man ページにこの過程の詳細が述べられている。

プログラムへの配送はとても強力で、メッセージのフィルタリングや自動応答、procmail のようなサードパーティの配送エージェントによる配送など、幅広い機能を実現するのに使われる。

例:

|preline /usr/ucb/vacation djb

こうすると qmail/usr/ucb/vacationdjb を引数として preline を起動し、標準入力にメッセージの写しを与える。

4.1.2. mbox への配送

mbox は UNIX の標準的なメールボックス形式である。複数のメッセージがひとつのファイルに格納され、各メッセージは "From " 行で始まる。この行はヘッダフィールドに似ているがそうではない。それぞれのメッセージがどこから始まるかをメールリーダがわかるように配送エージェントが付加するものである。

./Mailbox

こうすると、メッセージは "From " を付加されて $HOME/Mailbox に追加される。メッセージが1通だけの簡単な mbox メールボックスは以下のようになる。

From user1@example.net Thu May 13 18:34:50 1999
Received: (qmail 1287205 invoked from network); 13 May 1999 18:34:49 -0000
From: user1@example.net
To: user2@example.com
Subject: hey

What's up?

1行目が qmail による配送の際に付加されたものである。

4.1.3. maildir への配送

maildir は mbox 形式の欠点を解決するために Dan Bernstein が考案したメールボックス形式である。maildir メールボックスは newcurtmp という3つのサブディレクトリを持つディレクトリである。maildir メールボックスのそれぞれのメッセージは状態に応じてそのサブディレクトリのどれかに1通ずつ別のファイルで格納される。new は未読メッセージ、cur は既読メッセージ、tmp は配送処理中のメッセージである。maildir の man ページで maildir の形式について詳しく説明されている。

maildir 形式の利点のひとつは、異なる配送エージェントによる同時更新を防ぐためにロックしなくても確実であるということである。これは mailbox メールボックスを NFS でマウントされたファイルシステムに置いても安全であることを意味する。

例:

./Maildir/

こうするとメッセージは maildir 形式のメールボックス $HOME/Maildir に保存される。

Note: qmail-local はメールを maildir メールボックスに配送することはできるが、作成することはできない。maildir メールボックスは qmail に付属してくる maildirmake プログラムで作成しておく。例えば、"maildirmake ~/Maildir" を実行する。 maildirmake は root ではなく maildir の所有者として実行する。useraddadduser コマンドが「スケルトン」ディレクトリ(例えば /etc/skel)をサポートしていれば、そこに maildir を作成しておけば新規ユーザすべてにコピーされる。

4.1.4. 転送

転送は指定したアドレスにメッセージを再送信する。.qmail ファイルで指定されるアドレスにはコメントフィールドやよけいな空白を含めることはできない。

これは 間違い:

&<user@example.com>
& user@example.com
&Joe User <user@example.com>

これは正しい:

&user@example.com
user@example.com
&user

最初のふたつはメッセージの写しが user@example.com に送られる。最後のはローカルユーザの user に送られる。

4.1.5. 拡張アドレス

qmail はユーザ制御の拡張アドレスをサポートしている。ユーザは基本となるアドレス username@hostname.domain に加え、username-extension@hostname.domain というアドレスでもメールを受け取ることができる。ローカルシステムでの動作について考えるので、この節では以降 "@hostname.domain" の部分は省略する。

username への配送指示は ~username/.qmail でおこない、username-extension への配送指示は ~username/.qmail-extension でおこなう。

たとえば、dave-lwq@sparge.example.com は sparge というホストの ~dave/.qmail-lwq で制御される。

拡張部は、たとえば ~dave/.qmail-list-qmail で制御される dave-list-qmail のように、複数のフィールドを持つことができる。この例では qmail メーリングリストに dave-list-qmail で登録し、~dave/.qmail-list-qmail ファイルで別のメールボックスにメーリングリストのメッセージを保存する。

.qmail ファイルでは -default というワイルドカードを使える。なので、dave-list-qmail~dave/.qmail-list-default でも扱える。これはひとつの .qmail ファイルで dave-list-なんとか というアドレスすべてを扱うようになる。dave-list~dave/.qmail-list-default では扱われないので注意すること("list" の後の "-" にマッチしないので)。

qmail は見つかったもののうちいちばん近いものを使う。たとえば、メッセージが dave-list-qmail に届いたとき、以下のうち最初に見つかったものが使われる。

.qmail-list-qmail
.qmail-list-default
.qmail-default

マッチする .qmail が見つからなければ、配送は失敗してメッセージは送信者にバウンスされる。

4.2. メッセージの送信

メールユーザはメッセージを送るのにふつう MTA を直接使わない。典型的には、pinemutt のような、メッセージを配送するために MTA にアクセスするメーラー(Mail User Agent; MUA)を使ってメッセージを書いて送る。MTA にメッセージを渡す過程のことを 投入 (injection) と呼ぶ。

[訳注] この翻訳の他の節では inject を「送信」と訳していることがある。send と区別がつかないけど、区別できなくて困るような文脈ではないので。どうしても違いをはっきりしたければ、この翻訳ではなく原文を読んでほしい。なお、injection という言葉を使うのは qmail だけで、ふつうは submission という。

ほとんどの MTA にメッセージを投入するには、Simple Mail Transfer Protocol (SMTP) を使うか、その目的のために MTA で用意しているプログラムを使うかのふたつの方法がある。

4.2.1. SMTP

MUA はローカルホストや指定されたメールサーバの25番ポート(標準的な SMTP ポート)に TCP 接続することができる。MUA と MTA はそこでやりとりをして、結果として以下のいずれかになる。

SMTP には認証機構がないので、メッセージを送信するのにユーザ名やパスワードは要求されない。しかしながら、多くの MTA は送信者か受信者がローカルユーザでないメッセージを受け付けるのを拒否する。適切な書式のメッセージが拒否されたら、中継制限が原因の可能性が高い。中継の設定についての詳細は中継の節を参照のこと。

[訳注] 認証がないのはあくまで qmail の話であって、ESMTP には SASL や TLS によるクライアント認証の拡張機能があり、最近の MTA では設定しだいで利用可能なものが多い。qmail にも非公式のパッチがいくつか存在する。もちろん、MUA 側も認証に対応している必要がある。

4.2.2. /var/qmail/bin/sendmail

長年にわたって Sendmail こそ UNIX の MTA だった。どこにでもあるので、多くのプログラマは Sendmail が MTA だと決めてかかっていた。結果として、Sendmail のローカル送信機構が標準の Application Programmer's Interface (API) となった。qmail およびほかの非 Sendmail MTA はローカルからの送信用に本物の Sendmailsendmail と同じように動作する sendmail プログラムを用意している。

qmailsendmail は通常 /var/qmail/bin/sendmail にあり、qmail システムではふつう Sendmailsendmail を置き替える。sendmail プログラムの典型的な場所は、

である。qmail システムでは "ls -l sendmailのパス" は /var/qmail/bin/sendmail へのシンボリックリンクを示すはずである。

$ ls -l /usr/lib/sendmail
lrwxrwxrwx   1 root     root           29 Feb 19 11:04 /usr/lib/sendmail -> /var/qmail/bin/sendmail
[訳注] NetBSD、FreeBSD などでは、/usr/sbin/sendmailSendmailsendmail ではなく、mailwrapper というラッパープログラムになっている。このような OS では /var/qmail/bin/sendmail にシンボリックリンクを張るのではなく、/etc/mail/mailer.conf というファイルに設定を書く。詳しくは mailwrapper(8)、mailer.conf(5) を参照のこと。

4.2.3. qmail-inject

sendmail API のエミュレーションに加えて、qmail には qmail-inject という独自の送信プログラムがある。実際のところ sendmailqmail-inject の単なるラッパーである。

API としては、sendmail の方が広範に使えてよいだろう。qmail-inject による qmail API は qmail のあるシステムでしか動かないが、sendmail インターフェースはほぼどこでも使える。

たとえば、空メッセージを joe@example.com に送るのは以下のようになる。

echo To: joe@example.com | /var/qmail/bin/qmail-inject

4.3. 環境変数

qmail のプログラムのいくつかは環境変数をセットしたり参照したりする。下表はこれらの変数とその使い道の一覧である。

名前 man ページ セット/参照 目的
DATABYTES qmail-smtpd 参照 control/databytes を上書きする
DEFAULT qmail-command セット .qmail ファイルの "-default" に対応するアドレスの部分
DTLINE qmail-command セット Delivered-To ヘッダフィールド
EXT qmail-command セット アドレス拡張部
EXT2 qmail-command セット EXT の最初のハイフンに続く部分
EXT3 qmail-command セット EXT の2番目のハイフンに続く部分
EXT4 qmail-command セット EXT の3番目のハイフンに続く部分
HOME qmail-command セット ユーザのホームディレクトリ
HOST qmail-command セット 受信者アドレスの domain
HOST2 qmail-command セット HOST の最後のドットまでの部分
HOST3 qmail-command セット HOST の最後からふたつめのドットまでの部分
HOST4 qmail-command セット HOST の最後から3つめのドットまでの部分
LOCAL qmail-command セット 受信者アドレスの local
LOGNAME qmail-inject 参照 From ヘッダフィールドのユーザ名 (4)
MAILHOST qmail-inject 参照 From ヘッダフィールドのホスト名 (2)
MAILNAME qmail-inject 参照 From ヘッダフィールドの個人名 (2)
MAILUSER qmail-inject 参照 From ヘッダフィールドのユーザ名 (2)
NAME qmail-inject 参照 From ヘッダフィールドの個人名 (3)
NEWSENDER qmail-command セット 転送時の送信者アドレス("man dot-qmail" 参照)
QMAILDEFAULTDOMAIN qmail-inject 参照 control/defaultdomain を上書きする
QMAILDEFAULTHOST qmail-inject 参照 control/defaulthost を上書きする
QMAILHOST qmail-inject 参照 From ヘッダフィールドのホスト名 (1)
QMAILIDHOST qmail-inject 参照 control/idhost を上書きする
QMAILINJECT qmail-inject 参照 さまざまなオプションを指定する(次表参照)
QMAILMFTFILE qmail-inject 参照 Mail-Followup-To 生成のためにメーリングリスト一覧を書いたファイル
QMAILNAME qmail-inject 参照 From ヘッダフィールドの個人名 (1)
QMAILPLUSDOMAIN qmail-inject 参照 control/plusdomain を上書きする
QMAILSHOST qmail-inject 参照 エンベロープ送信者のホスト名
QMAILSUSER qmail-inject 参照 エンベロープ送信者のユーザ名
QMAILUSER qmail-inject 参照 From ヘッダフィールドのユーザ名 (1)
RECIPIENT qmail-command セット エンベロープ受信者アドレス
RELAYCLIENT qmail-smtpd 参照 control/rcpthosts を無視する。また、受信者アドレスに追加する値
RPLINE qmail-command セット Return-Path ヘッダフィールド
SENDER qmail-command セット エンベロープ送信者
UFLINE qmail-command セット UUCP 形式の "From " 行
USER qmail-command セット 現在のユーザ
USER qmail-inject 参照 From ヘッダフィールドのユーザ名 (3)
[訳注] セットというのは .qmail から起動するスクリプトの便宜のために、qmail が値をセットしてくれる環境変数。参照というのは、その環境変数に適当な値をセットしておくと、qmail がその値に応じて動作を変えるもの。
QMAILINJECT のフラグ
文字 目的
c From フィールドので アドレス-コメント形式を使う
s 入力中の Return-Path フィールドを無視する
f 入力中の From フィールドを削除する
i 入力中の Message-ID 削除する
r 宛先ごとの VERP を使う
m メッセージごとの VERP を使う

5. 進んだ話題

5.1. procmail

procmail は定評ある Message Delivery Agent (MDA) である。MDA の機能は MTA から指定されたユーザないしはメールボックスへのメッセージを受け付けてユーザの望んだとおりにメッセージを配送することである。procmail はさまざまなヘッダフィールドやメッセージ本文の内容によってメッセージを「フィルタ」するのにも使われる。たとえば、ある人からのメッセージをその人用のメールボックスに仕分けたりできる。

qmailprocmail を動かすにはいくつかの小細工が必要である。まず、procmail はふつう /var/spool/mail にある mbox メールボックスに配送するようにビルドされる。デフォルトが $HOME になるよう procmail をリビルドしたり、mbox の場所を procmail のデフォルトにしないようユーザに指示することも可能であるが、procmail は依然として /var/spool/mail を一時ファイル置き場として使う。

もうひとつの問題は、qmail-commandprocmail は終了コードの意味が同じではないということである。procmail は標準的な UNIX の終了コードを使う。ゼロは成功、非ゼロは失敗という意味で、失敗の原因は /usr/include/sys/errno.h で示される。qmail-command は恒久的エラーを示すのにある非ゼロのコードを使う、残りは一時エラーとみなされる。qmail-command で終了コードの翻訳をする小さなシェルスクリプトラッパーが使われる。このラッパーは qmail メーリングリストに投稿され、過去ログから入手できる(http://www.ornl.gov/lists/mailing-lists/qmail/1998/04/msg00487.html)。

また、procmail の古いバージョン(3.14 より前)は maildir 形式のメールボックスに直接配送しない。procmail の現在のバージョンにアップグレードするのがいちばんいい考えだ。もうひとつの方法は、指定された maildir に標準入力のメッセージを書きこむ safecat というプログラムである。メッセージをファイルするのに safecat を使うよう procmail のレシピ(配送指示)を書くことができる。procmail をまったくすっとばして maildrop を使うこともできる。

最後に、procmail は受け取るメッセージが mbox 形式であることを期待する。ふつうの qmail プログラムは配送の際には実際のメールメッセージだけで、"From " 行は含めない。procmail が期待するようなメッセージに整形するのには preline コマンドが使われる。上でリンクしたラッパーは preline を含んでいる。

たとえば、ユーザ "dave" が自分のメールを procmail に処理させようとしたとしよう。システム管理者は procmail をデフォルトで $HOME に配送するようビルドし、上でリンクした終了コードのラッパーを /usr/local/bin/qmail-procmail として用意している。その場合、.qmail はこのようになるだろう。

|/usr/local/bin/qmail-procmail

5.2. POP と IMAP サーバ

qmail には qmail-pop3d という POP サーバが含まれているが、qmail の導入の部分では設定、インストールしなかった。また、ほとんどは Sendmail 向けに書かれていて qmail で使うにはちょっと作業が必要だが、他の POP、IMAP サーバも使うことができる。

5.2.1. qmail-pop3d

qmal-pop3dqmail に含まれる POP サーバである。良質な POP サーバであり、多くの qmail で使われている。機能ごとに分割されており、認証モジュールを入れ替えることで複数の認証スキームを使える。

Note: qmail-pop3d は maildir 形式メールボックスだけサポートするので、POP サーバにログインしてローカルで MUA を使っているユーザがいれば、MUA すべてが maildir をサポートしていなければならない。ユーザのすべてがメールを POP で読むのであれば、サーバのメールボックス形式は大した問題ではない。

5.2.1.1. qmail-pop3d の構造

qmail-pop3d は3つのモジュールで構成される。

典型的には qmail-popup を POP3 の110番ポートの接続を待つように inetdtcpserver 経由で起動する。接続が確立するとユーザ名、パスワードを送るよう促す。次に checkpassword を起動してユーザ名/パスワードを照合し、一致したら qmail-pop3d を起動する。

5.2.1.2. qmail-pop3d のインストール

1. qmail を完全にインストール、テストする。すべてのユーザがメールボックスに POP アクセスできるようにしたいなら、defaultdelivery./Maildir/ に設定しておく。導入の章の /var/qmail/rc スクリプトをインストールしているのなら、これは control/defaultdelivery に設定する。そうでなければ、 /var/qmail/rcqmail-start のコマンドラインに書くことになる。

2. http://www.qmail.org/top.html#checkpassword から checkpassword プログラムをダウンロードする。特別なことが必要なければ、標準の checkpassword (http://cr.yp.to/checkpwd.html) を選ぶのがいいだろう。

3. 手順にしたがって checkpassword をコンパイル、インストールする。/bin/checkpassword としてインストールされるのを確かめること。

Note: もし標準の checkpassword をインストールするのならば、ソースを展開した後で忘れずに errno パッチを適用しておくこと。
patch < /usr/local/src/netqmail-1.06/other-patches/checkpassword-0.90.errno.patch
[訳注] こういうのは /bin ではなく /usr/local/bin とか、あるいはどうせ qmail-pop3d でしか使わんのだから /var/qmail/bin とかにインストールしておいた方がいいと思う。標準の checkpassword の場合は、ソースディレクトリの conf-home の1行目を、前者なら /usr/local、後者なら /var/qmail に書き換えてからコンパイルする。その場合、次項のスクリプト内の checkpassword のパスを実際にインストールしたパスに変更するのをお忘れなく。

4. mkdir /var/qmail/supervise/qmail-pop3d

5. /var/qmail/supervise/qmail-pop3d/run を以下の内容で作成する。

#!/bin/sh
exec /usr/local/bin/softlimit -m 2000000 \
    /usr/local/bin/tcpserver -v -R -H -l 0 0 110 /var/qmail/bin/qmail-popup \
        FQDN /bin/checkpassword /var/qmail/bin/qmail-pop3d Maildir 2>&1

ここで、FQDN は設置する POP サーバの完全修飾ドメイン名である。たとえば、pop.example.net のようになる。

Note: softlimit コマンドで指定されたメモリ制限は OS やハードウェアによっては値を大きくする必要があるかもしれない。110番ポートへの接続が失敗したり POP3 接続の謎の失敗があったり、あるいは
/usr/local/bin/tcpserver: error while loading shared libraries:
libc.so.6: failed to map segment from shared object: Cannot
allocate memory

というようなメッセージを目にしたりしたら、この値を 3000000 か 4000000 ぐらいまで上げてみよう。

6. mkdir /var/qmail/supervise/qmail-pop3d/log

7. /var/qmail/supervise/qmail-pop3d/log/run を以下の内容で作成する。

#!/bin/sh
exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t \
    /var/log/qmail/pop3d

8. ログディレクトリと run スクリプトのパーミッションを設定し、/service にサービスへのリンクを張る。

chmod +t /var/qmail/supervise/qmail-pop3d   # daemontools < 0.75 のとき
mkdir /var/log/qmail/pop3d
chown qmaill /var/log/qmail/pop3d
chmod 755 /var/qmail/supervise/qmail-pop3d/run
chmod 755 /var/qmail/supervise/qmail-pop3d/log/run
ln -s /var/qmail/supervise/qmail-pop3d /service

9. qmailctl の "start" の部分に以下を追加する。

    if svok /service/qmail-pop3d ; then
      svc -u /service/qmail-pop3d /service/qmail-pop3d/log
    else
      echo qmail-pop3d supervise not running
    fi

10. qmailctl の "stop" の部分に以下を追加する。

    echo "  qmail-pop3d"
    svc -d /service/qmail-pop3d /service/qmail-pop3d/log

11. qmailctl の "stat" の部分に以下を追加する。

    svstat /service/qmail-pop3d
    svstat /service/qmail-pop3d/log

12. qmailctl の "pause" の部分に以下を追加する。

    echo "Pausing qmail-pop3d"
    svc -p /service/qmail-pop3d

13. qmailctl の "cont" の部分に以下を追加する。

    echo "Continuing qmail-pop3d"
    svc -c /service/qmail-pop3d

14. qmailctl の "restart" の部分に以下を追加する。

    echo "* Restarting qmail-pop3d."
    svc -t /service/qmail-pop3d /service/qmail-pop3d/log
[訳注] ここでは qmailctl で qmail-pop3d の制御ができるように処理を追加しているが、これでは MTA と POP3 の起動や停止が必ず連動してしまう。MTA と POP3 は本質的に異なるものであり、一括で扱うのではなく独立に制御できるようにした方がいいと思う。つまり、qmailctl スクリプトに追加するのではなく、qmail-pop3d の制御専用の別スクリプトをゼロから書く。

5.2.2. Qpopper

mbox 形式のメールボックスで動く POP デーモンが必要ならば、Qualcomm の Qpopper が使える。Qpopperhttp://www.eudora.com/products/unsupported/qpopper/ から入手できる。

5.2.3. Binc IMAP

Andreas Hanssen は Binc IMAP サーバを書いている。Binc IMAP は qmail-pop3d が使っているのと同じ認証機構 (checkpassword) を使うよう設計されているので、qmail サーバとは相性がいい。qmail-pop3d と同様に Maildir メールボックスのみをサポートする。http://www.bincimap.org/ を参照のこと。

5.2.4. Dovecot

Timo Sirainen は mbox と maildir 両方のメールボックスをサポートする IMAP と POP サーバ Dovecot を書いている。安全になるよう設計されている。http://www.dovecot.org/ から入手できる。

5.2.5. imap-maildir

David R. Harris はワシントン大学 IMAP サーバに maildir サポートを追加するパッチを整理し、インストール手順の文書を書いている。http://www.davideous.com/imap-maildir/ を参照のこと。

[訳注] いわゆる UW-IMAP とか IMAP-200x とか言われてるアレ。日本ではこっちのパッチの方が知られているか。開発元で maildir に正式にサポートする予定はないようだ

5.2.6. Courier-IMAP

Sam Varshavchik は maildir メールボックスのみサポートする IMAP サーバを書いている。http://www.courier-mta.org/imap/ から入手できる。

5.2.7. Cyrus

カーネギーメロン大学の Project Cyrus には IMAP サーバが含まれている。http://asg.web.cmu.edu/cyrus/imapd/ から入手できる。Rick Updegrove は Cyrus のメールストアにメッセージを配送する qmail2cyrus というラッパーを書いている。このラッパーは http://msgs.securepoint.com/cgi-bin/get/qmail0308/41/1/1.html から入手できる。

5.3. POP と IMAP クライアント

5.3.1. fetchmail

fetchmail は POP/IMAP サーバからメールを回収してきてローカルで再送信するプログラムである。fetchmailqmail サーバからのメールの取得には問題ないが、qmail クライアントでうまく動くようにするにはいくつか小細工が必要である。

これは qmail システムでの .fetchmailrc のサンプルである。

poll mail.example.net proto pop3 nodns
    user dsill with password flubgart is dave here
    fetchall forcecr

これは fetchmail に mail.example.net に POP3 で接続し、ユーザ dsill、パスワード flubgart でログインしてすべてのメールを取得し、dave@localhost に配送させる指示である。forcecr により、fetchmail がローカルシステムに SMTP でメッセージを投入するときに、各行末に復帰 (CR) をつけさせる。qmail にはこれが必要である。

[訳注] fetchmail は POP/IMAP サーバから取得したメールを直接メールボックスに書き込むのではなく、ローカルホストで動いている MTA に SMTP 経由で配送させるというのがデフォルトの動作になっている。SMTP の改行コードは CR+LF であると RFC で定められていて、qmail はこれを厳密に守っていないと一時エラーとして受信を拒否する(qmail 以外のたいていの MTA は LF のみでも寛容に受け付けるので問題にはならない)。そのため、あらかじめ fetchmail の側で改行を CR+LF にしておかなければならない。これをするのが forcecr オプション。qmail 側で対処するには、qmail-smtpducspi-tcp に含まれる fixcrio の子プロセスとして起動してやればよい。が、しかしそれよりもわざわざローカルの qmail を使うのではなく、procmail などの MDA に直接メールボックスに配送させた方がいいだろう。デフォルトの SMTP による配送では、最悪の場合、ローカルの MTA の設定が悪いだけでも、メールを送ってくれた人に意味不明のバウンスを返してしまうことがある。fetchmail を実行するユーザとメールボックスの所有者が異なる場合は SMTP を使わないと無理だが、そうでもないかぎりは "mda /usr/local/bin/procmail" などと指定しておいた方がいいだろう(もちろん .procmailrc を適切に書く必要がある)。mda を指定しない場合は最低限、.qmail での転送設定は解除しておくべき。

5.3.2. getmail

getmail は POP サーバからメールを回収してきて maildir メールボックスに配送するプログラムである。中身は Python スクリプトなので、getmail を使う前に Python インタープリタをインストールしておく必要があるだろう。

getmail を書いているのは Charles Cazabon で、http://pyropus.ca/software/getmail/ に web ページがある。

5.4. 相乗り配送と個別配送

あなたが MTA で、あなたのユーザのひとりが hostx.example.com にいる3人の人にメッセージを送ると仮定しよう。これにはいくつか方法がある。

  1. hostx に SMTP で1回接続し、最初のユーザにメッセージの写しを1回送り、2番目のユーザに送り、3番目に送って、それから切断する。
  2. 3つのプロセスを開始し、そのそれぞれで hostx に SMTP で1回接続してユーザのうちのひとりにメッセージの写しを1回送り、それから切断する。
  3. ホストに SMTP で1回接続し、3人すべてに宛ててメッセージの写しを1回送り、それから切断する。

最初の方法はあきらかに3番目に劣る。たとえメッセージが小さかったとしても、とにかく長くかかる。メッセージが大きかったとしたらもっと長く、さらにネットワーク帯域もよけいに使う。

だからそいつは考えない。

2番目と3番目はちょっと興味深い。

3番目の方法は hostx に1回だけ接続し、メッセージの写しを1回だけ送る。帯域を効率的に使っている。

2番目の方法は複数の接続で複数のメッセージを送る。これは帯域の「浪費」である。しかし、SMTP プロトコルの性質に起因する往復の遅延がほとんどなく、3番目の方法よりも高速である。3番目の方法よりも単純なので MTA のコードはより簡単になる。最後に、それぞれの受信者がそれぞれメッセージを受けとるので、VERP (次節参照)の実装が可能になる。

[訳注] 1回の SMTP 接続だけに着目すれば、RCPT TO の数が違うだけである。そりゃ確かに RCPT と 250 のやりとりが多い分3番目の方が長くなるが、ほとんどの MTA は ESMTP PIPELINING 拡張をサポートしているし、そんなのは誤差の範囲だろう(qmail は受信(qmail-smtpd)は PIPELINING をサポートしているが、送信(qmail-remote)ではサポートしていない)。VERP にしても、それが必要なときだけ2番目の方法を使えば可能である(実際、Postfix はそのようにして実現している)。それよりも、送信者と受信者の関係が常に 1 対 1 になるため、複数の宛先のひとつだけが失敗した場合を考慮する必要がなくなり、エラー処理が簡単になることの方が大きい。処理の単純性こそ、2番目の方法を使う最大のメリットである。

qmail常に2番目の方法(個別配送/single RCPT)を使う。3番目の方法 (相乗り配送/multiple RCPT)を実装するパッチはない -- やるとしたら仕事になるだろう。

相乗り配送よりも遅くなるような病的なケースもあるけれど、単純さと VERP の利点はそれを補って余りある。

[訳注] 個別配送の方が遅くなる場合というのは、受信者の数が concurrencyremote の制限より多いとか、受信側の接続数制限(同時接続数、接続レート)にひっかかる、あるいは受信側のマシンパワー不足や途中経路の回線容量が飽和しているとかの場合かな。どれも病的 (pathological) というほど特異なケースではない。これ以外の理由で遅くなったら異常かも。

個別配送は相乗り配送よりもよけいに帯域を使うのは確かだが、その違いはしばしば誇張される。ほとんどのメッセージは多くとも受信者は数人ほどで、通常別々のホストにいるので、相乗り配送のメリットはない。相乗り配送が役にたつメーリングリストサーバでも、SMTP はネットワーク全体の帯域の小さな一部分でしかないので -- ふつう HTTP がシェアの筆頭である --、潜在的な利得は小さい。

たとえば、あなたの上流の帯域のうち 10% が SMTP であり、相乗り配送を使うことで SMTP の帯域を仮に 25% 減らすことができたとしても、SMTP の帯域は 7.5% に下がるだけである。

[訳注] 原著者があまりにも必死になって相乗り配送の利点は大した利点でないと力説しているように感じられるので、いくつか反論してみる。 なお、訳者は、だから相乗り配送しろ、バラして送るのはけしからん、といっているわけではない。立場の違い、考え方の違いであり、どちらが優れているといえる類のものではない。いちおう、RFC2821 #4.5.4.1 では相乗りで送るべき (SHOULD) となっている。

5.5. VERP

メッセージを配送できなかったとき、責任ある MTA はバウンスメッセージを envelope return path (ERP) に返すことが想定されている。バウンスメッセージには受信者のアドレス、メッセージを配送できなかった理由、、一時エラーと恒久的エラーのどちらなのかが含まれるべきである。しかしながらいくつかの MTA はこれを正しくおこなわない。バウンスを From ヘッダフィールドのアドレスに送ったり、どの受信者に送った結果のかわからないバウンスを出したりする。

[訳注] メールの送信者アドレスは SMTP の MAIL FROM コマンドにあらわれるものとヘッダの From フィールドにあらわれるものの2種類あり、必ずしも両者が一致している必要はない(メーリングリストなどから届くメールではむしろ一致していないのがふつう)。envelope return path とはこの前者のアドレスのこと。それから、一時エラーではふつうバウンスしない。恒久的エラーのみである。

ほとんどのユーザどうしのメッセージでは、これはたいした問題ではない。一方がバウンスのタイミングや内容に基づいて指摘してやることができるのがふつうだ。メーリングリストでは、おかしなバウンスの問題は深刻になる。登録者がメールの転送先を新しいアドレスに変更する。このアドレスへの配送に問題があると、もしバウンスメッセージに新しいアドレスしか書いていなかったら、どの登録者宛のメールがバウンスしているのかわからなくなってしまう。

Dan Bernstein はこの問題に VERP (Variable Envelope Return Path) という解決策をもたらした。VERP を使うことで、メーリングリストのそれぞれの登録者に送られたそれぞれのメッセージにただひとつの返送先アドレス (return path) がつく。これにより、問題の発生している登録者を識別してバウンスを処理できるようになる。

たとえば、VERP を使っていない典型的なメーリングリストの返送アドレスは listname-owner@domain である。VERP を使っているメーリングリストでは返送アドレスは listname-owner-subscriber=sdomain@ldomain になる。これには登録者のアドレス subscriber@sdomain が "owner" と "@" の間に埋め込まれている(登録者アドレスの "@" は "=" に置き替えられる)。

ezmlm メーリングリストマネージャはバウンスを自動処理するのに VERP を使う。一時的に配送の問題があった登録者に読めなかったメッセージの一覧を提供するので、登録者は過去ログからそれを回収することができる。

Russell Nelson は qmail で動いている Majordomo で使えるバウンス管理ツールを書いたが、現在はメンテナンスされていない。これは http://www.qmail.org/bounceman-0.4.shar から入手できる。

[訳注] 現在、VERP は qmail 以外に Postfix でもサポートされており、ふだんは相乗り配送する Postfix も VERP を使うときに限り個別配送に切り替える。また、Mailman や fml などの ML マネージャでも VERP がサポートされている。なお、RFC2821 にはメールアドレスのローカルパートは最大64文字までという規定がある。VERP を使うとこの制限を越えて不正な送信者アドレスを生成してしまうことがあるので注意すること。

5.6. トラブルシューティング

5.6.1. プロセス

適切に動作する、完全な、最小ではない構成で qmail をインストールすると、以下の4つのプロセスが常に動いているはずだ。

[訳注] 最小構成というのは QMQP を使った mini-qmail のことと思われる(この文書では触れられていない)。mini-qmail では常駐プロセスが存在しない。

使っている UNIX の種類によって、次のふたつのコマンドのいずれかでこれらのプロセスと、もしかしたら他にもういくつか見えるはずだ。

ps -ef | grep qmail
ps waux | grep qmail

例:

[dave@sparge dave]$ ps waux|grep qmail
dave      2222  0.0  0.8   836   348  p4 S    10:25   0:00 grep qmail
qmaild     351  0.0  1.0   840   400  ?  S N  12:43   0:00 /usr/local/bin/tcpserver -v -x /etc/tcp.smtp.cdb -u 49491 -g 31314 0 smtp /var/qmail/bin/qmail-smtpd-
qmaild    2220  0.0  1.0   844   420  ?  S N  10:25   0:00 /usr/local/bin/tcpserver -v -x /etc/tcp.smtp.cdb -u 49491 -g 31314 0 smtp /var/qmail/bin/qmail-smtpd-
qmaill     365  0.0  0.8   748   344  ?  S N  12:43   0:00 splogger qmail
qmailq     368  0.0  0.7   736   292  ?  S N  12:43   0:00 qmail-clean
qmailr     367  0.0  0.6   732   272  ?  S N  12:43   0:00 qmail-rspawn
qmails     350  0.0  0.8   776   336  ?  S N  12:43   0:00 qmail-send
root       340  0.0  0.6   724   252  ?  S N  12:43   0:00 /usr/local/sbin/supervise /var/supervise/qmail-send /var/qmail/rc
root       341  0.0  0.6   724   252  ?  S N  12:43   0:00 /usr/local/sbin/supervise /var/supervise/tcpserver-qmail /usr/local/bin/tcpserver -v -x /etc/tcp.smtp
root       366  0.0  0.7   736   276  ?  S N  12:43   0:00 qmail-lspawn ./Mailbox
[dave@sparge dave]$
[訳注] 本文書の解説どおりにインストールしたなら、supervise と tcpserver のパスや引数は上の例とは違っているはず:-)

qmailqmail-smtpdsupervise の下で動かしていれば、上の例にあるように、それらのプロセスも見えるはずだ。また、qmail-smtpdtcpserver から起動していれば、tcpserver の親プロセスに加えて、現在アクティブな SMTP 接続を受け付けている tcpsever プロセスが見えるはずだ。

ログを取るのに splogger(や multilogcyclog)を使っていれば、そのプロセスがひとつないしはふたつ、ユーザ qmaill として動いているだろう。

また、qmail が内部あるいは外部への配送処理中であれば、最大で concurrencylocal までの qmail-local プロセスと、最大で concurrencyremote までの qmail-remote プロセスが見えるだろう。

5.6.2. ログ

5.6.2.1. multilog

multilogdaemontools パッケージに含まれているもので、指定したディレクトリの一連のファイルにメッセージを記録する。

ログディレクトリは multilog のコマンドライン引数として指定するので、qmail の起動スクリプトを調べてみると見つかるだろう。

ログディレクトリのファイルの数とそれぞれのファイルの最大サイズは multilog のオプションで決まる。ログファイル名はファイルが作られたときの TAI (Temps Atomique International) タイムスタンプになる。tai64nlocal コマンド(これも daemontools にある)で TAI タイムスタンプを人間が読めるローカル時刻に変換する。

multilog の典型的なログは次のようになる。

@4000000038c3eeb104a6ecf4 delivery 153: success: did_1+0+0/

"@4000000038c3eeb104a6ecf4" は任意だが付加するのが推奨の TAI タイムスタンプである。"delivery 153: success: did_1+0+0/" がログメッセージである。

5.6.2.2. splogger

splogger はメッセージにタイムスタンプをつけて syslog デーモンに送ってログを記録する。syslog/etc/syslog.conf で設定する。syslog デーモンに送られたメッセージは facilitypriority を持つ。 /etc/syslog.conf にあるエントリはメッセージを望みのログファイルやリモートの別ホスト、コンソールなどにに振り分けるために facility と priority で選別する。splogger はデフォルトで mail facility でログ出力するので、syslog.conf ファイルを "mail" で grep すると qmail のログメッセージが吐かれる場所がわかるはずだ。

典型的な場所は以下のようになる。

sysog の典型的なログは次のようになる。

Jun  3 11:35:23 sparge qmail: 928424123.963558 delivery 153: success: did_1+0+0/

"Jun 3 11:35:23" は syslog のタイムスタンプである。

"sparge" はメッセージを送ったシステムの名前である。

"qmail:" は sploggerqmail のログエントリすべてに付加するタグである。

"928424123.963558" はオプションの TAI タイムスタンプである(次節参照)。

"delivery 153: success: did_1+0+0/" がログメッセージである。

[訳注] 原文には an optional TAI timestamp とあるが、optional ではない。必ず付加される。また、TAI ではなくただの UNIX タイムのような気がする(ちょっと自信がない)。

5.6.2.3. Log messages

ローカルからリモートにメッセージを送ったとき、一連のログは典型的にはこのようになる。

1 @4000000038c3eeb027f41c7c new msg 93869
2 @4000000038c3eeb027f6b0a4 info msg 93869: bytes 2343 from <dave@sill.org> qp 18695 uid 49491
3 @4000000038c3eeb02877ee94 starting delivery 2392: msg 93869 to remote lwq@w3.to
4 @4000000038c3eeb0287b55ac status: local 0/10 remote 1/20
5 @4000000038c3eeb104a13804 delivery 2392: success: 209.85.127.177_accepted_message.
   /Remote_host_said:_250_CAA01516_Message_accepted_for_delivery/
6 @4000000038c3eeb104a4492c status: local 0/10 remote 0/20
7 @4000000038c3eeb104a6ecf4 end msg 93869

1行目は qmail が新しいメッセージを受け取り、そのキュー ID が 93869 であることを示している。キュー ID は /var/qmail/queue/mess/NN/ にあるファイル(メッセージを含むキューファイル)の i-node 番号である。キュー ID はメッセージがキューに滞留しているかぎりはユニークであることが保証されている。

2行目からメッセージが dave@sill.org からのもので 2343 バイトであることがわかる。

[訳注] さらに以下のことがわかる。キューにメッセージを登録した qmail-queue の PID は 18695 である。qmail-log の man ページでは msg は disk inode number、qp は long-term queue identifier となっていて、msg ではなく qp の方をキュー ID と呼ぶ方が適切のようである。また、送信したユーザの UID は 49491 である。これがユーザ qmaild の UID であれば、ネットワーク経由で(SMTP で)送信されたものであることを示す。ログ出力に関して特に細工をしていなければ、ネットワーク経由で送信されたのか、ローカルから qmail-inject で送信されたのかを判別する唯一の方法がこの UID である(SMTP だった場合、どこの IP アドレスから送られたのかは tcpserver などのログの時刻から「推定」することは可能だが、「確定」させることは、特にハックしていなければ、できない。G.7. 参照)。

3行目から qmail-remotelwq@w3.to 宛のメッセージの配送処理を開始し、その配送に ID 2392 を割り当てられたことがわかる。

4行目から処理中のローカル配送がゼロ、リモート配送が1件であることがわかる。

5行目から配送 ID 2392 の処理が完了、成功し、配送先サーバの応答を返しているのがわかる。この応答にはしばしば送信先のメール管理者が配送を追跡する助けになる情報が含まれている。この場合、"CAA01516" が配送先システムの配送 ID である。

[訳注] 配送先サーバからの応答のうち空白文字は "_" に置き替えられる。また、qmail-smtpd の場合は "ok SSSSSSSSSS qp NNNNN" のような応答を返す。このうち、qp NNNNN が前述した qp に対応する。SSSSSSSSSS は受け付けた時刻(1970年元旦からの通算秒)。

6行目から処理中のローカル配送がゼロ、リモート配送がゼロであることがわかる。すなわち、配送は完了した。

7行目からメッセージの配送が完了し、キューから削除されたことがわかる。この時点でキュー ID (93869) は別の配送のため再利用が可能になる。

5.7. 大規模サーバ

qmail-ldap も参照のこと。

5.7.1. 拡張性のある並列処理

ユーザのディレクトリを蓄積するのには高速な NFS ファイルサーバを使おう。等しい優先度の SMTP サーバを複数構築して、ファイルサーバ上の maildir メールボックスに配送するようにする。

5.8. Sendmail から qmail への移行

http://cr.yp.to/qmail/sendmail.html にある Dan Bernstein の Sendmail->qmail ページをチェックせよ。

5.9. メーリングリストマネージャ

メーリングリストマネージャ (MLM) はメーリングリストを運用する管理者の助けになるシステムである。その任務はふたつの主な任務に帰結する。ML 登録者を管理することと、登録者へのメッセージの再送信を制御することである。

ほとんどの(すべての?) UNIX 上のメーリングリストマネージャは qmail で動かせる。

5.9.1. ezmlm

ezmlmqmail の作者 Dan Bernstein か書いたものである。qmail とともに使うように書かれていて、qmail のいくつかの機能を前提にしている。とりわけ、信頼性の高いバウンスメッセージの処理のために VERP を使う。ezmlm は中心となる MLM のアドレスに送られたコマンドを処理しないという点において MLM の中ではいくぶん珍しい。ezmlm ではメーリングリストの名前にコマンドを付加する。たとえば、"foo@list.example.net" に登録するには、"foo-subscribe@list.example.net" にメッセージを送る。

ezmlm に関する詳しい情報は http://www.ezmlm.org/ を参照してほしい。ここは ezmlm の非公式の Web サイトであり、たくさんの便利な機能を持ったすぐれたアドオンである ezmlm-idx の公式ホームページである。

5.9.2. Majordomo

Majordomo はもっとも人気のある UNIX の MLM のひとつだ。かんたんな変更を少しだけほどこした qmail でうまく動く。Russ Allbery が qmail/Majordomo についての FAQ を書いている。これは http://web.archive.org/web/20050308091420/http://www.eyrie.org/~eagle/faqs/mjqmail.html にある。

5.10. パッチ

qmail のソースコードに対するさまざまなパッチが入手可能である。パッチを導入するには、ダウンロードして、qmail のソースツリーに cd して、patch コマンドでパッチを適用する。

cd /usr/local/src/qmail/qmail-1.03
patch -p0 </tmp/patchfile
Note: 詳しくは patchman ページを参照のこと。これは一例にすぎない。また、いくつかのパッチはうまく適用するために GNU patch の現行バージョンを使う必要があるだろう。http://www.gnu.org/software/patch/patch.html を参照。
qmail-send を kill して qmail を停止する。あるいは、導入の章で qmailctl スクリプトをインストールしていれば、
qmailctl stop

を実行する。その後、新しいバイナリを再構築、インストールする。

make setup check

qmail を再起動する。

qmailctl start

最後に、qmail の動作試験をする -- 特にパッチを当てた部分を。

Note: http://www.qmail.org/ には qmail のたくさんのパッチが列挙されているが、qmail の作者が承認したものはひとつもないqmail には存在していないセキュリティ、信頼性、効率、機能的な問題をひきおこすかもしれない。qmail を導入するほとんどのケースでは以下の推奨パッチのうちのいくつかだけが必要だろう。明らかに必要としていないどんなパッチもインストールするべきではない。

qmail.org には「推奨パッチ (Recommended Patches)」の節がある (http://qmail.org/top.html#patches)。これらのパッチは qmail にわずかしかない既知のバグを扱う。

Note: 推奨パッチはすべて netqmail 版に取り込まれている。http://www.qmail.org/netqmail/ を参照のこと。

5.10.1.1. errno.h パッチ

このパッチは errno.h のインクルードに失敗する問題を修正する。詳しい説明とパッチ自身は http://article.gmane.org/gmane.mail.qmail.general/13960 を参照のこと。

Mate Wierdl のところには qmaildaemontoolsucspi-tcp を含む Dan Bernstein のソフトウェアすべてに対する errno.h パッチがある。これは http://www.thedjbway.org/patches/djb_errno_patches.tgz から入手できる。

5.10.1.2. qmail-local TAB パッチ

このパッチは TAB 文字で始まっていた場合の .qmail ファイルの解析における小さなバグを修正する。http://www.ornl.gov/lists/mailing-lists/qmail/2000/10/msg00696.html

5.10.1.3. IP 0.0.0.0 パッチ

このパッチはローカルのものと認識されるべき 0.0.0.0 という IP アドレスが認識されないのを解消する。http://www.suspectclass.com/~sgifford/qmail/qmail-0.0.0.0.patch

5.10.2. DNS

歴史的に DNS 応答は 512 バイトに制限されてきた。いくつかの大きなサイトではそれよりも長い MX 応答を返す。qmail および他の多くのプログラムは非常に大きな結果を返す Domain Name Server (DNS) の問い合わせに問題がある。qmail でこれを修正する方法がふたつ、いくらかのアプリケーションにも十分な対処がひとつある。

[訳注] E.2 節も参照のこと。最近では SPF、DNSSEC などで DNS の応答サイズは大きくなる傾向にあり、512バイト以上の DNS 応答はとくに珍しいことではなくなってきている。この節に挙げられているパッチは事実上必須であるといってよい。なお、この Life with qmail で扱っている netqmail は、素の qmail にいくつかのバグ修正をほどこしたものであるが、その netqmail にもこのパッチは適用されていない。各自でかならずパッチを当てること。

5.10.2.1. Christopher K. Davis のパッチ http://www.ckdhr.com/ckd/qmail-103.patch

これは Chuck Foster によるパッチを、どんな名前解決ライブラリでも、それがどんなに古くても動くように修正したものである。これは "number of bytes placed in the buffer" というライブラリのバグを避けるために防御バイトを使用する。ちょうど必要なサイズではなく、65536 まで一回だけ再割り当てするので、Chuck のパッチよりもメモリ効率はよくない(もっとも、彼のパッチと同様、応答がデフォルト 512 バイトの PACKETSZ より大きいときだけ再割り当てするのだが)。再割り当てした後、名前解決ライブラリに再度要求するのではなく、TCP 問い合わせを強いる(qmail とネームサーバ間のよけいな往復を避けるため。同じマシンやローカルネットワークにあればさほど大きな懸念にはならないが)

[訳注] 何かわかりにくい訳ですんませんが、要するに 512 バイトで足りなきゃ 65536 バイトに増やしてから TCP でやりなおすということみたい。

5.10.2.2. パケットのバッファサイズを 65536 まで増やす

最近の BIND 名前解決ライブラリで動作する。このライブラリは truncation bit がセットされた応答が返ってきたらライブラリコードの中で自動的に TCP 問い合わせをする。これはもっとも簡単だが、また、システムがページングをどのように扱うかによってはメモリをいちばん浪費するかもしれない。この方策を取るには dns.c の中の PACKETSZ65536 に書き換えて qmail を作りなおせばよい。

[訳注] こっちははじめから 512 ではなく 65536 バイト確保しておいて、TCP で問い合わせるのは自前ではなく外部ライブラリにまかせるということで。

5.10.2.3. djbdnsの中の dnscache を動かす

dnscache は名前が示すとおりキャッシュ DNS サーバである。これは大きな DNS 応答をどうやって扱い、必要ない情報をどうやって削るかを知っているので、dnscache が返す応答はふつう直接応答を受ける場合よりかなり小さくなる。これはまた全体として DNS を使うサーバすべての DNS 検索の性能を改善する。qmail へのパッチは必要ないので、受け入れやすい対処であろう。それでも qmail にとって応答が大きすぎることはありうるので、残念ながら完全な修正にはならない。詳しくは関連パッケージdjbdns の節を参照してほしい。

[訳注] これで問題を解決できることもないではないが、むしろ解決できないことの方がふつうで極めて限定的な効果しかない。どうしてもパッチを当ててコンパイルしなおしたくない、という場合ですらこの方法は推奨できない。

5.10.3. qmail-ldap

Andre Oppermann らによるこのパッチは qmail に Lightweight Directory Access Protocol (LDAP) のサポートを実装する。LDAP とはネットワークの電話帳のようなものである。qmail-ldap を使うと POP サーバが数千ものユーザにサービスすることも可能になるはずだ。http://www.nrg4u.com/ 参照。

5.11. QMTP

QMTP (Quick Mail Transfer Protocol) は Dan Bernsterin が設計した SMTP にかわるプロトコルである。プロトコルの定義は http://cr.yp.to/proto/qmtp.txt にある。QMTP は SMTP に似ているが、SMTP より単純で、高速で、互換性がない。qmail には qmail-qmtpd という QMTP サーバ が入っている。これは qmail-smtpd とまさに同じように動く。QMTP はふつうポート 209 を使用する。

qmail には QMTP クライアントが同梱されていないが、serialmail パッケージに入っている。maildirqmtp は maildir メールボックスを受け取って、そこに含まれるメッセージを希望の QMTP サーバに QMTP で配送する。

QMTP は SMTP のお手軽な代替品ではなく、まだインターネットで広く普及しているものでもない。

Russ Nelson のところに qmail-remote で QMTP をサポートするパッチがある。これは http://www.qmail.org/qmail-1.03-qmtpc.patch にある。また、/service に展開するだけで QMTP サービスが可能になる tar 玉も http://www.qmail.org/qmtpd-service.tar.gz にある。

5.12. SMTP セッション中での無効な受信者の拒否

リモートのサーバが qmail-smtpd に接続してメールを送ろうとするとき、qmail-smtpdcontrol/rcpthosts の内容に応じて受信者アドレスをチェックする。@ 記号の後のホストないしはドメインが control/rcpthosts に挙げられているものであれば、qmail-smtpd はメッセージを受け付け、キューに入れ、qmail-send が配送を試みる。もしローカルの受信者が無効 -- そういう名前のユーザやエイリアスがいない -- であれば、qmail-send はバウンスメッセージを生成して SMTP セッション中に指定された返送アドレスに返す。

行儀のよい世界では、どちらの方策もうまくいくだろう。残念ながら、外には行儀のよくない spammer がたくさんいる。あなたのサーバにいる「かもしれない」受信者にメッセージを配送しようとする者もいるだろう -- ありふれた名前や辞書、自動生成された英数文字列のありうるすべての組み合わせのリストを使って。

qmail システムでは、そのような spam 攻撃はシステムにかなりの負荷を与え、ゴミでキューをあふれさせ、有効なメッセージの配送を遅らせることがある。

MTA によっては SMTP セッション中にローカル受信者を検証し、無効であればメッセージの受け取りを拒否するものがある。これにより、サーバは無用な仕事の多くが軽減されるが、マイナスの効果もある。正当性チェックをおこなうことにより、spammer はどのアドレスが有効なのかすぐに見分けられるのだ。

qmail で SMTP セッション中の受信者チェックにはいくつかの実装がある。Eben Pratt は http://netdevice.com/qmail/rcptck/ でそれらの一覧を作成している。その方法のほとんどは有効な、あるいは無効な受信者やパターンのデータベースの保守が必要である。保守が不要なものとしては、Paul Jarc の qmail-realrcptto があり、これは http://code.dogmap.org./qmail/ から入手できる。

[訳注] spammer やワームが送信者アドレスを詐称して存在しないアドレス宛にメールを送り、その結果発生する詐称されたアドレス宛のバウンスのことを backscatter と呼ぶ。backscatter で大きな被害を受けた国内 ISP も、自分が加害者にならないよう、backscatter はできるだけ出さないようにするのが望ましい。しかし上述のように、qmail はローカルユーザが存在するかどうか確認せずにいったんすべて受け取ってしまうので、backscatter の発生源になりやすい。紹介されたようなパッチを使って受信者の有効性は検証しないもののとりあえず backscatter を防ぐには、以下のようにしてどのローカルユーザにもマッチしなかったアドレスをバウンスさせずに捨ててやればよい。
echo '#' > /var/qmail/alias/.qmail-default
.qmail-default については 4.1.5 を、# については G.17 を参照のこと。ただし、このように対処すると、ほんとうに宛先アドレスを入力ミスしただけの場合でもエラーメールが返ってこなくなり、メールが届いていないのに届いていると誤解してしまう事故が発生するおそれがあるので十分に注意すること。

5.13. TLS と STARTTLS

Scott Gifford は qmail で transport layer security (TLS) を使うためのたいへん丁寧で詳しいガイドを書いている。このガイドでは、とくに netqmail において SMTP での STARTTLS と POP3D での STLS に触れている。これは http://www.suspectclass.com/~sgifford/ucspi-tls/ucspi-tls-qmail-howto.html で入手できる。


A. 謝辞

First, thanks to Dan Bernstein for designing and writing such a powerful and elegant system. After nearly ten years of use, qmail still impresses me.

I'd also like to thank the members of the qmail mailing list. Two members deserve special mention. The first is Russ Nelson, one of the most helpful, patient, knowledgeable, and funny contributors. His contributions to the qmail community are second only to DJB's. The second is Charles Cazabon, who's close on Russ' heels. Charles is currently the major contributor to the mailing list, answering more questions correctly than anyone else. Charles has also written a couple of very useful utilities, getmail and pymsgauth, and was technical editor for The qmail Handbook where his contributions were critical to the success of the book, and for which he has received too little reward and recognition.

Thanks also to everyone who reviewed or contributed to this document, including:

Special thanks to Henning Brauer for donating the lifewithqmail.org domain and hosting it!

Special thanks also to Michael M. Kadrie of ATLAS Design Group, http://www.atlasdesigngroup.com, for the nifty new qmail logo!

Life with qmail was written using Simple Document Format (SDF), a very cool Perl-based markup language that generates HTML, plain text, PostScript, POD, and other formats. It made the job much easier. See http://search.cpan.org/author/IANC/sdf-2.001/ for more information.

[訳注] 日本語の翻訳版では上述の SDF は使ってない。テキストエディタでタグを手打ち。

B. 関連パッケージ

B.1. dot-forward

Sendmail はユーザが受け取ったメッセージの配送を制御させるのに .forward ファイル(どっと・ふぉわーどと発音する)を使う。qmail は似たような .qmail という機構を使う。dot-forward パッケージを使うと qmail.forward ファイルを使えるようになる。Sendmail.forward を使う他の MTA で動いているシステムでは、すでにある .forward を同じ意味の .qmail に変換するのを避けるために -- あるいは単純にユーザに見えにくいように qmail に移行するために -- dot-forward の使用を考慮したくなるだろう。

dot-forward は小さなパッケージで、導入も設定も簡単である。ソースは http://cr.yp.to/software/dot-forward-0.71.tar.gz から入手できる。

dot-forward は Dan Bernstein が作成したもので、Web ページは http://cr.yp.to/dot-forward.html にある。

B.2. fastforward

fastforward はもうひとつの Sendmail 互換アドオンである。Sendmail は集中的なエイリアスデータベースをひとつのファイル(ふつうは /etc/aliases)に保持する。qmail はエイリアスごとにひとつのファイルとして /var/qmail/alias にある一連の dot-qmail ファイル群を使用する。もし qmail に移行しようとしていて、Sendmail 形式のエイリアスファイルを変換したくないなら、fastforward を使うことで aliases ファイルをそのまま使えるようになる。

ソースは http://cr.yp.to/software/fastforward-0.51.tar.gz から入手できる。

fastforward は Dan Bernstein が作成したもので、Web ページは http://cr.yp.to/fastforward.html にある。

B.3. ucspi-tcp

qmail の SMTP サーバはスタンドアロンのデーモンとしては動作しない。inetdxinetdtcpserver のようなほ補助プログラムがデーモンとして動く。ポート 25(SMTP ポート)への TCP 接続を受けると、qmail-smtpd のコピーを起動する。

inetd は標準的なネットワークサーバ "super-server" である。qmail-smtpd を動かすには etc/inetd.conf で設定するが、推奨ツールは ucspi-tcp パッケージの一部である tcpserver である。ucspi-tcp とは UNIX Client-Server Program Interface for TCP の略で、うーくすぱい・てぃー・すぃー・ぴー (ooks-pie tee see pee) と発音する。

tcpserver は以下の理由で inetd より好まれる。

[訳注] ひとくちに inetd といってもいろいろな実装があって、たとえば FreeBSD の inetd は全体の同時接続数の上限はもとより、IP アドレスごとの同時接続数や、1分あたりの接続数なども細かく設定できる。tcpserver は全体の同時接続数でしか制限できない(そういう機能を追加するパッチもある)。

ソースは http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz から入手できる。

Gerrit Pape は ucspi-tcp の文書を man ページの形式で http://smarden.org/pape/djb/ で配布している。

[訳注] 同じ人が tcpserver と同じような感覚で扱える ipsvd というプログラムを作成している。これは IP アドレスごとの同時接続数制限を標準で装備している。

ucspi-tcp は Dan Bernstein が作成したもので、Web ページは http://cr.yp.to/ucspi-tcp.html にある。

B.4. daemontools

daemontools パッケージの内容はサービスの制御・監視ユーティリティ一式である。必須ではないが、特にアクセスが多いシステムでは強く推奨される。これには以下のものが含まれる。

daemontools のソースは http://cr.yp.to/daemontools/daemontools-0.76.tar.gz から入手できる。

Gerrit Pape は daemontools の文書を man ページの形式で http://smarden.org/pape/djb/ で配布している。

[訳注] 同じ人が daemontools と同じような感覚で扱える runit というプログラムを作成している。

daemontools は Dan Bernstein が作成したもので、Web ページは http://cr.yp.to/daemontools.html にある。

B.5. qmailanalog

qmailanalogqmail のログファイルを処理して、システムがどれだけどんな種類の仕事をしたのかのレポートを生成する。どれだけのメッセージを送信/受信したか、メッセージのサイズはどれだけか、どれだけの速度で処理したのかといった統計が必要なら、qmailanalog が求めるものだろう。

おまけとして、配送ごとに複数行になる qmail のログを1行にまとめてくれる matchup プログラムがついてくる。-- おなじみ Sendmail のログのように見えなくもない。

qmailanalog のソースは http://cr.yp.to/software/qmailanalog-0.70.tar.gz から入手できる。

qmailanalog は Dan Bernstein が作成したもので、Web ページは http://cr.yp.to/qmailanalog.html にある。

Note: qmailanalog はログエントリのタイムスタンプが accustamp によって使われる小数秒形式(fractional second format) であることを前提にしている。multilog で生成されるログ(TAI64N 形式)でこれを使うには、古い形式にタイムスタンプを変換する必要があるだろう。この変換プログラムは http://www.qmail.org/tai64nfrac から入手できる。
[訳注] タイムスタンプの変換は こういうのもあるけど、古いバージョンの daemontools へのパッチだからやめておいた方がいいかも。

B.6. rblsmtpd

もし一度も spam を受けたことがないのなら、あなたはとんでもなくラッキーだと思っていい。ほとんどの e-mail ユーザはみんな Unsolicited Bulk E-mail (UBE)、いわゆる spam をよく知っているはずだ。ほとんどはエロサイトの宣伝だったり、チェーンメールだったり、その他の詐欺だったりする。昔をふりかえると、だいたい1998年ごろまではインターネット上のほとんどの MTA は オープンリレー だった。すなわち、送信者と受信者のどちらもローカルでなくても、誰からの誰のメールも受けつけていた。spammer は、もし見つかれば、spam を送るのにオープンリレーのホストを使っていた。オープンリレーは spammer の足跡を隠し、「罪のない」中継サイトにバウンスを向け、spammer の CPU 時間とネットワーク帯域を節約した。

このようなオープンリレーは現在ではとても悪い形態とみなされていて、SMTP 接続を受け付けなくて済むように、いくつかの反 spam 自警組織がオープンリレーやその他誰からも使える spam 発信源を見分けるしくみを作るようになった。

rblsmtpd は RBL SMTP デーモンである。tcpserverqmail-smtpd の間に置かれて、このようなリストに挙げられているシステムからの接続を拒否する。

たとえば、rblsmtldtcpserver の下で動かすにはこんなふうにしてみよう。

#!/bin/sh
QMAILDUID=`id -u qmaild`
NOFILESGID=`id -g qmaild`
MAXSMTPD=`cat /var/qmail/control/concurrencyincoming`
exec /usr/local/bin/softlimit -m 2000000 \
  /usr/local/bin/tcpserver -v -R -H -l 0 -x /etc/tcp.smtp.cdb -c "$MAXSMTPD" \
    -u "$QMAILDUID" -g "$NOFILESGID" 0 smtp /usr/local/bin/rblsmtpd\
    -r relays.ordb.org /var/qmail/bin/qmail-smtpd 2>&1

rblsmtpd は以前は独立したユーティリティとして入手できたが、現在は ucspi-tcp といっしょになっている。

rblsmtpd は Dan Bernstein が作成したもので、Web ページは http://cr.yp.to/ucspi-tcp/rblsmtpd.htmlにある。

rblsmtpd のソースに元から埋め込まれているデフォルトの RBL は現在フリーではないため、Charles Cazabon はこれを取り除くパッチを提供している。これは http://pyropus.ca/software/misc/rblsmtpd-nodefaultrbl.patch から入手できる。

B.7. serialmail

qmail は高速回線に常時つながっているシステム向けに設計されている。serialmail は低速で間欠接続でも qmail がうまく動くようにするツール群である。このようなシステム上の serialmail では、qmail は外部宛てメールをすべてひとつの maildir に配送するよう設定される。接続が確立されたら、ISP のメールサーバにその maildir をアップロードするために serialmailmaildirsmtp コマンドを使う。もし ISP が QMTP(進んだ話題QMTP の節を参照)をサポートしていたら maildirqmtp を使うこともできる。

serialmailAutoTURN を実行するため、接続している ISP の側で使うこともできる。クライアントからの SMTP 接続があると、サーバにたまっているそのクライアント向けのメッセージを送るために、サーバの方からクライアントに接続しなおす。これは SMTP の機能のうちの ETRN に似ている。

serialmail のソースは http://cr.yp.to/software/serialmail-0.75.tar.gz から入手できる。

serialmail は Dan Bernstein が作成したもので、Web ページは http://cr.yp.to/serialmail.html にある。

B.8. mess822

mess822 はRFC822 準拠のメールメッセージを解析するライブラリとアプリケーション群である。アプリケーションには以下のものがある。

mess822 のソースは http://cr.yp.to/software/mess822-0.58.tar.gz から入手できる。

mess822 は Dan Bernstein が作成したもので、Web ページは http://cr.yp.to/mess822.html にある。

B.9. ezmlm

ezmlm は qmail 用の高性能で簡単に使えるメーリングリストマネージャ (MLM) である。LISTSERVMajordomo をよく知っていれば、メーリングリストマネージャが何をするものなのかもわかっているだろう。qmail でのメーリングリストについてのさらなる情報は進んだ話題 の章のメーリングリストマネージャの節を参照してほしい。

ezmlm のソースは http://cr.yp.to/software/ezmlm-0.53.tar.gz から入手できる。

ezmlm は Dan Bernstein が作成したもので、Web ページは http://cr.yp.to/ezmlm.html にある。

Fred Lindberg と Fred B. Ringel ezmlm-idx という ezmlm への拡張を開発した。たくさんの便利な機能が追加されており、とてもお勧めできる。今は保守が Bruce Guenter に引き継がれており、http://www.ezmlm.org/ から入手できる。

B.10. safecat

safecat は maildir メールボックスにファイルを安全に書き込む。とくに procmail のレシピでメッセージをファイルに書き出すのに便利だ。たとえば、次のレシピはすべてのメッセージを Maildir に書き込む。

:0w
|safecat Maildir/tmp Maildir/new

safecat は Len Budney が作成したもので、Web ページは http://jeenyus.net/~budney/linux/software/safecat.html にある。

[訳注] 最近の procmail は自前で maildir をサポートしているので不要。mbox や mh などのメールボックスを変換するときには使えるかも。

B.11. djbdns

djbdnsqmail の作者が書いた DNS サーバである。DNS コンテンツサーバの tinydns とキャッシュ DNS サーバの dnscache からなる。

djbdns の公式 Web ページは http://cr.yp.to/djbdns.html である。

B.12. maildrop

maildropprocmail に似たメールフィルタである。

maildrop が Sam Varshavchik が作成したもので、Web ページは http://www.courier-mta.org/maildrop/ にある。

B.13. syncdir

syncdirlink() システムコールを同期書き込みさせる小さなライブラリである。これは Linux の ext2fs や ReiserFS、SGI の XFS、softupdate が有効になっている BSD FFS のような、link() が非同期に実行されるファイルシステムに qmail のキューを置いて使っているときに必要である。

syncdir は Bruce Guenter が作成したもので、http://untroubled.org/syncdir/ から入手できる。インストール手順は http://www.ornl.gov/lists/mailing-lists/qmail/2001/12/msg00949.html にある。


C. インターネットのメールのしくみ

C.1. A 地点から B 地点にメッセージはどのように届くか

あるホストにいるユーザが別ホストにいるユーザにメッセージを送るとき、意識していないだろうけれど、舞台裏ではさまざまなことが起きている。

アリス (alice@alpha.example.com) がボブ (bob@beta.example.com) にメッセージを送る場合のことを考えてみよう。次のようなことが起きているのだ。

1. アリスが muttpine といったようなメーラー (mail user agent; MUA) を使ってメッセージを作成する。To フィールドに宛先を、Subject フィールドにメッセージの件名を、そしてメッセージの文章自体を書く。こんな感じになるだろう。

To: bob@beta
Subject: 昼ごはん

ピザでどう?

2. メッセージがこれでよければ、MUA でそれを送る。

3. このとき、MUA は DateMessage-Id のようなヘッダフィールドをさらに追加したり、アリスが入力した値を書き換えたり(たとえば bob@beta を "Bob <bob@beta.example.com>" に置換したり)することがある。。次に、MUA はメールシステムにメッセージを投入(inject)する。これにはふたつの方法がある。ひとつはメールシステム側で用意しているメッセージ投入のための専用プログラムを使う方法、もうひとつはローカルないしはリモートの Simple Mail Transfer Protocol (SMTP) のポートに接続する方法である。たとえば、MUA が MTA にメッセージを渡すのに ローカルの投入プログラムを使うとしよう。投入する過程の細かい部分は MTA によりさまざまだが、UNIX システムでは sendmail を使うのが事実上の標準である。この方法では、MUA はヘッダとボディを空行で分割してファイルに書いて、それを sendmail プログラムに渡すことができる。

[訳注] inject という言葉は qmail 以外ではほとんど使われない。ふつうは submit という。

4. 投入が成功すれば -- メッセージが文法的に正しく、sendmail が適切に起動されれば --、そこからメッセージは MTA の管轄になる。MTA によってその詳細は大きく異なるが、一般的には alpha の MTA はメッセージをどこに送るかを決めるためヘッダを調べ、beta に SMTP で接続し、beta の MTA にメッセージを転送する。SMTP のやりとりでメッセージを送るにはふたつの部分が必要とされる。すなわち、受信者アドレス (bob@beta.example.com) と返送先アドレス (alice@alpha.example.com) を示すエンベロープと、ヘッダと本文 (body) からなるメッセージ自体である。

[訳注] ヘッダを調べるというのは間違い。SMTP では受信者アドレスはヘッダではなくエンベロープで決まるし、sendmail プログラムを使う場合はコマンドライン引数で指定する。-t という引数を与えて sendmail を起動した場合はヘッダを見るが、それがおこなわれるのはメッセージの投入前、つまりここではなく、前項 3. の時点である。

5. もし beta の MTA がメッセージを拒否したとしたら、たぶん bob がそのユーザにいないせいだろう。alpha の MTA は問題が起きたことを通知するため、バウンスを返送先アドレスである alice@alpha に送る。

6. beta の MTA がメッセージを受け取ったら、beta へのローカル宛なのか、あるいは外部のシステムにいるのかを決定するため、受信者のアドレスを見る。この場合はローカル宛なので、MTA はメッセージを自分自身で配送するか、あるいは /bin/mailprocmail のような mail delivery agent にわたす。

7. 配送が失敗したとしたら、たぶんボブのメール容量が制限を越えていたせいだろう。beta の MTA はエンベロープの返送先アドレス (alice@alpha) にバウンスメッセージを送る。

8. 配送が成功すれば、メッセージはボブのメールボックスの中で MUA が読み出して表示するのを待つことになる。

C.2. さらなる情報

インターネットのメールのしくみについての情報は以下のようなところを参照されたい。

[訳注] それぞれの邦訳は、順に 1 2 3

C.2.1. インターネット RFC

Internet Requests for Comment (RFC) はインターネットの公式文書である。これらのほとんどは注釈の段階をとおりこして TCP や FTP、Telnet、そしてさまざまなメールの標準や手順のようなインターネットプロトコルを定義している。

メール関連の RFC の包括的なリストは Internet Mail Consortium http://www.imc.org/mail-standards.html から入手できる。

[訳注] RFC974 は RFC2821 で obsolete されている。ほかにもあるかも。

D. 構造

D.1. 機能分割システム構造

インターネット MTA はさまざまな仕事をおこなう。Sendmailsmail のように初期に設計されたものは一枚岩 (monolithic) だった。言い替えると、ひとつの大きくて複雑な「帽子をとっかえひっかえする」プログラムだった。SMTP サーバになる帽子がひとつ、SMTP クライアントに別の帽子、メッセージをローカルで送信するのに別の帽子、キューを管理するのにまた別の帽子、などといった具合で。

qmail機能分割されている。 これらの機能のそれぞれが別々のプログラムで実行される。結果として、プログラムはずっと小さく単純になり、機能やセキュリティに関するバグはほとんどなくなるだろう。セキュリティをさらに強化するため、qmail のモジュールは異なる権限で動作し、お互いを「信用」しない。ほかのモジュールがいつも思ったとおりのことだけをしてくれるという仮定をしない。

核となるモジュールは以下のとおりである。

モジュール 機能
qmail-smtpd SMTP でメッセージを受信/拒否する
qmail-inject ローカルでメッセージを送信する
qmail-rspawn/qmail-remote 外部配送を扱う
qmail-lspawn/qmail-local 内部配送を扱う
qmail-send キューを処理する
qmail-clean キューを掃除する

機能を分割するという手法には欠点もある。一枚岩の MTA と違って、モジュール間の相互作用がはっきりしていて、モジュール相互で必要最低限の情報しかやりとりしない。一般的にこれは長所であるが、このために実現が困難なこともある。たとえば、sendmail の "-v" フラグはデバッグ用に Sendmail の動作トレースを標準出力に表示する。ひとつの sendmail のバイナリがローカル送信やキューイング、エイリアス処理、.forward ファイル処理、SMTP での外部配送を受け持つので、メッセージが配送されるまでのすべてをかんたんに追跡できるのだ。qmail には同じような能力はなく、もしやるとすればモジュールからモジュールに「デバッグ」フラグの受け渡しを実装するのにかなりの量のコード修正と複雑なものの追加が必要になるだろう。

[訳注] 先日やっとαテストがはじまった次世代 Sendmail X では一枚岩構造を捨ててモジュール構造になっている。ぱっと見た感じでは qmail より Postfix の構造に近いかな。

D.2. ファイル構造

/var/qmailqmail のファイル構造のルートになる。これは qmail をビルドするときに変更できるが、どこにあるか他の管理者でもわかるように、そのままにしておくのがいい。もしほんとうに qmail ツリーの一部ないしは全部を別の場所に置きたいのなら、シンボリックリンクを張った方がいいだろう。詳しくは導入の章のディレクトリの作成の節を参照してほしい。

ルート直下のサブディレクトリは以下のとおりである。

ディレクトリ 内容
alias システム全体のエイリアス用の .qmail ファイル
bin プログラムのバイナリとスクリプト
boot 起動スクリプト
control 設定ファイル
doc 文書 (man ページ除く)
man man ページ
queue 未送信メッセージのキュー
users qmail-users のデータベースファイル

D.3. キュー構造

キューイングの詳細についての議論はビルドしたディレクトリにある INTERNALS というファイルにすべて書かれている。以下はもっとおおざっぱなキュー構造の概要である。

サブディレクトリ 内容
bounce 恒久的配送エラー
info* エンベロープ送信者アドレス
intd qmail-queue が作業中のエンベロープ
local* エンベロープ受信者アドレス(ローカル)
lock ロックファイル
mess* メッセージファイル
pid i-node 番号を取得するために qmail-queue が使用
remote* エンベロープ受信者アドレス(リモート)
todo 完全なエンベロープ
Note: "*" つきのディレクトリはさらに 0 から conf-split-1 までの名前の分割したサブディレクトリを含んでいる。ここで、conf-split はコンパイル時の設定で、ビルドするディレクトリにある conf-split というファイルに書かれている。デフォルトは 23 である。ディレクトリを分割する目的は、非常に流量の多いサーバでひとつのディレクトリのファイルの数を減らすことである。conf-split は素数でなければならない。
[訳注] 参考: Why conf-split prime?

mess サブディレクトリにあるファイルは i-node 番号がファイル名となる。これが意味するのは、mvdump/restoretar といった標準的な UNIX ユーティリティを使って手で移動することは不可能であるということである。キューファイル名を正しくリネームする、ユーザによって作成されたユーティリティが http://www.qmail.org/ にいくつか存在する。

Note: qmail の動作中にキューファイルを修正するのは安全ではない。もしキューを修正したいなら、まず qmail を停止し、注意してキューをいじって、それからqmail を再起動する。

D.4. 図版

/var/qmail/doc には PIC という名前ではじまるファイル名のファイル群がある。これらはテキストで書かれた qmail が扱うさまざまな状況の「図」である。さまざまなモジュールを通過する制御の流れを示していて、デバッグや複雑な設定を作るときの助けになる。

ファイル名 概要
PIC.local2alias ローカルのエイリアスに配送されるローカルから送信されたメッセージ
PIC.local2ext 拡張アドレスに配送されるローカルから送信されたメッセージ
PIC.local2local ローカルユーザに配送されるローカルから送信されたメッセージ
PIC.local2rem リモートに配送されるローカルから送信されたメッセージ
PIC.local2virt ローカルのバーチャルドメインに配送されるローカルから送信されたメッセージ
PIC.nullclient ヌルクライアント上で送信されたメッセージ
PIC.relaybad ローカルホストに中継させる試み(失敗する場合)
PIC.relaygood ローカルホストに中継させる試み(成功する場合)
PIC.rem2local ローカルユーザ宛に SMTP で送信されたメッセージ

これらのファイルはオンラインでも以下から見ることができる。

ほんとqmail の図版がよければ、Andre Opperman の http://www.nrg4u.com/ にある "big qmail picture" を見てみよう。


E. たまにある質問とその答

これらはよくある質問というわけではないけれど、重要かつ回答が難しい質問である。

E.1. 遅延メッセージはどれぐらいの頻度で再送されるのか?

メッセージの再送はそれぞれ1通ごとにスケジュールされる。メッセージが配送できないまま長く残っているほど、qmail の再送頻度は小さくなっていく。再送スケジュールは設定で変更できない。下表に配送できないメッセージをバウンスするまでに再送試行するスケジュールを示す。ローカル宛メッセージは似ているがもっと頻度が高くスケジュールされる。

[訳注] 以下の表は最初の配送試行をした時刻からの経過秒である。前回試行時からの再送間隔ではない。再送間隔は400秒、1200秒、2000秒…と、800秒ずつ長くなっていく。また、ローカル宛の再送は100秒、400秒、900秒…(間隔は100秒、300秒、500秒…)となる。これは設定では変更できず、qmail-send.c の chanskip[] を修正してコンパイルしなおす必要がある。
配送試行 日-時:分:秒
1 0 0-00:00:00
2 400 0-00:06:40
3 1600 0-00:26:40
4 3600 0-01:00:00
5 6400 0-01:46:40
6 10000 0-02:46:40
7 14400 0-04:00:00
8 19600 0-05:26:40
9 25600 0-07:06:40
10 32400 0-09:00:00
11 40000 0-11:06:40
12 48400 0-13:26:40
13 57600 0-16:00:00
14 67600 0-18:46:40
15 78400 0-21:46:40
16 90000 1-01:00:00
17 102400 1-04:26:40
18 115600 1-08:06:40
19 129600 1-12:00:00
20 144400 1-16:06:40
21 160000 1-20:26:40
22 176400 2-01:00:00
23 193600 2-05:46:40
24 211600 2-10:46:40
25 230400 2-16:00:00
26 250000 2-21:26:40
27 270400 3-03:06:40
28 291600 3-09:00:00
29 313600 3-15:06:40
30 336400 3-21:26:40
31 360000 4-04:00:00
32 384400 4-10:46:40
33 409600 4-17:46:40
34 435600 5-01:00:00
35 462400 5-08:26:40
36 490000 5-16:06:40
37 518400 6-00:00:00
38 547600 6-08:06:40
39 577600 6-16:26:40
40 608400 7-01:00:00

E.2. 多数の MX を持つ大きなサイトに送れないのはなぜか?

もし以下のようなログが出ていれば

deferral: CNAME_lookup_failed_temporarily._(#4.4.3)/

qmail がネームサーバへの問い合わせに対する大きな応答を扱えないのが問題だろう。パッチを当てたり回避策を実施することで修正できる。進んだ話題の章のパッチの節を参照のこと。

なぜこのようなトラブルにならない人もいるのかという疑問もまた出てくる。基本的にはローカルのネームサーバへの問い合わせのタイミングと順番に依存するので、"aol.com" への ANY の問い合わせへの応答のサイズが UDP パケットの 512 バイト制限より大きくなることがあるかもしれないし、小さくなるかもしれない。

A と MX レコードがタイムアウトして NS レコードがタイムアウトしなければサイズは「小さく」なりそうだ。.COM のサーバは TTL が2日になっているが、AOL では1時間になっているので、あまり問い合わせの多くないネームサーバではしばしば 512 バイトより小さくなるだろう。問い合わせの多いネームサーバではこのようなレコードがいつでもキャッシュに入ってる可能性がより高いので、パッチを当ててない qmail が CNAME を調べようとして失敗する。

nosuchuser@large-mx.ckdhr.com にメールを送ってみるとよい試験になるだろう。もしキューが掃けて ckdhr.com からバウンスされてきたら、その MTA は 512 バイトを越える MX のリストを持つホストにメールを送ることができる。(単一の RRset、単一の TTL で、512 バイトを越えるものを使うことで、他の問い合わせのタイムアウトと順番に依存せずに問題を見ることができる)

[訳注] 2005年4月時点では large-mx.ckdhr.com は存在していないようだ。送ろうとすると、ckdhr.com ではなく、送信に使った手元の MTA からバウンスが返ってくるだろう。
[訳注] ここで例に挙げられている aol.com のような大きな DNS 応答を返してくる場合だけでなく、外部配送されるべきすべての宛先で CNAME_lookup_failed_temporarily になるのであれば、単純に /etc/resolv.conf の設定が間違っている可能性が高い。
[訳注] 配送先ドメインが DNSSEC に対応している場合、ANY への応答には DNSSEC の署名データも追加されるため、(キャッシュサーバが DNSSEC に対応していなくても)ほぼ確実にこのエラーにひっかかって配送に失敗する。また、DNSSEC に対応していなくても、SPF のために大きな TXT レコードが設定されるケースが増えており、この場合も ANY への応答サイズが大きくなりがちである。これで配送が失敗するのは、文中にもあるとおり qmail が CNAME を調べるのに CNAME ではなく ANY で問い合わせるせいであり、また大きな応答を扱えない qmail の問題である。DNS の問題ではない。

E.3. QUEUE_EXTRA とは何か?

QUEUE_EXTRA はコンパイル時の設定変数であり、どんな配送にも追加される受信者を指定する。これは主にロギングに使われる。たとえば、FAQ では受信、送信するすべてのメッセージのコピーを保存するのに QUEUE_EXTRA を使う方法について述べている。

QUEUE_EXTRA を使うには、extra.h を編集して、追加受信者を "Trecipient\0" の形式で指定し、また QUEUE_EXTRA の長さ("\0" も1文字と数える)を QUEUE_EXTRALEN に指定する。例:

#define QUEUE_EXTRA "Tlog\0"
#define QUEUE_EXTRALEN 5

qmail が動いていたら止める。導入の章で qmailctl スクリプトを入れていれば以下を実行。

qmailctl stop

qmailctl を使っていなければ、自分の起動/停止スクリプトで qmail-sendTERM シグナルを送る。

その後 qmail を再構築する。

make setup check

ログ取得したいものを ~alias/.qmail-log に書く。たとえば、Message-ID のログを取るなら、

| awk '/^$/ { exit } /^[mM][eE][sS][sS][aA][gG][eE]-/ { print }'

とする。最後に、qmail を再起動する

[訳注] ここで指定した recipient が何らかの理由でエラーになってメールを受けられない場合、送信元にバウンスが返ってしまうので注意すること(確認はしてないけどそうなるはず)。

F. エラーメッセージ

qmail のエラーメッセージとその意味。

括弧でくくられたエラーコードの説明については RFC 1893 を参照のこと。

この付録は未完である。

[訳注] 括弧のエラーコードというのは、qmail-send のログのたとえば
Sorry,_I_wasn't_able_to_establish_an_SMTP_connection._(#4.4.1)
という出力の 4.4.1 のこと。

G. Gotchas

これらの "gotchas" は qmail 初心者でよく起きる問題である。

G.1. qmail がスーパーユーザにメールを配送しない

特権ユーザとして qmail-local がコマンドを実行する可能性を防ぐため、UID が 0 のユーザすべてを無視する。これは qmail-getpw の man ページに記載されている。

これは qmailroot に配送しないという意味ではない。このような配送が非特権ユーザによって扱われなければならないというだけである。典型的には、 ~alias/.qmail-root を登録してやって root に対するエイリアスを作成してやればよい。

G.2. qmail がホームディレクトリの所有者が自分でないユーザにメールを配送しない

もうひとつのセキュリティ上の特徴であり、一般的なよい慣習である。これは qmail-getpw の man ページに記述されている。

G.3. qmail が名前に大文字を含むユーザにメールを配送しない

qmail は「ローカルパート」(アドレスの "@" より左全部)の全体を小文字に変換する。man ページには出てこないが、コードはそうなっている。大文字のユーザを無視するということについては qmail-getpw の man ページに記載がある。

G.4. qmail が拡張アドレスのピリオド(.)をコロン(:)に置換する

別のセキュリティ上の特徴である。拡張アドレスが ".." を使ってファイルツリーをさかのぼるのを防ぐのが目的である。コロンに置き替えることで、qmail はユーザのすべての .qmail ファイルがホームディレクトリにあることを保証する。dot-qmail の man ページに記述されている。

G.5. qmail が拡張アドレスの大文字を小文字に変換する

qmail がアドレスのローカルパート全体を小文字にするという事実のもうひとつの結果である。dot-qmail の man ページに記載がある。

G.6. qmail/etc/hosts を使わない

qmail はホスト名に関連づけられた IP アドレスを決定するのに /etc/hostsけっして使わない。制御ファイルに名前を使ったら、qmail はネームサーバにアクセスできなければならない。

だがネームサーバへの到達性がないシステムで qmail を動かすことできる。制御ファイルにあるホストは角括弧([])で括って IP アドレスを指定することができる。例:

[10.1.2.219]

実際には角括弧はいつも必要なわけではない。しかしなんにせよそうしておくのはいい考えだ。

G.7. qmail が SMTP の活動をログに記録しない

いくつもの理由により、qmail は SMTP の接続、拒否、不正なコマンド、正当なコマンドのログを取らない。tcpserver が接続ログを取得するのに使われ、recordio が SMTP のやりとり全体を記録するのに使われる。recordioucspi-tcp パッケージに含まれている。手順は http://cr.yp.to/qmail/faq/servers.html#recordio の FAQ で述べられている。

[訳注] recordio をそのまま使うとほんとに SMTP のやりとりぜんぶが記録されてしまうので、あっというまにログが大量になってたいへんなことになる。そこで、recordio の出力からさらに必要なものだけを multilog で選択する。具体的な方法は qmail.org の tips滝澤さんの daemontools HOW-TO を参照のこと。同様の方法で qmail-pop3d のログも記録できる。ただしこの方法は完全ではない。前者 qmail.org の例をそのまま使うと、5xx のエラーを記録できるようになるが、誰が誰に送ろうとしたのかという根本的な情報を記録できない。後者の滝澤さんの例をそのまま使うと、クライアントが MAIL などの SMTP コマンドを Mail のように小文字混じりで送ってきた場合にログが欠落する。また、SMTP コマンドではなくメール本文中に出現した MAIL という文字列も記録してしまって、後からログを調べるときに誤認してしまう恐れがある。MAIL ではなく Mail も記録できるように修正すると、本文中の Mail も拾って嘘ログを記録してしまう可能性も高まる。
さらに、訳者が recordio を使ってログを取っていたサーバでは
     UID   PID  PPID  C    STIME TTY      TIME CMD
  qmaild 18647     1  0   Feb 06 ?        0:00 recordio qmail-smtpd
  qmaild 18789     1  0   Nov 16 ?        0:00 recordio qmail-smtpd
  qmaild 17302     1  0   Apr 08 ?        0:00 recordio qmail-smtpd
  qmaild  7126     1  0   Mar 15 ?        0:00 recordio qmail-smtpd
  qmaild  7981     1  0   Apr 05 ?        0:00 recordio qmail-smtpd
のように、qmail-smtpd が終了しているのに recordio がずっと終了せず、親も tcpserver ではなく init(PPID が 1)になって数ヶ月も浮いたままになる現象が発生していた(Solaris8 の複数のサーバで再現性あり。Solaris 以外で発生するかどうかは不明)。原因は不明。

G.8. qmail が遅延通知をしない

Sendmail はメッセージを数時間(通常は4時間)送信できなければ送信元に遅延通知を送る。この通知はバウンスメッセージのようにも見えるが、恒久的失敗で配送できなかったことを示すものではない。

qmail はこのような警告を送らない。queuelifetime 以上の期間キューに滞留した後で、配送できなかったメッセージは送信者に戻される。

G.9. /var/qmail/queue/lock/trigger がない/権限がおかしい/通常ファイルのとき qmail が遅い

qmail-queueqmail-send/var/qmail/queue/lock/trigger という名前つきパイプで通信する。このパイプがおかしくなっていると、qmail-send は30分かそこら新しいメッセージを通知しない。

正しくセットアップされていることを確実にするにはソースディレクトリから "make check" を実行するのがいちばんよい方法である。もしできなければ、以下のようになっていることを確認しよう。

# ls -l /var/qmail/queue/lock/trigger
prw--w--w-   1 qmails   qmail           0 Jul  5 21:25 /var/qmail/queue/lock/trigger

特に行頭の "p"(名前つきパイプをあらわす)、モード(誰からも書き込めること)、そしてオーナーとグループに注意が必要である。

[訳注] 手で直すには以下を実行。作りなおした後は qmail-send の再起動が必要(HUP や ALRM を送ってもダメ)。
rm -f /var/qmail/queue/lock/trigger
mkfifo -m 622 /var/qmail/queue/lock/trigger
chown qmails:qmail /var/qmail/queue/lock/trigger

G.10. DNS や IDENT の問い合わせで SMTP が遅くなる

qmail-smtpd が接続への応答が遅いのなら、問題はおそらく DNS 逆引きか IDENT の問い合わせのせいである。qmail-smtpdtcpserver で使っているのなら、引数から "-h"、"-p"、"-r" を削り、"-H"、"-P"、"-R"、さらに "-l ホスト名" を加えるとよい。

これらの引数についての説明は http://cr.yp.to/ucspi-tcp/tcpserver.htmltcpserver のドキュメントを参照せよ。

[訳注] 接続制御データベースは IP アドレスだけでなく、ホスト名での制御も可能だが、"-h" と "-p" のいずれかが指定されていないと無効になる。

G.11. 復帰改行 (CRLF) がおかしい

qmail-inject および sendmail のようなローカルからの送信機構はメッセージの改行コードが DOS 形式の復帰改行(CRLF)だとうまく動かない。Sendmail とは異なり、qmail はローカルから送信されるメッセージには UNIX の改行(LF のみ)である必要がある。これは PHP スクリプトでよく問題になる。

[訳注] qmail-inject は LF でないとうまく動かないが、qmail-smtpd は LF だけのものは受け取らず、CRLF にする必要がある。

G.12. ログが詰まると qmail-sendtcpserver が止まる

もしログを2章で説明したように supervise で記録していて、ディスク溢れ、run スクリプトの間違い、ログディレクトリの設定エラーなどの何らかの理由でログサービスが機能しなくなると、そのうちパイプラインがいっぱいになってサービスがブロックされたりハングしたりすることになる。問題を修正すれば(トラブルシューティングを参照)、すべて通常に戻るだろう。

G.13. qmail-smtpd がアドレスのローカル部の有効性を検証しない

example.comcontrol/rcpthosts にリストされていれば、SMTP セッション中では anything@example.com 宛のメールが受け付けられてしまう。 anything が有効なユーザやエイリアスでなかったら、qmail はエンベロープ送信者にバウンスを送る。

頭の悪い中継テストにはメッセージが受け付けられ、配送されるかのように見なされるものがある。これは正しくない。もし誰かからオープンリレーだと言われたら、中継されたメッセージの写し(ヘッダ、特に Received フィールドを含むもの)を見せるよう要求し、それからログと見比べなさい。

qmail で受信者チェックをおこなう方法についての情報は SMTP セッション中での無効な受信者の拒否の節を参照のこと。

G.14. ファイアウォールが SMTP/POP3/IMAP サーバへのリモートアクセスをブロックする

SMTP、POP3、IMAP サーバを導入してローカルホストまたはローカルネットワーク上のホストからは接続できるのに、外部のホストからは接続できないという場合、おそらくファイアウォールが問題だろう。

最初にサーバ自身を調べる。たとえば RedHat Linux はデフォルト設定では iptables で SMTP をブロックするようになっている。ipchains のような他のパケットフィルタも原因かもしれない。

また、spam を防止したり、利用規約 (Terms of Service; TOS) を強制するために自分のプロバイダ(ISP) が 特定のポートをふさいでいることもありうる。パケットフィルタの責任ではなく、また、TOS に違反しないことを確認したで ISP の技術サポートに問い合わせてみよう。

[訳注] 2005年に入ってから WAKWAK やらぷららやらが Outbound SMTP block を始めてますな(後者は現在のところ携帯事業者への接続だけなので本項とは関係ないけど)。

G.15. USERLOGNAME がセットされていないと qmail-injectFrom フィールドを anonymous にする

qmail-inject で送信されたメッセージに From フィールドがないと、qmail-inject はどのユーザがメッセージを送っているのか環境変数を調べる。調べる環境変数は、順番に QMAILUSERMAILUSERUSERLOGNAME である。

通常ユーザのログインセッションでは USERLOGNAME の片方ないしは両方がセットされるが、cron などによって起動されるバッチ処理ではどちらもセットされないだろう。

cron ジョブに正しい From フィールドをつけさせるには、メールを送る前にこれらの環境変数のひとつをセットしてやればよい。

[訳注] cron にもいろいろ実装があるが、FreeBSD や多くの Linux で使われているいわゆる vixie-cron や、Solaris で使われている cron などでは、とくに何もしなくてもちゃんと LOGNAME を設定してくれる(man に明記されている)のでこのようなことは起きないはず。

G.16. qmail-send を kill してもただちに終了しないことがある

qmail-sendTERM シグナルを送っても、配送処理が途中のものがあればただちには終了しない。qmail-send は配送結果を記録するために qmail-localqmail-remote のプロセスがすべて終了するまで待つ。このため、"qmailctl restart" や "qmailctl stop" は qmail-send がまだ動いていても止まったと報告することがあるかもしれない。実際に停止や再起動が完了したかどうかは "qmailctl stat" を実行すればいつでも確認できる。

また、qmail-send は終了前にキューを通過させるので、とても大きなキューで顕著な遅れが発生することがある。

G.17. /dev/null に配送してもメッセージを捨てられない

以下のような配送指示

/dev/null

を設定すると、qmail/dev/null が mbox 形式のメールボックスだとみなすが、/dev/null は特別なファイルなので qmail はこれにうまく配送することができない。

メッセージを捨てるには、有効な配送指示がひとつも含まれていない空でない .qmail ファイルを作成するのがもっともよい(空の .qmail ファイルは defaultdelivery または qmail-start のコマンドラインで指定されたデフォルトの配送指示が含まれるものとして扱われる)。これはコメント以外何もないファイルを作ることで実現する。

たとえば、

#

または、

# throw messages away undelivered

という内容だけを含む .qmail はどこにも配送せずに効率的にメッセージを捨てられる。

G.18. qmail-send の動作中にキューを修正するのは危険

自分が何をしようとしているのか正確な知識を持たずに、qmail-send の動作中に /var/qmail/queue の下にあるファイル、ディレクトリを修正すると、キューを壊す結果になる。-- 例えば、未定義の状態にあるメッセージ、ログ上の奇怪なエラーメッセージ、二重配送、偽のバウンスなど。いったんこうなってしまうと、キューをチェックするユーティリティ(qmail.org にいくつか挙げられている)を探してきて実行するか、あるいは新しい空のキューを作らなければならないだろう。

もしキューを修正したいのならば、まず qmail を停止し、注意してキューをいじってから、qmail を再起動する。なお、qmail-send が停止していてもキューが壊れることはありうるので、自分がやろうとしていることを理解していなければならないことは同じである。

[訳注] 動作中にキューをいじってはいけない、停止後でも注意が必要、というのは qmail に限らずどんな MTA でも同じことである。キューを安全に操作できるよう注意深く書かれたツールが提供されていることもあるが、そういうものを使わずにキューを直接いじるのは、その MTA についてよほど深く理解しているのでなければ厳禁である。

H. Life with qmail に関するよくある質問と答

[訳注] 本章では Life with qmail および LWQ は英語オリジナル版を指すものとする。この日本語翻訳版を指すときは qmail のある暮らし、あるいは単に邦訳と表記する。

H.1. Life with qmail のバージョンは?

これは LWQ バージョン 2006-01-02 である。

[訳注] 邦訳は上記オリジナル英語版をもとにした日本語 2006-02-25 版。

Life with qmail is Copyright 1999-2006 David E. Sill

http://Web.InfoAve.Net/~dsill/dave/

[訳注] qmail のある暮らしの翻訳や訳注部分に関する著作権はやまぐちたかのりが有してるらしい。

H.3. Life with qmail のライセンスは?

Life with qmail is covered by the OpenContent License, version 1.0. See http://www.opencontent.org/opl.shtml for the full license. Basically, you can copy, redistribute, or modify Life with qmail provided that modified versions, if redistributed, are also covered by the OpenContent License.

Life with qmail は OpenContent License バージョン 1.0 が適用される。ライセンスの全文は http://www.opencontent.org/opl.shtml を参照のこと。基本的に、もし再配布するのならば、改変された版にも OpenContent License が適用されることを規定してあれば Life with qmail を複製、頒布、改変することが可能である。

[訳注] というわけで、邦訳も同じく OpenContent License 1.0 に従う。OpenContent License の日本語参考訳(あくまで参考)

H.4. LWQ の新版リリースはどうやって知ればいいの?

lwq-announce メーリングリストに参加しよう。lwq-announce-subscribe@sws1.ctd.ornl.gov にメッセージを送ることで加入できる。

[訳注] 邦訳はいちいちそんなアナウンスはしない。てきとーに Web をチェックしといてくだされ。というか、気まぐれに翻訳しただけなので、邦訳がオリジナルの新版に追従するかどうかもわからん。

H.5. LWQ に貢献した人やファンはどこで話してるの?

lwq メーリングリストに参加しよう。lwq-subscribe@sws1.ctd.ornl.gov にメッセージを送ることで加入できる。

[訳注] 邦訳の訳者は参加していない。

H.6. Life with qmailXXX 語への翻訳ってある?

もしかしたら。LWQ はいくつかの言語に翻訳されている。LWQ の翻訳については詳しくは http://lifewithqmail.org/trans.html を参照。

[訳注] で、まあ、これがその翻訳版のひとつというわけだ。知ってると思うけど。

H.7. HTML 以外に Life with qmail の PostScript や PDF やべたテキストやその他の形式はあるの?

ある。別の形式のものは http://lifewithqmail.org/ から入手できる。

[訳注] 邦訳は HTML のみ。

H.8. Life with qmail を使ったらシステムがぶっこわれた/ディスクがトンだ/我が愛しき暮らしがメチャクチャになった/犬が死んだ/とかなんとか

ごめん。ほんとごめん。でも Life with qmail は無保証なんだ。上述の OpenContent License を見てくだされ。筆者はこれを書いて対価をもらってない。qmail のコミュニティに何が役に立つ貢献がしたかっただけなんだ。

実際にはこれは FAQ ではない。それどころか、NAQ(ぜったいにない質問と答)であることを望む。

[訳注] もちろん邦訳も無保証である。ちなみに訳者はコミュニティへの貢献なんてことはちっとも考えてなかったりする。だって、qmail は好きじゃないもの:-)

H.9. どうしたら LWQ に貢献できる?

訂正、提案、苦情その他は lwq@sill.org に送ってほしい。

もっと大きなもの、たとえば新しい節とか付録とかを寄稿したいというのなら、そりゃすごい! その話題が LWQ に収録したいものか、他に誰もまだ取り組んでいないか確かめるためにまず相談してほしい。

LWQ を支援する別の方法は、筆者のアマゾンアソシエイトのリンク http://www.amazon.com/exec/obidos/redirect-home/davesill から買い物してくれることだ。

応援ありがとう!

[訳注] 邦訳に関する誤訳の指摘や要望苦情、訳者への歳暮に中元、ラブレター、呪いその他は y@maya.st まで。

H.10. LWQ のこの版の変更点は?

[訳注] この版で最大の変更はライセンスに関する記述。なぜ上記リストから抜けているのかは謎。

H.10.1. LWQ 2006-01-02 版の変更点は?

H.10.2. LWQ 2004-06-30 版の変更点は?

H.10.3. LWQ 2004-03-28 版の変更点は?

H.10.4. LWQ 2004-03-01 版の変更点は?

H.10.5. LWQ 2004-01-26 版の変更点は?

H.10.6. LWQ 2003-11-10 版の変更点は?

H.10.7. LWQ 2003-10-30 版の変更点は?

H.10.8. LWQ 2003-08-16 版の変更点は?

H.10.J. qmail のある暮らしの変更点は?

邦訳の履歴。あたりまえだが、この節は原文にない。

Take One!