/etc/aliases
によるエイリアス設定
~/.forward
によるメールの転送
sendmail に関する詳細な情報はほかの専門書に譲りますが、 ここでは sendmail と qmail の主な違いを挙げます。 移行作業と移行後の運用を円滑に行うには、違いだけでなく、 双方の本質を理解することも重要だということを付け加えておきます。
qmail の付属文書ファイル SENDMAIL
には、
一般ユーザーから見た sendmail と qmail の違いについて記述されています。
sendmail はメール配送エージェントとしてのほぼすべての機能を 「sendmail」という名前のプロセス (コマンド) が担当しています。 そのため sendmail プロセスは巨大かつ複雑です。 しかも、1つで様々な権限が必要な役割りを負うため、 sendmail デーモンプロセスは root 権限で動作し、 しかも sendmail コマンドの実行ファイルは root 権限に setuid されています。 配送に関する処理を細分化し、 各処理ごとに必要最低限な実効権限のみを与えられている qmail とは大きく異なります。
qmail のプロセスは、 ある処理に特化された複数のプロセスで構成されています。 これらはまるで、 旧来からある UNIX の小粋で柔軟性の高いコマンド群のようです。 実際 qmail によるメール配送処理はシェルプログラムのようであり、 環境変数による動作の制御や情報の受け渡し、データのパイプライン、 コマンドの終了コードによる条件分岐といった動作をします。
役割り | sendmail | qmail |
---|---|---|
SMTP によるメール受信 | sendmail | qmail-smtpd |
コマンドラインからのメール送信(受信) | qmail-inject | |
メールをキューに登録 | qmail-queue | |
キューの掃除 | qmail-clean | |
キューに溜っているメールの送信 | qmail-send | |
リモートユーザーへのメール送信 | qmail-rspawn + qmail-remote | |
ローカルユーザーへのメール送信 | mail.local | qmail-lspawn + qmail-local |
... | ... | ... |
qmail は一つ1つのプロセスが小さく単純です。 しかも、ソースコードは sendmail の数分の一しかありません。 サイトを運用・管理する上で、 ソースコードに目を通し実装をより深く理解する必要に迫られることもあるので、 これは大きな利点です。
「機能主義」に走り、 メールに関するあらゆる機能を取り入れている sendmail に対し、 qmail は純粋な MTA としての機能しか有していません。 qmail にはない sendmail の代表的な機能としては、 To:/From: フィールドのアドレス書き換えや補完、 複雑なメール配送の制御といったものがあります。 qmail と同じような目的の機能でも、 sendmail ではより柔軟な条件指定と制御が可能です。
sendmail は、 誤った動作をするクライアントに寛容という特徴もあります。 例えば、 SMTP 通信におけるコマンドやデータの 1行は CR (Carriage-Return, ASCII コードで 0x0D) と LF (LineFeed, 0x0A) で終っていなければならないと定められていますが、 これに従わず行末に LF だけを送信するクライアントがあります。 sendmail はそのような行も受け付けますが、 qmail (qmail-smtpd) は処理を中断します。 また、 メールクライアントが付加すべき Date:/Message-ID: といったヘッダーフィールドがメールに含まれていない場合、 sendmail は生成して付加しますが、 qmail はそのようなことはしません。
sendmail 特有の機能・振舞いに依存しているサイトから qmail へ移行するには、
と、少しばかり厄介です。 どれも不可であれば、 残念ながら qmail に移行することを諦め、 sendmail を使い続けることになります ただ筆者の経験では、 sendmail でなければならない場面に遭遇したことはありません。
sendmail の設定は、
その難解さで有名な「sendmail.cf」という名前のファイルに記述します。
ご覧になったことがない方は、
sendmail がインスールされたシステムの
/etc/sendmail.cf
(あるいは /etc/mail/sendmail.cf
)
に目を通してみてください。
おおよそ、
人が読んで理解することを前提としていないことがわかるでしょう。
通常、sendmail.cf ファイルを直接編集することはせず、
sendmail 付属のツール cf や、
WIDE Project の中村素典氏により作成された CF
(現在は開発停止) などを利用して、
より簡単なメタファイルから sendmail.cf を生成します。
cf や CF のメタファイルと比較しても、 qmail の設定ファイルは単純明解です。 設定項目ごとに設定ファイルが分離しており、 そのほとんどはたった 1行記述するだけで機能します。 qmail 付属のマニュアル qmail-control(5) を読めば、 どの設定ファイルがどの処理 (プロセス) に影響するか一目瞭然です。
時々「qmail は設定ファイルがたくさんあってわかりにくい」 といった声が聞かれますが、 sendmail.cf を理解するのと比較するとどうでしょうか。
sendmail 標準のメールボックスは、
誰でも読み書きできる共有ディレクトリ
(ただし /tmp
のように他人のファイルは削除できない)
内の「mbox 形式」と呼ばれるファイルです。
mbox 形式のメールボックスファイルはユーザーごとに 1ファイルあり、
ファイル名はユーザーのログイン名となっています。
共有ディレクトリは、
一般的には /var/mail
あるいは /var/spool/mail
です。
mbox 形式のメールボックスは、 1つのファイルに複数のメールを保持するのも特徴です。 各メールは次のような行で始まり、最後に空白行が付きます。
From 送信者アドレス タイムスタンプ
sendmail 標準のメールボックスには、 次ような非常に悩ましい問題があります。
通常 qmail では、 各ユーザーのホームディレクトリにメールボックスを保持します。 上記のように扱い難い mbox 形式にも対応していますが、 より安全で信頼性の高い maildir 形式が利用できます。 maildir 形式は qmail 付属のマニュアル maildir(5) で解説されています。
この節では、
sendmail の停止から qmail に移行するまでの手順について解説します。
qmail 付属文書ファイル REMOVE.sendmail
にも同様の解説がありますので、そちらも参考にするとよいでしょう。
より安全・確実に移行を実施したい場合は、 システムをシングルユーザーモードにして作業することをお勧めします。 シングルユーザーモードであれば、 メールサービスを利用する可能性のあるほかのサービス (POP3 サーバー、cron など) は 稼働しておらず、また、一般ユーザーはログインしていない状態になります。
もしくは、移行用に別のマシンを用意するとよいでしょう。 そちらに qmail を導入し、メールサービスを段階的に移行しましょう。 (ただしこの方法は本書では解説しません)
sendmail をインストールし利用しているなら、 システムのブート時に sendmail デーモンが起動し、 常駐するように設定されていることでしょう。 sendmail デーモンは、 SMTP 接続の待ち受けと定期的なキューの処理を行っています。 まずは sendmail デーモンのプロセスを停止し、 SMTP 経由でメール着信しないようにします (キューの扱いについては次節)。
sendmail デーモンプロセスを停止するには、 root で次のようにします。 ここで使用している ps コマンドは、 種類によってオプションや表示が異なることがあるのでご注意ください。
# ps ax | grep sendmail
291 ? S 3:18 /usr/sbin/sendmail -bd -q15m
26556 pts/12 S 0:00 grep sendmail
# kill 291
# ps -ef | grep sendmail
root 291 1 0 Apr 25 ? 3:18 /usr/sbin/sendmail -bd -q15m
fumiya 28199 28112 0 02:29:35 pts/12 0:00 grep sendmail
# kill 291
System V 系の起動スクリプトを採用しているシステムでは、
/etc/init.d
(古い Red Hat Linux などでは /etc/rc.d/init.d
)
にある制御スクリプトを利用してもよいでしょう。
# /etc/init.d/sendmail stop
sendmail を無効にする前に、 sendmail のメールキューに滞留しているメールを配送させることを忘れないように注意してください。 qmail は sendmail のキューに関知しないため、 これを怠ると、sendmail のキューのメールは紛失したのと同然です。
sendmail キューの処理は sendmail -q
コマンドで実行し、
キューの状態は mailq コマンドで確認します。
# sendmail -q
# mailq
/var/spool/mqueue is empty
なんらかのパッケージ管理システムにより sendmail がインストールされているなら、 それに従い適切な方法でアンインストールしてください。
しかし、 sendmail のようにシステムの標準的なサービスを提供するパッケージは、 ほかのパッケージに依存されいることでしょう。 パッケージ管理システムは、 sendmail がほかのパッケージに必要とされるため、 通常の方法では sendmail をアンインストールすることを拒否します。
次の例は、 logcheck パッケージが「smtpdaemon」に依存しているため、 それを提供している sendmail パッケージの削除が中断されています。
# rpm -e sendmail
error: removing these packages would break dependencies:
smtpdaemon is needed by logcheck-1.1.1-2
qmail で sendmail の代替ができるのであれば、 依存関係を無視するオプションを指定して sendmail パッケージを強制的に削除しても問題ありません。 しかし、以下のような場合には注意が必要です。
アンインストールしない場合は、 sendmail を介してのメールの送受信がされないようにします。 sendmail は以下のように利用されます。
ブート時のデーモンの起動設定はシステムの種類により異なり、
ブートスクリプト /etc/rc
中
(BSD 系、あるいは /etc/rc.local
など) か、
/etc/rc?.d
(あるいは /etc/rc.d/rc?.d
) ディレクトリ中の
sendmail スクリプト (System V 系) によって実現されています。
/etc/rc
スクリプトの場合は、
スクリプト中の sendmail デーモンを起動する箇所をコメントアウトします。
例えば、FreeBSD 4.3 の /etc/rc
スクリプト内には、
次のような箇所があります。
この部分の各行の行頭に、シェルスクリプトのコメントを表す
「#
」を付けます。
/etc/rc
):
case ${sendmail_enable} in
[Yy][Ee][Ss])
if [ -r /etc/mail/sendmail.cf ]; then
echo -n ' sendmail'; /usr/sbin/sendmail ${sendmail_flags}
fi
;;
esac
/etc/rc
):
#case ${sendmail_enable} in
#[Yy][Ee][Ss])
# if [ -r /etc/mail/sendmail.cf ]; then
# echo -n ' sendmail'; /usr/sbin/sendmail ${sendmail_flags}
# fi
# ;;
#esac
FreeBSD 4.0 以降の場合、
sendmail デーモンの起動を
/etc/rc.conf
ファイルの記述で制御することができます
(詳しくはマニュアル rc.conf(5) を参照のこと)。
このように、標準的な方法はシステムにより異なることがありますのでご注意ください
(後述の System V の場合も同様)。
System V 系では、
sendmail デーモンの起動スクリプトが
/etc/rc?.d/SNNsendmail
(あるいは /etc/init.d/rc?.d/SNNsendmail
,
? は英数字, NN は 2桁の数字)
に置かれています。
それらは /etc/init.d/sendmail
(/etc/rc.d/init.d/sendmail
)
とのハードリンクもしくはシンボリックリンクなっています。
これを削除ないしは移動することで無効化します。
_SNNsendmail
に移動する場合):
# cd /etc
# for r in rc?.d; do (cd $r && eval 's=`ls S??sendmail`' && mv $s _$s); done
Red Hat Linux あるいはその派生システムでは、
「chkconfig --del sendmail
」で
システムブート時の sendmail デーモンの起動を無効にすることができます。
SMTP サービスを提供しないシステムでは sendmail デーモンは稼働せず、 送信キューに滞留しているメールを処理するため、 定期的に sendmail コマンドを起動するように設定されています。 定期的な処理は cron デーモンを利用します。
root の cron テーブル (crontab -e
で編集)、
あるいは
/etc/cron.d
か /etc/cron.hourly
ディレクトリ内のスクリプトで
「sendmail -q
」を実行している箇所がないか調べ、
無効にしてください。
Windows で動作するメールクライアントは、 メールの送信に SMTP サーバーを利用するのが一般的です。 一方、UNIX で動作するメールクライアントは、 メール送信用のコマンドを利用するものがあります。 代表的なメール送信用コマンドとしては mail コマンドや mailx コマンドが一般的ですが、 sendmail コマンドもその中の一つです。
mail, mailx コマンドはメールクライアントの一種で、 その内部では sendmail コマンドを利用してメールの送信を行います。 このため sendmail コマンドが利用できないと sendmail コマンドを利用しているメールクライアントはもちろん、 mail, mailx コマンドによるメール送信もできなくなってしまいます。 この問題は 「10.3.1 qmail の sendmail 互換コマンドインターフェイス」 の節で紹介する qmail 付属の sendmail コマンドを利用して回避します。
sendmail コマンドは、
/usr/sbin/sendmail
/usr/bin/sendmail
,
/usr/lib/sendmail
といった場所にあるので、
これを実行できないようにしましょう。
いずれかがシンボリックリンクになっていることがありますのでご注意ください。
# cd /usr/sbin
# ls -l sendmail
-r-sr-xr-x 1 root other 316348 Aug 19 2000 sendmail
# mv sendmail sendmail.dist
# chmod 0 sendmail.dist
# ls -l sendmail.dist
---------- 1 root other 316348 Aug 19 2000 sendmail.dist
sendmail コマンドは元に戻せるように削除はせず、 移動だけします。 また、移動した sendmail コマンドが誤って実行されないように、 アクセス許可をすべて落すことをお勧めします。 sendmail コマンドは root に setuid されて実行されるため、 ローカルユーザーによって sendmail のセキュリティホールを突かれる恐れがあります。
以上の sendmail コマンド無効化の手順は、
FreeBSD 4.0 以降には適用できません。
FreeBSD 4.0 以降の /usr/sbin/sendmail
コマンドはラッパーで、
mailer.conf(5) により実際に起動されるコマンドを切り換えるようになっています。
sendmail パッケージをアンインストールせずに qmail を導入した場合は、 システムのアップグレードやパッチを適用する際に注意が必要です。 例えば、「10.3 sendmail 互換環境を作る」 で紹介している qmail 付属の sendmail コマンドや fastforward 付属の newalias コマンドを sendmail のものと置き換えていると、 アップグレードやパッチを適用した際に、 新しい sendmail パッケージのコマンドに上書きされてしまう恐れがあります。 無効にした sendmail デーモンの起動が復活して、 qmail-smtpd と衝突することも考えられます。
qmail の標準では、 各ユーザーのホームディレクトリ内 に、 mbox 形式か maildir 形式のメールボックスにメールを配送します。 sendmail 時代のメールボックスは、 誰でも読み書きできる共有ディレクトリ内に mbox 形式で保持されていますので、 これを qmail が扱うメールボックスに移行しなければなりません。
qmail (qmail-local) がメールボックスへのメール配送に procmail や mail.local コマンドなど使用するように設定され、 sendmail と同じパス/同じ形式のファイルのメールボックスに配送するのであれば、 この作業は必要ありません。 (10.3.4 節)
sendmail の mbox 形式のメールボックスから qmail 標準の maildir 形式のメールボックスに変換するには、 mbox2maildir コマンドを利用します。 mbox2maildir は qmail には付属していないため、別途入手してください。 いくつかの変種がありますが、代表的なものは以下から入手できます。 このコマンドは Perl スクリプトですので、 別途 Perl が必要です。
このコマンドは変換元と変換先のメールボックスを環境変数で指定します。
以下に実行例を示します。
sendmail 標準の mbox 形式のメールボックスファイルは、
共有メールスプールディレクトリ
/var/mail
(もしくは /var/spool/mail
)
以下にあります。
ファイル名はユーザーのログイン名です。
$ MAIL=/var/mail/fumiya
$ MAILDIR=$HOME/Maildir
$ export MAIL MAILDIR
$ mbox2maildir
この mbox2maildir コマンドには次のような問題があり、 あまり柔軟性はありません。 そのままでは特定の場面でしか利用できません。 qmail への移行の段階で、メールサービスを停止して変換作業を行うのであれば、 2. は問題とはなりません。
mbox2maildir コマンドと同じような目的のコマンドは多数存在します。 mbox2maildir に満足できないのであれば、 別途、目的に合ったコマンドを探してみてください。 それでも満足できるものがなければ、それらを参考にして、 ご自分の mbox2maildir コマンドを作成しましょう。
Google (http://www.google.com/) でキーワード「mbox2maildir」で検索してみたところ、 次のような変換ツールを見つけることができました。 しかし、 mbox 形式の変種に対応しているものは見つけることができませんでした。
qmail (qmail-local) は、 mbox 形式のメールボックスへの配送に対応していますが、 sendmail のような共有メールスプールディレクトリではなく、 各ユーザーのホームディレクトリ内に保持します。
sendmail 時代に利用していた IMAP/POP サーバーやメールクライアントに対応するため、 共有メールスプールから各ユーザーのメールボックスへシンボリックリンクを作成するとよいでしょう。 もちろん、 各 IMAP/POP サーバーとメールクライアントのほうで対応することもできますが、 シンボリックリンクにより旧来と同じパスでメールボックスを参照できるようにするほうが手間がかかりません。
次に作業の例を示します。
この例では共有メールスプールは /var/mail
になっていますが、
システムにより適宜読み換えてください (/var/spool/mail
など)。
この作業は、既存のユーザーのメールボックスのことだけを考慮しています。
新規にユーザーを追加した場合、同様の作業を行うのを忘れないようにしてください。
# cd /home
# for n in *; [ -d $n ] && ln -s /home/$n/Mailbox /var/mail/$n; done
主なメールクライアントは、正式あるいはパッチによって maildir 対応がなされています。 しかしいくつかのメールクライアント、特にユーザーが少ないものや古いもの、 そして開発が停止しているものは、maildir に対応していません。 そんな時に助けになるのが qmail 付属の maildir2mbox コマンドです。
maildir 形式に対応していないメールクライアントを利用しているユーザーは、 maildir2mbox を利用して、 定期的に maildir から mbox への変換するようにします。
maildir2mbox は、次の環境変数を介してメールボックスの位置を知ります。 いずれも絶対パスを指定しなければなりません。
MAILDIR
MAIL
MAILTMP
MAIL
に指定したパスと同じファイルシステム内のパスでなければならない
(変換処理終了後に MAIL
で指定された名前にリネームするため)
例として、 ユーザーが簡単にメールボックスの変換を行えるスクリプト maildir2mbox.sh を用意しました。 mbox 形式のメールボックスが必要なユーザーは、 適宜このスクリプトを起動するか、 ユーザー自身の crontab(5) に記述して定期的に実行するように設定するとよいでしょう。
#!/bin/sh
if [ -z "$HOME" ]; then
echo "HOME not set"
exit 1
fi
MAILDIR=$HOME/Maildir
MAIL=$HOME/Mailbox
MAILTMP=$HOME/.maildir2mbox.$$.tmp
export MAILDIR MAIL MAILTMP
/var/qmail/bin/maildir2mbox
0 * * * * /usr/local/bin/maildir2mbox.sh
POP サーバーや IMAP サーバーを利用しているなら、 ホームディレクトリのメールボックスを参照するように設定変更してください。 mbox 形式であってもホームディレクトリ内のメールボックスに対応していなかったり、 maildir 形式に対応していない POP/IMAP サーバーもあります。 コンパイル時オプションやソースにパッチに適用するなどして再コンパイル、 インストールするか、別のソフトウェアに乗り換えてください。
qmail (qmail-local) がメールボックスへのメール配送に procmail や mail.local コマンドなど使用するように設定され、 sendmail と同じパス/同じ形式のファイルのメールボックスに配送するのであれば、 この作業は必要ありません。 (10.3.4 節)
IMAP や POP サーバーを利用せずに直接メールボックスを参照するメールクライアントは、 設定を変更して maildir 形式のメールボックスを参照するようにします。 方法はメールクライアントによって異なりますので、 詳細はお使いのメールクライアントのマニュアルなどを参照してください。
mbox 形式のメールボックスに配送しているのであれば、環境変数 MAIL
を変更してホームディレクトリ内のメールボックスを指すようにしましょう。
MAIL
環境変数は mbox 形式のメールボックスを指示するもので、
/bin/mail
などのいくつかの UNIX のメールクライアントが参照します。
これに従わないメールクライアントもありますのでご注意ください。
/etc/profile
に追加):
MAIL=$HOME/Mailbox
export MAIL
/etc/csh.cshrc
に追加):
setenv MAIL $HOME/Mailbox
maildir に対応していないメールクライアントの救済については、 10.2.4 節 の「maildir 形式から mbox 形式への変換」の節を参照してください。
sendmail の
/etc/aliases
ファイル
(あるいは /etc/mail/aliases
)
のエイリアスの設定を、
qmail の
users/assign
と
エイリアス用ユーザー alias の .qmail ファイルに移行します。
qmail はユーザー root 宛のメールの配送は行ないません。
~alias/.qmail-root
ファイルを用意して、
ユーザー alias で受け取るか別のアドレスに転送するようにしてください。
これを怠ると、root 宛のメールが紛失してしまいますのでご注意ください。
sendmail のエイリアスには、
伝統的に「nobody」というテスト用の名前が定義されています。
この定義により nobody 宛のメールを受信しますが、
そのまま /dev/null
に捨てるようになっています。
これを qmail で実現するには、.qmail ファイルにコメントだけを記述します。
# cd /var/qmail/alias
# echo '#' > .qmail-nobody
# chmod 644 .qmail-nobody
qmail で sendmail の
/etc/aliases
ファイルを利用する方法については、
「10.3.2 /etc/aliases
によるエイリアス設定」を参照のこと。
sendmail のユーザーごとの転送設定である ~/.forward
ファイルを
qmail の ~/.qmail
に移行します。
移行の際には次の表を参考にしてください。
表中の preline, forward は qmail 付属のコマンドです。
.qmail については qmail 付属のマニュアル
dot-qmail(5) に記述されています。
「第7章 .qmail ファイルの利用」も参照のこと。
転送先の種類 | sendmail + .forward | qmail (qmail-local) + .qmail |
---|---|---|
コメント | # comment |
# comment |
アドレスへ転送 | username@example.com |
&username@example.com |
ローカルユーザーへ転送 | username |
未対応 代替案: |forward "username@$HOST" 代替案: &username (control/envnoathost に依存)
|
ローカルコピー | 自分のユーザー名を記述 | 自分のメールボックスのパスを記述 例: ./Maildir/
|
mbox 形式メールボックスへ出力 | /path/to/outputfile |
/path/to/outputfile |
.forward 用コマンドの利用 | "|/path/to/command args" |
|preline /path/to/command args |
転送先リストの取り込み | :include:/path/to/listfile |
未対応 代替案: |forward `cat /path/to/listfile`
|
複数の転送先 | それぞれ別の行に記述 1行にカンマ区切りで列挙可 |
それぞれ別の行に記述 |
qmail で sendmail の ~/.forward
ファイルを利用する方法については、
「10.3.3 ~/.forward
によるメールの転送」
を参照のこと。
ここまで来れば、快適な qmail の世界まであと少しです。 最後に qmail のデーモンを稼働させ動作を確認したら、 いよいよサービススタートしましょう。
おめでとうございます。 ようこそ、qmail の世界へ!
この節では、 追加のソフトウェアをインストールしたり qmail の設定に手を加えることで、 sendmail と同じような機能・振舞いを実現する方法を紹介します。 次のような場合に有用です。
sendmail 互換とすることにより、 qmail の長所が生かされないことがあります。 また、互換環境を実現するための仕掛けがトリッキーなものがあり、 環境が複雑になってしまいます。 原理はもちろん、利点・欠点をよく理解の上、導入するようにしてください。
10.2.3 節 の 「sendmail コマンドの無効化」で触れたように、 メールの送信を sendmail コマンドで実行するメールクライアントが存在します。 CGI や何らかの通知システムなどが 直接 sendmail コマンドを利用してメールを送信することもあります。 qmail ではこれに対応するため、 その名もずばり「sendmail」という名前の sendmail 互換のコマンドが付属しています。
qmail の sendmail 互換コマンドは、
通常のインストール形態では
/var/qmail/bin/sendmail
に置かれています。
これを本物の sendmail が置かれていたパスから参照できるように、
シンボリックリンクを作成しましょう。
sendmail コマンドは
/usr/sbin/sendmail
,
/usr/bin/sendmail
,
/usr/lib/sendmail
といった場所にあるので、
そこから /var/qmail/bin/sendmail
へのシンボリックリンクを作成します。
# ln -s /var/qmail/bin/sendmail /usr/sbin/sendmail
/etc/aliases
によるエイリアス設定
sendmail では、エイリアスアドレスの設定を
/etc/aliases
ファイルで指定します。
qmail には、sendmail の aliases ファイルを利用するための
fastforward というソフトウェアがあります。
fastforward は、qmail と同じく D. J. Bernstein 氏による作品です。
fastforward のコンパイルとインストールの手順は qmail とほぼ同様です。
実行バイナリとマニュアルも qmail と同じく
/var/qmail
以下にインストールされます。
$ gzip -dc fastforward-0.51.tar.gz | tar xf -
$ cd fastforward-0.51
$ make it install instcheck 2>&1| tee make.out
… バイナリなどのコンパイル状況 …
$ su
Password: root のパスワード
# make setup
./install
# make check
./instcheck
fastforward には「newaliases」という名前のコマンドが付属しています。 このコマンドは sendmail の newaliases コマンドと同じ目的のもので、 実行すると、 テキスト形式の aliases ファイルからバイナリのエイリアスデータベースファイルを生成します (双方のデータベースに互換性はありません)。 必要であれば、 qmail の newaliases コマンドを sendmail のものと同じパスで参照できるようにしてください。
qmail の newaliases コマンドは
/etc/aliases
ファイルを参照しますが、
最近の sendmail のエイリアスファイルは
/etc/mail/aliases
にあります。
これも調整しておくと便利です。
最初から /etc/aliases
から
/etc/mail/aliases
にシンボリックリンクが張られているシステムもあります。
# ln -s /var/qmail/bin/newaliases /usr/sbin/newaliases
# ln -s /etc/mail/aliases /etc/aliases
build-fastforward
コマンドを実行してバイナリパッケージを作成する
まず始めに、
/etc/aliases
ファイルからエイリアスのデータベースファイル
/etc/aliases.cdb
を作成しておきます。
この作業は aliases ファイルを更新する度に実行する必要があります。
# /var/qmail/bin/newaliases
fastforward は、 qmail のエイリアス処理用のユーザー alias の .qmail-default ファイルに組込みます。
「7.2 拡張メールアドレス」で解説しているように、
.qmail による拡張アドレス定義 .qmail-default ファイルは特別で、
ほかの拡張アドレスに一致しない場合には
.qmail-default ファイルの設定に従いメール配送されます。
これと同様に、
ユーザー alias の .qmail-default ファイルもワイルドカードアドレスとして働きます。
つまり、既存のユーザーとエイリアスのどれにも一致していない場合にデフォルトの配送指定として ~alias/.qmail-default
が評価されます。
というわけで、~alias/.qmail-default
に
fastforward コマンドを起動する記述をします。
fastforward のコマンドライン引数には、
エイリアスデータベースファイルのパスを指定します。
# cd /var/qmail/alias
# echo '|fastforward /etc/aliases.cdb' > .qmail-default
# chmod 644 .qmail-default
qmail + fastforward によるエイリアスの動作は、 sendmail の動作とはいくつか異なります。
エイリアスアドレス宛に届いたメールをファイルに出力させることはできません。 ユーザー alias の .qmail ファイルを利用してください。
:include: 構文でインクルードされる外部のアドレスリストファイルは、 直接参照されません。 事前に newinclude コマンドを使用して、 バイナリファイルを生成しておかねばなりません。 詳細は newinclude(1) を参照のこと。
qmail は、 自ホスト宛のメールの配送先を以下のような順番で評価し、決定します。 いずれかの段階で宛先アドレスに対応する配送先が見つかれば、 それ移行の評価は行いません。
users/assign
による宛先アドレスとユーザーの対応表~alias/.qmail-aliasname
によるエイリアス設定
この中でもエイリアスのワイルドカードである
~alias/.qmail-default
ファイルは、
一番最後に評価されます。
このため、
fastforward による /etc/aliases
ファイルのエイリアス指定は、
ローカルユーザーへのメール配送を制御 (上書き) することはできません。
sendmail は、
/etc/aliases
の指定をローカルユーザーより先に評価します。
sendmail では、ユーザーごとのメールの転送設定を .forward ファイルで指定します。 qmail には .forward ファイルを利用するための dot-forward というソフトウェアがあります。 dot-forward は、qmail と同じく D. J. Bernstein 氏による作品です。
dot-forward のコンパイルとインストールの手順は qmail とほぼ同様です。
実行バイナリとマニュアルも qmail と同じく
/var/qmail
以下にインストールされます。
$ gzip -dc dot-forward-0.71.tar.gz | tar xf -
$ cd dot-forward-0.71
$ make it install instcheck 2>&1| tee make.out
… バイナリなどのコンパイル状況 …
$ su
Password: root のパスワード
# make setup
./install
# make check
./instcheck
build-fastforward
コマンドを実行してバイナリパッケージを作成するdot-forward は、 qmail のメール配送エージェントのスタートアップコマンド qmail-start に「デフォルトの配送方法の指定」引数として指定します。 この引数は qmail-lspawn を介して qmail-local に渡され、 宛先メールアドレスのローカル部に対応する .qmail ファイルがない場合のデフォルトの配送方法となります。
qmail-start のコマンドラインは
qmail によるメール配送のスタートアップスクリプト
/var/qmail/rc
に記述されているので、
このスクリプトを書き換えます
(独自のスタートアップスクリプトを使用しているなら、
もちろんそちらを書き換える必要があります)。
スタートアップスクリプトを /var/qmail/boot/home
からコピーして用意した場合、その中身は次のようになっています
(コメントは省略)。
/var/qmail/rc
):
#!/bin/sh
exec env - PATH="/var/qmail/bin:$PATH" \
qmail-start ./Mailbox splogger qmail
この状態では qmail-start の第1引数(デフォルトの配送方法の指定)に
「./Mailbox
」が指定されており、
デフォルトではホームディレクトリの mbox 形式のメールボックスに配送されることがわかります。
これに dot-forward を組み込むと、次のようになります
(実は /var/qmail/boot/home+df
と同一)。
/var/qmail/rc
):
#!/bin/sh
exec env - PATH="/var/qmail/bin:$PATH" \
qmail-start '|dot-forward .forward
./Mailbox' splogger qmail
少しわかりにくいですが、qmail-start の第1引数は
「|dot-forward .forward
」 + 改行 + 「./Mailbox
」
となります
(シングルクォート「'」で括られている部分)。
これを見てわかるように、
qmail-start (qmail-local) のデフォルトの配送方法指定の形式は、
.qmail ファイルに記述する形式とまったく同じです。
(→「第7章 .qmail ファイルの利用」)
dot-forward は標準入力からメールを受け取り、
コマンドライン引数で指定されたファイル (この例では .forward
)
に従いメールを転送し、配送の成功を示す終了コード 99 を返します。
.forward
ファイルが存在しない場合はなにも実行しませんが、
続く配送指定の実行を促すために終了コード 0 を返します。
また、
転送先に自分自身のユーザー名かメールアドレスが指定されていた場合も終了コード 0 を返します。
このため、前者の場合は転送処理だけ実行されますが、
後者の場合は qmail-local により「./Mailbox」への配送も実行されます。
.qmail から起動するコマンドの終了コードの意味と
qmail-local の動作についてはマニュアル
qmail-command(8)
に解説されていますので、そちらをご覧ください。
(→「7.3 コマンドによるメールの処理」)
qmail + dot-forward による転送の動作は、 sendmail の動作とはいくつか異なります。 以下に代表的な違いを紹介しますが、 詳細はマニュアル dot-forward(1) を参照してください。
メールをファイルに出力させることはできません。 .qmail ファイルを利用してください。
sendmail では、
.forward ファイルで指定された転送先のユーザー名は、
エイリアスの設定 (/etc/aliases
) で評価されます。
また、転送先のユーザーが .forward
ファイルを持っているなら、
その指定に従って転送します。
この動作は、
ユーザー名の頭にバックスラッシュ「\」を付けることで抑制することができます。
qmail (dot-forward) では、バックスラッシュはなにも意味を持ちません。 バックスラッシュが付いていても、付いていないのと同じように評価され、 動作にはなんら影響しません。
転送先のユーザー名が自分自身の場合は、 エイリアスも(当然)転送の設定も無視され、 ローカルのメールボックスに配送されます。 転送先がほかのユーザー名あるいはメールアドレスの場合、 qmail-inject と同じ規則でアットマークやドメイン名が付加され、 送信キューに登録されます。
sendmail は転送先の種類を以下のように判別します。
一方、qmail (dot-forward) では、以下の順番で判別を試みます。
qmail の安全性の高いホームディレクトリへの配送を捨てて、
sendmail と同じ共有スプールディレクトリへの配送を実現する方法を紹介します。
maildir 形式と比較すると、信頼性も失われることを認識しておいてください。
qmail の付属文書ファイル INSTALL.vsm
にも同様の解説があります。
sendmail は自ホスト宛のメールをメールボックスに配送するときに、 「ローカルメーラー」あるいは「MDA (Mail Delivery Agent)」 と呼ばれる外部コマンドに依頼します。 sendmail とローカルメーラーは sendmail.cf で指定された手順で通信します。 ローカルメーラーとの通信の手順を制御する細かいオプションが多数用意されていますが、 おおまかに分類すると代表的な通信手順は以下の 2種類に分けられます。
この中で、1. のような通信をサポートするローカルメーラーであれば、 qmail (qmail-local) から利用することできます。
qmail は自ホスト宛のメールの配送に qmail-local を使用します。 qmail-local は、 qmail-start を介して指定されたデフォルトの配送方法に従って配送しますので、 qmail-start を起動するスタートアップスクリプトを変更し、 qmail-local が sendmail のローカルメーラーを使用して配送するようにします。 手順は 10.3.3 節 の dot-forward の組み込むと同様ですので、 合わせてそちらも参照しておくと理解できるでしょう。
sendmail のローカルメーラーは、
標準では /usr/libexec/mail.local
, /bin/mail
といったものが利用されます。
これらはコマンド名が同じでも置かれているパスや仕様がシステムによって異なるため、
ここで全てを紹介することはできません。
そこで本書では、Solaris 8 における例を紹介します。
そのほかのシステムをお使いの場合は、
qmail 付属の /var/qmail/boot
にあるスタートアップスクリプトを参考にしてください。
スクリプト名 | 対応するシステム |
---|---|
binm1 |
BSD 系 (/usr/libexec/mail.local -r) |
binm1+df |
同上 + dot-forward |
binm2 |
System V Release 4 (SVR4) 系 (/bin/mail -r) |
binm2+df |
同上 + dot-forward |
binm3 |
UNIX V7 (/bin/mail -f) |
binm3+df |
同上 + dot-forward |
proc |
procmail (後述) |
proc+df |
同上 + dot-forward |
Solaris 8 付属の sendmail は、
標準では /usr/lib/mail.local -l
をローカルメーラーとして使用しています。
-l
オプションはマニュアル mail.local(1M) には記載されていませんが、LMTP (Local Message Transfer Protocol, RFC 2033) で sendmail と通信するための指定です。
qmail-local は LMTP による通信には対応していないので、
-l
オプションは指定しません。
そして、送信者のアドレスと宛先のユーザーはコマンドライン引数で指定します。
/var/qmail/rc
, Solaris 8):
#!/bin/sh
exec env - PATH="/var/qmail/bin:$PATH" \
qmail-start \
'|preline -f /usr/lib/mail.local -f "${SENDER:-MAILER-DAEMON}" "$USER"' \
splogger qmail
qmail 付属の preline コマンドは、 メールに先頭の「From 送信者アドレス タイムスタンプ」行、 Return-Path: フィールド、Delivered-To: フィールドを付加し、 指定されたコマンドに渡すラッパーコマンドです。 マニュアル qmail-command(8) で解説されているように、 qmail ではそれらの情報を環境変数によりコマンドに渡すようになっていますが、 sendmail 向けに作成されたコマンドは理解できません。 メール先頭の「From 」行の付加は mail.local が行うので、 ここでは preline に -f オプションを指定して「From 」行の付加を抑制しています。 (→「7.3.2 qmail 付属の .qmail 用コマンド」の「.forward 用コマンドの利用 - preline」)
環境変数 SENDER
は送信者のメールアドレス、
USER
はメールボックスの所有者のユーザー名です。
詳細は
「7.3.1 どのようにしてコマンドが起動されるのか」か、
マニュアル
qmail-command(8)
をご覧ください。
メールのフィルタリングや振り分けなどに利用されるソフトウェア、 procmail を組み込む例を紹介します。 procmail は sendmail のローカルメーラーとして利用されることもあり、 デフォルトの配送先は sendmail と同じ共有スプールディレクトリ内の mbox 形式のメールボックスです。
厳密なパッケージ管理システムの下では qmail パッケージと sendmail パッケージが共存できず、 qmail から sendmail パッケージに含まれるローカルメーラーを利用できないことが考えられます。 そんな場合には、 sendmail とは独立している procmail を利用するとよいでしょう。
以下に procmail のインストール例を示します。
付属の Makefile
では /usr
にインストールされますが、
この例では /usr/local
にインストールされるよう変更しています。
また、コンパイル中にロックのテストのための追加ディレクトリの入力を求められますが、
通常は必要ありませんのでリターン (Enter キー) だけ入力してください。
カスタマイズしてコンパイルするには、
make する前に Makefile
と
config.h
ファイルを編集してください。
詳細は付属の INSTALL
ファイルを参照のこと。
$ gzip -dc procmail-3.22.tar.gz | tar xf -
$ cd procmail-3.22
$ cp -p Makefile Makefile.dist
$ sed 's!^BASENAME.*=.*$!BASENAME=/usr/local!' < Makefil.dist > Makefile
$ make 2>&1| tee make.out
… コンパイル前の準備 …
I will temporarily use a testdirectory named _locktest
in the following directories:
/tmp .
If you would like to add any, please specify them below,
press return to continue:
リターンのみ入力
… ロックのテスト、バイナリなどのコンパイル状況 …
$ su
Password: root のパスワード
# make install-suid
… バイナリのインストール状況 …
# make install.man
… マニュアルのインストール状況 …
このインストールの例では procmail は
/usr/local/bin/procmail
に置かれるので、
スタートアップスクリプトは次のようになります。
/var/qmail/rc
):
#!/bin/sh
exec env - PATH="/var/qmail/bin:/usr/local/bin:$PATH" \
qmail-start '|preline procmail' splogger qmail
RFC 2822 「Internet Message Format」によると、 インターネットメールには From:/Date: フィールドが必須と定義されています。 また同文書には、メールを一意に識別するための Message-ID: フィールドも「付けるべき」と定義しています。 よって、 これらのヘッダーフィールドは、 メールの生成と送信を行うメールクライアントが付加すべきものですが、 メールクライアントの中にはこれに従わないものが存在します。
sendmail は必須とされるヘッダーフィールドが含まれていないメールを受信すると、 自前で生成しメールに付加してから配送します。 しかし、純粋にメールの配送処理しか行わない qmail は、 経路情報を示すフィールド (Received:/Delivered-To: フィールド) を追加する以外、メールを書き換えることはありません。 このため、sendmail から qmail に以降すると、 メールクライアントの不具合が健在化します。
qmail の FAQ に、この問題に対処するための方法が紹介されています。
ここで紹介されている設定を施すと、 SMTP (qmail-smtpd) 経由で受信したメールが、 次の図のような流れで配送・加工が行なわれます。
図: 必要なヘッダーフィールドがないメールの矯正 (FAQ に紹介されている手法) 問題のあるメールクライアント (1) 宛先アドレス bob@example.com Date:/Message-ID: フィールドなし | v tcpserver (RELAYCLIENT="@fixme") qmail-smtpd (2) 宛先アドレス bob@example.com@fixme Date:/Message-ID: フィールドなし | v qmail-send (3) | v ~alias/.qmail-fixup-default (4) qmail-inject 宛先アドレス bob@example.com Date: ... Message-ID: ... | (5) v qmail-send | v ......
(1)メールクライアントからメールを送信します。
(2)qmail-smtpd は特定のクライアントからメールを受信したときに、
宛先アドレスを書き換えて「実際の宛先アドレス@fixme」宛に送付します。
(3)「fixme」ドメイン宛のメールは自ホストの仮想ドメインで受け取るように設定されているため、
qmail-send は virtualdomains の設定に従って
ローカルの「fixup-実際の宛先アドレス@fixme」に配送しようとします。
(4)ユーザー「fixup」は存在しないのでエイリアスの
~alias/.qmail-fixup-default
が評価され、
メールは qmail 付属のメールクライアント qmail-inject に渡されます。
(5)qmail-inject はメールに足りないヘッダーフィールドを付加し、
実際の元の宛先アドレスに送信します。
まず始めに、
fixme ドメイン宛のメールを自ホストの仮想ドメイン宛に配送し、
qmail-inject に渡されるようにします。
仮想ドメインに定義したドメインは
control/locals
に記述しなくてもローカル配送されます。
また、SMTP 経由で fixme ドメイン宛のメールを受け取る必要はないため、
control/rcpthosts
に記述する必要もありません。
仮想ドメインの定義は control/virtualdomains
ファイルに記述します。
fixme ドメイン宛のメールが
「fixup-宛先アドレスのローカル部」
というメールボックス名に配送されるように指示します。
control/virtualdomains
の変更を有効にするには、
qmail-send のプロセスに HUP シグナルを送信するか、再起動が必要です。
control/virtualdomains
):
fixme:fixup
メールボックス名「fixup-宛先アドレスのローカル部」
宛のメールをすべて受け取るように、
ワイルドカードアドレスとして
~alias/.qmail-fixup-default
ファイルを用意します。
メールはこのファイルの指示に従って qmail-inject に渡されます。
その際、宛先アドレスは「実際の宛先アドレス@fixme」のローカル部
(「@」の前の部分)、つまり元の宛先アドレスに戻ります。
環境変数についての解説は
「7.3.1 どのようにしてコマンドが起動されるのか」と
qmail-command(8)
を参照してください。
~alias/.qmail-fixup-default
):
|bouncesaying 'Permission denied' [ "@$HOST" != "@fixme" ]
|qmail-inject -f "$SENDER" -- "$DEFAULT"
次に、 問題のあるクライアントからのメールを 「実際の宛先アドレス@fixme」宛にリダイレクトされるようにします。
qmail-smtpd は、
環境変数 RELAYCLIENT
が設定されている場合、
クライアントにメールのリレーを許可するとともに、
クライアントから指定された宛先アドレスに
RELAYCLIENT
の値を追加します。
通常は RELAYCLIENT
は空白が設定されるようにしますが、
問題があるクライアントからの場合は
「RELAYCLIENT="@fixme"
」とし、
受け取ったメールが fixme ドメイン宛に送付されるようにします。
qmail-smtpd の起動に ucspi-tcp の tcpserver を利用しているのであれば、 アクセスコントロールファイルに次のように記述します。 この例では、問題のあるクライアントの IP アドレスが 192.168.0.100 〜 192.168.0.120 の範囲にあるものとしています。
/etc/tcp.smtp
):
192.168.0.100-120:allow,RELAYCLIENT="@fixme"
192.168.0.:allow,RELAYCLIENT=""
:allow
/etc/tcp.smtp.cdb
の更新:
# cd /etc
# tcprules tcp.smtp.cdb tcp.smtp.$$ < tcp.smtp
FAQ に紹介されているメール矯正の設定では、
From: フィールドがないメールを受信すると、
「From: alias@defaulthost
」
フィールドが付加されてしまうという問題があります。
~alias/.qmail-fixup-default
で呼び出している
qmail-inject の代わりに、
次のようなラッパースクリプトを利用すれば回避できます。
#!/bin/sh
QMAILUSER=`echo $SENDER | sed 's/@[^@]*$//'`
QMAILHOST=`echo $SENDER | sed 's/^.*@//'`
export QMAILUSER QMAILHOST
qmail-inject -f "$SENDER" -- "$DEFAULT"
しかしなお、次のような問題が残ります。 1 と 2 は sendmail にあるヘッダー内のアドレスの補完機能に似ていますが、 qmail のこの設定では抑制できません。 3 はほとんどないと思われるケースですが、 まったくないとも言いきれません。
control/defaulthost
(なければ control/me
) のドメイン名が付加されてしまう。
control/defaultdomain
(なければ control/me
) のドメイン名が付加されてしまう。
From: alias@defaulthost
」となってしまう。
このように、 条件によっては望まない書き換えが実行されてしまうことがあります。 書き換えの対象とするクライアントは、 あなたの管理下にあるものだけに限るべきです。 外部からのメールには適用されないように設定してください。
sendmail は自ホスト宛のメールが宛先ユーザー不明の場合、 送信者にバウンスメールを送信するだけでなく、 自ホストの postmaster 宛にもその旨を通知するメールを送信することができます。 (実際にはそのほかのエラーについても通知可能らしい)
この動作を qmail で実現するには、
どのエイリアス/ユーザーにも一致しない場合のワイルドカードアドレスとなる
~alias/.qmail-default
ファイルに細工を施します。
宛先ユーザー不明のメールを postmaster@example.co.jp 宛に転送する例を示します。
bouncesaying は qmail 付属のコマンドで、
.qmail ファイルで送信者にバウンスメールを返す場合に使用します。
10.3.2 節で解説している
fastforward を利用しているなら -p
オプションを追加して、
/etc/aliases
に一致する名前がなかった場合に
fastforward 以降の配送指定が評価されるようにします。
~alias/.qmail-default
):
&postmaster@example.co.jp
|bouncesaying 'Sorry, no mailbox here by that name. (#5.1.1)'
~alias/.qmail-default
):
|fastforward -p /etc/aliases.cdb
&postmaster@example.co.jp
|bouncesaying 'Sorry, no mailbox here by that name. (#5.1.1)'
先の例はとてもシンプルでお手軽ですが、 管理者に通知 (転送) されるメールに次のような問題点があります。
そこで、この問題を対処したバウンスメール情報通知用のスクリプト notifynomailbox を用意しました。 その特徴を示します。
#!/bin/sh
#
# NAME
# notifynomailbox - Notify header of bounced mail that deliverred to
# this host but no such mailbox on this host.
#
# SYNOPSIS
# in .qmail-default:
# |notifynomailbox address ...
# |bouncesaying "Sorry, no mailbox here by that name. (#5.1.1)"
#
# AUTHOR
# SATOH Fumiyasu <fumiya-s-qmail@samba.gr.jp>
# 2001-11-05, since 2001-09-10
#
# VERSION
# 1.0.3
#
# COPYING
# GNU General Public License ver.2
cmd=notifynomailbox
qmail_home=/var/qmail
me_file=$qmail_home/control/me
if [ $# -eq 0 ]; then
echo "$cmd: usage: $cmd address ..." 1>&2
exit 0
fi
if [ ! -s $me_file ]; then
echo "unable to read control $me_file" 1>&2
exit 0
fi
me=`cat $me_file`
from=MAILER-DAEMON@$me
to=''
for t in "$@"; do
to="$to$t, "
done
to=`echo "$to" | sed 's/, $//'`
(cat <<EOF_MAIL; awk '/^$/{body=1} body==0{print}') | \
qmail-inject -f '' -- "$@"
From: $from
To: $to
Subject: nomailbox notice
Hi. This is the $cmd program at $me.
The qmail-send tried to deliver a message to this address, but no such
mailbox on $me. This is a warning message for postmaster.
Bounce notice mail was back to envelope sender $SENDER.
<$RECIPIENT>:
Sorry, no mailbox here by that name on this host. (#5.1.1)
--- Below this line is a copy of the message (header only for privacy).
Return-Path: <$SENDER>
EOF_MAIL
exit 0
この notifynomailbox スクリプトは
/var/qmail/bin
などにインストールしてください。
また、このスクリプトはあくまでも一例ですので、
必要に応じて改造を施してください。
次に組み込んだ例を示します。
~alias/.qmail-default
):
|notifynomailbox postmaster@example.co.jp
|bouncesaying 'Sorry, no mailbox here by that name. (#5.1.1)'
~alias/.qmail-default
):
|fastforward -p /etc/aliases.cdb
|notifynomailbox postmaster@example.co.jp
|bouncesaying 'Sorry, no mailbox here by that name. (#5.1.1)'
SENDMAIL
REMOVE.sendmail
INSTALL.vsm