Blog

Mac miniでメールサーバを組む手順

By Hiroyuki OYAMA Sun Dec 4 00:20:41 2005

Mac miniでPostfix + CyrusIMAPなメールサーバを組む手順の覚え書き。Client版のMac OS X Tigerを使うんだけど、できるだけMac OS X Serverの仕様に近くしておければいいかなと。

使用するMac mini

最近SPAMが酷いのと、出先から自宅のPowerBookにsshしてshellでメールを読むのに飽きてきたので、IMAP4のメールサーバが欲しくなりました。ってなわけでApple StoreでMac mini (M9687J/B) 1.42GHzをメモリ1 Gbyteで購入。届いた製品は1.5GHzのCPUと、5400rpmで80GbyteのHDD (Seagate社Momentus)が乗ったモデルでした。OSはMac OS X 10.4 Tigerのクライアント版。つまりタイトルはMac miniでとありますが、実質的にはMac OS X 10.4 Clientでってことです。

使用するソフトウェア

OSに標準で入っているソフトウェアとライブラリを可能な限り活かせた方が、アップデートなどが楽かなと思ったので、こんな感じでメールサーバを組むことにしました。
  • Postfix(OS標準添付)
  • Cyrus IMAP Server 2.2.12
  • Cyrus SASL 2.1.21(実際にリンクするライブラリはOS標準添付の方)
  • Berkeley DB 4.3.29
Mac OS X Tiger Clientに入っているPostfixはdaemonとしては動いてない設定なので、その辺変更。あとPOP before SMTPとかは面倒なので、SMTP Authを使います。
IMAP4のサーバとしてはCyrus IMAP Serverを使います。これはMac OS X ServerがCyrus IMAPを使っているからというだけ。
SMTP AuthとCyrus IMAPで扱う認証情報はOS本体のそれとは切り離して管理したかったので、Cyrus SASLを使います。ちなみにMac OS X Tiger ClientにはCyrus SASLのライブラリは標準インストールされています(/usr/lib/libsasl2.dylib)。しかしながらデータベースファイルの管理ツールや、ヘッダファイルはインストールされていないため別途インストールしてあげる必要があります。
Berkeley DBはCyrus IMAPのメールスプール用。

ちなみにMac OS Xがバンドルしているオープンソースなソフトウェアとそのビルド手順とかは、Apple Developer ConnectionのWebサイトから参照・取得できます。ビルドに際してコンパイルオプションやパッチなどこの辺を参考にします。
あと、今回使用するソフトウェアのビルドにはGCC 3.3を使います。Developer Toolsをインストールした直後はGCC 4.xを使うように設定されているので
 $ sudo gcc_select 3.3
と設定しておきます。

FinkやDarwinPortsなどのパッケージ管理システムはありますが、僕自身があまり好きじゃないというのと、Mac OS X 10.4で使えるCyrus IMAPのパッケージが見つけられなかったのでソースからビルドします。

ライブラリのインストール

まず認証まわりのライブラリCyrus SASLをインストール。
$ curl -O ftp://ftp.andrew.cmu.edu/pub/cyrus/cyrus-sasl-2.1.21.tar.gz
$ tar zxvf cyrus-sasl-2.1.21.tar.gz
$ cd cyrus-sasl-2.1.21/
$ CFLAGS='-Os -no-cpp-precomp' \
LDFLAGS='-force_flat_namespace -bind_at_load' \
./configure --prefix=/usr/local --disable-macos-framework \
--with-plugindir=/usr/local/lib/sasl2
$ make
$ sudo make install
--with-plugindirをわざわざ指定しているのは、システム標準のSASLプラグインとぶつかるのを避けるため。ちなみにCyrus IMAPとPostfixはOSに標準添付されている方のSASLライブラリを使うので、ここでビルドしインストールするライブラリは使用しません。使いたいのは認証データベースの管理ツールとヘッダファイルだけ。 次にメールボックスに使うライブラリBerkeley DBをインストール。
$ curl -O http://downloads.sleepycat.com/db-4.3.29.tar.gz
$ tar zxvf db-4.3.29.tar.gz
$ cd db-4.3.29/build_unix/
$ CFLAGS='-no-cpp-precomp -Os' \
LDFLAGS='-force_flat_namespace -bind_at_load' \
../dist/configure --disable-java --prefix=/usr/local
$ make
$ sudo make install
Mac OS X Serverのビルド時には /usr/local/BerkeleyDBにインストールしてるみたいですが、個人的趣味で/usr/localにインストールします。

以上で必要なライブラリはそろいました。

Postfixのdaemon化

Postfixをdaemon起動して、メールの配送・受信できるように設定します。Mac OS X TigerのPostfixはLaunchdが管理しているので /System/Library/LaunchDaemons/org.postfix.master.plistをいじります。
$ cd /System/Library/LaunchDaemons
$ sudo cp -p org.postfix.master.plist org.postfix.master.plist.org
編集内容はこんな感じ。
$ diff -u org.postfix.master.plist.org org.postfix.master.plist
--- org.postfix.master.plist.org        2005-03-21 12:52:59.000000000 +0900
+++ org.postfix.master.plist    2005-11-12 22:44:27.000000000 +0900
@@ -9,12 +9,12 @@
        <key>ProgramArguments</key>
        <array>
                <string>master</string>
-               <string>-e</string>
-               <string>60</string>
        </array>
        <key>QueueDirectories</key>
        <array>
                <string>/var/spool/postfix/maildrop</string>
        </array>
+       <key>OnDemand</key>
+       <false/>
 </dict>
 </plist>
launchdのリロードは後回しで、先にPostfixの設定を変えておきます。
$ cd /etc/postfix
$ sudo cp -p main.cf main.cf.org
/etc/postfix/main.cfの変種内容はこんな感じ
$ diff -u main.cf.org main.cf
--- main.cf.org 2005-03-21 12:52:52.000000000 +0900
+++ main.cf     2005-11-12 22:59:50.000000000 +0900
@@ -106,6 +106,7 @@
 #inet_interfaces = all
 #inet_interfaces = $myhostname
 #inet_interfaces = $myhostname, localhost
+inet_interfaces = all

 # The proxy_interfaces parameter specifies the network interface
 # addresses that this mail system receives mail on by way of a
@@ -154,6 +155,8 @@
 #mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
 #mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain,
 #      mail.$mydomain, www.$mydomain, ftp.$mydomain
+mydestination = $myhostname, localhost.$mydomain, localhost,
+       example.jp

 # REJECTING MAIL FOR UNKNOWN LOCAL USERS
 #
@@ -634,7 +637,7 @@
 #
 # bind to localhost only
 #
-inet_interfaces = localhost
+# inet_interfaces = localhost

 # turn off relaying for local subnet
 #
上記ではmydestinationにexample.jpが設定されていますが、これはスプールを持つドメインにあわせて変更してください。

これで用意ができたのでlaunchdでPostfixを再起動します。
$ sudo launchctl stop org.postfix.master
$ sudo launchctl unload /System/Library/LaunchDaemons/org.postfix.master.plist
$ sudo launchctl load \
/System/Library/LaunchDaemons/org.postfix.master.plist
$ sudo launchctl start org.postfix.master
netstatとかで25/tcpをLISTENしてるかとか確認して終了。デフォルトの設定ではPostfixのmasterプロセスが起動後60秒で終了するよう設定されているので、psなどで確認するときには注意。「お、うごいてるじゃーん」と思っても60秒後に使えなくなって悲しくなれます。上記の設定が有効になっていれば(だいたいは)死ねというまで死にません。

PostfixのSMTP Auth化

今度は外部にメールを配送するクライアントに認証を求めるSMTP Authの設定に。認証情報はさっきインストールしたCyrus SASLのsasldbを使います。というわけで認証用のユーザデータベースを作成。
$ sudo /usr/local/sbin/saslpasswd2 -c $USER
saslpasswd2コマンドでパスワードとかを指定した後は、ユーザデータベースのアクセス権を変更。
$ sudo chgrp mail /etc/sasldb2.db
$ sudo chmod 660 /etc/sasldb2.db
このユーザデータベースは、Mac OS XのNetinfoとは別個にユーザ情報を管理します。Postfixや後記するCyrus IMAPのプロセスがアクセスできるようにしておきます。っと、Postfixの実行ユーザpostfixはmailグループに入っていないので、Netinfoのgroupを変更。

Netinfoの操作はいろいろな方法がありますが、僕はnidumpとniloadの組み合わせをよく使います。nidumpでテキストファイルにダンプして
$ sudo nidump group . > $HOME/group.txt
編集後niloadで読み込み
$ sudo niload -m group . < $HOME/group.txt
ちなみにダンプしたファイルの編集内容はこんな感じで
$ diff -u $HOME/group.txt.org $HOME/group.txt
--- /Users/oyama/group.txt.org  2005-11-12 23:26:09.000000000 +0900
+++ /Users/oyama/group.txt      2005-11-12 23:27:27.000000000 +0900
@@ -6,7 +6,7 @@
 sys:*:3:root
 tty:*:4:root
 operator:*:5:root
-mail:*:6:
+mail:*:6:postfix
 bin:*:7:
 staff:*:20:root
 lp:*:26:
あと、SASLは認証方法をpluginで拡張できるようになっているのですが、Mac OS X Tigerのデフォルトでは今回使用するsasldb2のpluginは無効化されています。なので
$ cd /usr/lib/sasl2/disabled
$ sudo mv libsasldb.2.so libsasldb.la ../
と、pluginを移動し有効化します。ちなみにMac OS X Tigerに入っているsasldb pluginは、データベースファイルとしてndbmを使うようにビルドされています。Cyrus SASLではsasldbにBerkeleyDBを使ったりもできるのですが、この辺が一致していないと自前で用意したsaslpasswd2コマンドで作るデータベースファイルと、システムが要求するデータベースファイルが異なってうまく認証できないといったことが起こりえます。
これで足回りはできあがったので、Postfix側の設定に移ります。また/etc/postfix/main.cfを編集します。編集内容はこんな感じ。
$ diff -u /etc/postfix/main.cf.org /etc/postfix/main.cf
--- /etc/postfix/main.cf.org    2005-03-21 12:52:52.000000000 +0900
+++ /etc/postfix/main.cf        2005-11-12 23:06:25.000000000 +0900
@@ -653,3 +656,9 @@
 mailbox_size_limit = 0

 smtpd_tls_key_file =
+
+# smtp auth
+smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
+smtpd_sasl_auth_enable = yes
+smtpd_sasl_local_domain = $myhostname
+smtpd_sasl_security_options = noanonymous, noplaintext
編集したらPostfixに内容を読み込ませます。
$ sudo postfix reload
適当なMUAで送信時にSMTP authがかかっているか確認して終了。

Cyrus IMAP Serverのインストールと設定

Cyrus IMAPをインストールします。
$ curl -O ftp://ftp.andrew.cmu.edu/pub/cyrus/cyrus-imapd-2.2.12.tar.gz
$ tar zxvf cyrus-imapd-2.2.12.tar.gz
$ cd cyrus-imapd-2.2.12/build_unix
$ CFLAGS='-Os -no-cpp-precomp' \
LDFLAGS='-force_flat_namespace -bind_at_load' \
./configure --build=powerpc-apple-netbsd --with-sasl=/usr \
--with-mboxlist-db=berkeley --with-seen-db=skiplist \
--with-subs-db=flat --with-openssl=/usr --enable-gssapi \
--disable-krb4 --with-comm_err --with-snmp=/usr/share/snmp \
--with-extraident='OS X 10.4.0' --enable-murder \
--with-service-path=/usr/local/bin/cyrus/bin \
--with-pidfile=/var/run/cyrus-master.pid \
--with-cyrus-user=cyrusimap --without-snmp
っとmakeする前にエラーテーブルを作り直します。
$ perl -pi -e 's/\/usr\/lib\/libcom_err.a/-lcom_err/g' ./imap/Makefile
$ perl -pi -e 's/\/usr\/lib\/libcom_err.a/-lcom_err/g' ./master/Makefile
$ perl -pi -e 's/\/usr\/lib\/libcom_err.a/-lcom_err/g' ./notifyd/Makefile
$ perl -pi -e 's/\/usr\/lib\/libcom_err.a/-lcom_err/g' ./sieve/Makefile
$ perl -pi -e 's/\/usr\/lib\/libcom_err.a/-lcom_err/g' ./timsieved/Makefile
$ cd et
$ compile_et test1.et
$ compile_et test2.et
$ cd ../imap/
$ compile_et imap_err.et
$ compile_et mupdate_err.et
$ compile_et nntp_err.et
$ cd ../sieve
$ compile_et sieve_err.et
$ cd ..
これをやっておかないとMac OS Xではビルドするときにエラーになるっぽ。本来はconfigure.inやMakefile.inを編集して対応した方がいいんでしょうけど。

あとはmake; make installするだけ。
$ make depend
$ make all
$ sudo make install
とここに罠があって、Cyrus IMAPが一緒にインストールするPerlのライブラリが何故か /usr/local に入ってしまっているので、手作業で移動。
$ sudo rm -rf /usr/local/System
$ sudo mv /usr/local/lib/perl5/site_perl/5.8.6/darwin-thread-multi-2level \
/Library/Perl/5.8.6/
あと、メールボックスのメンテナンスに使うスクリプトをコピーしておきます。
$ sudo cp perl/imap/cyradm /usr/local/sbin/
次にCyrus IMAPのログや起動スクリプト周りを編集します。まず/etc/syslog.confをこんな感じに修正。
$ diff -u /etc/syslog.conf.org /etc/syslog.conf
--- /etc/syslog.conf.org        2005-08-22 04:53:22.000000000 +0900
+++ /etc/syslog.conf    2005-11-13 00:36:16.000000000 +0900
@@ -17,5 +17,7 @@
 install.*                                              /var/log/install.log
 install.*                                              @127.0.0.1:32376
 local0.*                                               /var/log/ipfw.log
+local6.debug                                           /var/log/imapd.log
+auth.debug                                             /var/log/auth.log

 *.emerg                                                        *
levelはdebugじゃないほうがいいかも。後でかえておきましょう。編集したらsyslogdを再起動。
$ sudo touch /var/log/imapd.log /var/log/auth.log
$ sudo launchctl stop com.apple.syslogd
$ sudo launchctl start com.apple.syslogd
べつに kill -HUPでもいいけどなんとなくlaunchctlで。

Cyrus IMAPの設定は /etc/cyrus.conf と /etc/imapd.conf で行います。cyrus.conf はとりあえずソースパッケージに含まれるサンプルをコピーしてそのまま使って
$ sudo cp master/conf/normal.conf /etc/cyrus.conf
imapd.confはだいたいこんな感じに記述します。
$ cat /etc/imapd.conf
admins: imap-admin
configdirectory: /var/imap
partition-default: /var/spool/imap
sievedir: /var/mail/sieve
sasl_pwcheck_method: sasldb
あとは/etc/imapd.confで指定した各ディレクトリを作成。
$ sudo mkdir /var/imap
$ sudo chown cyrusimap:mail /var/imap
$ sudo chmod 750 /var/imap
$ sudo mkdir /var/spool/imap
$ sudo chown cyrusimap:mail /var/spool/imap
$ sudo chmod 750 /var/spool/imap
$ sudo mkdir /var/mail/sieve
$ sudo chown cyrusimap:mail /var/mail/sieve
$ sudo chmod 750 /var/mail/sieve
ちなみにMac OS X Tiger Clientにはデフォルトで cyrusimap ユーザが入っているのでそのまま使います。
作成したディレクトリの初期化のために、ソースパッケージ付属のmkimapコマンドを実行します。
$ sudo -u cyrusimap ./tools/mkimap
今度は/etc/imapd.confで指定したIMAPの管理ユーザを作成します。
$ sudo /usr/local/sbin/saslpasswd2 -c imap-admin
そして作成した管理ユーザでメールボックスの管理ツール cyradmを使いユーザのメールボックスを作成します。
$ echo createmailbox user.$USER | cyradm --user imap-admin localhost

PostfixとCyrus IMAPの接続

PostfixとCyrus IMAPの通信はLMTPを使いたいので、/etc/postfix/main.cfをさらに次のように編集します。
$ diff -u /etc/postfix/main.cf.org /etc/postfix/main.cf|head
--- /etc/postfix/main.cf.org    2005-03-21 12:52:52.000000000 +0900
+++ /etc/postfix/main.cf        2005-11-13 01:32:04.000000000 +0900
@@ -453,6 +456,7 @@
 #
 #mailbox_transport = lmtp:unix:/file/name
 #mailbox_transport = cyrus
+mailbox_transport = lmtp:unix:/var/imap/socket/lmtp

 # The fallback_transport specifies the optional transport in master.cf
 # to use for recipients that are not found in the UNIX passwd database.
ちなみにCyrus IMAPが起動していない状態(/var/imap/socket/lmtpが無い状態)で、Postfixがメールを受け取るとロストしちゃうので注意。最初ゲゲッと思いましたが、普通の設定でもHDDが壊れてたらメールがロストするよなということで納得。

Cyrus IMAPをdaemonとして起動

最後はlaunchdにCyrus IMAPを起動させます。/System/Library/LaunchDaemons/edu.cmu.andrew.cyrus.master.plist を追加します。内容はこんな感じで。
$ cat /System/Library/LaunchDaemons/edu.cmu.andrew.cyrus.master.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>edu.cmu.andrew.cyrus.master</string>
        <key>OnDemand</key>
        <false/>
        <key>Program</key>
        <string>/usr/local/bin/cyrus/bin/master</string>
        <key>ProgramArguments</key>
        <array>
                <string>master</string>
        </array>
</dict>
</plist>
追加したらlauncdにロードして起動させます。
$ sudo launchctl load \
/System/Library/LaunchDaemons/edu.cmu.andrew.cyrus.master.plist
$ sudo launchctl start edu.cmu.andrew.cyrus.master
以上。設定が終わったMac miniはIDCに持っていって設置。MXいじって運用開始。今のところ非常に快適に使えてます。
その他mDNSResponderとかいらないプロセスを止めるとか、PostfixとCyrus IMAP Serverのその他細かい設定については割愛。そのへんはそれ用のドキュメントを見てくだされ。

クライアントの設定と注意点

特にかわったことはないんですがMUAにSMTP Authの設定する時は、ユーザ名を
 USER@hostname
で設定する必要があるみたい。IMAP4の設定はユーザ名だけでいけるんだけどはて。

あとMUAによって「ゴミ箱」や「送信済み」「下書き」とかのサブメールボック名が異なるのがちょっと困りもの。私は自分のPowerBookではMail.app、取引先のオフィスではMozilla Thunderbirdを使うので、Thunderbirdが作ったサブメールボックスをMail.app側で「メールボックス - このメールボックスの用途」でそれぞれ指定して統一させています。
あと、Mac OS Xでオープンソースソフトウェアをビルド・使用する場合は、可能な限りMac OS 拡張(大文字と小文字を区別/ジャーナリング)なボリュームを使った方がいいです。今回のネタだとCyrus IMAP Serverのソースパッケージには
SIEVE/
sieve/
という用途の違う2つのディレクトリを含んでいるので、デフォルトの Mac OS 拡張(ジャーナリング)のファイルシステムだと、単一のディレクトリにファイルが展開されます。Cyrus IMAP Serverのビルドに関してはこの点はたまたま問題になりませんでしたが、ほかのパッケージでは嫌なことになる可能性がちょっとあります。
また、Cyrus IMAP Serverは各メールボックスの情報をスプールディレクトリ内にディレクトリを作って管理しています。そのため大文字小文字を区別しないファイルシステムの場合はMUAからメールボックス名を変更する場合、大文字小文字の変更だけの場合失敗します。

とりあえずデフォルトのファイルシステムをそのまま使っていますが、可能ならばメールスプールだけでも大文字小文字を区別するファイルシステムを使った方が無難だと思います。
こういう文書はWikiとかに書いた方が便利なんだけど、とりあえずここに。なんか変なところあったらツッコミキボンです。

Apple Mac mini (1.42GHz, 80G, 512, Combo, AM, BT, E) [M9687J/B]
アップルコンピュータ (2005/07/27)
売り上げランキング: 296

Postfix実用ガイド
Postfix実用ガイド
posted with amazlet on 05.12.03
カイル・D. デント Kyle D. Dent 菅野 良二
オライリージャパン (2004/08)
売り上げランキング: 27,136

IMAP
IMAP
posted with amazlet on 05.12.03
ダイアナ マレット ケビン マレット Dianna Mullet Kevin Mullet 木田 直子 オレンジソフト
オライリー・ジャパン (2001/05)
売り上げランキング: 103,898

Berkeley Db
Berkeley Db
posted with amazlet on 05.12.03
Inc. Sleepycat Software
Sams (2001/06/14)
売り上げランキング: 259,657


Comments

Post a comment

Name:


URL:


Comments:


WebエンジニアのためのApacheモジュールプログラミングガイド

ApacheをHackする!
モジュールプログラミング強烈初体験!!
定価: 2,919円(税込)
ISBN: 4-7741-1799-4

hiroyuki_oyama IM status

Apache Users

Apache Modules

CPAN


Home > Blog > Mac miniでメールサーバを組む手順