この記事は、GMOペパボエンジニア Advent Calendar 2020の10日目の記事です。
9日目はmochikoさんのエンジニア未経験・異業種からの転職で早くも1年経っていたでした。
さて、本題です。
私は2020年にDovecotをガツガツ触っていました。
その際に公式のドキュメントを見つつ要件に合う設定を導入していました。
この時、事例をネットで検索したのですがなかなか出てこなくて困っていました。
そこで、今回POP3/IMAP4サーバのDovecotの設定あるあるをできるだけまとめてみることにしました。
まとめ
- Dovecotを最近使っているので情報をまとてみた
- 意図:ネット検索に引っかかる情報は古い情報が多めと感じたので2020年からみた情報を残したい。
- 設定。動作確認。DB接続。postfixのSASL認証利用。暗号化などなど。
役割
- POP3, IMAP4対応のミドルウェア
- 今も更新し続けられているソフトウェアなのでセキュアな要件に見合う機能がある。
- 一昔前だと、この役割にCourier-IMAPも候補に上がっていたが、更新は止まっておりセキュア対応に近年は懸念がある。
メジャーバージョン差異の注意点
1.xと2.xとに別れるが、今は2.xを使うのが一般的。
ドキュメントの場所が、1.xと2.xと違うので注意。Google検索でたどると古い情報にたどり着きやすいので公式の2.x系のドキュメントを必ず参照すること。
2.2 to 2.3アップデート時の警告
2.x系も今は2.4(今は2.3がstable)まであり、2.2から2.3の差異よりアップデート情報が多いのが注意。
latestを使わない限りは、大体のOSでの標準は2.2系を扱う。
特にSSL周りの警告が増える。
ssl_protocols setting was replaced by ssl_min_protocol. Now you only specify the minimum ssl protocol version Dovecot accepts, defaulting to TLSv1.
ssl_parameters was replaced with ssl_dh. See Diffie-Hellman Parameters for SSL.
SSLv2 is no longer supported as SSL protocol.
公式引用より。このあたりの扱いが変わる。
ssl_min_protocol
の指定も変わる。まだ警告レベルのエラー。
dovecot: doveconf: Warning: Obsolete setting in /etc/dovecot/conf.d/10-ssl.conf:7: ssl_protocols has been replaced by ssl_min_protocol
Diffie-Hellman(DH)の対応を何も設定していないと以下のエラーが出る。
dovecot: doveconf: Warning: NOTE: You can get a new clean config file with: doveconf -Pn > dovecot-new.conf
なお、のちに紹介するdoveadm
コマンドで動作確認をしても以下のように警告が促される。
dd if=/var/lib/dovecot/ssl-parameters.dat bs=1 skip=88 | openssl dhparam -inform der > /etc/dovecot/dh.pem
対応OS
ソースファイルはあるがパッケージのダウンロードもある。対応OSはCentOSやUbuntuと広範囲。ここではCentOS7/8より。
[dovecot-2.3-latest]
name=Dovecot 2.3 CentOS $releasever - $basearch
baseurl=http://repo.dovecot.org/ce-2.3-latest/centos/$releasever/RPMS/$basearch
gpgkey=https://repo.dovecot.org/DOVECOT-REPO-GPG
gpgcheck=1
enabled=1
yumrepoからダウンロードしてインストールすることができる。
対象ファイル
対象ファイルは、dovecot
がメイン。
ユーザ・パスワードをMySQLやPostgreSQLを使う場合は dovecot-mysql
, dovecot-pgsql
を使う。
ここではMysqlにユーザ・パスワードが保存されているとして、のちに接続方法を紹介する。
パスワードのセキュリティ強化の要件に答えることができる
このとき、DBのパスワード暗号化に相当する要件が欲しいとなるので、dovecotのセキュアな対応仕様が活躍する。
Password Schemes — Dovecot documentation
公式にあるように、SHA512-CRYPTなどセキュアなハッシュアルゴリズムを選択可能。
※ Courier-IMAPだと機能はあるが選択できるハッシュアルゴリズムがMD5ぐらいと新しいものに追随できていない。
imaptest
dovecot-imaptest なるパッケージはimapのパフォーマンステストが可能。
なお、簡易接続テストにはtelnetコマンドもよいが、 doveadm
コマンドが機能が豊富なので使えるようになると便利。使用例。
実設定
pop,imapのサーバを構築することを想定する。
加えてユーザ・パスワードの保存はDB(MySQL)にあるものとする。
その際の特殊設定としてSQLを用意してアクセスするので、その設定を紹介する。
ファイル群
設定箇所のデフォルトは以下。
主に、 /etc/dovecot/
にある、dovecot.confがiclude元となり、 /etc/dovecot/conf.d/
を読み込む設定のON/OFFをする。
ここに二種類の設定がある。主にconfがコメントアウトされているので必要に応じて使い、ext
はそのconfが必要に応じて読み込む設定となる。
/etc/dovecot
/etc/dovecot/conf.d
/etc/dovecot/conf.d/10-auth.conf
/etc/dovecot/conf.d/10-director.conf
/etc/dovecot/conf.d/10-logging.conf
/etc/dovecot/conf.d/10-mail.conf
/etc/dovecot/conf.d/10-master.conf
/etc/dovecot/conf.d/10-ssl.conf
/etc/dovecot/conf.d/15-lda.conf
/etc/dovecot/conf.d/15-mailboxes.conf
/etc/dovecot/conf.d/20-imap.conf
/etc/dovecot/conf.d/20-lmtp.conf
/etc/dovecot/conf.d/20-pop3.conf
/etc/dovecot/conf.d/20-submission.conf
/etc/dovecot/conf.d/90-acl.conf
/etc/dovecot/conf.d/90-plugin.conf
/etc/dovecot/conf.d/90-quota.conf
/etc/dovecot/conf.d/auth-checkpassword.conf.ext
/etc/dovecot/conf.d/auth-deny.conf.ext
/etc/dovecot/conf.d/auth-dict.conf.ext
/etc/dovecot/conf.d/auth-ldap.conf.ext
/etc/dovecot/conf.d/auth-master.conf.ext
/etc/dovecot/conf.d/auth-passwdfile.conf.ext
/etc/dovecot/conf.d/auth-sql.conf.ext
/etc/dovecot/conf.d/auth-static.conf.ext
/etc/dovecot/conf.d/auth-system.conf.ext
/etc/dovecot/conf.d/auth-vpopmail.conf.ext
/etc/dovecot/dovecot.conf
POP3, IMAP4
/etc/dovecot/conf.d/20-pop3.conf
/etc/dovecot/conf.d/20-imap.conf
この二つのファイルに相当する設定がある。
このとき、 /etc/dovecot/dovecot.conf
にて使うプロコトルを指定する(デフォルトで起動するが明示的に)。
protocols = imap pop3
!include conf.d/20-pop3.conf
!include conf.d/20-imap.conf
他にもSSLや認証要件にあわせて追加可能。
POP3の具体例
コメントアウトを意識せずに必要なものだけを抜き出すとこのような感じ。
dirverはsqlを使用を想定とする。
protocol pop3 {
passdb {
args = /etc/dovecot/conf.d/auth-sql.conf.ext
driver = sql
result_failure = return-fail
result_internalfail = return-fail
result_success = return-ok
}
}
パスワードの保存をpassdbを使っての保存。argsにある箇所がsqlを指定したextファイルを指定している。
公式情報のMySQLのクエリ例から一部抜粋だと以下。
driver = mysql
connect = host=/var/run/mysqld/mysqld.sock dbname=mails user=admin password=pass
#connect = host=localhost dbname=mails user=admin password=pass # port=3306
password_query = SELECT userid AS username, domain, password \
FROM users WHERE userid = '%n' AND domain = '%d'
user_query = SELECT home, uid, gid FROM users WHERE userid = '%n' AND domain = '%d'
password_query, user_queryがメインのクエリとなる。
パスワードを参照するクエリを用意。ASを使っているようにDBの名前にあわせてdovecotが必要とする名前に変更する必要がある。
あと、username, domain, passwordとあるが全部で持って認証するのかは要件次第。
なお、デフォルトは平文想定の default_pass_scheme = PLAIN
。
DBに生パスワードを保存していることが想定だが今時は使わないほうがよい。
そこで、あらかじめ対応したハッシュ強度(MD5, SHA2など)にあわせて設定する。
例えばテーブル側でハッシュ化処理をした場合は以下の様な接続条件を追加する。
driver = mysql
default_pass_scheme = SHA512-CRYPT
今回は SHA512-CRYPT
としてのは、MySQL側の該当のパスワードをハッシュ保存しているためこの値。
参考:MySQL :: MySQL 5.6 リファレンスマニュアル :: 12.13 暗号化関数と圧縮関数
SHA2(str, hash_length)
にあわせて設定する必要がある。
POP3同様にIMAPも似た設定をすることでDBでの認証前提アクセスが用意可能。
PROXYで透過的に疎通する方法
公式情報:Dovecot Proxy — Dovecot documentation
このとき、フロントとなるdovecotをproxyとして介し、実際の認証をバックエンドに任せる方法もある。
今回紹介した構成の場合は、直接アクセスするのではなく、クエリ発行時にproxy設定をすればよい。
password_query = SELECT 'Y' as proxy,
このおまじないのような設定を加えてあげると透過してクエリを発行することができる。
この方法はdovecot1.xのドキュメントのほうが具体例が参考になる。
参考:HowTo/ImapProxy - Dovecot Wiki
ロードバランサを前段に用意したときのIPアドレスの表示
ロードバランサ配下にdovecotを搭載した場合、ロードバランサあるあるでログに残る送信元IPアドレスがロードバランサのIP固定になることがある。
これを変更して表示したいときは、dovecot側の設定として以下を行う。
haproxy = yes
haproxy_trusted_networks = xxx.xxx.xxx.xxx/yy
service imap-login {
inet_listener imap {
haproxy = yes
}
inet_listener imaps {
haproxy = yes
}
}
service pop3-login {
inet_listener pop3 {
haproxy = yes
}
inet_listener pop3s {
haproxy = yes
}
}
haproxyじゃなくても設定の意味として想定したものとして設定を用意する。
ポイントは、それぞれのserviceごとに設定が必要。
ssl対応なのかどうか。ssl未対応もサポートするのかで設定値が変わる。
なお、このserviceの値はポート番号の指定や変更などにも用いる箇所。
たまに紹介時にあるように、documentが1.xのほうが詳しい情報が残ったままということもある。
HAProxy - Dovecot Wiki
今回だとこちらの公式ドキュメントのほうが欲しい情報が書いている。
SSL
公式情報はこちら:SSL Configuration — Dovecot documentation
ssl_cert = </etc/dovecot/dovecot.crt
ssl_key = </etc/dovecot/dovecot.key
とあるように、 <xxx
と書くところがポイント。
なお、SSLv3を使わせたくない。ciphersを絞りたいといった場合は以下。
公式情報参考:Dovecot SSL configuration — Dovecot documentation
ssl = yes
ssl_cipher_list=ALL:!kRSA:!SRP:!kDHd:!DSS:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!RC4:!ADH:!LOW@STRENGTH
ssl_prefer_server_ciphers = yes
ssl_min_protocol = !SSLv3 !SSLv2
ssl_chiper_listは要件にあわせて。今時のメーラーを意識して対応するとよさそう。
これらの設定を優先さえるために、 ssl_prefer_server_ciphers = yes
は必須。
ssl_min_protocol
は2.3のアップデート情報を紹介したとおりで、 ssl_protocols
で情報を探すと参考事例はみつかる。
ssl = yes はdefaultの値だが or no
or required
と特殊。
これはメーラーのSSL対応を想定して設定する必要がある。
全体設定
default_client_limit = 1000
default_process_limit = 500
log_path = syslog
mail_location = maildir:~/Maildir
default_process_limit が接続数上限となる。
この値を超える接続がある場合は、以下のログがはかれる。
dovecot: master: Warning: service(imap-login): process_limit (100) reached, client connections are being dropped
なお、デフォルトは100。
また、1024を超える場合は以下のログを気にすること。ulimit周りの設定が必要。
dovecot: Warning: fd limit (ulimit -n) is lower than required under max. load (1024 < 2000), because of default_client_limit
mail_locationの指定はMailbox形式かMaildir形式を洗濯したいときに用いる。
dovecotのデフォルトは、mboxである。これは用途による。
リプレースするといった要件の場合は過去踏襲で気にする箇所。
稼動確認
実設定後に設定確認や接続確認する方法をまとめる。
telnetもよいが便利なコマンドもあるのでご紹介。
設定確認:doveconf
必要な設定はpostfixにおけるpostconf
のように doveconf
を使うこと。
実際に用意した設定が反映されているかはこの結果次第なので比較する。
例えば、先ほどの設定は以下の様に一覧される。
なお、のちに紹介するdoveadmの doveadm config
でも代替え可能。
protocol pop3 {
passdb {
args = /etc/dovecot/conf.d/auth-sql.conf.ext
driver = sql
name =
result_failure = return-fail
result_internalfail = return-fail
result_success = return-ok
}
}
なお、今回はpop3, imap4とpassdbの用意をプロトコルごとに用意したが、
デフォルトで使用するpassdbをグローバルに設定しないと動作しない点が注意。
doveconfより、以下の様にpop, imapを指定しない設定が必要
passdb {
args = /etc/dovecot/conf.d/auth-default.ext
auth_verbose = default
default_fields =
deny = no
driver = sql
master = no
mechanisms =
name =
override_fields =
pass = no
result_failure = return-fail
result_internalfail = return-fail
result_success = return-ok
skip = never
username_filter =
}
### pop, imapのservice指定ではなくpassdbを直接記載すること。
passdb {
args = /etc/dovecot/conf.d/auth-default.ext
driver = sql
result_failure = return-fail
result_internalfail = return-fail
result_success = return-ok
}
configでの定義は何もないpassdbを定義することになるが、その設定が必要となる。
プロトコルごとに定義を分ける場合は注意が必要(はまる)。
このように切り分けは設定したconf+extファイルを見るだけでなく、実反映を見極めるとよいです。
debug
パスワードの中身のレベルで確認したいときや、より詳細に情報を知りたいときは以下の設定をとりあえず書いておけば出したい情報は全て足すことができる。
本番での設定の扱いは注意。あくまでintegration環境を想定。
auth_debug = yes
auth_debug_passwords = yes
auth_verbose = yes
mail_debug = yes
verbose_ssl=yes
設定したものがうまく動かないときはここのエラーを捕まえるとクエリの結果レベルまで見ることができるので切り分けに便利。
動作確認:doveadm
doveadm
が便利。
いろいろな組み合わせがあるので以下紹介する。
doveadm log
Dovecot Logging — Dovecot documentation
doveadm log find
doveadm log errors
このあたりが便利。
doveadm auth login
例えば使用するメールアドレスとパスワードを使って、認証をすることができるのか?といった確認ができる。
# doveadm auth login hogehoge@hogehoge.com
Password:
passdb: hogehoge@hogehoge.com auth succeeded
extra fields:
user=hogehoge@hogehoge.com
userdb extra fields:
hogehoge@hogehoge.com
auth_mech=PLAIN
失敗すると以下。
# doveadm auth login hogehoge@hogehoge.com
Password:
passdb: hogehoge@hogehoge.com auth failed
extra fields:
user=hogehoge@hogehoge.com
これで、存在するメールアドレスがあるのか。パスワードは正しいのか。
また、両方が正しくても疎通ができないのか、アカウントロック処理をアプリケーションで行なっているのかと行った監視対象としても使うことが可能。
doveadm service status
doveadm
コマンドより状態確認が可能。接続数確認が可能。
$ sudo doveadm service status imap-login
name: imap-login
process_count: 244
process_avail: 0
process_limit: 500
client_limit: 1
throttle_secs: 0
exit_failure_last: 0
exit_failures_in_sec: 0
last_drop_warning: 0
listen_pending: n
listening: y
doveadm_stop: n
process_total: 827
$ sudo doveadm service status pop3-login
name: pop3-login
process_count: 44
process_avail: 0
process_limit: 500
client_limit: 1
throttle_secs: 0
exit_failure_last: 0
exit_failures_in_sec: 0
last_drop_warning: 0
listen_pending: n
listening: y
doveadm_stop: n
process_total: 1491
このように接続数を取得することが可能なのと、あらかじめ設定した processs_limit
を確認することができる。
この上限に達するかどうかをスペックとあわせて調整することができる。
また、topコマンドの様な doveadm stats top
というコマンドもある(バージョンによってコマンドも異なるので実施にコマンドを打ち込んで確認するとよい)。
接続数監視(doveadm応用)
Mackerelなどで簡易に上記の値を取得すれば採取可能。
カスタムメトリックをワンライナーで用意できる。
公式マニュアル参考:ホストのカスタムメトリックを投稿する - Mackerel ヘルプ
例えば、以下であればlimit数と接続数をグラフ化することができる。
[plugin.metrics.doveadm_pop3_login_count]
command = "echo -e \"dovecot.doveadm.pop3-login-count\t$(doveadm service status pop3-login | grep process_count | awk '{print $2}')\t$(date +%s)\""
[plugin.metrics.doveadm_pop3_login_limit]
command = "echo -e \"dovecot.doveadm.pop3-login-limit\t$(doveadm service status pop3-login | grep process_limit | awk '{print $2}')\t$(date +%s)\""
[plugin.metrics.doveadm_imap_login_count]
command = "echo -e \"dovecot.doveadm.imap-login-count\t$(doveadm service status imap-login | grep process_count | awk '{print $2}')\t$(date +%s)\""
[plugin.metrics.doveadm_imap_login_limit]
command = "echo -e \"dovecot.doveadm.imap-login-limit\t$(doveadm service status imap-login | grep process_limit | awk '{print $2}')\t$(date +%s)\""
postfixのSASL認証にdovecotを使う方法
公式情報:Postfix SASL How
postfixのsasl認証の定番は昔はCyrus SASLだったが、今時ならdovecot認証を利用する。
これも、postfixの公式情報の通りで設定例は用意されているのでpostfix側は以下の設定。
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_authenticated_header = yes
smtpd_sasl_type = dovecot
### 以下はdovecotをunix socketに持つか別サーバに接続するかでわかれる
smtpd_sasl_path = private/auth
smtpd_sasl_path = inet:xxx.xxx.xxx:12345
smtpd_sasl_auth_enable = yes
が基本。sasl認証を使う。
加えて、smtpd_sasl_type = dovecot
と 指定。なお、cyrus-saslを使う場合はここを特に指定しない。
ここで、dovecotでsaslとして接続するにはpostfixが導入されたホストにdovecotをインストールしてunix socketk経由で使うか、dovecotがすでに入っているimap/popサーバに認証を間借りするかで設定が変わる。
postfix+dovecot(認証専用)を同居させる場合
この場合はpostfixの設定は
smtpd_sasl_path = private/auth
あとはdovecotをインストールしたときの設定として認証情報の用意が必要
service auth {
unix_listener /var/spool/postfix/private/auth {
group = postfix
mode = 0666
user = postfix
}
}
dovecotは起動しつつunix socketを使う設定を用意。
注意点は、デフォルトだとpop/imapサーバを使わないのに起動してしまう点。
デメリットとしてdovecotを管理する必要が出てきます。ただ、障害時は単一の範囲に収まります。
そこで、無理やりlmtp(ポート番号起動がない)を立てるだけ立てる方法もあります。
protocols = lmtp
あらかじめ用意したdovecotサーバにsasl認証として接続する
この場合はpostfixの設定は接続先のIPアドレスを指定する必要があります。
smtpd_sasl_path = inet:xxx.xxx.xxx:12345
このときポート番号はdovecot側で用意する必要があります(例の12345は適当なポートを指定しています)。
この場合は、dovecot側は
service auth {
inet_listener {
port = 12345
}
unix_listener /var/spool/postfix/private/auth {
group = postfix
mode = 0666
user = postfix
}
}
これで、指定したポート(12345)に対してアクセスするポートの待ち受けサービスが起動する。
話を省略したが、このsmtpのauth認証の場合、
imap/popサーバ構築で用意した様なユーザ・パスワード認証が同様に必要になる。
その際はextファイルを指定すればよい。
passdb {
args = /etc/dovecot/conf.d/smtp-auth.conf.ext
driver = sql
result_failure = return-fail
result_internalfail = return-fail
result_success = return-ok
}
バージョンは2.2系だがpostfixのdovecotを意識したSASL認証はこちらの情報が参考になる。
postfixadmin/Postfix-Dovecot-Postgresql-Example.md at master · postfixadmin/postfixadmin
こういう情報が欲しかった!!!
という感想になるといいなの思いです。