Dovecotのインストール


POP3/IMAP4サーバにDovecotの採用を決めたので早速インストールを始める。
まずはDovecotのホームページからソースをダウンロードしてくる。
私がダウンロードした時点の最新版は v1.1.7 でした。

ソースを展開してconfigureを行うが、ここでPostgreSQLに対応させておく必要がある。
# ./configure --with-pgsql
続けて
# make
 
# make install

で、インストール完了。
続けて実行用のアカウントとグループを作成する
# pw groupadd dovecot
# pw useradd dovecot -g dovecot -d /nonexistent -s /usr/sbin/nologin

そして設定ファイルの編集。
/usr/local/etc/ にサンプルファイルがインストールされているのでコピーして使う。
# cp dovecot-example.conf dovecot.conf
設定ファイルの中で変更したのはプロトコル関係が主。
#protocols = imap imaps
protocols = imap pop3
 
#disable_plaintext_auth = yes
disable_plaintext_auth = no
 
#mail_location =
mail_location = maildir:~/Maildir
 
#ssl_disable = no
ssl_disable = yes

とりあえず実験中なのでSSLは非対応とし、IMAPとPOP3を有効にした。

設定が終わったのでDovecotを実行する。
# /usr/local/sbin/dovecot
で、PCの方からPOP3とIMAP4の両方でアクセスしてみてる。
無事受信できているので、とりあえずインストール完了。

ついでにIMAP-IDLEも試してみたい。
PC用のメールソフトでIDLEコマンドに対応していそうなのがThunderbirdなので、こいつにアカウントを設定してやる。
定期受信をしないよう設定しておき、別のPCからテストアカウントへメールを送る。
Thunderbirdを見ると受信箱に新着がすぐに入ってくる。
ちゃんと動いていそうだ。 (^-^)

MRAはDovecotにする事に


Maildir形式でPostfixは動き出した。
しかし、現時点でまだPCからメールを受信することが出来ない状況なので、そろそろMRAを入れて受信できるようにしないと実験が進まないのでMRAをインストールしよう。

これまではQpopperを使ってPOP3を提供してきたが、今回はIMAP4も提供したいのでこちらも切り替えることにする。
IMAP4はUW-IMAPを実験的にインストールしたことはあるが、今回はちゃんと選定しよう。

で、選択肢は何があるかというとOBATA Akio氏のThe IMAP Conneco-chan良い比較表を見つけた。

選定にあたっての条件としては

  • POP3とIMAP4が両方使える
  • Maildir形式に対応している
  • Postfixと認証連携が出来る
  • PostgreSQLでバーチャルホストのユーザー管理が出来る
  • コメントをくれたito氏の期待に応えIMAP-IDLEでiPhoneにプッシュ配信できる

と行った所。

最後の条件の所だが、iPhoneの仕様を色々調べてみるとiPhone自体には普通の携帯メールのようなキャリアのメールサーバ側から端末へメールを送りつけて着信させるプッシュ配信の仕組みは無いようだ。
SoftBankが提供するメールアドレスについてはアプリの方で何らかの対応をしてプッシュ配信っぽく見せている様子。
米国YahooとmobileMeに関してはIMAP-IDLEを使ってプッシュ配信をしている様子。

IMAPもPOP3同様定期的にクライアント側からサーバ側に「新しいメール来てない?」と問い合わせを行うことで新着情報を得ている。
PCならそれでも良いのかもしれないが携帯だと定期的にパケットが出るため通信費が嵩む上、通信を行うと電池の消費が進むことになり面白くない。

そこで登場するのがIMAPの拡張機能であるIDLEコマンド。
クライアント側は受信等を終えて待機状態にはいる時サーバに対してIDLEコマンドを送ると、サーバ側は新着メール等サーバ側の情報に変化があった時通知をしてくれる。
クライアントは通知を受けたら受信等の処理を行うという手筈になっている。
これなら新着メールが来なければ通信は発生しないのでパケット代も掛からないし電池の消費も抑えられるという仕組み。
なかなか良く出来てる。

これはPCの方でも結構有効になりそう。と言うのも定期的に「新しいメール来てない?」と問い合わせを受けるサーバ側はその度に処理が動くので負荷が発生する。一人や二人なら良いが大人数になるとそれなりに大変。
みんながIDLEを使えば定期的に負荷が発生することは無くなり、トータルとして負荷軽減になりそうかなと思っている。

と言う訳で、上記の条件に照らし合わせて今回採用するMRAはDovecotに決めた。
新しい物好きというのもあるが、後発であるだけに機能が洗練されていてセキュリティーへの配慮もされているように思われる。
そして、設定ファイルの記述が比較的簡単そうだというのも選定理由。
ただ新しいだけに日本語での情報が少ないのが難点だが、まぁなんとかなるでしょうって事で採用決定。

頑張ってインストールしなければ・・・

PostfixをMaildir形式に変更する


とりあえずPostfixのインストールを終え、PostgreSQLとの連携もうまくいっている様子。
次なる野望はメールスプールをmbox形式からMaildir形式への変更。

なぜ、mbox形式からMaildir形式に変えるかというと、mbox形式のメールスプールは一人のユーザーのメールを一つのファイルに纏めて書き込んでいるため、たくさん溜め込むとファイルの容量が肥大化してしまうのが一番の問題。
POP3等で受信を始めるとMTAとの競合を避けるためMRAがメールスプールのファイルのコピーを作り、コピーしたファイルからメールを受信させるという動きをする。
この時、コピーするファイルが大きいと時間が掛かり、場合によってはタイムアウトが発生してしまう。
メールソフトの定期受信の時間間隔が短いと、コピーしたファイルの書き戻し(削除されたモノ等の整合性を取ってる)作業が間に合わずデッドロックを起こしたりすることがある。
今どきの添付ファイルが付いていたり、HTML形式で画像が添付されていたりするメルマガが大量に届くメール事情を考えると、一考の余地がある。

Maildir形式にすると何が良いのかというと、まず一番はメールスプールは一通のメールに付き一つのファイルが作成される。
たくさんメールを溜め込んでも溜まったメールの分だけファイルが作成されるだけで、一つのファイルの容量はそんなに大きくはならない。
また、MTAが受け取った新しいメールは新しいファイルで保存させるため競合を気にしなくなるので、変にファイルのコピーを行ったりしなくなり処理が高速で安定してくる。
IMAP4を運用するにあたってもmbox形式よりは親和性が高いので安心して利用できる。
と言うのが私の私見です。

と言うことでメールスプールの形式をMaildir形式へと変換することにする。
まず初めにやることは、現状のmbox形式で貯まっているメールをMaildir形式にコンバートしてやること。
ググってみるといくつか有名な変換スクリプトがあるみたいで、今回はmbox2maildirというのを使うことにした。
まずはmbox2maildirをこちらから入手してサーバーに保存。PerlのスクリプトなのでPerlのパスが自分の環境と違っていれば修正し、実行権を付けてやる。
続いて変換するユーザーアカウントでサーバーへログインして実行してみる。
% /usr/local/src/mbox2maildir/mbox2maildir.pl /var/mail/xxxxx ./Maildir/
ここで注意しなければいけないのが、出来上がったメールスプールファイルのパーミッションが 644 になっていて、他人からも覗けてしまうこと。
なのでパーミッションを変更してやる。
% chmod 600 ./Maildir/new/*
これでコンバートは完了。
後はPostfixの設定ファイルを書き換えてやり、新たに受信したメールもMaildirの方へ保存するようにする。
/etc/postfix/main.cf を以下のように書き換える。
#mail_spool_directory = /var/mail
home_mailbox = Maildir/

そしてPostfixに設定ファイルを読み込ませる。
# /usr/sbin/postfix reload
これで、メールを送ってみて Maildir/new/ にファイルが増えれば設定成功なので試しに送ってみる。
無事メールが届いている様子なので、次なる挑戦はメールをPCで受信することかな。

Postfix + PostgreSQL でメールアカウントを制御


まずはMTAをPostfixに切り替えて無事動き出した。
次なる野望はPostgreSQLでメールアカウントを制御すること。

Postfixの設定でDB化出来ることは結構あるみたいだ。
基本的に maptype:mapname 形式で指定される情報はDBで対応できると見ていい。

で、早速実験開始!
いきなりバーチャルホストを使った実験は他の準備が整っていないので止める。
手っ取り早そうなのは Alias をPostgreSQLで扱うこと。
まずはPostgreSQL側の設定から始める。

他のサイトを見るとDBにPostfix用のユーザーアカウントを作って、それで全てを操作するようにしている。
でも、私の方はちょっと違った方法を試してみたい。
と言うのも、Postfix側からはDBを参照するだけでDBの中身を書き換える必要性は無い。
であれば、参照しかできないDBのユーザーアカウントをPostfix用に用意して、参照だけさせるのがいいと思われる。
なんせPostfixの設定ファイルにDBのユーザー名とパスワードがはっきり書かれる訳で、何かの理由で他の人に見られてしまったらメールの配送に関わる情報を自由に書き換えられてしまう可能性が残ってしまう。これはセキュリティー上決して良い状態ではない。
しかし、読み出ししかできないユーザーアカウントであれば最悪見えるだけで変更は出来ないので、若干ではあるがセキュリティーが向上される。(気分の問題って話もあるけど・・・)
まぁ実験なんで色々試してやろうと言うことで、Postfix用の読み出し専用アカウントをPostgreSQLに用意することにする。
% createuser -P postfix
Enter password for new role: ********
Enter it again: ********
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n

続いて普段PostgreSQLで使用しているユーザーアカウントで pgsql を起動し、Database と Table を作り、Postfix用のユーザーアカウントにアクセス権を設定する。
CREATE DATABASE postfix OWNER ***** ENCODING 'LATIN1';
 
GRANT CONNECT ON DATABASE postfix TO postfix;
 
CREATE TABLE aliases (
  record_id    SERIAL    PRIMARY KEY,
  alias        TEXT      NOT NULL,
  address      TEXT      NOT NULL,
  status_flag  SMALLINT  DEFAULT 0,
  note         TEXT
);
 
GRANT SELECT ON TABLE aliases TO postfix;

ここで一つ注意点が見つかった。
初めは何も考えず Database を作ってテストを行った所、
warning: dict_pgsql: cannot set the encoding to LATIN1, skipping unix:/tmp
というエラーメッセージが出てしまい、Postfixが起動できなくなってしまった。
どうやらpostfixはDBの文字コードが LATIN1 じゃないとダメらしい...我が儘なヤツだ。

aliasesテーブルの中身としては

record_id:レコードの管理番号
alias:OS上のアカウントなど最終配送先
address:メールが送られてくる時の宛先メールアドレス
status_flag:レコードの有効性を管理する 0は無効、1は有効
note:後で管理ツールを作った時にメモを書き込むためのカラム

続いてDBにAlias用のデータを入れる。
INSERT INTO aliases (alias,address,status_flag) VALUES ('root','postfix',1);
と言った感じで /etc/mail/aliases にあるモノをどんどん入れていく。
今回は実験第一弾なので全て入れたが、必ずしも全て入れる必要はない。
/etc/mail/aliases と PostgreSQLに作ったテーブルを併用することも可能なのだが、併用パターンは後日実験する。

Alias用のデータを入れ終えたら、次はPostfixがPostgreSQLを参照するよう設定を変える。
まず用意するのはPostgreSQLを参照するための設定ファイル。
/etc/postfix/pgsql-aliases.cf というファイルを作り、中に設定情報を記述する。
hosts = unix:/tmp
user = postfix
password = ********
dbname = postfix
select_field = alias
table = aliases
where_field = address
additional_conditions = and status_flag = 1

設定情報の意味としては

hosts:PostgreSQLのホスト情報、今回はUnixドメインソケットを使用した
user:PostgreSQLのユーザー名
password:PostgreSQLのパスワード
dbname:データベース名
select_field~additional_conditions:こいつらは
SELECT select_field FROM table WHERE where_field = 'メールの宛先' additional_conditionsに置き換わる

続いて /etc/postfix/main.cf を修正する。
#alias_maps = hash:/etc/mail/aliases
alias_maps = pgsql:/etc/postfix/pgsql-aliases.cf

後はPostfixに設定ファイルを再読込させるだけ。
# /usr/sbin/postfix reload
これでAliasに設定した宛先にメールを送って正しく受信できればOK。
更にDBのstatus_flagを変えてAliasを無効にした時、エラーメールが返ってくれば完璧。

って事でメールを送ってみると無事動いている。
めでたしめでたし。

次はMaildirへの変換あたりを実験してみるかな。

まずはPostfixをインストールしてみる


色々と思いを巡らしていてもしょうがないので、まずは一度Postfixを入れてみることにしよう。
実験の一番の目的はDBでバーチャルホスト用のメールアカウントを管理することなので、LANの中だけでテストしていても面白くない。
そこで、実環境で稼働している二台目のサーバーを使って実験することにした。
このサーバはWebサーバーとしての役割がメインで、メールについてはこれまでセカンダリーサーバーとしての役割とJmailの開発実験用だった。
Jmailはサーバーにアカウントを用意しているのではなく、Jmail用のドメイン宛のメールは一括で受信処理用のプログラムに渡して処理させている。
自分がログインするアカウント宛にメールが来ても全てメインサーバーのメールアカウント宛に転送しているので、このサーバーにはこれまでメールを受け取るアカウントが存在していない。
すなわち、実験中にメールの処理が出来なくても運用上支障がないとても都合の良いサーバーなのだ。

と言う訳で二台目のサーバーのMTAをPostfixに変え、適当にサブドメインでバーチャルホストを実現し、DBを使ったメールアカウント管理の実験を行おう。

まずは作業開始前のサーバーの状況。

OS:FreeBSD 6.0
MTA:Sendmail 8.13.4
DB:PostgreSQL 8.3.0

と言った構成である。

最初にどこから手を付けるかといえば、MTAをPostfixにしてみることが先決。
と思ったが、メインサーバーの移行時のことを考えると現状のSendmailでmbox形式でメールを受け取らせておいて、Postfix移行時にMaildir形式へコンバートする実験も行わないといけない。
と言う訳で実験用にアカウントを作成。そのアカウント宛にメールを送りメールスプールに貯まっていることを確認した。

続いてPostfixのインストール開始。
まずはPostfixのサイトからソースをダウンロードする。私が実験を始めた時の最新バーションは v2.5.5 だった。
ダウンロードしたファイルを展開し作業開始。
初回のインストールなので本当は必要ないが、なんとなくおまじないとして初期化から行う。
# make tidy

次にMakefileの初期化を行うが、PostgreSQLに対応させるためにはオプションの指定が必要となるみたいだ。
指定する内容はPostgreSQLのヘッダーファイルの在りかとライブラリーの在りか。
私のサーバではPostgreSQLのディレクトリ内に両方があったので、その場所を指定してMakefileの初期化を行った。
# make -f Makefile.init makefiles 'CCARGS=-DHAS_PGSQL -I/usr/local/pgsql/include' 'AUXLIBS=-L/usr/local/pgsql/lib -lpq'

無事初期化を終えたらコンパイル開始ということで、お決まりの
# makeを実行する。
make が無事終わったら make install を行う前にPostfix用の実行アカウントとグループ、それとmaildropの処理で使われるグループを作成しておく。
# pw groupadd postfix
# pw groupadd postdrop
# pw useradd postfix -g postfix -d /nonexistent -s /usr/sbin/nologin

更に、Sendmailを終了させOSの再起動時に動かないよう/etc/rc.confを書き換えておく。
そして、現在のSendmail関連のファイルを待避させる。
# mv /usr/sbin/sendmail /usr/sbin/sendmail.OLD
# mv /usr/bin/newaliases /usr/bin/newaliases.OLD
# mv /usr/bin/mailq /usr/bin/mailq.OLD

ここまで用意できたらいよいよインストール実行。
# make install

途中で設定ファイル等のインストール先を聞かれる。
本を読んでも、いろいろなWebサイトを見ても、ここで聞かれることに対しては基本的にデフォルト値から変える必要がないので[Enter]を押していけばよいと書いてある。
しかし!
私のインストール環境ではどういう訳かデフォルト値が空になっている...
何かがおかしい。でも、何がおかしいのか分からないので、とりあえず聞かれた項目に一つずつ答えていく。
最後のsetgid_groupを入力し終えるとインストールが始まった。

が、途中でlibpq.so.5が見つからないとエラーを吐いて止まってしまった。
libpq.so.5自体はMakefileの初期化を行った際に指定した /usr/local/pgsql/lib の中にちゃんとある。
なのに見つからないと怒られる...なぜ(ToT)
で、makeの実行状況をよく見ると /usr/local/lib の中から libpq.so.5 を読み出そうとしている。
いやいや、折角Makefileの初期化をする際にディレクトリを指定したのに、なぜ指定したディレクトリから探してくれないんだ。
何度かmakeをやり直してみたが結果は同じ。
う~ん、これってMakefileのバグ??
などと悩んでてもしょうがないので、とりあえず /usr/local/lib の中に libpq.so.5 をコピーしてやる。
# cp /usr/local/pgsql/lib/libpq.so.5 /usr/local/lib
もう一度make tidyからやり直してやると、今度はインストール先等を聞かれた時にちゃんとデフォルト値が入っている。明らかに先ほどとは違う。
で、進んでいくと見事インストール成功!!

後は /etc/postfix/main.cf を動作環境に合わせていじってやる。
とりあえずメールスプールはmbox形式のままで動かしてみることにして、変更した内容は以下のような感じ。
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
html_directory = no
manpage_directory = /usr/local/man
sample_directory = /etc/postfix
readme_directory = no
mail_spool_directory = /var/mail
#home_mailbox = Mailbox
#home_mailbox = Maildir/
mail_owner = postfix
setgid_group = postdrop
unknown_local_recipient_reject_code = 550
relay_domains = $mydestination, $mydomain
alias_maps = hash:/etc/mail/aliases
alias_database = hash:/etc/mail/aliases
virtual_alias_maps = hash:/etc/mail/virtusertable
virtual_alias_domains = /etc/mail/virtuser-domains
disable_vrfy_command = yes
smtpd_helo_required = yes
コメント等は端折ってあるのでご容赦ください。

準備が出来たらいよいよPostfixの起動。
# /usr/sbin/postfix start

syslogを見るとちゃんと起動できていそう...
先ほど作った実験用のアカウント宛やJmailのアカウント宛にメールを送ってみると無事届いた。

まずはPostfixのインストール成功!

次はいよいよPostgreSQLを使う実験だな。

← 前のページ次のページ →