第9章 非常時接続環境におけるメール送受信 - qmail で作る快適メールサーバー

佐藤 文優 <https://fumiyas.github.io/>
2001年12月17日 更新, 2001年9月18日 以来

目次

9.1 非常時接続環境における問題と解決方法
9.2 非常時接続環境におけるメール送信
9.2.1 qmail によるメール送信
9.2.2 serialmail によるメール送信
9.3 非常時接続環境におけるメール受信
9.3.1 fetchmail によるメール受信
9.3.2 serialmail によるメール受信
9.3.3 メール受信するためのそのほかの方法
付録
参考文献
更新履歴

9.1 非常時接続環境における問題と解決方法

ADSL など安価な常時接続の手段が普及した昨今でも、 モバイル環境やダイアルアップ接続環境といったオフライン状態があるネットワーク形態もなお残されています。 そのような非常時接続環境では、 オフライン状態はもちろん、 オンライン/オフライン切り換えのタイミングにおいて考慮すべき問題がいくつか浮上します。

  1. オフライン時のメールの送信をどう扱うか?
  2. オフライン時に外部から自ドメイン宛に送付されたメールはどうなる?
  3. オンラインになった時に効率良くメール送受信処理を行なうには?
  4. オンライン/オフライン移行時のメール環境の設定の切り替えは?
  5. 一般ユーザーへの影響は?
  6. そのほか…?

消極的に、 オフライン状態ではメールの利用を諦めるという選択肢もあります。 メールクライアントの中には、 オフライン時のメールの読み書きをサポートする機能を有しているものがありますので、 そのようなメールクライアントをユーザーに利用してもらうのも手です。

設定の工夫をし、オフライン状態でもオンライン状態と (ほぼ) 変わりなくメールの送受信ができる環境が実現できれば便利です。 ユーザーがオフライン状態を意識せずに利用できる環境を用意すれば、 オフライン状態に関してユーザーに教育する必要がなくなります。 また、 あなた自身も含め、 ユーザーはストレスなくメールの読み書きができるでしょう。

9.2 節9.3 節 では、 ISP (Internet Service Provider) などにダイアルアップ接続するような非常時接続環境において、 常時接続環境と同じ具合にメールの送受信が可能になるように、 以下のような動作を実現する方法を解説しています。 これらを実現すれば、 オフラインの期間だけメールの配送が遅延すること以外、問題はなくなるでしょう。

メールの送信 - 9.2 節
オフライン時にメールクライアントから送信されたメールは、 一時的にローカルな環境内のメールサーバーのキューに溜めておく。
オンライン状態になったならキューのメールの配送を開始する。
メールの受信 - 9.3 節
一次的なメールの受信は、常時接続環境にあるメールサーバーに任せる。
オンライン状態になったら、 そのメールサーバーからメールをダウンロードする。
ローカルな環境内のホストに POP/IMAP サーバーなどを用意し、 メールクライアントはそれらからメールを取得するように設定する。

9.2 非常時接続環境におけるメール送信

9.2.1 qmail によるメール送信

多くの MTA は、 何らかの理由で配送先のメールサーバーに接続できなかった場合、 メールをキューに滞留し、 しばらく時間をおいた後に配送を再試行するようになっています。 qmail (qmail-send) の配送の仕様もそのようになっており、 一時的な理由で配送に失敗したメールは、 しばらくはキューに滞留し続けます。

MTA のこの特性を利用するならば、 オフライン状態になるローカルの環境内に 1つ MTA サーバーを用意して、 ローカル環境のメールクライアントからのメール送信にそれを使用するように設定するだけで、 目的は達成されます。

ローカルの qmail の配送経路の設定

接続先 (ISP など) に SMTP サーバーが用意されているなら、 ローカルの qmail がそのサーバーに配送を依頼するように設定しましょう。

オンライン時に DNS が利用できるなら、 もちろんローカルの qmail 自身に配送させることもできます。 しかし特定の SMTP サーバーに配送を任せることで、 ローカルの qmail は宛先アドレスごとの送付先ホストの検索 (ドメインの MX レコード検索) をしなくても済む分、 配送にかかる時間を短縮できます。 また、わずかですが、ネットワークの帯域を節約できます。 接続にかかる費用が従量課金制であったり、 ネットワーク帯域が狭いといった場合に有利です。

qmail (qmail-remote) に静的な配送経路を指示するには、 control/smtproutes ファイルを設定します。 詳細は qmail 付属のマニュアル qmail-remote(8) を参照のこと。 control/smtproutesファイルの各行には、 ドメイン名とそのドメイン宛のメール配送を依頼する SMTP サーバー名を、 以下のような書式で記述します。

ドメイン名:SMTP サーバー名:SMTP ポート番号

リモートへのメール配送をすべて特定の SMTP サーバーに送るには、 次のようにドメイン名を省略した行を記述します。 ポート番号を省略すると、SMTP 標準のポート番号 (25) が利用されます。

リモートへのメール配送をすべて ISP の SMTP サーバーに依頼する (control/smtproutes):
:mailhost.isp.example.net

control/smtproutes ファイルの設定を終えたら、 オンライン状態でメールを送信し、 正しく配送が行なわれることを確認してください。

ローカルの qmail に配送させたいなら

オンライン時に qmail が稼働するホストから DNS が利用できるなら、 qmail 自身に宛先ホストの検索 (MX レコードの検索) と配送を行なわせることができます。 よって、先の節で解説した control/smtproutes ファイルの設定は必要ありません。

特定のドメイン宛のメールだけ MX レコードに従い配送させたいという場合は、 control/smtproutes ファイルに宛先の SMTP サーバー名を省略した行を記述します。 control/smtproutes の設定は、 明示的にドメインが指定されている行のほうが優先されます。

特定のドメイン宛のメールは MX レコードに従い配送させる (control/smtproutes):
:mailhost.isp.example.net
specific.domain.example.jp:

キューの最長滞留時間の調整

長期にわたりオフライン状態になる可能性があるなら注意が必要です。 qmail はデフォルトで 7日以上キューに滞留していたメールはバウンスし、 送信者に返してしまいます。 キューの最長の滞留時間は control/queuelifetime ファイルで設定可能です。 通常であれば、 このファイルを用意せずデフォルト (604800 秒、つまり 7日間) にしておけばよいでしょう。

qmail にキューの処理を即時開始させる

オンライン状態になったときに、 qmail がキューの処理を開始するように設定します。 放っておいても qmail (qmail-send) は定期的にメールの再送を試みますが、 ある程度の遅延が生じます。 また、配送の遅延が長いメールほど、 次回の再試行までの間隔が長くなるという特性があります。

例として次のようなスクリプトを作成しました。 qmail-tcpok は qmail 付属のコマンドで、 過去に発生した SMTP 接続のタイムアウトの記録を抹消します。 SMTP によるリモートへのメール配送を実行する qmail-remote は、 前回タイムアウトした配送が再び失敗すると、 少なくとも 1時間は再送を試みません。 また、動作中の qmail-send のプロセスにアラームシグナル (ALRM) を送ることで、 キューに滞留しているメールの配送を即座に試みるよう促します。

qmail のキューの処理を即時開始させるスクリプト:
#!/bin/sh
/var/qmail/bin/qmail-tcpok
killall -ALRM qmail-send
※ Solaris の killall コマンドは、 プロセス名を指定したシグナルの送信はサポートしていない。 Solaris 7 以降であれば代わりに pkill コマンドを利用できる。

このスクリプトは、 オンライン状態になると同時に自動で実行されるようにしてください。 オンラインになる方法は、通常のネットワークカードによる接続、 PC カードによる接続、ダイアルアップ接続と様々ですが、 オンラインまたはオフラインへの移行時に追加の処理を組み込む方法もシステムにより様々です。

Red Hat Linux で ppp パッケージによりダイアルアップ接続しているなら、 /etc/ppp/ip-up スクリプトのコメントに記述されている解説に従って、 /etc/ppp/ip-up.local スクリプトに追加の処理を記述します。

Red Hat に限らずなんらかの Linux 系のシステムで PC カードによりネットワーク接続しているなら、 /etc/pcmcia/network.opts スクリプト内の start_fn() 関数内に上記と同じコマンドラインを記述します。 以下に記述例を示します。

オンライン時に qmail のキューの処理を即時開始させる (/etc/pcmcia/network.opts, Linux で PC カードにより接続する場合):
    …省略…
    # Extra stuff to do after setting up the interface
    start_fn () {
        /var/qmail/bin/qmail-tcpok
        killall -ALRM qmail-send
    }
    # Extra stuff to do before shutting down the interface
    stop_fn () { return; }
    …省略…

9.2.2 serialmail によるメール送信

serialmail は、qmail と同じく D. J. Bernstein 氏による作品です。 serialmail は maildir 形式のメールボックスをキューに見立て、 メールボックス内のメールを取り出し、 任意の SMTP サーバー (もしくは qmail 独自の QMTP サーバー) に配送を依頼することができます。

serialmail の Web サイト
http://cr.yp.to/serialmail.html

この節では、 オフラインとなる環境から送信されたメールを、 すべてキュー用の maildir 形式のメールボックスに配送し、 オンラインになったときに serialmail 付属の maildirsmtp コマンドを利用してメールを送信する方法を紹介します。 この方法は serialmail の付属文書ファイル TOISP にも記述されていますが、 本書では maildirsmtp 起動用の専用のユーザーを用意します。

図: maildirsmtp によるメール送信形態の例 (ISP にダイアルアップ接続): Send mail from maildir by serialmail(maildirsmtp) to ISP

serialmail のインストール

serialmail のコンパイルとインストールの手順は qmail とほぼ同様です。 実行バイナリやマニュアルなどは qmail と違い /usr/local 以下にインストールされます。

serialmail のソースの所在
http://cr.yp.to/software/serialmail-0.75.tar.gz
ftp://ftp.jp.qmail.org/qmail/serialmail-0.75.tar.gz (ミラー)
serialmail のコンパイルとインストール:
$ gzip -dc serialmail-0.75.tar.gz | tar xf -
$ cd serialmail-0.75
$ make it 2>&1| tee make.out
… バイナリなどのコンパイル状況 …
$ su
Password: root のパスワード
# make setup
./install
# make check
./instcheck

serialmail の各種バイナリ/ソースパッケージ

バイナリ/ソース RPM パッケージ (Red Hat Linux など)
http://www9.jp.qmail.org/rpms/qmail-addons/ (ミラー)
http://www.qmail.org/rpms/qmail-addons/
Debian GNU/Linux
開発版 (unstable, sid) かテスト版 (testing, woody) に含まれている 「serialmail-src」というパッケージをインストールし、 build-serialmail コマンドを実行してバイナリパッケージを作成する
FreeBSD など
FreeBSD の ports-current に「serialmail」という port が用意されている

ほかのドメイン宛のメールをキュー用メールボックスに集約

qmail の設定を変更し、 SMTP 経由 (qmail-smtpd) もしくはローカルのコマンド (qmail-inject など) から配送依頼されたメールを、 キュー用の maildir 形式のメールボックスに集めるようにします。 これを実現するには、qmail の仮想ドメイン機能を利用します。

qmail (qmail-send) は、 仮想ドメインのユーザー名/ドメイン名と配送先のローカルユーザーを control/virtualdomains ファイルで 「仮想ユーザー名@仮想ドメイン名:ローカルユーザー名」 という形式で指定します。 仮想ユーザー名、またはそれに加え仮想ドメイン名は省略可能です。 仮想ドメイン名まで省略するとワイルドカードとなり、 あらゆるドメイン宛のメールをこの設定で受け取ることになります。 ただし、qmail-send は control/virtualdomains より先に control/locals ファイルを評価するため、 自ホスト宛に配送されたメールは仮想ドメインの設定に影響されず、 ちゃんとローカルユーザーのメールボックスに配送されます。

まずはキュー用の maildir 形式のメールボックスを用意しましょう。 ここでは、専用のユーザー serialmail とメールボックス pppdir を作成することにします。 ユーザー serialmail のホームディレクトリは /var/qmail/serialmail とします。

serialmail 実行用ユーザーとキュー用メールボックスの作成:
# useradd -m -d /var/qmail/serialmail -s /bin/sh serialmail
# cd /var/qmail/serialmail
# /var/qmail/bin/maildirmake pppdir
# chonw -R serialmail pppdir
# ls -ld pppdir
drwx------    5 serialmail users       120 Sep 20 21:55 pppdir
※ ユーザーを追加する方法はシステムにより異なるため、適宜読み換えること。 この例は多くの Linux ディストリビューションや Solaris で有効である。

次に、 仮想ドメインの設定によりユーザー serialmail に配送されるメールが ~serialmail/pppdir に保存されるように、 .qmail ファイルを用意します。 ここでは、 「serialmail-ppp-実際の宛先アドレスのローカル部」 で受け取ることにします。 よって、ワイルドカードな拡張アドレス定義となる ~serialmail/.qmail-ppp-default を作成します。

仮想ドメインで受信したメールを pppdir に配送させる:
# su - serialmail
$ echo ./pppdir/ > .qmail-ppp-default
$ chmod 644 .qmail-ppp-default
$ exit

最後に仮想ドメインの設定を施し、 control/locals のドメイン宛以外のすべてのメールが serial-ppp に配送されるようにします。 control/virtualdomains ファイルの設定を終えたら、 qmail-send プロセスを再起動するか HUP シグナルを送信してください。

自ホスト宛以外のすべてのメールを serial-ppp で受け取る (control/virtualdomains):
:serialmail-ppp

キュー用メールボックスへの配送のテスト

他ドメイン宛のメールが ~serialmail/pppdir に配送されることを確認しましょう。 通常の配送テストと同様に qmail-inject でメールを送信してみます。 メールを送信した結果、 ~serialmail/pppdir/new ディレクトリ以下に送信したメールが保存されるはずです。

保存されたメールのファイルを覗いてみると、 qmail によっていくつかのヘッダーフィールドが追加されていることがわかります。 その中でも Return-Path: と Delivered-To: フィールドは serialmail にとって重要です。 serialmail はメールボックス内のメールを配送するときに、 この 2つのフィールドから送信元と宛先のアドレスを決定します。

キュー用メールボックスへの配送のテスト:
# /var/qmail/bin/qmail-inject -f fumiya@local.example.com
To: bob@external.example.org
Subject: delivery test

sent?
Ctrl+d を入力
# cd /var/qmail/serialmail/pppdir/new
# ls -l
total 4
-rw-------    1 serialmail users       338 Sep 20 23:01 1000994490.20471.sugar
# cat 1000994490.20471.sugar
Return-Path: <fumiya@local.example.com>
Delivered-To: serialmail-ppp-bob@external.example.org
Received: (qmail 20440 invoked by uid 0); 20 Sep 2001 14:00:35 -0000
Date: 20 Sep 2001 14:00:22 -0000
Message-ID: <20010920140022.20439.qmail@sugar.local.example.com>
From: fumiya@local.example.com
To: bob@external.example.org
Subject: delivery test

sent?

serialmail (maildirsmtp) によるメール送信

キュー用メールボックスに保存されたメールは、 serialmail 付属の maildirsmtp コマンドを利用して配送します。 maildirsmtp コマンドは、 指定されたメールボックスからメールを読み込み、 Return-Path: フィールドのアドレスを送信者アドレス、 最初の Delivered-To: フィールドのアドレスから prefix (後述) を取り除いたものを宛先アドレスとして、 指定された SMTP サーバーにメールの配送を依頼します。

書式
maildirsmtp dir prefix host helohost
引数
dir
送信すべきメールが保存されている maildir 形式のメールボックス
prefix
最初の Delivered-To: フィールドのアドレスの先頭から、 この引数で指された部分を削除し、宛先のアドレスとする
host
メールの配送を依頼する SMTP サーバー
helohost
SMTP の HELO コマンドで通知するホスト名

それでは手動で maildirsmtp コマンドを実行してみましょう。 仮想ドメインの設定により、 最初の Delivered-To: フィールドに表われる宛先は 「serialmail-ppp-実際の宛先アドレス」となるので、 prefix には「serialmail-ppp-」を指定します。 host には接続先にある SMTP サーバーを指定します。

maildirsmtp コマンドでキュー用メールボックスのメールを送信:
# su - serialmail
$ PATH=/usr/local/bin:$PATH; export PATH
$ maildirsmtp pppdir serialmail-ppp- mailhost.isp.example.net `hostname`

9.2.1 節の 「qmail にキューの処理を即時開始させる」で解説しているのと同様に、 オンラインになったときに自動でメール送信処理が開始されるようにしましょう。 以下にスクリプトの例を示します。 Red Hat Linux の ppp パッケージでダイアルアップ接続しているなら、 /etc/ppp/ip-up.local スクリプトに組み込んでください。

maildirsmtp コマンドでキューのメールを送信させるスクリプト:
#!/bin/sh
ms_cmd=/usr/local/bin/maildirsmtp
ms_user=serialmail
ms_dir=pppdir
ms_prefix=$ms_user-ppp-
ms_host=mailhost.isp.example.net
ms_helohost=`head -1 /var/qmail/control/me`
if [ -f /var/qmail/control/helohost ]; then
    ms_helohost=`head -1 /var/qmail/control/helohost`
fi
su - $ms_user -c "$ms_cmd $ms_dir $ms_prefix $ms_host $ms_helohost"
※ このスクシプトは root が起動することを想定している。
※ この例では、 helohost の値を qmail の設定により決定している。

9.3 非常時接続環境におけるメール受信

この節では、 接続先にあるメールサーバーに到着しているメールをオンライン時にダウンロードし、 ローカルのメールボックスに配送する方法を紹介します。 ローカル環境に POP/IMAP サーバーを用意すれば、 オフライン時でも支障なくメールを読むことができます (もちろん、メールボックスを保持するホストで直接メールボックスを参照するメールクライアントを利用すれば、ローカルの POP/IMAP サーバーは必要ありません)。

9.3.1 fetchmail によるメール受信

fetchmail は、非常時接続環境において、 効率的にメールを取得・転送するためのソフトウェアです。 具体的には、 fetchmail はリモートの POP/IMAP サーバーからメールをダウンロードし、 任意の MTA かローカルメーラーに配送を依頼することができます。

fetchmail の Web サイト
http://tuxedo.org/~esr/fetchmail/

fetchmail のインストール

以下に procmail のコンパイルとインストール例を示します。 カスタマイズしてコンパイルする場合は、 configure スクリプトに適宜オプションを指定します。 詳細は付属の INSTALL ファイルと `./configure --help` の出力を参照のこと。 デフォルトでは /usr/local 以下にインストールされます。

fetchmail のソースの所在
http://tuxedo.org/~esr/fetchmail/
ftp://ftp.win.ne.jp/pub/network/mail/fetchmail/ (ミラー)
fetchmail のコンパイルとインストール:
$ gzip -dc fetchmail-5.9.5.tar.gz | tar xf -
$ cd fetchmail-5.9.5
$ ./configure 2>&1| tee configure.out
… コンパイル前の準備の状況 …
$ make 2>&1| tee make.out
… バイナリなどのコンパイル状況 …
$ su
Password: root のパスワード
# make install 2>&1| tee make_install.out
… インストール状況 …

Linux ディストリビューションや FreeBSD などでは標準で fetchmail のパッケージが用意されていることでしょう。 お手軽にそちらをインストールしてご利用ください。

ローカル配送に使う procmail の準備

この後の解説では、 fetchmail でダウンロードしたメールを、 procmail を利用してメールボックスに配送させています。 procmail のソースからのコンパイル/インストールについては、 「10.3.4 sendmail と同じメールボックスヘの配送」を参照のこと。

procmail の標準設定では、メールは sendmail と同じ、 共有スプールディレクトリ内の mbox 形式のメールボックスに配送します。 これを変更するには、システム全体の procmail の設定ファイル /etc/procmailrc を用意します。 例えば、デフォルトで各ユーザーのホームディレクトリの maildir 形式のメールボックスに配送させるには、以下のように記述します。

procmail のデフォルトの配送先の指定 (/etc/procmailrc):
DEFAULT = $HOME/Maildir/

fetchmail によるメール受信の実験

あるユーザーで個人用の fetchmail の設定をして、動作のテストをしてみましょう。 ユーザー用の標準の設定ファイルはホームディレクトリの .fetchmailrc になります。 以下に POP3 サーバーからメールをダウンロードし、 procmail を利用してメールボックスへ配送させるための .fetchmailrc の例を示します。 fetchmail は、 設定ファイルのアクセス許可がほかのユーザーが参照できる状態になっていると、 実行を拒否します。 `chmod 600 .fetchmailrc` などとしておきましょう。

POP3 サーバーからのダウンロードと procmail による配送 (~/.fetchmailrc):
defaults
    protocol pop3
    keep
    no mimedecode
    mda "/usr/local/bin/procmail -f'%F'"

poll mailhost.isp.example.net
    user "fsatoh" pass "fumiya's-pass"
※ この設定例では keep キーワードを指定してあるため、 サーバーのメールボックスからメールは削除されないことに注意。

ここで記述している設定の意味は以下の通りです。 ここではテストのために fetchmail を実行するので、 keep キーワードを指定しています。 詳細は fetchmail(1) などを参照のこと。

defaults
この行以降にデフォルトの設定を記述する
protocol pop3
ダウンロード元のサーバーとの通信プロトコルを POP3 とする
keep
ダウンロードしたメールをサーバー上から削除せずに残す
no mimedecode
quoted-printable 形式で MIME エンコードされた部分をデコードしないようにする
最近の fetchmail はこれがデフォルト
mda "/usr/local/bin/procmail -f'%F'"
配送を依頼するコマンド (Mail Delivery Agent) の指定
%F は実行時に送信者アドレスに置き換えられる
procmail の -f オプションは送信者アドレスを指定するためのもの
poll mailhost.isp.example.net
ダウンロード元のサーバー名の指定
この行以降にこのサーバー固有の設定を記述する
user "fsatoh" pass "fsatoh's-pass"
サーバーのメールボックスアクセス用のユーザー名とパスワードの指定
fetchmail の手動実行によるメール配送:
$ fetchmail 
4 messages for fumiya at mailhost.isp.example.net (15562 octets).
reading message 1 of 4 (4129 octets) .... not flushed
reading message 2 of 4 (2289 octets) .. not flushed
reading message 3 of 4 (6031 octets) ..... not flushed
reading message 4 of 4 (3113 octets) ... not flushed

複数のユーザーのメールボックスに対応

複数のユーザーのメールボックスをまとめてダウンロードし、 ローカルのメールボックスに保存するための設定を解説します。 ここでは fetchmail から procmail を利用して各ユーザーのメールボックスに保存させるため、fetchmail を root 権限で動作させます。

procmailrc ファイルは次のようになります。 メールボックスにアクセスするためのユーザー名/パスワード指定に加え、 配送先のローカルユーザーのログイン名を to キーワードに続けて指定します。 これは双方のユーザー名が一致している際も必要です。 mda キーワードの procmail には、 配送先のローカルのユーザー名を指定する -d オプションを追加します。 %s は、実行時に to キーワードで指定されたユーザー名に置き換えられます。

複数のユーザーのメールをまとめてダウンロードする設定 (/etc/fetchmailrc):
defaults
    protocol pop3
    no mimedecode
    mda "/usr/local/bin/procmail -f'%F' -d'%s'"

poll mailhost.isp.example.net
    user "fsatoh" pass "fsatoh's-pass" to "fumiya"
    user "bob" pass "bob's-pass" to "bob"
    user "carol" pass "carol's-pass" to "carol"
※ ファイルのアクセス権は 0600 (-rw-------) にすること

スーパーユーザーになり、手動で fetchmail を実行してみましょう。 fetchmail に特定の設定ファイルを指示するには -f オプションを用います。

fetchmail の手動実行によるメール配送 (複数ユーザー対応):
$ su 
Password: root のパスワード
# fetchmail -f /etc/fetchmailrc
…ダウンロードと配送の状況…

fetchmail をデーモンモードで稼働させる

fetchmail をデーモンモードで稼働させることで、 メールのダウンロードと配送を定期的に実行させることができます。 デーモンモードで稼働させるには、--daemon オプションと、 ダウンロードと配送を実行する間隔を秒数で指定します。 デーモンプロセスによる実行の経過が syslog により記録されるように、 --syslog オプションも同時に指定するとよいでしょう。 稼働中の fetchmail デーモンプロセスは、

fetchmail デーモンの起動 (複数ユーザー対応):
$ su 
Password: root のパスワード
# fetchmail -f /etc/fetchmailrc --daemon 300 --syslog

fetchmail に -q オプションを指定して実行することで停止することができます。 必要であれば、オフライン状態に戻ったときに停止させましょう。

fetchmail デーモンの停止:
# fetchmail -q
fetchmail: background fetchmail at 6497 killed.

fetchmail 利用上の注意

fetchmail は、 ダウンロードしたメールを procmail のようなローカルメーラーに渡す方法のほか、 任意の SMTP サーバーに渡して内部環境へのメール配送を依頼することもできます。 fetchmail を稼働させるホストとメールボックスを保持するホストが別の場合は、 この方法を用いて配送するとよいでしょう。 fetchmail をスーパーユーザー権限で動作させる必要がなくなるため、 より安全であるというメリットもあります。

ただし fetchmail で SMTP サーバー (MTA) を利用する場合は細心の注意を払うようにしてください。 過去に数回、fetchmail や MTA の設定ミスにより、 次のような現象に遭遇したことがあります。 しかもこのような現象は運用している本人にはすぐにはわからず、 テストを繰り返すうちに被害を拡大してしまう例が多くあります。

1.8.2 エンベローブアドレス」以降の節で解説しているように、 MTA に指示した送信者アドレスと宛先アドレスは、 メールに含まれる From: フィールド, To:/Cc: フィールドのアドレスと一致しないことがあります。 一方メールのそのほかのヘッダーフィールドには、 明示的に送信者アドレス/宛先アドレスを示すものが含まれていないことがあります。

fetchmail はリモートのメールボックスから取得したメールを再配送するために、 いくつかのヘッダーフィールドから送信者アドレスと宛先アドレスを「類推」します。 このため時には類推に失敗し、誤ったアドレスを導き出す可能性があります。 先の紹介したような fetchmail の障害は、 この苦肉の策によって引き起こされているのかもしれません。

qmail (qmail-local) は、 メールをメールボックスに保存するときに、 Return-Path: フィールドに送信者アドレス、 Delivered-To: フィールドに最終的な宛先アドレスを記録します。 エイリアスなどにより転送する際も、 qmail は元の宛先アドレスを追加の Delivered-To: フィールドに記録します。

ダウンロード元のメールボックスサーバーが qmail でメールを受信しているなら、 fetchmail が Return-Path:/Delivered-To: フィールドを参照するように -E Return-Path オプション (envelope キーワード)、 -Q prefix オプション (qvirtual キーワード) などを指定するとよいでしょう。 オプションの詳細は fetchmail(1) を参照してください。

9.3.2 serialmail によるメール受信

送信と同じように、 受信においても serialmail を利用できます。 ただし、メールボックスは接続先のメールサーバーに保持されており、 そのホスト上で serialmail を実行しなければなりません。 この節で紹介する設定例は、 接続先 (ISP など) に qmail (あるいは互換 MTA) と serialmail が用意され、 SSH などの方法でローカルから接続先の serialmail (maildirsmtp) を実行できることが前提です。 この方法は serialmail の付属文書ファイル FROMISP にも紹介されています。

図: maildirsmtp によるメール受信形態の例 (ISP にダイアルアップ接続): Receive mail from maildir on ISP via maildirsmtp

これ以降の解説では、 以下のような環境でメールを受信することとします。 また、ダイアルアップ接続するホストには受信用の qmail が稼働していることにします。

接続形態
ISP へのダイアルアップ IP 接続
受信するメールのドメインの名前
yoursite.example.com
メールボックスを保持している ISP のホストの名前
mailhost.isp.example.net
mailhost.isp.example.net へのログイン権限を与えられたユーザー
youraccount

ローカルの qmail で受信するための設定

ローカル環境に qmail (qmail-smtpd) などの SMTP サーバーを用意し、 リモートの maildirsmtp コマンドから配送されるメールを受け取れるようにします。

yoursite.example.com ドメイン宛のメールは DNS の MX の設定により ISP のメールサーバー内のメールボックスに配送されます。 これを maildirsmtp コマンドでローカルの SMTP サーバーに配送するわけですが、 その際の宛先アドレスのドメイン名は元のまま yoursite.example.com になります。 そこで、ローカルの qmail の設定ファイル control/rcpthostscontrol/locals ファイルに yoursite.example.com を記述します。

リモートの qmail の設定

接続先 (ISP など) の qmail では、 yoursite.example.com ドメイン宛のすべてのユーザーのメールを、 単一のメールボックスに配送するように設定してもらいましょう。 ユーザーごとにメールボックスが分かれていても、 その数だけ maildirsmtp を起動すれば対応できますが、 一つにまとまっていたほうが簡単です。

次のように、 仮想ドメインの設定で yoursite.example.com ドメイン宛のメールを youraccount に配送するように設定し、 ユーザー youraccount の .qmail ファイルで保存先のメールボックスを指定します。

yoursite.example.com ドメイン宛のメールをユーザー youraccount-ppp に配送させる (ISP ホストの control/virtualdomains):
yoursite.example.com:youraccount-ppp
youraccount-ppp 宛のメールを ./pppdir/ に保存させる (ISP ホストの ~youraccount/.qmail-ppp-default):
./pppdir/

serialmail (maildirsmtp) によるメール受信

maildirsmtp のインストール方法やコマンドライン引数については 「9.2.2 serialmail (maildirsmtp) によるメール送信」を参照のこと。 ここでの使い方も基本的に送信の場合と同じです。 ただし、 メールボックスがある接続先 (ここでは ISP) のホストにログインして maildirsmtp コマンドを実行しなければなりません。

オンライン時に動的に IP アドレスが割り当てられるなら、 まずはそのアドレスを求めます。 端末型ダイアルアップ接続であれば、大抵は動的割り当てになっていることでしょう。 ネットワークインターフェイスに割り当てられている IP アドレスを知るには、 ifconfig コマンドを利用します。

ダイアルアップ接続で割り当てられた IP アドレスを求める (ダイアルアップで使用しているインターフェイスが ppp0 の場合):
local$ /sbin/ifconfig ppp0
ppp0      Link encap:Point-to-Point Protocol  
          inet addr:172.25.0.198  P-t-P:172.25.0.1  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1524  Metric:1
          RX packets:10 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3 
          RX bytes:831 (831.0 b)  TX bytes:564 (564.0 b)

自分のサイトに割り当てられた IP アドレスが判明したら、 ISP のメールサーバーに SSH (Secure SHell) などの手段でログインし、 maildirsmtp コマンドを起動してメールボックスのメールを自分のサイトの SMTP サーバーに向けて送信します。 メールボックス内のメールの最初の Delivered-To: フィールドは、 仮想ドメインによる配送指示によって 「youraccount-ppp-宛先ユーザー名@yoursite.example.com」 となります。 よって、maildirsmtp コマンドの prefix には 「youraccount-ppp-」を指定します。

ISP のホストへのログインとローカルの SMTP サーバーへのメール配送:
local$ ssh -l youraccount mailhost.isp.example.net
Enter passphrase for RSA key 'yourname@local.yoursite.example.com': 秘密鍵のパスフレーズを入力
mailhost$ maildirsmtp pppdir youraccount-ppp- 172.25.0.198 `hostname`

9.3.3 メール受信するためのそのほかの方法

RFC 1985 「SMTP Service Extension for Remote Message Queue Starting」 には、 リモートの SMTP サーバーに対し、 キューに滞留しているメールを即時送信するよう要求するための SMTP 拡張コマンド、 ETRN が定義されています。 9.3.1 節で紹介している fetchmail は ETRN コマンドの発行をサポートしています。

qmail (qmail-smtpd) は ETRN コマンドに対応していませんが、 ETRN と同様の動作を実現する方法が serialmail の付属文書ファイル AUTOTURN で紹介されています。 また、qmail に ETRN を実装するためのパッチも存在します。

qmail の ETRN コマンド対応パッチの所在
ftp://ftp.win.ne.jp/pub/network/mail/qmail/qmail-etrn-0.1f.diff

付録

参考文献

serialmail の付属文書ファイル
TOISP
FROMISP
AUTOTURN
マニュアル
fetchmail(1)
procmail(1)
maildirsmtp(1)
dot-qmail(5)
qmail-remote(8)
qmail-send(8)
オフラインでメール
http://plaza17.mbn.or.jp/~chi/FreeBSD/HowTo/mail/
RFC: SMTP Service Extension for Remote Message Queue Starting
RFC 1985

更新履歴

2001-12-17 佐藤文優
初版発行前の校正の取り込み。
2001-11-12 佐藤文優
http://www.qmail.org を紹介している箇所にミラー http://www9.jp.qmail.org を追加。
2001-10-11 佐藤文優
フィールド名のあとにコロン「:」を追加
2001-10-08 佐藤文優
「ヘッダー」→「フィールド」、あるいは「ヘッダーフィールド」
2001-10-07 佐藤文優
第1稿の完成
2001-09-18 佐藤文優
執筆開始