連載
» 2002年03月30日 00時00分 公開

モバイル環境に優しいメールプロトコルIMAP(3):CyrusでIMAPサーバを構築する

[OBATA Akio,@IT]

 フリーで提供されているIMAPサーバといえば、リファレンス実装的に使われる「UW(University of Washington) IMAP Server」、qmailなどで使われるMaildirに特化した「Courier-IMAP」などがあります。今回は、「Cyrus IMAPサーバ」の実装を取り上げ、実際にIMAPサーバを構築してみます。

Cyrus IMAPサーバとは?

 Cyrus IMAPサーバは、カーネギーメロン大学のProject Cyrusにより開発されている実装で、次のような特徴を持っています。

  • サーバが完全に閉じた環境で動作する
     メールのユーザーは、OSのアカウントが必要ありません。これは、サーバのセキュリティの点でも、ユーザーを一括管理できるという点でも有利です。また、デーモンがroot以外のユーザーで実行されるので、セキュリティの面でも安心です。
  • 多様なセキュリティ、認証に対応している
     SASL(Simple Authentication and Security Layer:RFC2222)に対応することにより、さまざまな安全な認証をサポートしています。ケルベロス(Kerberos)にも対応しています。また、従来のUNIXのユーザー/パスワードを使用して認証することも可能なほか、PAM(Pluggable Authentication Modules)を用いて、例えばLDAP(Lightweight Directory Access Protocol)で認証ということも可能です。この場合は、危険な平文でのパスワード交換になりますが、TLS(SSL)にも対応していますので、TLS上で安全に認証すると同時に、データを隠ぺいすることができます。
  • さまざまな拡張機能に対応
     特徴的なものとして挙げられるのは、容量制限のQUOTA(RFC2087)、アクセス制限のACL(RFC2086)、メールの振り分けのSieve(RFC3028)などです。
  • パフォーマンス
     IMAP4専用に設計されているので、パフォーマンスも比較的良い。また、UW IMAP Serverで標準的に使われている形式などと異なり、単一メールボックスへの多重アクセスなど、IMAPサーバとして使用するのに適した保存形式を採用しています。

構築に必要なソフト

 Cyrus IMAPサーバのソースは、ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/が一次配布元です。 国内ではRing Serverにも置かれていますので、そちらから取得するとよいでしょう(本稿の執筆時点では、リリースバージョンは2.0.16ですが、2.1.3がベータバージョンとして開発中です)。今回は安定バージョンである2.0.16を基にして、IMAPサーバを構築します。このバージョンを使用するには、以下のパッケージが必要です。

  • Cyrus SASL
     1.5.15以上が求められます。認証に使われるライブラリで、sendmailやPostfixなどのSMTP AUTHの実装でも用いられています。SASLの2.1.xはIMAPサーバの2.1.xと組み合わせて使うバージョンで、2.0.16とは組み合わせることができませんので、1.5.xのバージョンを使用してください。IMAPサーバと同じところから入手可能です。
  • Berkeley DB
     3.0.55以上が必要ですが、4.xではコンパイルできませんので、3.xを使用してください。Sleepycat Softwareから入手できます。
  • GNU make
     ソースをコンパイルするのに必要です。

 また、以下のパッケージも用意しておくとさまざまな機能が有効になり、便利です。

  • Perl 5
     5.00502以降が推奨されています。管理ツールに使用されるので、できれば用意しておきましょう。
  • OpenSSL
     TLS(SSL)を使いたい場合に必要です。0.9.4以降が必要です。
  • TCP wrapper
     クライアントからのアクセスに制限をかける場合に必要です。
  • LMTPをサポートしたMTA
     sendmailでは8.10.0以降、またPostfixも正式リリース版以降はLMTP (Local Mail Transfer Protocol)に対応しています。
※LMTPは、SMTP(Simple Mail Transfer Protocol)に似たプロトコルで、SMTPがメールを転送するプロトコルなのに対し、LMTPはローカルにメールを配信するためのプロトコルです。 これにより、sendmailのようなMTA(Message Transfer Agent)とIMAPDのようなMRA(Mail Retrieval Agent)のマシンを分離することが可能になります。また、Cyrus IMAPDでは、MDA(Mail Delivery Agent)だとあて先ユーザーごとに配送されますが、LMTP経由だと複数ユーザー同時に配送されることを利用して、 メールの保存を1通だけにして、ディスク容量を稼ぐということも行っています。

Cyrus IMAPサーバのインストール

 インストールに必要なソフトウェアのパッケージが用意されているOSもあるでしょう。例えば、FreeBSDやNetBSDではパッケージが用意されていますし、LinuxでもRPMパッケージが存在します。

 ここではパッケージが用意されていないシステム、あるいは手で微調整して導入したい人のために、必要条件のBerkeley DB、Cyrus SASL、そしてCyrus IMAPDの導入方法について簡単に解説します。

Berkeley DB

 オプションはいろいろありますが、今回はバージョン1.85の互換機能を有効にして導入します。

% tar xvfz db-3.3.11.tar.gz
% cd db-3.3.11/build_unix
% ../dist/configure --enable-compat185
% make
# make install

 このようにすると、Berkeley DBが/usr/local/BerkeleyDB.3.11以下にインストールされます。別のディレクトリにインストールしたい場合は、configure実行時に、

--prefix=/any/dir/name

のオプションを指定すればよいでしょう。これ以降は、デフォルトのディレクトリにインストールしたとして解説します。

Cyrus SASL

 Cyrus SASLのインストールは、configureを実行してからmakeする形式です。オプションで認証方法などを指定できます。

 認証方法として、PAM経由、またはpwcheckやsaslauthdのようなヘルパーデーモンを経由して、OSのパスワードやLDAPを利用する方法も指定できます。しかし、この方法では平文認証しかできませんので、ここでは利用しません。

 平文でない認証方法としては、SASLに対応したクライアントの場合、まずCRAM-MD5をサポートしていますので、これを指定してコンパイルしておけば大丈夫でしょう。また、SASLがうまく利用できないクライアントのために、PLAIN認証も許可しておく必要があります。

 認証用のデータは独自のデータベースに保存しますが、そのデータベースとして、gdbm、Berkeley DB、ndbmの3つが選択できます。

 Berkeley DBを選択する場合は、前述のように、Cyrus IMAPDをコンパイルするときに用いるバージョンと合わせておく必要があります。

 ここでは、先ほどインストールしたBerkeley DBを用いることにします。ただし、SASLを用いるほかのアプリケーションとの兼ね合いなどで、Berkeley DBの複数のバージョンの混在が困難なシステムの場合には、gdbmやndbmを指定しておくのが良い選択かもしれません。

% tar xvfz cyrus-sasl-1.5.27.tar.gz
% cd cyrus-sasl-1.5.27
% env LDFLAGS="-L/usr/local/BerkeleyDB.3.11/lib -R/usr/local/BerkeleyDB.3.1/lib"
CFLAGS=-I/usr/local/BerkeleyDB.3.11/include
./configure --with-dblib=berkley --enable-cram --enable-plain
% make
% su
# make install
# ln -s /usr/local/lib/sasl /usr/lib/sasl

 デフォルトでは/usr/lib/saslの下の共有ライブラリを検索しますが、今回のインストールでは/usr/local/lib/sasl以下に行われるので、最後の行のようにリンクしておきます。configure時に、[--with-plugindir=/usr/local/lib/sasl] を指定しておけば、このリンクは必要ありません。

Cyrus IMAPD

 インストールは、こちらもconfigureを実行してからmakeする形式です。

 ここでは、Berkeley DBとCyrus SASLは先ほどインストールしたものを利用することにし、そのほかのPerl、OpenSSLなどは自動検出を利用しています。

% tar xvfz cyrus-imapd-2.0.16.tar.gz
% cd cyrus-imapd-2.0.16
% ./configure --with-dbdir=/usr/local/BerkeleyDB.3.11 --with-sasl=/usr/local
% gmake
# su
# gmake install

 これで、必要なモジュールは一通りインストールできました。

IMAPサーバを設定し、起動する

 さて、引き続いて、Cyrus IMAPサーバの設定を行います。

●ユーザー、グループの設定

 configureのときに指定したユーザーとグループ(デフォルトでは、ユーザー“cyrus”とグループ“mail”)を作成します。安全のために、パスワードは使えないようにしておくのがよいでしょう。

●syslogの設定

 ログを取得するには、syslogdを使用します。最近のシステムでは大丈夫だと思いますが、もしも古いタイプのsyslogdが含まれているシステムの場合、Cyrus IMAPDに付属しているsyslogdと入れ替えます。

 ログの設定は、/etc/syslog.confに以下のように指定します。

local6.debug /var/log/imapd.log

 あらかじめ指定したログファイルをtouchなどで作成し、syslogdにHUPシグナルを送って再起動します。

 Cyrus IMAPDに加えて、Cyrus SASLの認証のログも取得したい場合は、/etc/syslog.confに以下のような設定を書き加えます。

auth.debug /var/log/auth.log

●Cyrus IMAPDの設定

 Cyrus IMAPDの設定ファイルは、/etc/imapd.confです。設定ファイル中の書式は、

オプション名: 値

という形式です。行頭に“#”を付けると、その行をコメントにできます。また、論理値を取るオプションの場合には以下のように指定可能です。代表的なオプションを以下の表に示します。

有効 無効
yes no
on off
t f
1 0

オプション デフォルト値 概要
configdirectory なし 設定ファイルを置くディレクトリを指定する。このオプション指定は必須
defaultpartition default 新規メールボックスをデフォルトで作成するパーティション名。Cyrus IMAPサーバでは、メールデータを保存する場所を複数指定でき、この保存場所のことを「パーティション」と呼んでいる
partition-name なし nameという名前のパーティションに対応する、ファイルシステム上のパスを指定する。defaultpartitionで指定されたパーティションの指定は必須。また、「partition-news」という名前は、NetNews用に予約されているため、通常は使用できない
allowanonymouslogin no 匿名ログインの許可
quotawarn 90 QUOTAの何パーセントまでを使用したら警告を出すかを指定する
timeout 30 IMAPでの自動ログアウトタイマ(分)。30は最小値
poptimeout 10 OPでの自動ログアウトタイマ(分)。10は最小値
admins なし 管理者権限を持つユーザーの一覧。通常は、メールを受け取るユーザーを管理者として指定すべきではない。複数のユーザーを指定する場合はスペースで区切る
defaultacl anyone lrs 親のないメールボックスを新たに作成した場合のACL。ちなみに、サブメールボックスを作成した場合は、親メールボックスの権限を引き継ぐ
autocreatequota 0 ユーザーが自分のinboxを作成するとき、自動的に設定されるQUOTAを指定する。0は無制限
plaintextloginpause 0 平文ログインに成功した後に、待たせる秒数を指定する。これは、平文によるログインをなるべく使わないように促すために用意されているようだ
singleinstancestore yes 複数人あてのメッセージをLMTP経由で受信した際に、1メッセージを保存し、ほかはそのメッセージへのハードリンクを張ることにより、容量を稼ぐ動作を指定する
reject8bit no ヘッダに8bits文字を含むメッセージを受信した際に、受信を拒否することを指定する。“no”にした場合でも、8bits文字は“X”に置き換えられる。これは、8bits文字をヘッダに含むことはRFCに反しており、RFCを基準に作成されているIMAP4の動作に悪影響を与えるから
sieveusehomedir false 有効にした場合、sieveスクリプトは、ユーザーのホームディレクトリの“~/.sieve”を参照する。OS上にアカウントを用意してsieveスクリプトを編集する場合以外は、指定しない方がよい
sievedir /usr/sieve sieveusehomedirを無効にしている場合の、sieveスクリプトの保管場所
sendmail /usr/lib/
sendmail
sieveでメールの受付を拒否したり、転送したりする際に使用する、sendmailへのパスを指定する
hashimapspool false 有効にすると、パーティション内をハッシュして保存する。ユーザー数が非常に多い場合などはパフォーマンス的に有効
sasl_pwcheck_method PAM 平文パスワードを認証するのに用いる方法を指定する。“PAM”のほかに、セキュリティの強力な認証のときに使用するのと同じものを使う“sasldb”、OSのアカウント情報を用いる“passwd”、shadow passwordを読み取る“shadow”、ケルベロスを用いる“kerberos_v4”などが指定できる
sasl_auto_transition no 有効にすると、平文パスワードの認証が行われたときに、自動的にSASL用の認証DBを作成する
lmtpsocket /var/imap
/socket/lmtp
lmtpdが用いるUNIX domainソケットを指定する

 オプションはこのほかにもありますので、詳細はman imapd.confで確認してください。

 表にある“sasl_”で始まるオプションは、SASL用のオプションです。ここで設定する方法もありますが、/usr/lib/sasl/Cyrus.confを用意して、その中で“sasl_”を取り除いた名前で設定する方法もあります。どちらの方法でもいいのですが、Cyrus.confに書いておけば、imapd以外のCyrusのソフトでも同じ設定が利用され、個別に設定する必要がなく混乱も少ないでしょう。

 ここでは、/etc/imapd.confは以下のように指定してみました。

configdirectory: /var/imap
partition-default: /var/spool/imap
admins: cyrus-admin

 また、/usr/lib/sasl/Cyrus.confは、以下のように設定しました。

pwcheck_method: sasldb

 次に、 必要なディレクトリを作成します。この設定ファイルの場合ですと、次にようにします。

(設定ファイルの置き場所を用意)
# cd /var
# mkdir imap
# chown cyrus imap
# chgrp mail imap
# chmod 750 imap
(デフォルトのパーティションを用意)
# cd /var/spool
# mkdir imap
# chown cyrus imap
# chgrp mail imap
# chmod 750 imap
(sieveのディレクトリを用意)
# cd /usr
# mkdir sieve
# chown cyrus sieve
# chgrp mail sieve
# chmod 750 sieve
(残りのディレクトリを作成)
# su cyrus
% tools/mkimap
% exit

 最後のmkimapは、ソースに付属しているPerlスクリプトなので、Perlをインストールしていない場合には、スクリプトを参照して手動で残りの設定を行ってください。

●TLS(SSL)を使うには?

 TLS(SSL)については、Cyrus IMAPは2つの方法に対応しています。

  • SSLでラップする方法
     以前からよく使われていた方法です。あらかじめ、SSLのトンネルを掘っておき、その中でIMAP4プロトコルでやり取りする方法です。この方法の利点は、SSLに対応していないサーバ/クライアントでも、「stone」などのラップするツールを使えば、容易にSSLに対応できることです。欠点は、トンネルを掘るため、サーバ側で通常のポートとは別のポートを用意しなければならないことです。
  • STARTTLS
     IMAP4で接続した後、STARTTLSコマンドでTLSに移行する方法です。この方法の利点は、クライアントがTLSに対応している場合、サーバへの接続先を変更することなくTLSに移行できることです。

 Cyrus IMAPDでは、OpenSSLを使用していますが、これは、PEMフォーマットの認証書を必要とします。ここでは、サーバのプライベートキーと自己証明書を作成してみましょう。

# openssl req -new -x509 -nodes -out /var/imap/server.pem -keyout /var/imap/server.pem -days 365
Using configuration from /etc/ssl/openssl.cnf
Generating a 1024 bit RSA private key
...............++++++
......................++++++
writing new private key to '/var/imap/server.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Okayama
Locality Name (eg, city) []:Okayama
Organization Name (eg, company) [Internet Widgits Pty Ltd]:OONAMI Ltd
Organizational Unit Name (eg, section) []:Tea Room
Common Name (eg, YOUR name) []:pixy.oonami.co.jp
Email Address []:staff@oonami.co.jp

 次に、作成された鍵をユーザー“cyrus”が読めるように変更します。

# chown cyrus /var/imap/server.pem

 最後に、/etc/imapd.confに、以下の2行を追加します。

tls_cert_file: /var/imap/server.pem
tls_key_file: /var/imap/server.pem

●/etc/serviceの設定

 /etc/serviceに、以下のものが設定されていなければ追加します。

pop3 110/tcp
imap 143/tcp
imsp 406/tcp
acap 674/tcp
imaps 993/tcp
pop3s 995/tcp
kpop 1109/tcp
sieve 2000/tcp
lmtp 2003/tcp
fud 4201/udp

●Masterプロセスの設定

 Cyrus IMAPDは、2.0からはinetd経由ではなく、Masterプロセスがすべての接続を管理するようになりました。このMasterプロセスの設定ファイルのサンプルは、master/confにあります。取りあえず、normal.confをひな型にして設定します。

# cp master/conf/normal.conf /etc/cyrus.conf

 不要なサービスはコメントにしたり、preforkの数をチューニングしたりしましょう。あとは、Masterプロセスを起動するだけです。

# /usr/cyrus/bin/master &

 これも、OSが起動するときに自動的に起動するような設定をしておきましょう。

●認証DBの準備

 SASLの認証DBの準備を忘れずにしておきます。所有者はユーザー“cyrus”にし、adminsとして登録したcyrus-adminをユーザーとして登録します。

# touch /etc/sasldb
# chown cyrus /etc/sasldb
# /usr/local/sbin/saslpasswd -c cyrus-admin
Password: XXXXXXXX
Again (for verification): XXXXXXXX

●メールボックスの用意

 あらかじめ、ユーザーのメールボックスは用意しておくのが親切でしょう。ここで、Cyrus IMAPDのメールボックスの構造について説明しておきます。ユーザー“foo”の通常メールを受け取るINBOXは、“user.foo”という名前のメールボックスになります。階層の区切りがNetNews風になっています。そして、“user.foo”の下に、個人のメールボックスを、例えば“user.foo.Trash”のように作成できます。“bborard.soccer”のような名前のメールボックスは共有メールボックスになります。このあたりの関係は、UNIXのファイルシステムと似ています。最後に、IMAP4の規約により、ユーザーのINBOXは、“INBOX”という名前で見えなければなりません。つまりユーザー“foo”がアクセスしたときには、“user.foo”が“INBOX”として見えるということです。 ここから先はUW IMAPDを使っていた人などは戸惑うのですが、“user.foo.Trash”は、“INBOX.Trash”として見えるのです。つまり、個人のメールボックスは“INBOX”の下に作っていく形になります。

 話を戻しましょう。メールボックスの管理には、cyradmコマンドを用います。ユーザー“foo”のINBOXを作成するには、次のようにします。

% cyradm --user cyrus-admin localhost
Please Enter your password: <cyurs-adminのパスワード>
localhost> cm user.foo
localhost> quit

 cyradmの詳しい説明は、man cyradmするか、cyradmのプロンプトでhelpと入力してください。

●MTAの設定(sendmailの場合)

 設定には、sendmail付属のcfを使用します。sendmailにも、Cyrus IMAPサーバ用のひな型が付いてきますが、これは1.x用です。そこで、IMAPDのdoc/cyrusv2.mcをひな型として用います。なお、cfの詳しい使用方法は、本稿では主題ではないので割愛します。

 キモの部分は後半部分です。

define('confLOCAL_MAILER', 'cyrus')
FEATURE('nocanonify')
FEATURE('always_add_domain')
MAILER('local')
MAILER('smtp')
MAILER_DEFINITIONS
Mcyrus, P=[IPC], F=lsDFMnqA@/:|SmXz, E=\r\n,
S=EnvFromL, R=EnvToL/HdrToL, T=DNS/RFC822/X-Unix,
A=FILE /var/imap/socket/lmtp
LOCAL_RULE_0
Rbb + $+ < @ $=w . > $#cyrus $: + $1

 ここで、最後の行でおや? と思った方もいるかもしれません。これによって、“bb+foo@domain.ne.jp”あてのメールは、共有メールボックス“foo”に配送されます。ニュースレターの受信アドレスとして使って、みんなで情報を共有するという方法も考えられるかもしれません。実は、同様のことは、普通のユーザーにもいえて、“foo+bar@domain.ne.jp”あてのメールは、メールボックス“user.foo.bar”、つまり、ユーザー“foo”の“INBOX.bar”に配送されます。

 ただし、この機能を使うには、1つやっておかなければならないことがあります。それは、そのメールボックスがだれからでもポストできるようになっていなければならないということです。具体的には、“anyone”に対して、“p”の権限を与えておく必要があります。ユーザーのメールボックスに対しての配送の場合、もしも権限が設定されていない場合には、代わりにINBOXに配送されます。これは、ユーザーが意図していないメールボックスに対して、メールが配送されることを防ぐ狙いがあるものと思われます。

●MTAの設定(Postfixの場合)

 Postfixの場合は非常に簡単です。main.cfの以下の部分を書き換えます。

mailbox_transport = lmtp:unix:/var/imap/socket/lmtp
fallback_transport = lmtp:unix:/var/imap/socket/lmtp

 先ほどのsendmailの場合と異なり、“+foo@domain.ne.jp”あてのメールが共有メールボックス“foo”あてへ配送されます。

cyradmコマンドによる管理

 ここまでにACLとQUOTAについて何度か出てきました。ACLとQUOTAの設定・操作方法もIMAPの拡張として定義されていますが、実際にはそれができるMUAはほとんどありません。もしも、それができるMUAを持っているならばそれを使えばよいのですが、そうでない場合にはcyradmコマンドを使用します。

●ACL

 共有メールボックス“foo”に外部から投稿できる権利“p”を追加するには、以下のようにします。

% cyradm --user cyrus-admin localhost
Please Enter your password: <cyurs-adminのパスワード>
localhost> sam foo anyone +p
localhost> quit

●QUOTA

 ユーザー“foo”のメールボックス容量を10Mbytesに制限するには、以下のようにします。

% cyradm --user cyrus-admin localhost
Please Enter your password: <cyurs-adminのパスワード>
localhost> sq user.foo 10000
localhost> quit

●管理の自動化

 ここまでで、cyradmコマンドでの管理例をいくつか挙げましたが、このコマンドは付属のモジュールを利用して、Perlで実装されています。従って、一連の作業を自動化することは可能です。大量にユーザーを登録する必要がある場合などは、独自のスクリプトを書く方がよいでしょう。


 以上、簡単にですが、一通りの説明をしました。Cyrus IMAPサーバの実装は、ほかのフリーな実装に比べてインストール後の管理などがとっつきにくいところがありますが、これを機会に挑戦していただければ幸いです。


Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。