2013/01/23

OpenSMTPDとmaildropで仮想メールボックス環境を構築

この前書いたOpenBSD 5.2でOpenSMTPDの試運転した話の続きです。最近は企業・組織でもGoogle Appsを使うと言うケースをしばしば耳にしますが、自前でメールサーバを構築する場合は *BSD やLinux 上で信頼と実績・歴史と伝統のSendmailまたはPostfix と Dovecotを使って構築する事が多いでしょう。

今どきのメールサーバに求められるのは、POP3やIMAP でメールが取得できればよい環境です。なのでuidもshellも不要(そんなに沢山adduserしてられんし、危なそうな事はなるべく避ける)です。

いつも通り前置きが長くなるとアレなので、ここで書く事を簡潔に書くと、OpenBSD 5.2で動く OpenSMTPD で仮想的なメールボックス環境(バーチャルメールボックス)を構築して、各仮想ユーザのMaildir/へ配送する話です。なお、まだstableになっていないので、書いている内容が次のリリースで全く動かなくなる可能性もあります。よって、OpenSMTPDにもOpenBSDにも興味ない人にとっては、この記事は全くの無価値です。
[追記] 安定版での記事を書きました → 安定版OpenSMTPD 5.3で仮想メールボックスの試運転/CentOS 6

環境の概略

OpenBSD 5.2でOpenSMTPDの試運転した話が前提になっていますが、簡単に纏めると以下のような前提でやります。
  • OpenSMTPDの設定ファイルは/etc/smtpdに入れている
  • hostname(1)の実行結果がmta.example.jpとなるホストでやる
  • バーチャルドメインの対応と定義は/etc/smtpd/virtusersに書く
  • バーチャルドメインはexample.jpとkyoto.azumakuniyuki.orgの二つとする
  • 仮想メールボックスの位置は/home/virtmail/ドメイン/ユーザ/Maildirとする
  • 仮想メールボックスの所有ユーザはvirtmailとする
  • 仮想メールボックスのMaildir/への配送はmaidropプログラムを使う

仮想メールボックスの所有ユーザ追加

仮想メールボックス(バーチャルメールボックス)の所有者であるユーザ``virtmail''を追加します。このユーザはUIDもShellも$HOMEも持つユーザとして作成します。
# /usr/sbin/groupadd -g 660 virtmail ⏎
# /usr/sbin/useradd -u 660 -g 660 -s /bin/sh -d /home/virtmail -m -c 'Virtual Mailbox' virtmail ⏎

# finger virtmail ⏎
Login: virtmail                         Name: Virtual Mailbox
Directory: /home/virtmail               Shell: /bin/sh
Never logged in.
No Mail.
No Plan.
UID,GID共に660としていますが、被らなければなんでもいいです。

maildropのコンパイルとインストール

BerkeleyDBとPCRE

maildropをビルドするのに必要なBerkeleyDBPCREを予めportsで入れておきます。

maildropそのものもports(/usr/ports/mail/maildrop)で入れる事は出来ますが、OpenLDAPとかMySQLとか、今回直接関係のないものが芋づるの先に付いてくるので、maildropはCourierのところで配布されているソースから入れる事にします。

# for P in databases/db devel/pcre; do ⏎
> cd /usr/ports/$P && make install ⏎
> done ⏎
...

maildrop

maildropはこのあたりから取ってきて、/usr/local/srcで開けてからビルドします。
# cd /usr/local/src ⏎
# bunzip2 -c maildrop-2.6.0.tar.bz2 | tar xvf - ⏎
maildrop-2.6.0
maildrop-2.6.0/maildroptips.txt
maildrop-2.6.0/makedat
maildrop-2.6.0/makedat/aclocal.m4
...

# cd ./maildrop-2.6.0 ⏎

portsから入れたdb.hとかpcre.hが/usr/local/includeに入ってるので
# export CFLAGS='-I/usr/local/include' LDFLAGS='-L/usr/local/lib' ⏎
# export CPPFLAGS='-I/usr/local/include' ⏎

# export D=/usr/local/virtmail
# sh configure --prefix=$D --bindir=$D/bin --sysconfdir=$D/etc --localstatedir=$D/var --enable-sendmail=/usr/sbin/sendmail --enable-keep-fromline=1 --enable-unicode --with-etcdir=$D/etc --enable-maildrop-gid=_smtpd ⏎
...
# make && make install
maildropは/usr/local/virtmail以下にいれる事にします。

設定ファイルmaildroprcを作る

maildropが実行時に参照するファイルmaildroprcを/usr/local/virtmail/etcに下記の内容で作成します。
# mkdir /usr/local/virtmail/etc ⏎
# cd /usr/local/virtmail/etc ⏎
# mkdir ./rcs ⏎
# vi ./maildroprc
先に作成したユーザ``virtmail''でmaildropを実行しますので、maildroprcの$HOMEは/home/virtmailに展開されます。maildroprcをもっと細かく丁寧に(?書くならmaildropfilterのマニュアルを読むと良いです。

ログファイル/var/log/maildrop-virtual.logを作っておく

/usr/local/virtmail/etc/maildroprcでログファイルの位置を定義してますので、空のファイルを作って実行ユーザ権限で書き込みが出来るようにしておきます。
# touch /var/log/maildrop-virtual.log ⏎
# chown virtmail /var/log/maildrop-virtual.log
あとはログの循環設定もやっておくとよいです。
# maildrop log
/var/log/maildrop-virtual.log {
    missingok
    notifempty
    compress
    weekly
    create 0600 virtmail wheel
    rotate 8
}

/etc/smtpd/smtpd.confの編集

基本的な設定はOpenBSD 5.2でOpenSMTPDの試運転した話で出した内容のままです。そのsmtpd.confの28行目に書いた accept for virtual のところを次のように書き換えます。

今回は deliver to mda "コマンドと引数" と書いています。maildropへのPATHが長いのでマクロを定義したところですが、mda の次の引数は""で挟む必要があるようで、そうすると定義したマクロが展開されないので、直接書いています。

%u@%dはman smtpd.confにも書いてますが、%uがエイリアス展開前の宛先のローカルパート、%dが宛先のドメインに展開されます。-dの引数はmaildropコマンドを実行するユーザとしてのvirtmailです。

バーチャルドメインと仮想メールボックスの作成

maildropの準備が整ったので、バーチャルドメインとMaildir/格納用ディレクトリの作成をやります。

/etc/smtpd/virtusersの編集

Sendmailでも原則としてそうですが、バーチャルドメイン(sendmailではvirtuser-domains, virtusretable)の設定をしない限り、そのMTAが受けとるメールアドレスは ****@`hostname` なものだけです。その場合、このホストのでは、(ローカルに存在するユーザ|aliasesの左辺)@mta.example.jp だけとなります。

virtusers(.db)では、前述のexample.jpとkyoto.azumakuniyuki.orgで受けとるメールアドレスの設定を行います。

バーチャルドメインの定義

最初の二行は、受けとるべきバーチャルドメインの定義をします。これがないとメールアドレスのエントリがあってもメールは受けとれません。右辺値はなんでもよいっぽいです、たぶん。

postmaster@とabuse@

続いて、メールサーバを立てたら必ず設定しろと言われるpostmaster@とabuse@の設定です。最初の二つはvirtmailユーザ配下の/home/virtmailではなく、~/Maildirへ配送する為の設定です。

UIDとShellを持っているユーザ宛だけは、$HOME/Maildir へ配送したい場合は、このように ローカルパート@`hostname` と書けば良いっぽいです。

次の二つは、別ドメイン(example.com)のpostmaster, abuseに転送しています。ドメインが沢山在る場合は、一ヶ所に纏めたほうが合理的です。

仮想メールボックスへの配送

9行目から下は、今回の目的である仮想メールボックスへの配送です。受けとるべきメールアドレスを左辺値に、配送先のユーザ(virtmail)を右辺値に書きます。このように書く事で、mikeneko@example.jp 宛のメールは maildrop -d virtmail mikeneko@example.jp というコマンドでMDAが受け取り、maildroprcで /home/virtmail/example.jp/mikeneko/MaildirというPATHに展開して、そこへ配送します。

ごみ捨て用

一番下の行は、最終的に/dev/nullへ捨てる為のものです。

sendmailのvirtusertable→aliasesと違って、virtualで定義したマップの右辺値には、エイリアスの左辺値を直接かけないっぽい(今後かわるかも)ので、一旦、`hostname(1)`のホスト名なアドレスに書き換えています。

/etc/smtpd/aliasesの編集

virtusers.dbで編集した最後のエントリ用の設定をします。gomi@mta.example.jpを/dev/nullに流すあれです。sendmailのそれと同じなので、気楽に書けます。
# /etc/smtpd/aliases
gomi: /dev/null
書き終わったらそれぞれのファイルをmakemapしておきます。
# /usr/libexec/smtpd/makemap virtusers ⏎
# /usr/libexec/smtpd/makemap aliases

仮想メールボックスのディレクトリを作っておく(mkdir)

配送先のMaildir/がないとエラーになりますので、virtusers.dbに書いたメールアドレスに対応するMaildirを/home/virtmail以下にmkdirします。
# su - virtmail ⏎
$ for A in mikeneko kijitora shironeko americanshorthair; do ⏎
> mkdir -p /home/virtmail/example.jp/$A/Maildir/{cur,new,tmp} ⏎
> done ⏎

$ for A in sabatora shibainu; do ⏎
> mkdir -p /home/virtmail/kyoto.azumakuniyuki.org/$A/Maildir/{cur,new,tmp} ⏎
> done

配送試験

telnet localhost 25でやるか、mailコマンドで手軽にやるか、です。先にsmtpdをデバッグモードで起動しておきます。
# /usr/sbin/smtpd -vd ⏎
using "fs" queue backend
using "ramqueue" scheduler backend
startup [debug mode]
...
別のターミナルでメールを作って、virtusersで定義したアドレスに送ります。
# hostname | mail -s 'test' kijitora@example.jp
smtpdを起動したターミナルに下記のような出力があれば配送OKです。
# /usr/sbin/smtpd -vd ⏎
...
smtp: new client on listener: 0x8a309800
aliases_vdomain_exist: 'example.jp' exists
aliases_virtual_exist: 'kijitora@example.jp' exists
aliases_virtual_get: 'kijitora@example.jp' resolved to 1 nodes
lka_resolve_node: node is local username: virtmail
34b36728: from=<neko@example.jp="example.jp">, size=579, nrcpts=1, proto=ESMTP, relay=localhost [127.0.0.1]
scheduler_ramqueue: insert
smtp: 0x87acb000: deleting session: done
scheduler_ramqueue: next
scheduler_ramqueue: next: found
scheduler_ramqueue: schedule
scheduler_ramqueue: next
scheduler_ramqueue: next: found
forkmda: to /usr/local/virtmail/bin/maildrop -d virtmail kijitora@example.jp as virtmail
34b367283d7db733: to=<kijitora@example.jp="example.jp">, delay=0, stat=Sent
scheduler_ramqueue: remove
#### fsqueue_envelope_delete: queue_envelope_delete: 34b367283d7db733
scheduler_ramqueue: next
scheduler_ramqueue: next: found

配送できたら、find /home/virtmail/example.jp/kijitora -type f でもやればメールがファイルとして出来ている事が確認できるでしょう。

Maildirの中にメールがちゃんと配信されたら、あとはDovecotとかのPOP3d/IMAPdでメールの読出しをすれば完成ですね。

他のOSで

自分がいくらOpenBSDを使っていても、世の中出くわす人や案件はLinuxの方が圧倒的に多いです。なので、LinuxでSendmail + Dovecotな仮想メールボックス(Maildir)な構築スクリプトのセットをGithubで公開しています。
今回の構築例も、そっちを基本として試験しました。

これから

最初の方でも書きましたが、まだOpenSMTPDはstableではありませんので、近い将来、この記事の内容が全てゴミになる可能性があります。文法が変わる事もありますし、SQLite対応な話が出ているので、今後大きな機能変更・拡張もありそうです。

とりあえずは、現段階でOpenSMTPDがどのくらいの完成度かなというお試し目的の実験ですし、リリースの度にちゃんとUpgradeしている場合は、毎回smtpd.confの書換をする必要があるかもしれません。なので本番環境で使うなら、stableになってから半年〜一年は経過してからかなぁという印象です。

1 件のコメント:

  1. 安定版のOpenSMTPD 5.3.1での記事を書きました >> http://blog.azumakuniyuki.org/2013/05/virtual-mailbox-with-opensmtpd-531-on.html

    返信削除