この文書では Postfix + Courier-IMAP で POP before SMTP と IMAP before SMTP をする方法について扱います。sendmail を使った方法についてはいろいろ解説があったり、Postfix や Courier-IMAP の古いバージョンについて書いてあったり(しかし日本語のものでも英語サイトの全訳しただけってのもありましたが)したので、新しいものがあればなにかと有用だろうという意味もあります。現在下記のものを使い、POP と IMAP-SSL で POP before SMTP と IMAP before SMTP のサービスを提供しています。
用意したもの:
まず Postfix と DRAC をインストールします。言うまでもなく Postfix が メールの配送を司るプログラムで、25番ポートで待ち受けてメールを受信し てメールボックスに配送したり、別のサーバにメールを転送したりします(最 近は587番のsubmission portを使うことも増えてきました)。いずれも Berkeley DB 形式対応でコンパイルし、共通のデータベースが読めるように します。
Ports で Postfix を make すると途中で1回止まり、設定をするなら make config を実行しろ、と出るので、ここで忘れず BDB というオプションを選びます。portupgrade/portinstall を使っている人は、/usr/local/etc/pkgtools.conf の MAKE_ARGS に
MAKE_ARGS = {
'mail/postfix*' => '-DBATCH WITH_BDB=yes WITH_BDB_VER=41',
}
などと書いておくと、毎回のアップグレードのときいちいち Postfix のビルドで止まらず、また、Berkeley DB の指定を忘れてはまったりもせず、便利です。Linux 等でビルドする場合は make の際 make -DBATCH WITH_BDB=yes WITH_BDB_VER="41" とすれば OK です。WITH_BDB_VER はインストールされている Berkeley DB のバージョンによって 40 だったり 42 だったりもしますが、それはシステムの管理コマンドで確認してください。FreeBSD の Ports の場合後述する drac が Berkeley DB 3 と Berkeley DB 4.1 しかサポートしていないので、41を指定しましょう。
FreeBSD で Postfix を初めてインストールする人は、/etc/mail/mailer.conf が
# # Execute the Postfix sendmail program, named /usr/local/sbin/sendmail # sendmail /usr/local/sbin/sendmail send-mail /usr/local/sbin/sendmail mailq /usr/local/sbin/sendmail newaliases /usr/local/sbin/sendmail hoststat /usr/local/sbin/sendmail purgestat /usr/local/sbin/sendmail
となっているのを確認してください(これは sendmail を Postfix で置き換える設定です)。完全に sendmail を止める方法は /usr/ports/mail/postfix/pkg-message に書いてあります。
次に DRAC のインストールです。DRAC は POP/IMAP before SMTP をする際、POP や IMAP での接続要求があると、要求があったクライアントの IP をデータベースに記録するプログラムです。また、デフォルトでは30分通信がないとデータベースから IP を消すようになっています。Postfix 自体はデータベースから IP を読んでメールの中継の可否を決める仕組みが最初から備わっていますが、そのデータベースを動的に生成することができないので、この DRAC の登場となるわけです。
DRAC は元々 sendmail 向けに作られているためか、Postfix で使うためにはコンパイルのときフラグを渡す必要があります。Postfix 同様 pkgtools.conf で設定すると、
MAKE_ARGS = {
'mail/postfix*' => '-DBATCH WITH_BDB=yes WITH_BDB_VER="41"',
'mail/drac' => 'WITH_POSTFIX=yes WITH_POSTFIX_DB41=yes',
}
となります。一般的に、pkgtools.conf にこのような形で書けるものは全て各 port の Makefile を見れば書いてあります。今回であれば /usr/ports/mail/drac/Makefile を見ればよい、ということになります。
DRAC のインストールが終わったら、これを自動で起動する設定にします。DRAC は RPC を使って通信するので、portmap が起動している必要があります。最初は手で起動してもかまいませんが、システムの起動時に portmap を自動で起動させるには、/etc/rc.conf に
rpcbind_enable="YES"
と書きます。dracd の起動スクリプトは /usr/local/etc/rc.d/dracd.sh にあり、これを見ると dracd_enable="YES" でないと起動しないことが分かり、また、dracd_flags を使えば渡すフラグを指定できるので、結局 /etc/rc.conf には
rpcbind_enable="YES" dracd_enable="YES" dracd_flags="-e 15"
と書いておくことになります。この例では15分通信がなければデータベースからクライアントの IP を削除する設定にしてあります。他のフラグについては man rpc.dracd を参照してください。
また、dracd は接続を参照するホストを指定してセキュリティを向上するようになり、/usr/local/etc/dracd.allow がないと起動しないようになりました。サンプルは /usr/local/etc/dracd.allow-sample にあるので、コピーしてコメントアウトされている1行目を自分のホストの IP に書き換えましょう。
# dracd.allow: clients trusted by rpc.dracd # # The format of this file is one of more lines of # # netmask netaddr # Both netmask and netaddr must be dotted quads. # 255.255.255.255 61.211.239.46 255.255.255.255 127.0.0.1 ####
さて、Postfix と DRAC のインストールが終わったので、残るは Courier-IMAP のインストールです。Courier-IMAP のインストールについては メールサーバのセットアップ についても書いたので、そちらを参照してください。今回気をつけなければならないのは、Courier-IMAP を DRAC 対応にすることですが、現在は FreeBSD の port 側で oliver さんがこのサイトで配布しているパッチを当てて下さっているので、WITH_DRAC というオプションを指定するだけで使えるようになっています。(FreeBSD の port に取り込むためのパッチの作成には ume さんのお手伝いをいただきました。どうもありがとうございます。また、shige さんには oliver さんに取り次いでいただきました。どうもありがとうございました。)
MAKE_ARGS = { 'mail/postfix*' => '-DBATCH WITH_BDB=yes WITH_BDB_VER="41"', 'mail/drac' => 'WITH_POSTFIX=yes WITH_POSTFIX_DB41=yes', 'mail/courier-imap' => 'WITH_DRAC=yes', }というように WITH_DRAC を書き足し、portupgrade/portinstall でインストールしましょう。
最後に Postfix の設定を、DRAC で更新したデータベースを見るように変更して完了です。/usr/local/etc/postfix/main.cf に、smtpd_recipient_restrictions というパラメータを指定します。このパラメータについての説明は /usr/local/etc/postfix/sample-smtpd.cf にあります。これを参考に、main.cf に以下を追加します。
# drac
smtpd_recipient_restrictions = permit_mynetworks,
check_client_access btree:/usr/local/etc/dracd,
check_relay_domains
dracd のデータベースは (FreeBSD の場合) /usr/local/etc/dracd.db というファイルに格納されているので、check_client_access にはこのように指定します(末尾の .db は書きません)。これまで Postfix を BDB 対応なしで使っていた場合、/etc/aliases.db や postmap が使うデータベースの形式が変わるので、Postfix を再起動する前に newaliases や postmap を忘れずに実行しておいてください。
さて、これで設定は全て完了です。Postfix と portmap に dracd を起動し、Courier-IMAP を立ち上げてください。Outlook Express なり MozillaThunderbird なり Apple Mail なりで Courier-IMAP に接続し、SMTP サーバに同じホスト名を入れて送れるかどうか試してください。どうもお疲れさまでした!
dracd が正しく動いているかどうかは、Courier-IMAP で動かしている POP/IMAP サーバに接続し、db41_dump コマンドで /usr/local/etc/dracd.db を覗いてみると分かります。
usata@sodans% db41_dump /usr/local/etc/dracd.db VERSION=3 format=bytevalue type=btree HEADER=END 3231302e3137332e3232352e32353200 3130363135393033323800 DATA=END
のように返ってくれば成功です。この状態でこのデータベースに対して strings すると、認証された IP がなにか分かります。
usata@sodans% strings /usr/local/etc/dracd.db 1061590328 210.173.225.252
dracd が動いていないとき、もしくは認証されている IP がない(たとえば認証後30分経って接続が切れている)場合は HEADER=END と DATA=END の間にはなにもありません。db41_dump してきちんと結果が返ってこない場合は、そもそも DRAC が正しく BDB 対応でコンパイルされているかどうか確認しましょう。DRAC のデータベースは正しく更新されているのに外部から SMTP できない場合は、Postfix が正しく BDB でコンパイルされているかどうか、また、BDB を有効にしないでビルドした Postfix を使っていて入れ直した場合、/etc/aliases.db などのデータベースの形式が変わるので、忘れず newaliases と postmap (転送設定などを hash などのデータベースで作っていた場合) を実行してください。いずれの場合も /var/log/maillog や /var/log/messages にログが残っているはずなので、こちらを参考にしましょう。Inappropriate file type or format と出ているときは、Postfix と DRAC で参照している DB のバージョンが違うために起こるので、スペルを間違えていないかどうか今一度確認してください。
POP before SMTP がちゃんと動いているかどうか知りたい、という場合は、
usata@rico% telnet mail.usata.org 25 Trying 61.211.239.46... Connected to mail.usata.org. Escape character is '^]'. 220 sodans.usata.org ESMTP Postfix MAIL FROM: c10344 -at- mail.ecc.u-tokyo.ac.jp 250 Ok RCPT TO: usata -at- sodan.ecc.u-tokyo.ac.jp 554 <usata -at- sodan.ecc.u-tokyo.ac.jp>: Recipient address rejected: Relay access denied ^](←Ctrl キーを押しながら ]) telnet> quit Connection closed.
メールの送信元は MAIL FROM:、送信先は RCPT TO: で指定します。テストのためには、RCPT TO: には接続先のサーバのドメイン(ここでは usata.org)とは違うもの(ここでは sodan.ecc.u-tokyo.ac.jp)を指定しましょう。普通自分のドメインが宛て先になっていると、それは中継と見なされず、そのまま受信してしまうので、テストになりません。ここではその2つを変えているので、ちゃんと中継が拒否されているのが分かります。次に POP で接続します。
usata@rico% telnet mail.usata.org 110 Trying 61.211.239.46... Connected to sodans.usata.org. Escape character is '^]'. +OK Hello there. USER usata +OK Password required. PASS ********(←パスワードを入れます) +OK logged in. LIST 1 3651 2 20142 (メールの数だけ続く……) 105 557 . QUIT +OK Bye-bye. Connection closed by foreign host.
こうすると /usr/local/etc/dracd.db が更新されるはず(db41_dump と strings で確認してください)なので、この状態でまた SMTP を叩きます。
usata@rico% telnet mail.usata.org 25 Trying 61.211.239.46... Connected to mail.usata.org. Escape character is '^]'. 220 sodans.usata.org ESMTP Postfix MAIL FROM: c10344 -at- mail.ecc.u-tokyo.ac.jp 250 Ok RCPT TO: usata -at- sodan.ecc.u-tokyo.ac.jp 250 Ok DATA 354 End data with <CR><LF>.<CR><LF> hogehoge . 250 Ok: queued as 0BA5EA981 QUIT 221 Bye Connection closed by foreign host.
のように、今回はメールがちゃんと中継できることが分かります。エラーが出る、または、思った通りいかない、ということがあれば、まず見るのは /var/log/maillog と /var/log/messages です。Postfix が動いているホストで tail -f /var/log/maillog として Postfix や Courier-IMAP がどんなエラーを出すのか監視した状態で、上記のように telnet てテストすると、問題点がどこにあるのか見つかりやすいでしょう。
最後になりますが、POP/IMAP before SMTP は IP ベースで認証を行なうため、たとえばルータで外部とつながれたネットワークの中の誰かが POP/IMAP before SMTP を行なって SMTP サーバが使えるようになると、そのネットワーク内の誰もがその SMTP サーバを使用できるようになってしまいます。DRAC が IP v6 に対応していないため、この問題は POP/IMAP before SMTP という手法自体が持っているものです。より安全性を求めるなら、(サポートしているクライアントが十分とは言えませんが) SMTP AUTH を使ったり SMTP を SSL で保護したりするのが本筋であることを申し添えておきます。
