コンテンツにスキップ

DovecotのLDAP認証

DovecotはLDAPをpassdbとuserdbとして直接参照できる。PostfixもLDAPでローカル受信者の存在を確認すると、Linuxアカウントを作らずにSMTP AUTH、LMTP配送、IMAPログインを同じLDAPユーザーへ統一できる。


passdb pam {}とuserdb passwd {}を使う構成では、DovecotはPAMとNSSへ問い合わせる。LDAPをLinuxログインにも使用するようNSS・PAMを設定していれば、その先でLDAPが参照される。

passdb ldap {}とuserdb ldap {}を使う構成では、Dovecot自身がLDAPクライアントになる。メールサーバーをLDAPのLinuxログインクライアントにする必要はなく、Dovecotの認証とメールボックス検索だけをLDAPへ接続できる。

どちらもLDAPでパスワードを確認できるが、問い合わせの経路とユーザー属性を取得する主体が異なる。


passdbは、SMTP AUTHまたはIMAPで提示されたユーザー名とパスワードを検証する。

LDAPのuserPasswordをDovecotへ読み出して比較する方法と、入力されたパスワードでユーザーDNへBindする方法がある。認証Bindを使うと、パスワードハッシュをDovecotへ返すACLを与えずに、LDAPサーバーへパスワード検証を任せられる。

ユーザーDNがuid=alice,ou=people,dc=example,dc=comのように配置されている場合、認証は次の順序で進む。

flowchart TD
    C["メールクライアント<br/>alice@example.comとパスワード"]
    D["Dovecot Auth<br/>ドメイン部分を除いてaliceに正規化"]
    S["LDAP検索<br/>uid=aliceのエントリを検索"]
    DN["ユーザーDN<br/>uid=alice,ou=people,..."]
    B["LDAP認証Bind<br/>ユーザーDNと入力されたパスワード"]
    R["認証成功または失敗"]

    C --> D
    D --> S
    S --> DN
    DN --> B
    B --> R

最初の検索はユーザー名からDNを特定する処理であり、その時点では利用者のパスワードを検証していない。検索で得たDNと入力されたパスワードによるBindが成功して初めて認証成功となる。

LDAP ACLが匿名検索を許可する場合、DN検索は匿名Bindで行える。匿名検索を許可しない場合は、検索だけを行えるサービス用DNとパスワードをDovecotへ設定する。サービス用DNにuserPasswordの読み取り権限は必要ない。


userdbは、認証後のIMAP処理やパスワードを伴わないLMTP配送のために、メールボックス所有者の情報を取得する。

LDAP属性 Dovecotのuserdbフィールド 用途
uidNumber uid メールボックスへアクセスするプロセスのUID
gidNumber gid メールボックスへアクセスするプロセスのGID
homeDirectory home ~/Maildirの~を展開する基準

LDAPがuidNumber: 20001、gidNumber: 20000、homeDirectory: /var/vmail/aliceを返すと、DovecotはUID 20001、GID 20000で/var/vmail/alice/Maildirへアクセスする。カーネルはUIDとGIDを数値で扱うため、同じ名前のLinuxユーザーを/etc/passwdへ作る必要はない。

メールボックスのディレクトリ所有者は、LDAPが返す数値と一致させる。値が異なると、認証は成功してもLMTP配送またはIMAPアクセスがPermission deniedで失敗する。

LMTPは利用者のパスワードを受け取らないため、認証Bindの結果を使って配送先を決めることはできない。LDAPサーバーへ通常の検索を行うuserdbが必要になる。


example.comをmydestinationに含めると、Postfixはalice@example.comをローカル受信者として扱う。既定のlocal_recipient_mapsはUNIX passwdデータベースとエイリアスを参照するため、LDAPだけに存在するaliceは見つからない。

PostfixのLDAP mapをlocal_recipient_mapsへ追加すると、SMTPのRCPT TOを受理する前にLDAPで受信者の存在を確認できる。検索結果の値は配送先として使わず、該当エントリが存在するかどうかだけを判断する。

flowchart TD
    S["SMTP RCPT TO<br/>alice@example.com"]
    P["Postfix<br/>local_recipient_mapsを検索"]
    L["LDAP<br/>uid=aliceが存在するか"]
    A["RCPTを受理"]
    M["Dovecot LMTP<br/>userdb ldapでUID・GID・homeを取得"]
    D["/var/vmail/alice/Maildirへ保存"]

    S --> P
    P --> L
    L --> A
    A --> M
    M --> D

LDAP mapを設定せずにlocal_recipient_mapsを空にすると、Postfixは存在しないローカル宛先も一度受理する。Dovecot LMTPで後から拒否されるため、SMTP接続中に未知の受信者を拒否できない。LDAP mapで有効な受信者だけを受理する方が、不要なキュー投入や配送不能通知を抑えられる。


SMTP、Submission、IMAPのTLSと、Dovecot・PostfixからLDAPサーバーへのTLSは別々の接続に適用される。メールクライアントとの通信をTLSで保護しても、LDAP接続が自動的に暗号化されるわけではない。

認証Bindでは利用者のパスワードがLDAP接続へ渡される。ldap://へ平文で接続すると、その資格情報を通信経路上から取得できる。StartTLSではTCP 389へ接続した後にTLSへ切り替え、LDAP検索とBindを暗号化する。

StartTLSでは、DovecotとPostfixの両方に信頼するCA証明書を設定し、LDAPサーバー証明書の署名チェーン、有効期間、接続先名ldap.example.comを検証する。暗号化だけを有効にして証明書検証を無効にすると、接続先が正しいLDAPサーバーであることを確認できない。


匿名検索を許可しないLDAP ACLでは、DovecotとPostfixに検索用のサービスアカウントを設定する。必要な権限は、対象Base DN配下でuid、objectClass、uidNumber、gidNumber、homeDirectoryを検索・参照する権限である。

検索用Bindパスワードを含む設定ファイルは、サービス以外の利用者から読めない権限にする。Dovecotではrootだけが読める0600、PostfixのLDAP mapではroot所有・postfixグループの0640にする。