複数ドメイン対応のdovecotを構成する
MySQL
DBを作成する
DB名はmailserverとする。
ユーザー名はpostfixで、パスワードはpasswordとしておく。(本番環境では必ず違うやつにしてください)
CREATE DATABASE mailserver; CREATE USER 'postfix'@'%' IDENTIFIED BY 'password'; GRANT USAGE ON * . * TO 'postfix'@'%' IDENTIFIED BY 'password' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ; GRANT ALL PRIVILEGES ON `mailserver` . * TO 'postfix'@'%';
テーブル等を作成
必要に応じて項目を増減させてください。
ER図とか外部キーやINDEXは今回、割愛させていただきたく。
--DROP TABLE domain; --DROP TABLE email; create table domain ( id INTEGER AUTO_INCREMENT PRIMARY KEY ,server_id INTEGER ,domain VARCHAR(128) ,dir VARCHAR(128) ,uid INTEGER ,uid_name VARCHAR(64) ,gid INTEGER ); create table email ( id BIGINT AUTO_INCREMENT PRIMARY KEY ,server_id INTEGER ,domain_id INTEGER ,name VARCHAR(128) ,dir VARCHAR(128) ,password VARCHAR(256) );
テストデータの挿入
メールサーバーにユーザーとグループを作成する。
sudo groupadd vmail -g 5000 sudo adduser vuser1 -u 5001 -g 5000 -m -s /sbin/nologin
作成するSQLに必ずuid,gidが一致するように作成してください。
INSERT INTO `mailserver`.`domain` (`id`, `server_id`, `domain`, `dir`, `uid`, `uid_name`, `gid`) VALUES (NULL, '1', 'mailtest.home.lan', 'mailtest.home.lan', '5001', 'vuser1', '5000'); INSERT INTO `mailserver`.`email` (`id`, `server_id`, `domain_id`, `name`, `dir`) VALUES (NULL, '1', '1', 'root', 'root');
ビューの作成
ここをpostfixが見に行く
CREATE OR REPLACE VIEW mailbox AS SELECT e.id , e.server_id , e.domain_id , e.name , d.domain , concat(e.name,'@',d.domain) AS email FROM email AS e INNER JOIN domain AS d ON e.domain_id = d.id AND e.server_id = d.server_id ;
ここをdovecotが見に行く
CREATE OR REPLACE VIEW mailusers AS SELECT e.id , e.server_id , e.domain_id , e.name , d.domain , d.uid , d.uid_name , d.gid , concat('{PLAIN-MD5}',MD5(e.password)) AS password , concat(d.dir,'/',e.dir) AS home , concat(e.name,'@',d.domain) AS email FROM email AS e INNER JOIN domain AS d ON e.domain_id = d.id AND e.server_id = d.server_id ;
注意点
password列については、本来MD5でハッシュ化されたデータを格納すべきです。
パスワードスキーマ を参照して「{スキーマ名}ハッシュ化されたパスワード文字列」とすることで、dovecotがどの処理を使ってパスワードの一致確認を行えばいいのか判断してくれます。上記例では、「{PLAIN-MD5}1a1dc91c907325c69271ddf0c944bc72」のようなデータになります。
[id:indication:20100211:1265892873]にもあるように他バックエンドの対応スキーマ等を配慮した上でスキーマを決定することを推奨します。
なお、平文(PLAIN)でパスワードをDBへ保存する愚かな行為は、来世に渡って負債を残すので、強く拒否いたします。
dovecot
CentOS5基準で設定します。
メインの設定
基本的な設定を行います。対応するプロトコル、待ち受けるIPアドレス等を設定します。
diff /etc/dovecot/dovecot.conf.org /etc/dovecot/dovecot.conf 20c20 < #protocols = imap pop3 lmtp --- > protocols = imap pop3 lmtp 26c26 < #listen = *, :: --- > listen = *, ::
認証設定
認証キャッシュ(auth_cache_size)をとりあえず、10M程度確保し、
デフォルト設定のシステムでの認証ではなく、sqlへの認証へ変更します。
diff /etc/dovecot/conf.d/10-auth.conf.org /etc/dovecot/conf.d/10-auth.conf 13c13 < #auth_cache_size = 0 --- > auth_cache_size = 10M 19c19 < #auth_cache_ttl = 1 hour --- > auth_cache_ttl = 1 hour 97c97 < auth_mechanisms = plain --- > auth_mechanisms = plain cram-md5 119,120c119,120 < !include auth-system.conf.ext < #!include auth-sql.conf.ext --- > #!include auth-system.conf.ext > !include auth-sql.conf.ext
認証結果のキャッシュ (ただしv1.x系)より引用
認証キャッシュに関する設定は、以下のようになります: * 'auth_cache_size': 認証キャッシュサイズをキロバイトで指定し、0 は無効と なります(デフォルト)。通常、passdb のキャッシュ情報は 50 バイトほどで、 userdb キャッシュ情報は、ユーザやパスワード検索の応答からの情報量に応じ て、100〜200 バイトほどになります。 * 'auth_cache_ttl': キャッシュ情報の保存時間を秒で指定します。ここで指定 した秒より前に作られた場合、(内部での失敗の場合以外では)、キャッシュ情 報は使われなくなります。情報はキャッシュがいっぱいになったか、新しい情 報が追加されたときのみ、削除されます。 * 'auth_cache_negative_ttl': (v1.1 以上のみ) もし passdb もしくは userdb 検索が何も返さなかった場合(例えば、ユーザが存在しないなどで)、それを同 様に否定的情報としてキャッシュに保存します。この設定は、否定的情報用の 別の TTL を与えることを可能にします。0 は完全に否定的キャッシュを無効に します。
メールの取り扱いについて設定
Maildir形式にする設定、および、ユーザーIDの下限値を設定しておく。
diff /etc/dovecot/conf.d/10-mail.conf.org /etc/dovecot/conf.d/10-mail.conf 24c24 < # mail_location = maildir:~/Maildir --- > mail_location = maildir:~/Maildir 167c167 < #first_valid_uid = 500 --- > first_valid_uid = 500
SQLの設定
/etc/dovecot/dovecot-sql.conf.ext
※設定の場所に注意(新規作成)
# NOTE: '\' line splitting works only with v1.1+# The mysqld.sock socket may be in different locations in different systems driver = mysql # Use "host= ... pass=foo#bar" if your password has '#' character #connect = host=/var/run/mysqld/mysqld.sock dbname=mails user=admin password=pass connect = host=192.168.1.1 dbname=mailserver user=postfix password=password password_query = SELECT email AS user, password FROM mailusers WHERE name = '%n' AND domain = '%d' # returning mail overrides mail_location setting for SQL users. user_query = SELECT concat('maildir:/home/',uid_name,'/Maildir/',home) AS mail, uid, gid FROM mailusers WHERE name = '%n' AND domain = '%d'
user_queryのmail列についてはファイル等を作成する場所を指定する。
基本的にビューを参照させて、メインテーブルの構成変更を吸収できるようにしておくのがポイント。
サーバーの構成に関わるところについては、上記設定で吸収できるようにしておく。
テスト
準備完了
サービスを再起動する
sudo service dovecot restart
動作確認
telnetで接続して、動作を確認する
telnet localhost 110 USER root@mailtest.home.lan PASS password STAT LIST QUIT
参考:実行結果
Trying ::1... Connected to localhost. Escape character is '^]'. +OK Dovecot ready. USER root@mailtest.home.lan +OK PASS password +OK Logged in. STAT +OK 0 0 QUIT +OK Logging out. Connection closed by foreign host.
参考文献
- dovecot本家
- Authentication/MultipleDatabases - Dovecot Wiki バックエンドにDBを使用する方法について記載あり
- AuthDatabase/SQL - Dovecot Wiki 1.x系だが、SQLのサンプル等があり、2系には乗っていない構成情報が記載あり
- Authentication/MasterUsers - Dovecot Wiki 2.x系のSQLのサンプル等があり。この記事を書いてから発見した oh...
- Authentication/PasswordSchemes - Dovecot Wiki パスワードスキーマの一覧
- UserDatabase - Dovecot Wiki 各列についての対応する内容についての説明
- UserDatabase/ExtraFields - Dovecot Wiki その他拡張項目。DB設定でQuota等設定できる
- dovecot日本
- 認証結果のキャッシュ 1.x系
- その他
- TCP/IP - SMTP/POPとは テストする際に参考にしたサイト