今どきのメールサーバに求められるのは、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をビルドするのに必要なBerkeleyDBとPCREを予めportsで入れておきます。
maildropそのものもports(/usr/ports/mail/maildrop)で入れる事は出来ますが、OpenLDAPとかMySQLとか、今回直接関係のないものが芋づるの先に付いてくるので、maildropはCourierのところで配布されているソースから入れる事にします。
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 ⏎
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# $Id: maildroprc.in,v 1.1 2010/02/02 03:41:35 ak Exp $ | |
# | |
# maildroprc for virtual mailbox | |
# | |
PATH='/usr/local/virtmail/bin:/usr/local/virtmail/sbin:/usr/local/bin:/usr/bin:/bin:.' | |
SHELL='/bin/sh' | |
UMASK='077' | |
logfile '/var/log/maildrop-virtual.log' | |
RECIPIENT="$1" | |
VIRTUALROOT="$HOME" | |
VIRTUALUSER=`echo $RECIPIENT | cut -d@ -f1` | |
VIRTUALHOST=`echo $RECIPIENT | cut -d@ -f2` | |
MAILDIR="$VIRTUALROOT/$VIRTUALHOST/$VIRTUALUSER/Maildir/" | |
DEFAULT="$MAILDIR" | |
`test -e $MAILDIR` | |
if( $RETURNCODE != 0 ) | |
{ | |
log "Maildir/ does not exist: $MAILDIR" | |
`for D in cur new tmp; do mkdir -p $MAILDIR/$D; done` | |
} |
ログファイル/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 のところを次のように書き換えます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
accept from all for virtual map virtusers deliver to mda "/usr/local/virtmail/bin/maildrop -d virtmail %u@%d" |
今回は 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で受けとるメールアドレスの設定を行います。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
example.jp OK | |
kyoto.azumakuniyuki.org OK | |
postmaster@example.jp postmaster@mta.example.jp | |
abuse@example.jp abuse@mta.example.jp | |
postmaster@kyoto.azumakuniyuki.org postmaster@example.com | |
abuse@kyoto.azumakuniyuki.org abuse@example.com | |
mikeneko@example.jp virtmail | |
kijitora@example.jp virtmail | |
shironeko@example.jp virtmail | |
americanshorthair@example.jp virtmail | |
sabatora@kyoto.azumakuniyuki.org virtmail | |
shibainu@kyoto.azumakuniyuki.org virtmail | |
spam@kyoto.azumakuniyuki.org gomi@mta.example.jp |
バーチャルドメインの定義
最初の二行は、受けとるべきバーチャルドメインの定義をします。これがないとメールアドレスのエントリがあってもメールは受けとれません。右辺値はなんでもよいっぽいです、たぶん。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で公開しています。
- sendmail-virtualmailbox | Virtual mailbox(Maildir) implementation with sendmail
今回の構築例も、そっちを基本として試験しました。
これから
最初の方でも書きましたが、まだOpenSMTPDはstableではありませんので、近い将来、この記事の内容が全てゴミになる可能性があります。文法が変わる事もありますし、SQLite対応な話が出ているので、今後大きな機能変更・拡張もありそうです。
とりあえずは、現段階でOpenSMTPDがどのくらいの完成度かなというお試し目的の実験ですし、リリースの度にちゃんとUpgradeしている場合は、毎回smtpd.confの書換をする必要があるかもしれません。なので本番環境で使うなら、stableになってから半年〜一年は経過してからかなぁという印象です。
とりあえずは、現段階でOpenSMTPDがどのくらいの完成度かなというお試し目的の実験ですし、リリースの度にちゃんとUpgradeしている場合は、毎回smtpd.confの書換をする必要があるかもしれません。なので本番環境で使うなら、stableになってから半年〜一年は経過してからかなぁという印象です。
安定版のOpenSMTPD 5.3.1での記事を書きました >> http://blog.azumakuniyuki.org/2013/05/virtual-mailbox-with-opensmtpd-531-on.html
返信削除