移転しました

独自ドメインサイトへ移行しました。5秒後に

https://straypenguin.winfield-net.com/

へジャンプします。

qmailの設定 (基本編)
設定例で使用する諸元 自分のドメイン:
実際のホスト名:
メールサーバの公開名:
保守用システムユーザ:
hoge.cxm
host1.hoge.cxm
mail.hoge.cxm
hoshu

基本的な設定ファイルの作成

初めてのインストールで、まだ行っていないなら、ソースdirにて:

root# ./config-fast mail.hoge.cxm

を実行。これによって /var/qmail/control/ 下の最低限必要なファイルが自動的に生成される。再インストールやバージョンアップの場合は、上記を行うとせっかく仕上げた設定ファイルが一部上書きされてしまうので、やってはいけない。

/var/qmail/control/下のファイル

ファイル 役割 使用プロセス 設定例
me 自メールホスト名。すべてのコントロールファイルの基本となる情報 すべて mail.hoge.cxm
locals ローカル宛として認識すべきドメイン/サブドメイン名 qmail-send hoge.cxm
mail.hoge.cxm
host1.hoge.cxm
rcpthosts smtp セッションの "RCPT TO:" (エンベロープ宛先) に書かれたドメイン/サブドメインがこの中にあれば、正当なものとして受信/中継を行う。該当しない宛先へのメールは受付が拒否される qmail-smtpd hoge.cxm
mail.hoge.cxm
host1.hoge.cxm
defaultdomain hoshu@host1 などドットを含まない宛先を指定したメールを、メールキューに送り込む前に、ヘッダに標準で付加するドメイン名 qmail-inject hoge.cxm
defaulthost hoshu など @ドメイン名 なしで指定したメールを、メールキューに送り込む前に、ヘッダに標準で付加するホスト名。ローカル上のメールユーザが差し出すメールの From アドレスもこれに影響される。ローカルのメールユーザが出すメールが相手に届いた時、From をメールホスト名 (@mail.hoge.cxm) でなくドメイン名 (@hoge.cxm) としたい場合には、このファイルの内容を hoge.cxm としておく (ホストマスカレードと呼ばれる処理)。 qmail-inject mail.hoge.cxm

(ホストマスカレードしたい場合は hoge.cxm)
plusdomain hosh+ など "+" で終わる宛先を指定したメールを、メールキューに送り込む前に、標準で付加するホスト名 qmail-inject mail.hoge.cxm
databytes smtp で送受信を許す最大メッセージサイズ (ただしディスク上でのサイズでありネットワーク上の転送サイズではない)。単位はバイト qmail-smtpd 4メガなら
4194304
concurrencyremote qmail-remote が同時に実行できるリモート配信の数 qmail-send 20
smtpgreeting smtpセッション内のコマンド応答で名乗るホスト名。me とは別にしたい時に指定 qmail-smtpd mail.hoge.cxm
badmailfrom smtp セッションで送受信を許可しない、エンベロープ上の MAIL FROM: アドレス。spam 避けに有効 qmail-smtpd 後述
badmailto smtp セッションで受付を許可しない RCPT TO: アドレス。qregex による拡張であり、正規表現で記述する qmail-smtpd 後述
validrcptto validrcptto パッチによって利用可能となる、smtp セッションで受信を許可する RCPT TO: アドレス。独自に拡張した qregex + validrcptto 統合パッチでは、このファイルも正規表現となる。環境変数 RELAYCLIENT が未定義の場合で、なお且つ badmailto で拒否されなかった場合にのみ評価される qmail-smtpd 後述
helohost 送信smtpセッションで helo/ehlo 時に名乗るホスト名。me とは別にしたい時に指定 qmail-remote mail.hoge.cxm
smtproutes 次のホップに使う SMTPサーバ(リレー)を指定。 domain:relay[:port] の形式 (スペース入れてはだめ) で 1行にひとつずつ書き、relay部を省略したものは「domain なら通常通り DNSで MXレコードを牽け」の意となり、domain部を空にした記述は「その他全部のドメインにはrelay を使え」の意味となる。domain はドットで始めることでワイルドカードとなるが、 .some.dom とすると例えば @mail.some.dom は該当するが @some.dom には一致しない点に注意 qmail-remote .some.dom:smtp.some
some.dom:mail.some
:my.provider:587

上記は実用上最低限のものだけ。コントロールファイルはこの他にもたくさん種類がある (man qmail-control を見よ)。各コントロールファイルの詳細は、ファイルを使用するプロセスの man に解説されている。例えば、rcpthosts の説明は qmail-smtpd の man に網羅されているといった具合。

/var/qmail/alias/下のファイル (ファイル名の頭にドットが付くので "dot-qmail" と呼ばれる)

qmail では、アカウントが見つからない「その他すべてのユーザ」 宛てのメールを、alias という特殊なユーザがコントロールする。 alias のデフォルトホームディレクトリが /var/qmail/alias であり、そこに適切な dot-qmail を置くことで、汎用アカウント宛てのメールの実際の受取人を指定できる。各ファイルの記述ルールについては ユーザのdot-qmailファイル作成 でさらに詳しく述べている。

ファイル 役割 設定例
.qmail-root root へのメールを誰が受け取るか。 qmail は、これをやらないと root へのメールを受け取らない hoshu
.qmail-mailer-daemon MTAデーモンへのメールを誰が受け取るか hoshu
.qmail-postmaster メール管理者へのメールを誰が受け取るか hoshu
.qmail-webmaster WEB管理者へのメールを誰が受け取るか hoshu
.qmail-<その他> RFCでは、上記の他に、info, sales アカウントも必要とある hoshu
.qmail-default 「上記にも実際の一般ユーザにもあてはまらないメールをどうするか」を指定する、非存在ユーザ宛メールの終着駅。普通は作らない。不用意に設定すると、宛先ユーザアドレスを打ち間違えた外からのメールに対して、不達通知が返されなくなる なし

qmailのmanページを読めるようにする

役に立つたくさんの man ページがインストールされるのだが、インストール先は /var/qmail/man/ の下。このままでは man コマンドで読めないので、 /etc/man.config を編集。
"MANPATH /usr/share/man" などが書かれている辺りに
"MANPATH /var/qmail/man" と足す。

qmail の sendmail ラッパーをシステムが使えるようにする

システム内の様々なサービスが、ログを管理者に送ったりするために sendmail コマンドを使うので、 「sendmail を殺す」 で調べておいた sendmail 実行ファイルを、 qmail 付属の sendmail ラッパーにリンクさせる。リンクがなかったり、Postfix や sendmail の sendmail バイナリを指したままになっていると、logwatch や cron からの報告メールが届かなくなったりという現象が起こる。

RedHat 系 ディストリビューションでは、PATHの通った位置にある sendmail ファイルが前述したように複雑なリンク構造をしている。alternatives フレームワーク (Windowsでいうところの「既定のプログラム」のようなもの) でコントロールされているからだ。リンクの張り直しも、alternatives を使ってやるのがスマート。

root# alternatives --display mta  <--現在の設定状態を表示。RHEL6ならsendmail.postfixが優先度50で出るだろう
root# alternatives --install /usr/sbin/sendmail mta /var/qmail/bin/sendmail 95 \
      --slave /usr/lib/sendmail mta-sendmail /var/qmail/bin/sendmail
	  <--新しくalternativesの定義を刻む。他のmtaより高い優先度にする
root# alternatives --auto mta     <--優先度に基づいて実際に切替えを実行
root# alternatives --display mta
root# which sendmail    <--/usr/sbin/sendmail と出力されるハズ
root# readlink -f /usr/sbin/sendmail    <--こういう確認方法もおもしろい

手動でリンクを張り直す場合は

root# ln -s /var/qmail/bin/sendmail /usr/sbin/sendmail
root# ln -s /var/qmail/bin/sendmail /usr/lib/sendmail

システム環境変数の調整

mbox 方式 から Maildir 方式に移行するために、システムのデフォルト設定を変える。
/etc/profile の以下の部分を編集:

MAIL="$HOME/Maildir"  <--変更
MAILDIR=$MAIL         <--追加
export PATH USER LOGNAME MAIL MAILDIR ...以下省略   <--MAILDIR を挿入

最近の Linux では PAM メカニズムが採用されているのでほとんど利用されることのないファイルだが、 /etc/login.defs も修正:

#QMAIL_DIR   Maildir  <--コメント解除しない
MAIL_DIR     Maildir/ <--変更
#MAIL_FILE   .mail    <--要らないのでコメントアウト

ユーザのMaildir整備

qmail には、ユーザの Maildir ディレクトリを整備してくれる maildirmake ユーティリティが付属している。

コマンド書式:
/var/qmail/bin/maildirmake Maildir名
システムアカウントを持つ "hoshu" の場合 (そのユーザの権限で):
hoshu$ /var/qmail/bin/maildirmake /home/hoshu/Maildir

ユーザのdot-qmailファイル作成

ドットqmail ファイルは、qmail-local プロセスに対して 「このユーザのメールはxxxしてくれ」 と指示を与えるファイル。

ユーザdot-qmailの書式:

形式/記述例 意味
#honyarara コメント行
|honyarara プログラムに渡す
&someaddress@honyara.cxm メールを転送 (&の後にスペース不可)
|forward some@honyara.cxm 同上
someaddress@honyara.cxm 同上 (ただし数字かアルファベットで始まるアドレスに限る)
./Maildir/ メールdirを指定 (相対アドレス)
/home/hoge/Maildir/ 同上 (絶対アドレス)

※/var/qmail/alias/ 下の dot-qmail で指定した "hoshu" という記述は、じつは転送だったことがわかる。

"hoshu" の場合 (ユーザ権限で):
hoshu$ echo ./Maildir/ >/home/hoshu/.qmail

1ユーザ当たりの Maildir 容量に制限を設けたい場合

mailquotacheck を使用する。ユーザーが受け取るメールボディの部分を日本語に訳したものも作ってみた (2005/9/18: nkfを通して日本語部分をJIS [ISO-2022JP] に変換して出力するよう改良)。 mailquotacheck は シェルスクリプトなので、インストールと言うほど大袈裟なものではない。 /var/qmail/bin/ にコピーするだけ。 [以前は /usr/local/bin/ にコピーしていたが、qmail-local は真っ先に自分の住処からフィルタプログラムを探そうとするようなので /var/qmail/bin/ が最適。]
あとは、最低限、スクリプト序盤の変数定義:

quota=xxxx

を好みに合わせて変更。10MB なら 10240 に。また、 .qmail と同じディレクトリの .quota ファイルに書けば、ユーザ毎に個別設定もできる。メール 1 通あたりのサイズを個別に制限するには .maxmsgsize ファイルにやはり KB 単位でサイズを書き、ユーザのホームディレクトリに置く。

インストールできたら、容量制限を掛けたいユーザの .qmail ファイルを以下のように修正する:

|mailquotacheck
./Maildir/

qmail起動スクリプトの整備

qmail の特徴は、qmail-smtpd が smtp でメールを受け付け --> qmail-queue がキューに書き込み --> qmail-send が配送を開始し --> qmail-rspawn を経由して qmail-remote が smtp で外部へ送り、という風に、必要最低限のパーミションで動く個々のプロセスがリレー方式でメールを処理していくところにある。 サーバの起動に関しても思想は同じで、最初のプログラムが真を返せば次のプログラムを起動、それが真を返せばまた次へ......とリレーしていき、最終目的のサーバプログラムが起動する。好みによるが、起動スクリプトはひとつにまとめず、qmail 本体, qmail-smtpd, qmail-pop3d の3つに分けている。

SystemV 方式の起動スクリプトで PID を確実に書き出す工夫

後述の qmail-smtpd と qmail-pop3d は tcpserver 経由で起動するようにしている。ところが、tcpserverを介すると、RedHat系の /etc/init.d./functions というサブスクリプト集にあるファンクションでは、プロセスの PID が探知できないという問題がある。そこで筆者が作成したのが detectpid という小さなシェルスクリプトで、その中には ps の出力をフルイにかけて当該の PID を見つけるコマンドが書いてある (tcpserverのページでも紹介している)。 detectpid のダウンロードは ここ

※ 2007/1/9 detectpid スクリプトを、引数を幾つでも与えられるよう改良した(Ver.2.0)。古いバージョン(1.0) も一応置いておく。ただし 1.0 では引数 (検索文字列) は常に 2つでなくてはならない。

detectpid の使い方:

detectpid {psから探し出すためのフィルタ文字列1} [フィルタ文字列2] [フィルタ文字列3...]
戻り値: PID

例) qmail-smtpd の場合:

detectpid qmail-smtpd tcpserver

ps の仕様やバージョンによるのか、ps の出力形態が多少異なることがあるため、最適なフィルタ文字列は違ってくるかもしれない。detectpid の中では、引数を /引数1/ && /引数2/ ... という具合に 正規表現のAND条件にして AWK でフィルタリングしているので、フィルタ文字列として正規表現を与えることもできる。ただしその場合、AWK に渡る以前にシェルの解釈を受けるということを頭に置いて、正規表現特殊文字は上手くエスケープしてやらなければならない。

qmail本体

コマンド書式:
qmail-start デフォルト配送先 splogger log_prefix [log_facility]

qmail-start は、メールキューからメールを読み取って配送するプロセス群 (qmail-send, qmail-lspawn, qmail-rspawn, qmail-clean) を起動する。「デフォルト配送先」 は、Maildir 方式ならば "./Maildir/" を指定。 splogger 以降は qmail パッケージ付属の logger (ログを syslog に渡すプログラム) splogger に対する引数で、 log_prefix はログに付ける接頭辞を指定、log_facility (省略可能) には syslog ファシリティを数字で指定する。log_facility を省略した場合のデフォルトは、 2 つまり mail ファシリティとなる。数字表記のログファシリティコードと mail, secure, deamon といった "名称" との対応は /usr/include/syslog.h に書かれている。

というわけで起動スクリプトの根幹部分はこうなる:

qmail-start ./Maildir/ splogger qmail &

※ 最後の"&"はプロセスをバックグラウンドに回すため。

完成版の qmail 用 rcスクリプト qmail はここにある (2007/8/1更新)。

qmail-smtpd

qmail-smtpd と qmail-pop3d は、 tcpserver を介して起動する。

qmail-smtpd の起動書式 (smtpd-auth パッチ使用時):
qmail-smtpd サーバ名 パスワードチェックPROG trueを返すPROG

根幹部分はこうなる:

tcpserver -H -R -u $QMAILDUID -g $QMAILDGID \
-x /etc/service/tcp.smtp.cdb 0 smtp \
rblsmtpd -r sbl.spamhaus.org -r dnsbl.ahbl.org \
qmail-smtpd $MYSVNAME checklocalpwd /bin/true &

※ 1行で書かなければいけない。きれいに書きたい場合は、このように "\" で改行をエスケープする。

完成版の qmail-smtpd 用 rcスクリプト qsmtpd はここにある (2007/8/1 更新)。 detectpid が要る。

サブミッションポート用SMTPサーバを併設したい場合は
qmail-vida 版の解説のほうで述べているのでそちらを参照していただきたい。

qmail-pop3d

POPユーザ名とパスワードを待つ qmail-popup 部、実際のPOPセッションを司る qmail-pop3d 部から成る。 これも tcpserver 経由で起動させる。

qmail-popupの起動書式:
qmail-popup サーバ名 パスワードチェックPROG
qmail-pop3dの起動書式:
qmail-pop3d Maildir名

※ Maildir名は通常は単に "Maildir"

つまり根幹部分はこうなる:

tcpserver -H -R -v 0 pop3 \
qmail-popup $MYSVNAME checklocalpwd \
qmail-pop3d Maildir \
2>&1 | splogger pop3d &

完成版の qmail-pop3d 用 rcスクリプトはここに置いておく (2007/8/1 更新)。前述した detecctpid スクリプトが必要。

あとは完成した起動スクリプトを /etc/rc.d/init.d/ に置くだけ。パーミションは通常 root.root の 755。 chkconfig で起動リストに登録 (chkconfig のmanを見よ)。