カテゴリー別アーカイブ: Mail

Dovecot, imapsync の更新

Dovecot 2.2.9, imapsync 1.564 の組合せにしたらエラーが出て接続できなくなった。

Error: user xxx: Initialization failed: namespace configuration error: There can be only one namespace with inbox=yes
Error: Invalid user settings. Refer to server log for more information.

/usr/pkg/etc/dovecot/local.conf にはこう書いてある。

# 略
namespace {
  separator = .
  prefix = INBOX.
  inbox = yes
}

こう修正したら、エラーは出なくなった。

# 略
namespace inbox {
# 略

あと、以前は imapsync の namespace 周りにバグがあって、オプションの –prefix2 と –sep2 で明示的に指定してやる必要があったのだけれど、今見たら必要なくなったみたい。

Dovecot でローカル配信する

Dovecot 1.x の時代、ローカル配信は Dovecot 付属の deliver を使うのが主流だった。

Dovecot 2.x になってから、deliver は dovecot-lda になって delibver は dovecot-lda へのシンボリックリンクに変わった。

そのせいかどうかはわからない(Dovecot 1.x の時代にどうであったかはわからない)が、system user じゃない virual user、つまり、OS のユーザじゃなく Dovecot 上にしか登録されていないユーザ、への配信がどうもうまくいかない。

Postfix 側の方の設定によるものなのか、 Dovecot 側なのかということもわからないのだが、パーミッションの関係かもしれないと思って Dovecot2 のドキュメントの Dovecot LDA with Postfix – Virtual users with multiple uids の節を読んでみると、dovecot-lda を setuid root しろとか、sudo で起動しろとか書いてある。

さらに、Dovecot LDA のセクションを読むと冒頭に、いや、いまどき普通 LMTP でしょ、とか書いてある。

Nowadays you should probably use the LMTP server instead, because it’s somewhat easier to configure (especially related to permissions) and gives better performance.

普通 LMTP というならしかたがない、ということで、ドキュメントを見ながら色々試行錯誤したまとめ。

まず、OS上のユーザ(システムユーザ)とDovecot上のユーザ(仮想ユーザ)の扱い。これは別ドメインとして管理することにして、OSのユーザへのローカル配信はPostfixで、仮想ユーザへの配信を dovecot-lmtp で行うことにした。そうすればシステムユーザに対しては /etc/mail/aliases とか ~/.forward も従来通り有効だし、レガシーなメールアプリケーションとも親和性がよいだろう。

postfix 側の設定は、/etc/postfix/main.cf に以下を追加する。

virtual_mailbox_domains = mbox.$mydomain
virtual_transport = lmtp:unix:private/dovecot-lmtp

1行目が Dovecot で管理する仮想ドメインの指定。2行目が仮想ドメインに配信するソケットの指定で、各要素がコロン ‘:’ で区切られている。

1つ目の ‘lmtp’ がプロトコル。2つ目の ‘unix’ がソケットの種類で、ここでは UNIX ドメインのソケットであることを示している。3つ目の ‘private/dovecot-lmtp’ は UNIX ドメインソケットのパスで、相対パスになっている。絶対パスだと ‘/var/spool/postfix/private/dovecot-lmtp’ だ。もちろん環境依存である。

Dovecot 側の設定では、関係するところを抜粋した。

protocols = imap lmtp

protocol lmtp {
  mail_plugins = quota
}

service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    user = postfix
    group = wheel
    mode = 0666
  }
}

userdb {
  driver = passwd-file
  args = username_format=%n /usr/pkg/etc/dovecot/userdb
}

protocols に lmtp を入れておくのは当然。

‘service lmtp’ が LMTP サーバの定義。プロトコルには UNIX と INET が使用できるが、Postfix からのローカル配信限定という条件なので、UNIX のみにした。したがって、’unix_listener’ の定義のみで、その直後に記述されている ‘/var/spool/postfix/private/dovecot-lmtp’ というのが待ち受けるソケットのパスになる。当然ながら、先の Postfix 側の設定と対応する。

ソケットの場所、ユーザとグループ、パーミッションは、Postfix の他のソケットと揃えておいた。NetBSD 5.1.2 では /var/spool/postfix/private が 0700 で、中のソケットが 0666 というレイアウトになっている。

そして最後に userdb の設定(これが一番ハマった)。ここでは仮想ユーザの検索ドライバとして passwd-file を使用し、args で指定している ‘/usr/pkg/etc/dovecot/userdb’ から仮想ユーザの情報を得ている。

args に ‘username_format=%n’ とあるのは、LMTP に検索キーとして渡される宛先アドレスからユーザ名を抽出するための設定。Postfix から dovecot-lmtp へはドメインを含む(メールアドレスの ‘@’ 右側を含む)宛先アドレスが渡される。仮想ユーザをドメイン込で passwd-file に記述していればそのままでいいが、ユーザ名部分のみ(’@’ の左側部分のみ)だと一致しないということで、ユーザが見つからないという結果になる。

複数のドメインを取り扱う場合にはドメイン込で記述する必要があるが、単一のドメインの場合は、略したいので ‘username_format=%n’ という設定が必要となる。

Dovecot ってサンプルとかチュートリアルがまだまだ少ないよね。

Dovecot 起動時に FD 足りないと言ってくる

NetBSD で Dovecot-2.1.12 起動時に以下の warning がでてくる。Dovecot は pkgsrc でインストールしたもの。

Warning: fd limit (ulimit -n) is lower than required under max. load (768 < 1000), because of default_client_count

FD、つまり一度にオープンできるファイルの数が足りないということらしい。

ulimit -n 1024; /etc/rc.d/dovecot start

と warning は出なくなる。問題はこの設定をどこでするか。

最初 login.conf でするのかと思ったけれど、warning message 中の 768 という数字はデフォルトではない。

とすると、どこかで設定してるはず、と思って /etc/rc*, /etc/rc.d/* に対して 768 で grep かけてみると、/etc/rc.d/dovecot の中に、下のような変数があった。

dovecot_fdlimit=${dovecot_fdlimit-"768"}

rc スクリプト書いた時には 768 でよかったけど、今ではもっと大きくしないといけない、ってことか。

ということで、/etc/rc.conf に以下を記述。

dovecot_fdlimit=1024

Dovecot – doveadm mount /mnt/foo ignore

Dovecot のログにいつしか下のような warning が出るようになっていた。

master: Warning: /mnt/foo is no longer mounted. See http://wiki2.dovecot.org/Mountpoints

指定の URL http://wiki2.dovecot.org/Mountpoints を見ると、Dovecot はマウントポイントの監視をしていて、以前あったマウントポイントがなくなると上記のような warnig を出すらしい。

マウントポイントの管理は doveadm(1) というツールを使うらしい。一覧を出すには “doveadm mount list”、削除は “doveadm mount remove /mnt/foo” のようにする。

登録されてしまったマウントポイントを無視するには、下のようにする。

# dovecot mound add /mnt/foo ignore

マウントポイントは /var/run/dovecot/mounts というファイルで管理されている (NetBSD+pkgsrc の場合)。
管理ファイルが置かれているディレクトリは doveconf(1) を使って確認できる。

# doveconf base_dir
base_dir = /var/run/dovecot

ていうか、マウントポイントの監視対象を制限したいんだけどそういう設定はないのかな?

dovecot2 と imapsync

さくらインターネットがやっているさくらのメールボックスというサービスがあって、メールの送受信はここを利用している。IMAP4 に対応していて、複数の端末でメールを利用するのが便利だからだ。基本的に全てのメールを IMAP サーバ上において整理、管理をしている。

だが、過去のメールのすべてが、業者のサーバ上にしかないというのも不安なので、手元にバックアップを取るようにしている。さくらのメールボックス上のデータには IMAP クライアントでしか接続できないので、imapsync というツールを使って、自宅サーバ上に構築した IMAP サーバとの同期をとっている(自宅サーバ上のデータは定期的に差分バックアップをとっている)。

以前の自宅サーバの環境は、dovecot 1.x で運用していたのだが、先日サーバを入れ替える際に、dovecot を 2.0 に置き換えたのだ。dovecot2 については、また別記事に記述することにするが、dovecot2 に入れ替えたことによって、imapsync がエラーを出して停止するようになってしまった。

エラーの内容は IMAP4 サーバの CAPABILITY に NAMESPACE が含まれていないというもの。

IMAP4 サーバに NAMESPACE の機能がない場合には、imapsync の –prefix2 や –sep2 オプションでプレフィックスとセパレータを指示する必要がある。でも dovecot2 にも NAMESPACE の機能はあるはずで、dovecot の設定ファイルで imap_capability = +NAMESPACE を指定して、接続時に CAPABILITY として返す文字列を追加すると imapsync は動作するようになる。ただし、imap_capability で指定する文字列は、実際の機能と関係なしに指定できるようで、回避策としてはちょっと不安だ。

そもそも、Thunderbird なんかだとプレフィックスやセパレータをちゃんと取得しているようだ。dovecot2 に NAMESPACE の機能があることは間違いなさそうだ。

で、調べてみると dovecot のメーリングリストにそれらしい話題を見つけることができた。

どうやら、CAPABILITY の一部はログインしてからでないと表示されないということらしい。NAMESPACE などはログインするまでは不要な機能なので接続時には表示しないということか。

根本的には imapsync (または imapsync が利用している IMAP 用のモジュール) がバージョンアップするのを期待するしかないようだが、それまでは、以下の2つのどちらかで対応するしかなさそう。

  1. imapsync のオプション –prefix2 および –sep2 で dovecot が使用しているプレフィックスとセパレータを指定する
  2. dovecot の設定ファイルで imap_capability = +NAMESPACE を指定し、接続時の CAPABILITY に NAMESPACE を追加する

imapsync が修正される頃には忘れてそうな話題だ。

Postfix のインストール (pkgsrcで)

以前 Atom で組んだ NetBSD サーバだが、相変わらず調子が悪く、不定期に再起動が発生している。

ネットワークとかディスクの負荷とかと関係があるかと思って、ルータとして動かすのをやめてみたり、NFSサーバをやめてみたり、各種サーバプロセスを止めてみたりしたものの、改善の様子はない。

結局、別のサーバに完全に移行することにした。

今はメールサーバも外部サーバで運用しているのが、自宅サーバの cron メールを外部のメールサーバに転送するために、当該サーバではまだ Postfix が動いている。そして SASL が必要なために NetBSD 付属のではなく、pkgsrc でインストールしたものを使用している。

そこで移行先のサーバで pkgsrc で Postfix をインストールしたのだが…。

はて? pkgsrc でインスト-ルした方の Postfix を使うにはどうするんだっけ?

元のサーバの /etc/rc.conf を見ても何も書いてない。/etc/mailer.conf もオリジナルのままだ。でも、 ps で確認すると /usr/pkg/sbin/postfix が動いている…。

正解は /etc/rc.conf.d/postfix だった。しかも、以前インストールした時のメモに書いてあるし。

悔しいのでもう一度書いておく。

$ pkg_info -D postfix
Information for postfix-2.8.3nb1:
Install notice:
(略)
===========================================================================
$NetBSD: MESSAGE.NetBSD,v 1.5 2010/03/02 08:07:36 martti Exp $
The existing /etc/rc.d/postfix can be forced to start /usr/pkg/sbin/postfix
instead of /usr/sbin/postfix, by adding the following lines to
/etc/rc.conf.d/postfix:
postfix_command='/usr/pkg/sbin/postfix'
required_files='/usr/pkg/etc/postfix/main.cf'
start_cmd='/usr/pkg/sbin/postfix start'
stop_cmd='/usr/pkg/sbin/postfix stop'
reload_cmd='/usr/pkg/sbin/postfix reload'
postconf='/usr/pkg/sbin/postconf'
Please note that /etc/rc.conf.d/postfix does not exist by default so
you need to create that file if you need to override the default settings.
Remember to modify /etc/mailer.conf to use /usr/pkg/sbin/sendmail instead
of /usr/libexec/postfix/sendmail.
===========================================================================

pkgsrc/mail/p5-Mail-IMAPClient

pkgsrc でインストールした imapsync (pkgsrc/mail/imapsync) を動かしていたら、下のようなエラーが出ていた。

Use of uninitialized value $_ in uc at /usr/pkg/lib/perl5/vendor_perl/5.12.0/Mail/IMAPClient.pm line 2630.

調べてみると、imapsync が依存する Perl module である Mail-IMAPClient-3.23 (pkgsrc/mail/p5-Mail-ImapCleint) のバグで、3.24 では修正済みの問題らしい。

pkgsrc-2011Q1、pkgsrc-HEAD のどちらもこの問題に対する対応はされていないようだ。

いずれ pkgsrc/mail/p5-Mail-ImapCleint でインストールされるバージョンが上がれば解決する問題なので、手元にインストールされているファイルを修正して対応することにした。

--- IMAPClient.pm.orig
+++ IMAPClient.pm
@@ -2627,7 +2627,7 @@
if ( ref($v) eq "SCALAR" ) {
push( @ret, $$v );
}
-        elsif ( exists $SEARCH_KEYS{ uc($_) } ) {
+        elsif ( exists $SEARCH_KEYS{ uc($v) } ) {
push( @ret, $v );
}
elsif ( @args == 1 ) {

サーバの引越し(4) メールボックスの移動

移行先のメールサーバはさくらのメールボックスとした。
対外的なメールアドレスはさくらのアドレスとして、
さくらから uconst.org にメールの転送設定をしてある。

つまり、全てのメールがさくら経由で uconst.org に配送される状態である。

これを、さくらに配送されるように切り替える。

手順は以下のとおり。

  1. uconst.org の SMTP サーバ (Postfix) を停止する。
  2. メールボックスの中身をコピーする。
  3. さくらから uconst.org へのメール転送設定を解除
  4. uconst.org からさくらへのメール転送設定
  5. uconst.org の SMTP サーバ (Postfix) を起動する。

メールボックスのコピーは imapsync を使用した。

imapsync \
--host1 mail.uconst.org --ssl1 \
--user1 user_at_uconst_org --passfile1 pwfile_imap_uconst_org \
--host2 subdomain.sakura.ne.jp --ssl2 --authmech2 plain \
--user2 user_at_sakura@subdomain.sakura.ne.jp --passfile2 pwfile_imap_sakura

これで、外部にアナウンスしている subdomain.sakura.ne.jp 宛のメールは
直接 subdomain.sakura.ne.jp に入るようになった。

そして、uconst.org 宛のメールは、subdomain.sakura.ne.jp に転送される。

あとは、uconst.org の MX レコードをさくらに向ければ完了…のはずだったが。

続きは DNS の設定編で。

サーバの引越し(3) これまでのメールサーバの構成

メールサーバの移行の前に、現状の構成の整理

受信については、各プロバイダのメールを全て、独自ドメインのサーバに転送するよう設定している。
サーバのアプリケーションは Postfix。
SASL などを使用できるよう、NetBSD 付属のではなく、
pkgsrc で mk.conf に以下のオプションを指定して作成したものを使用している。

PKG_OPTIONS.postfix = sasl pcre

IMAPサーバは Dovecot で運用。
Postfix の main.conf に以下を記述し、
ローカル配送に Dovecot の配送プログラムを使用するようにしている。

/usr/pkg/etc/postfix/main.conf
mailbox_command = /usr/pkg/libexec/dovecot/delive

送信は、独自ドメインのサーバ(Postfix)で全てを一旦受け取る。
ここは、Postfix でいう smtpd の担当。

送信の場合のメールクライアントからの受付は submission port (587) で、
STARTTLS、認証必須。
認証は Dovecot の認証用のソケット(ここでは /var/run/dovecot/auth-client)を利用。
STARTTLS で使用するサーバ証明書は、openssl で第四種オレオレ証明書を作成。

/usr/pkg/etc/postfix/master.cf
submission inet n       -       n       -       -       smtpd
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
/usr/pkg/etc/postfix/main.cf
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination
smtpd_tls_cert_file = /etc/openssl/certs/mailservercert.pem
smtpd_tls_key_file = /etc/openssl/private/serverkey.pem
smtpd_sasl_type = dovecot
smtpd_sasl_path = /var/run/dovecot/auth-client

Dovecot の認証用ソケットの設定(IMAP用も兼用)は以下。
認証は、UNIX のパスワード認証(passdb passwd)と
パスワードファイルによる認証 (passdb passwd-file)を使用可能とし、
パスワードファイルによる認証スキームとして CRAM-MD5 を指定している。

/usr/pkg/etc/dovecot.conf
auth default {
mechanisms = plain cram-md5
passdb passwd {
}
passdb passwd-file {
args = scheme=cram-md5 /usr/pkg/etc/cram-md5.pwd
}
userdb passwd {
}
user = root
socket listen {
client {
path = /var/run/dovecot/auth-client
mode = 0660
group = mail
}
}
}

Dovecot での CRAM-MD5 のパスワードは以下のようにして作成する。

$ dovecotpw -s CRAM-MD5
Enter new password: XXXXXX
Retype new password: XXXXXX
{CRAM-MD5}00747cf2ffaf11c5ea4a64979c3901fc1d20dee13f480bb598f7d8575b23e61b

“{CRAM-MD5}” より後の部分が CRAM-MD5 のパスワードのデータである。
これを切り取って、ユーザ名、”:”、パスワードデータ の形式で cram-md5.pwd に記述すればよい。
cram-md5.pwd は先の dovecot.conf 中で指定したファイルである。

/usr/pkg/etc/cram-md5.pwd
hoge:00747cf2ffaf11c5ea4a64979c3901fc1d20dee13f480bb598f7d8575b23e61b
fuga:4b05653a6b48eeeb7ef25800a514e2fe6d6ea31ff6d3a17bd2f4ac7cad390426

CRAM-MD5 だと MD5 の計算途中のデータを保存するので、
生のパスワードを保存するよりは安全らしい。

受け取ったメールは envelope sender の値に応じて、
送信する SMTP サーバを切り替える。
直接相手先には送らない。
独自ドメインを取得してはいるが、プロバイダのメールアドレスを使用して送るメールについては、
できるだけ一般のクライアントと同様となるように経路を選択するポリシーを適用する。

たとえば、 メールの envelope sender がプロバイダ A 所属のアドレスが記述されていれば
A の送信用サーバに、
プロバイダ B 所属のアドレスが記述されていれば
B の送信用サーバにメールを転送するといった具合である。

送信用サーバごとに切り替える情報は以下のとおり。

  • SMTPサーバのアドレスとポート (25 または 587)
  • 認証用IDとパスワードのセット

envelope sender で切り替えを行う設定は、以下のとおり。

/usr/pkg/etc/postfix/main.cf
sender_dependent_default_transport_maps =
hash:$config_directory/sender_transport
/usr/pkg/etc/postfix/sender_transport
@プロバイダAのドメイン     smtp:[Aの送信用サーバ]:587
@プロバイダBのドメイン     smtp:[Bの送信用サーバ]:587
@gmail.com                 smtp:[smtp.gmail.com]:587

プロバイダの送信用サーバは認証が必要(とくにそのプロバイダを接続業者としていない場合は)なので、
送信用サーバとその認証情報を関連付ける。

/usr/pkg/etc/postfix/main.cf
smtp_tls_security_level = may
smtp_sasl_auth_enable = yes
smtp_sasl_type = cyrus
smtp_sasl_password_maps = hash:$config_directory/sasl_passwd
smtp_sasl_tls_security_options = noanonymous
/usr/pkg/etc/postfix/sasl_passwd
[Aの送信用サーバ]:587   AのID:Aのパスワード
[Bの送信用サーバ]:587   BのID:Bのパスワード
[gmail.com]:587         gmailのID:gmailのパスワード

プロバイダへの送信時に使用する認証IDは、
メールを送信したユーザに関係なく共通になってしまうが、
ここは気にしないことにする。

あと、sender_transport や sasl_passwd は postmap を使って hashed database にしておく。

駆け足で、これまでの構成を記述したが、
あらためて読み返すとずいぶん複雑なものになってしまっている。
メールサーバを移行してしまった後は、これらは全て不要となるわけだが…。

サーバの引越し(2) メールサーバの選定

これまでは、固定IPを取得して外部に公開しているサーバで postfix を動かしてメールを受けていた。
このサーバは独自ドメインの名前をつけてある。
契約しているプロバイダのメールはこのサーバに転送し、まとめて参照するようにしていた。

送信するメールの発信元が独自ドメインだと、送り先によっては信用が足りないケースが懸念されるので、
公式には契約しているプロバイダのうち、最も古くから使用しているものを公式なメールアドレスとして使用していた。
具体的には IIJ4U であるが、これが長い間、メールアドレスを維持するためだけの契約となっていたのである。

ちなみに、IIJ4Uではメールアドレス付きの基本料金が840円/月、
アドレスを一つ追加するごとに+315円/月である。
いまどきの感覚だと、さすがにリーズナブルとはいいがたいのではなかろうか。

回線業者はこれまでに何度も切り替わっており、今後も切り替わる可能性が高いので、
回線業者の提供するメールアドレスとは独立している方が望ましい。
複数のアドレスを取得した場合に安価であることが必要だ。できれば追加料金はないほうがよい。

普段メールをチェックしないユーザも抱えているので、無料のサーバは使えない。
というのは、無料のサーバは一定期間利用しないと削除されてしまうからだ。
少なくとも調べた範囲ではそうなっていた。

また、複数の場所からメールを参照したいので、IMAPは必須である。

ということで、さくらインターネットのさくらメールボックスが候補に残った。

年間料金が1000円で、複数アドレスが作り放題なので、条件的としては申し分ない。
また、自由度も比較的高いようで、独自ドメインのメールを直接受けることもできる。

早速、さくらと契約した。

まずは、各所に登録しているアドレス(IIJ4U)をさくらに作成したアドレスに変更することだ。

大抵のところでは、ログインパスワードを忘れた場合、
パスワードを再登録するためのページを一時的作成して、そのアドレスを登録してあるメールアドレスに送ってくれる。

そのメールアドレスがなくなると、二度とログインできなくなってしまう。

新規登録しても問題ないようなものとか、
別経路(書類)で本人確認できるようなところ(銀行など)であればまだ何とかなるが、
mixy や flickr など、どうしようもないところもあるし、できるだけ面倒は避けたい。

思いつく限り、調べられる限りの所をリストアップして、メールアドレスの変更手続を行っていく。
アカウント情報を削除して構わないところは、この機会に削除手続きを行う。
あとは、不通になっても構わないところだけ。

もちろん自分だけではなく、メールを移行する他のユーザにもお願いして、
変更手続を行ってもらわなければならない。

面倒ではあるが、この作業を丁寧にやることがその後のトラブルを避ける最も近道であるはずだ。

普通の人はどうしているのだろう?