Dovecotの設定

移転しました

独自ドメインサイトへ移行しました。5秒後に

https://straypenguin.winfield-net.com/

へジャンプします。

LDAP連携に関係するファイル一覧

/etc/
   \_ dovecot.conf              [root:root 644] 主設定ファイル
      dovecot.d/                [root:root 755] 補助設定ファイル用ディレクトリ (新規作成)
             \_ ldapref.conf    [root:dovecotauth 640] LDAP参照定義ファイル

dovecot.conf - 主設定ファイル

以下は Dovecot 1.0.7 で検証したもの。LDAP と関わりがなくても主なパラメータについては網羅し、当実装に特に深く関わるものは 地で示す。最新のディレクティブリストはオフィシャルサイト Dovecot.orgDovecot configuration file(1.x系) で見られる。LDAP連携に関しては、Dovecot wiki の "HOWTOs / Examples / Tutorials" や、ソースに付属している dovecot-ldap-example.conf, AuthDatabase.LDAP.txt が参考になる。

1.x 系からは、Postfix と同様にコマンドで設定一覧がダンプできる。`dovecot -a' で全てのパラメータ、`dovecot -n' で非デフォルトのパラメータが出力される。

設定サンプル: dovecot.conf

パラメータ名 説明
基本設定
base_dir /var/run/dovecot/ ランタイムデータの保持に使用するディレクトリ
protocols pop3 提供するサービスプロトコル。複数時はスペース区切りで。本稿では IMAP は扱わない
ログ    
log_path   Dovecot 自体で直接ログを書き出す場合の出力ファイルパス。ヌルなら syslog() に渡す
info_log_path   Dovecot 自体で直接インフォメーションログを書き出す場合。ヌルなら syslog() に渡す
log_timestamp "%b %d %H:%M:%S " syslog 経由でない場合のタイムスタンプフォーマット
log_facility local6 syslog() へログを渡す際のログファシリティ。別途 syslog.conf で出力先を指定する
SSL    
ssl_disable yes SSL/TLS サポートの無効/有効
disable_plaintext_auth no クライアントとの通信が SSL/TLS で暗号化されていない限り平文パスワードによるログインを一切禁止する/しない。ただし、クライアントのIPアドレスがローカルIPと同一の時、つまりサーバ自体の上から接続した時には、これが yes だとしても平文認証は許可される
ログインプロセス
login_dir /var/run/dovecot/login loginプロセス用 UNIXソケットファイルの作成ディレクトリ。loginプロセスの役目は、クライアントからのコネクションの受入れと、認証プロセス、メール読取りプロセスへのディスクリプタの橋渡し
login_chroot yes loginプロセスは login_dirchroot() される
login_user dovecot loginプロセスの実行ユーザ。セキュリティ対策
login_process_size 32 loginプロセス 1個あたりの最大制限サイズ (MB)
login_process_per_connection yes yes は「高セキュリティモード」と呼ばれ、クライアントからのコネクション 1本毎にひとつの loginプロセスを割り当てる。no の「高パフォーマンスモード」では loginプロセスが共有されるため、プロセスがクラックされた場合にメモリを通じて他のセッションのデータ(パスワードなど)まで盗まれるおそれがある
login_processes_count 10 コネクション受入れ可能状態で待機させておく loginプロセスの数の基本値。例えば 10 なら、既に使用中の loginプロセスが 2個ある時、システムに存在する loginプロセスは計 12個になる
login_max_processes_count 128 一時に多数のログインが要求された時に、同時に存在できる loginプロセスの数。上記 login_process_count が使い尽くされた時には、生成可能な loginプロセス数の上限が login_process_count の2倍にされ、更に足りなくなったらまた 2倍... と、この値に達するまで上限数が引き上げられる。この数の loginプロセスが全て使用中になると、最も古いものから破棄されていく。つまり「高セキュリティモード」においては、これが同時に接続できるクライアントの数を決定する
login_max_connections 256 「高セキュリティモード」では無視される。各 loginプロセスの扱えるコネクション数。「高パフォーマンスモード」では、プロセスはこの数のコネクションで満たされて初めて「非待機状態」とみなされる。つまり、「高パフォーマンスモード」における同時接続数の上限は login_max_process_count * login_max_connections ということになる
メール読取りプロセス
mail_location maildir:/var/vmail/%d/%h/Maildir メールボックスの位置。%h は後述の userdb から得られたホームディレクトリ、%d はユーザ名のドメイン部に置き換えられる。当実装では、アカウントの LDAPエントリから取得された mailMessageStore 属性値が %h に入り、mail 属性値の `@' より後ろが %d に入ることになる。利用できるその他の変数は wiki の "Variables" や、ソース付属の Variables.txt を参照
mmap_disable yes mmap() システムコールを使用しない。メールインデックスを NFS上に置く場合には yes にする必要がある。「補足」に挙げたドキュメントも参照
dotlock_use_excl yes Dovecot独自のロックファイル方式の排他制御 `dotlock' に関するパラメータ。dotlock ファイルを作成する際に O_EXCL フラグを指定すると、ロックファイルが既に存在している場合にすぐに失敗が判定できるためロック処理が高速になる。Maildir の場合も、メールインデックスなどに対して排他ロックは使用される。NFS上でも、NFSv3/v4 ならば O_EXCL はサポートされている
lock_method fcntl インデックスファイルに対する排他ロック方式。選択肢は flock, fcntl, dotlockNFSでは flock は効かない。メールインデックスを NFS上に置く実装にしていて fcntl で問題が起こる場合は、遅くはなるが dotlock を試してみよ、とオフィシャルマニュアルにある
verbose_proctitle no ps の出力にログインユーザ名やクライアントIP なども表示
first_valid_uid 500 ログインを許可するユーザのUID下限
last_valid_uid 0 ログインを許可するユーザのUID上限 (0 で無制限)
first_valid_gid 500 ログインを許可するユーザのGID下限
last_valid_gid 0 ログインを許可するユーザのGID上限 (0 で無制限)
mail_max_processes 1024 同時に存在できるメール読取プロセス数の上限
mail_process_size 256 mailプロセスの最大サイズ (MB)
valid_chroot_dirs /var/vmail メール読み取りプロセスの chroot() を許可するディレクトリ基底
mail_chroot   全てのユーザをひとつのディレクトリに chroot() する場合のパス
mail_cache_fields   メールインデックスファイルにキャッシュするメール属性のリスト (スペース区切)。フィールドには flags, data.sent, size.virtual などがあるが、オフィシャル文書には「目に見えるほどの効果はないので、指定せずデフォルトの挙動に任せることを勧める」とある
mail_never_cache_fields   同、キャッシュしない属性
mail_save_crlf no メールの改行コードを通常の LF から CRLF にして保存するか。これは DovecotIMAP で使用していてユーザがメールを「保存」した時に行われることらしい。POP3 で使っている限り yes に設定しても何も起こらない
mail_debug no mailプロセスのログを冗長に。デバグに役立つ
Maildir特有のパラメータ    
maildir_stat_dirs no LIST コマンドで Maildir下のドットで始まるファイルを返す。yes では毎回ディレクトリを stat() してディレクトリリストを返す
maildir_copy_with_hardlinks yes 新着メール (new/) を既読メールフォルダ (cur/) へ移動する際などに、可能な限りハードリンクコールを使用する。速度アップにつながる
POP3プロトコル
protocol pop3 {   プロトコル名。以下のパラメータは POP3 定義ブロックの中身
listen * POP3 サービスでリッスンする IPアドレス。 * ならマシンの持つインターフェイスアドレス全て。host:port の書式でポートを変えることも可能。ただし複数のアドレスを指定することはできない (1.1以降では可能らしい)
login_executable /usr/libexec/dovecot/pop3-login loginプロセス実行プログラム
mail_executable /usr/libexec/dovecot/pop3 mailプロセス実行ファイル
pop3_enable_last no 古いメールクライアントに実装されていた LAST コマンドを有効にするか。有効にすると、RSET コマンドで全メールの既読フラグがクリアされる
pop3_no_flag_updates no POP3 コマンドの LISTRETR を発行した時、通常ならそれらのメールには既読フラグが付けられるが、これを yes にしておくとフラグを更新しない。Maildir の場合は、new/ ディレクトリから cur/ への移動が行われないので、ディスクI/Oを減らせる
pop3_lock_session no yes にすると、ログイン中にはユーザの Maildir の下の dovecot-uidlist ファイルが排他ロックされる。ロックされている時に同一のユーザメールボックスに POP3 アクセスすると、ログインはできるものの、メールの一覧や内容を取得しようとした時に Dovecot のタイムアウトまで反応が停止する。mbox フォーマットの場合はタイムアウトが別途設定できるのだが、Maildir の場合は 2分で変えられない上、クライアントが不正終了するなどしてロックが残る心配があるため、使用には注意が必要
pop3_uidl_format %08Xu%08Xv POP3 メールクライアントは個々のメールの識別を UIDL (Unique ID Listing) という一種のフィンガープリントに依存している。UIDL は、POP3 セッションで UIDL コマンドを発行するとサーバから一覧として取得することができる。その時の UIDL 生成規則を決めるのがこのパラメータ
pop3_client_workarounds outlook-no-nuls oe-ns-eoh メールクライアントの不具合への対策。
outlook-no-nuls: メール内にヌル文字が入っているとハングする Outlook/Outlook Express のために、ヌル文字を 0x80 に変換して渡す。
oe-ns-eoh: メールのヘッダパートの最後の改行 (ヘッダ部とメールボディとの境界にあるはずの空行のことか?) が存在しない時に Outlook Express, Netscape Mail がクラッシュする問題への対策として、無い時は挿入して渡す
}    
認証プロセス
auth_executable /usr/libexec/dovecot/dovecot-auth 認証プロセス実行プログラム
auth_process_size 256 認証プロセスの最大サイズ (MB)
auth_cache_size 1024 認証キャッシュのキャッシュ量 (KB)。デフォルトでは 0 つまり無効だが、有効にしておくと LDAP への問い合わせを減らすことができる。ただし、auth_default_realm によってドメインが補完された時はキャッシュにヒットしない。「補足」も参照のこと
auth_cache_ttl 3600 認証キャッシュデータの有効期間 (秒)。今のところ、このパラメータは平文認証でしか機能しない、と書いてある
auth_realms   SASL認証のレルムのリスト (スペース区切り)
auth_default_realm hoge.cxm @ 以降のないユーザ名でログインしようとした時にデフォルトで補完する @domain.tld。これを入れておくと POP3 ログイン時に user@domain.tld で来ても user だけで来ても認証できる
auth_username_chars abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
01234567890.-_@
ログイン名に使用できる文字。LDAPインジェクション避け
auth_worker_max_count 30 認証プロセスのワーカースレッド数
auth_verbose no ログに認証プロセスの詳しいログを出力するか
auth_debug no 認証プロセスのログを更に冗長にする。デバグの時に役立つ
auth default {   認証プロセス名。以下のパラメータは `default' 認証プロセス定義ブロックの中身
mechanisms plain クライアントと遣り取りする認証の方式。複数の候補を有効にする時にはスペース区切りで連ねる。大文字小文字は関係ないようだ
passdb ldap {   ldapドライバによるパスワードDB検索定義ブロック
args /etc/dovecot.d/ldapref.conf LDAP参照定義ファイルを指定
}    
userdb prefetch {
}
  prefetch ドライバによるアカウント情報DB検索。これを使うと、passdbLDAP参照で userdb の分の情報取得を兼ねることができる。LDAP問い合わせが 一度で済み LDAPサーバへの負荷が抑えられる
userdb ldap {   ldapドライバによるアカウント情報DB検索定義ブロック。prefetch を使うならこのブロックごと不要。別途 LDA機能 (Local Delivery Agent) も利用する場合は必要
args /etc/dovecot.d/ldapref.conf LDAP参照定義ファイルを指定
}    
user dovecotauth 認証プロセスの実行ユーザ。セキュリティ対策
chroot   認証プロセスを chroot() するディレクトリ。chroot() すると LDAP参照が成り立たないのでヌル(無効)
count 1 生成する認証プロセスの数
}    
補足
NFS上にメールボックスやインデックスファイルを置く場合の注意
以下の Dovecotドキュメントに注意点やコツが書かれている。
認証キャッシュについて
wiki の "Caching of authentication results" に説明がある。認証キャッシュが効いているかどうかは、dovecot-auth プロセスに SIGUSR2 を送ることで確認できる。つまり、
root# killall -s USR2 dovecot-auth
を行えば、Dovecot のログファイルにヒット数が出力される (同時にヒットカウンタはリセットされる)。また、HUP シグナルを送ると認証キャッシュがクリアできる。
auth_cache_size の値は多少大きめにとっておけば問題ない。1個分の passdb キャッシュは 50 バイト前後、userdb キャッシュは 100~200 バイト前後だという。

ldapref.conf - LDAP参照定義ファイル

まず、今後補助設定ファイルが増えることを見込んで、補助設定ファイル用のサブディレクトリ /etc/dovecot.d/ を作成する (root:root 755)。その配下に LDAP 参照定義ファイル ldapref.conf (ファイル名は任意) を以下の要領で作成する。このファイルには LDAP データ読み取り専用ユーザのパスワードが書かれているので、一般の UNIXユーザに読めないよう、パーミッションは必ず root:dovecotauth の 640 にしておかなければいけない。

設定サンプル: ldapref.conf

hosts = localhost
dn = cn=userretriever,dc=hoge,dc=cxm
dnpass = password
ldap_version = 3
base = ou=People,dc=hoge,dc=cxm
deref = never
scope = onelevel
 
# passdb configuration.
auth_bind = no
pass_attrs = mail=user,userPassword=password,mailMessageStore=userdb_home
pass_filter = (&(objectClass=mailRecipient)(mail=%u))
default_pass_scheme = SMD5
 
# userdb configuration.
#user_attrs = mailMessageStore=home
#user_filter = (&(objectClass=mailRecipient)(mail=%u))
user_global_uid = 1025
user_global_gid = 1025
hosts
LDAPサーバを別のマシンで動かしている場合はそれなりに。スペース区切りで複数指定することも可能で、トラブルがない限り先に書いた方が使われる。ラウンドロビンや明確なフェイルバック動作は行われない。host:port による指定も可能。
dn
問い合わせ時に bind する DN
dnpass
bind パスワード。当実装ではつまり LDAPアカウント userretriever のパスワード。ハッシュして書いておく方法はないようだ。
ldap_version
問い合わせに使う LDAPプロトコルバージョン。
base
アカウントエントリを検索する Directory ツリー。後述の pass_filter にあるような %x 変数も使用可能。
deref
属性のデリファレンス (dereference = LDAP属性のシンボリックリンクのようなもの) をどういう局面で辿るか。never, searching, finding, always のいずれか。
scope
ldapsearch で言うところの -s オプションにあたるもの。base, onelevel, subtree のいずれか (one, sub といった略記法ではダメ)。特に理由のない限り onelevel にして検索負荷を軽減。
passdb に関する設定

ログイン認証用の参照定義。

pass_attrs
パスワードチェックに使用する LDAP属性。`=' の左辺は LDAP上での属性名、右辺にはそれを Dovecot 上にマップする変数名を書く。属性は、user@domain.tld の得られる属性と、パスワードを格納している属性が必要だ。prefetch 機能を利用する場合は、userdb に必要な属性についても指定。その際、userdb 用の変数であることを示すために右辺の変数名には `userdb_' を前置しなければならない。
pass_filter
LDAP検索フィルタ。このファイル最大のポイント。値は LDAPクエリフィルタ規格 に基づくフォーマットで書く。例は、「オブジェクトクラスが mailRecipient」且つ「mail属性がユーザ名全体と等しい」エントリを検索せよ、というフィルタだ。組み込み変数 %u で表される「ユーザ名」は、POP3 ログイン時にクライアントの申告してくるアカウント名だが、dovecot.confauth_default_realm に補完ドメインが指定してある場合には補完後の文字列となる。例では、クライアントが `user@hoge.cxm' のカタチで名乗ることを前提にしているが auth_default_realm の効果で `user ' のみでも認証できる。この他の組み込み変数については、wiki の "Variables" や、ソース付属の Variables.txt を参照。余計な Directory ツリーを探し回らせず検索を効率化するために、フィルタはできるだけ限定的にするべき。
default_pass_scheme
パスワードデータベースに格納されているパスワードの格納形式。当稿では、389 DS で userPassword 格納形式SMD5 にしたのでそれに合わせる。Dovecot 1.x でサポートされている全ハッシュ形式は wiki の "Password Schemes" を参照。
userdb に関する設定

ユーザのメールボックスを特定するための参照定義。

user_attrs
データベースから取得する属性。prefetch を利用する場合は設定無用。それ以外の時は、ホームディレクトリを格納している属性を指定する。得られたホームディレクトリの値は最終的に dovecot.confmail_location パラメータに従って整形されて実用に供される。本来であれば uid ナンバーと gid ナンバーも必要だが、本稿のようにバーチャルユーザの場合は、下記の user_global_uid, user_global_gid で固定するので要らない。
user_filter
LDAP検索フィルタ。prefetch を利用する場合は設定無用。必要な場合は passdb ブロックでの説明を参照のこと。
user_global_uid, user_global_gid
メールの読み取り/削除やインデックスファイル操作を行う際に mail プロセスが setuid/setgid する UNIX UID/GID。一般のメールユーザをバーチャルユーザとして扱う当実装では常に mailadmin の権限で行わせたいので、UNIXユーザ mailadminUID, GID を設定しておく。

サービスの起動

root# chkconfig dovecot on
root# service dovecot start

テスト

ローカル上や別のマシン上から、バーチャルメールアカウントの例えば penguin@hoge.cxmPOP3 ログインしてメールを読んでみる。テストコマンドは Qmail のページの「動作テストのためのコマンド」でいろいろと紹介している。