要件
- 複数ドメインのメールが受信できる。
- メールアドレス毎にUNIX Userは作成しない。
- SMTP,POP3,IMAPで外部ネットワークのMUAから送受信可能。
- メールの容量制限をユーザ毎に設定可能にする。
- MUAでの送信、受信は認証必須。認証はメールアドレス+パスワード
- STARTTLSで送受信は暗号化する
- MUAでの送信と受信のパスワードは同じパスワードを使用できる。
概要
- MTAはsendmailからpostfixに変更
- メール配送はMaildir方式にする。
- postfixにバーチャルドメインを設定して、各ドメインからの受信を可能にする。
- ドメインとメールアドレスの管理用UIにpostfix Adminを採用
- メールアドレス、パスワードの管理はMySQL
- POP3,IMAPでの受信はdovecotを使用する。
- OB25対策をして、通常のプロバイダ接続でも送信可能にする。
構築準備
環境
- メールサーバにする予定のインスタンスにElastic IPを割り当てておく。
- メールサーバのドメインを決めておく。
- メールサーバ上で、webサーバとphp5以上が動くようにしておく
- メールサーバからMySQLサーバにアクセス可能にする
メールサーバのドメイン:mail.example.jp
PostfixAdminのURL: http://mail.example.jp
データベースサーバ: localhost
として作成したとする。構築に使用したバージョンは、
- postfix 2.6.6
- dovecot 2.0.9
- postfixAdmin 2.3.7
- MySQL 5.6
- Apache 2.4
- PHP 5.5
メール送信制限の解除とDNS逆引き申請
標準ではEC2インスタンスからの1日あたりのメール送信数は制限されているのと、
Elastic IPで割り当てたIPアドレスを逆引きした場合、アマゾンのドメインとなるためスパム判定される事がある。
制限解除兼、逆引き設定の依頼を行うフォームがあるのでそこから申請する。
Request to Remove Email Sending Limitations
https://portal.aws.amazon.com/gp/aws/html-forms-controller/contactus/ec2-email-limit-rdns-request
申請手順については、Amazon日本公式のドキュメント
http://www.slideshare.net/AmazonWebServicesJapan/aws-42885668
で確認できる
サーバの使用用途は、自社用メールサーバ等、素直に書けばOK。ただし英語で記載しないと無視される。
Elastic IP Address : 123.123.123.123 (使用する Elastic IP)
Reverse DNS Record for EIP 1 : mail.example.jp (メールサーバのドメイン)
を送信。数営業後に返答が決ます。
sendmailからpostfixへの差し変え
postifxインストール
# yum install postfix
MTAの切り変え
# alternatives --config mta
現在インストールされているMTA一覧が出るので、postfixを選択
sendmailの停止と、postfixの起動
# service sendmail stop
# chkconfig sendmail off
# service postfix start
# chkconfig postfix on
この時点では、外部からのメールはすべて拒否される状態。
動作が確認できるまで拒否設定のままにしておく。
sendmailは削除してもOK
dovecotのインストール
postfixAdminをインストール前に必要。pop3,imapのポートは閉じたままにしておく。
メールアドレス、パスワード管理にMySQLを使用するので、mysql backendも導入。
# yum install dovecot dovecot-mysql
postfix Admin のインストールと設定
postfixAdminは、ドメイン、メールアドレス、パスワード、メールボックス名をDBで管理するためのWebアプリ。
MTAにはpostfix、pop3,imapサーバはdovecotの利用が想定されている。postfixAdmin自体は、postfixとdovecotの設定は行わないので、自分で設定する。
まず、postfixAdminを使えるようにして、ドメインとメールアドレスをデータベースに登録できる状態にする。
postfix Adminのダウンロード
パッケージはないので公式よりダウンロード。
postfixadmin-2.3.7を使用した。
ダウンロードしたpostfixadminをwebサーバから見える所に展開する。設定が完了するまでWeb側にアクセス制限をつけておく。展開したファイルにあるINSTALL.txtを参照して設定
データベースの作成
mysqlに接続し、postfixのデータベースとユーザを作成。パスワードはhogehoge
CREATE DATABASE postfix CHARSET utf8
CREATE USER 'postfix'@'%' IDENTIFIED BY 'hogehoge'
GRANT ALL PRIVILEGES ON postfix.* TO postfix@%
FLUSH PRIVILEGES
postfixadminの設定ファイル変更
config.local.phpを新規作成する。
config.local.phpは、config.inc.phpの設定内容を上書きする仕組みになっているので、
デフォルトから変更する値のみをconfic.local.phpへ記載する。
config.inc.phpをコピーして使用する場合、下部にあるconfig.local.phpの読み込み部分を消さないと無限ループする。
// 設定完了フラグ
$CONF['configured'] = true;
// postfixAdminのURL
$CONF['postfix_admin_url'] = 'http://mail.example.jp';
//日本語表示にする
$CONF['default_language'] = 'ja';
// データベース接続情報
$CONF['database_type'] = 'mysqli'; // mysqlからmysqliに変更
$CONF['database_host'] = 'localhost'; // mysqlのホスト名
$CONF['database_user'] = 'postfix'; // postfixAdminで使用するデータベースのユーザ
$CONF['database_password'] = 'hogehoge'; // パスワード
$CONF['database_name'] = 'postfix'; // データベース名
// 管理者メールアドレス
$CONF['admin_email'] = 'postmaster@example.jp';
// postfixが稼動しているホストとポート
// メールアドレス作成時にwelcomeメールを送信するのに使う。
// welcomeメールを送っておかないとmailboxが作成されないため、pop3でエラーになる。
$CONF['smtp_server'] = 'localhost';
$CONF['smtp_port'] = '25';
//標準の管理者メールアドレス
$CONF['default_aliases'] = array (
'abuse' => 'abuse@example.jp',
'hostmaster' => 'hostmaster@example.jp',
'postmaster' => 'postmaster@example.jp',
'webmaster' => 'webmaster@example.jp'
);
// username@domain.tldのメールの配送を、domain.tld/username にする。
$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'NO';
// 自動応答ドメイン。DNSに設定しなくてもよい
$CONF['vacation_domain'] = 'autoreply.example.jp';
//mainメニューへのリンク
$CONF['user_footer_link'] = "http://mail.example.jp/main.php";
// ページ下部にトップへ戻るリンク設定
$CONF['footer_text'] = 'Return to mail.example.jp';
$CONF['footer_link'] = 'http://mail.example.jp';
システム管理者の登録
http://mail.example.jp/setup.php にブラウザでアクセスする。初回アクセス時に管理用テーブルが作成される。
動作に必要なモジュールが足りない場合画面に表示されるので、インストール後リロードしてチェック。
エラーが表示されなくなったら、画面に従い管理者を登録。セットアップパスワードが表示されるので、
config.local.phpに以下の行を追加する。
$CONF['setup_password'] = '画面に表示されたセットアップパスワード'
http://mail.example.jp にアクセスし、ログインできる事を確認したらsetup.phpは削除するかパーミッションを落としてアクセス不可にしておく。
ドメインとメールアドレスの登録
http://mail.example.jp に管理者でログインし、画面に従ってテスト用のドメインとメールアドレスを作成する。作成したドメインのMXレコードを設定し、メールサーバへメールが送信されるようにしておく。
postfixの設定
postfixAdminの設定に合わせる。
バーチャルホスト宛のメールは /var/spool/virtual/ 以下に配送し、user@domain.ltdのメール配送のディレクトリは、/var/spool/virtual/domain.ltd/user/ にする
MailDir形式への変更
home_mailbox = Maildir/
メールの配送方法をmbox形式からMailDir形式に変更する。
ついでに、/etc/skel へMaildirを作成し、新規ユーザでも自動作成されるようにする。
バーチャルドメインの設定
Postfix バーチャルドメインホスティング Howtoを参考に作成。
バーチャルドメイン用のユーザとメール用ディレクトリの作成
バーチャルドメインで受信したメールの所有者と保存先のディレクトリを作成。
ユーザはuid:10000で作成しておく。
# adduser -u 10000 vmailuser
# mkdir /var/spool/virtual
# chmown 10000.10000 /var/spool/virtual
DBへのアクセス用クエリ設定
postfixadminのDOCUMENTS/POSTFIX_CONF.txtを参考に、postfixAdminで登録したメールアドレス関連の情報を、postfixからMySQLに接続して取得するクエリを作成する。 /etc/postfix/sql ディレクトリを作成し、以下のファイルを新規作成
user = postfix
password = hogehoge
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'
#query = SELECT domain FROM domain WHERE domain='%s'
#optional query to use when relaying for backup MX
#query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'
#expansion_limit = 100
# handles catch-all settings of target-domain
user = postfix
password = hogehoge
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'
user = postfix
password = hogehoge
hosts = localhost
dbname = postfix
query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1'
user = postfix
password = hogehoge
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'
user = postfix
password = hogehoge
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
#expansion_limit = 100
user = postfix
password = hogehoge
hosts = localhost
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
#expansion_limit = 100
メール容量制限取得。容量制限を行わないなら不要
user = postfix
password = hogehoge
hosts = localhost
dbname = postfix
query = SELECT quota FROM mailbox WHERE username='%s' AND active = '1'
バーチャルドメイン用メールボックスの設定
以下の設定を追記し、バーチャルドメインのメールを配送できるようにする
# Virtual mailbox 基本設定
virtual_mailbox_base = /var/spool/virtual
virtual_minimum_uid = 100
virtual_uid_maps = static:10000
virtual_gid_maps = static:10000
# メールアドレス関連情報の取得
virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
virtual_alias_maps =
proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf,
proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf,
proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf
virtual_mailbox_maps =
proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf,
proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
# quota(容量制限)サポート設定。容量制限をしないなら不要
# 容量制限を越えた場合、送信元にエラーメールを返信する。
virtual_create_maildirsize = yes
virtual_mailbox_extended = yes
virtual_mailbox_limit_maps = mysql:/etc/postfix/sql/mysql_virtual_mailbox_limit_maps.cf
virtual_mailbox_limit_override = yes
virtual_maildir_limit_message = Sorry, the user's maildir has overdrawn his diskspace quota, please try again later.
virtual_overquota_bounce = yes
この時点でpostfixを再起動し、mailコマンドでテスト用に作成したドメイン宛てにメールを送信してチェック。user@domain.ltdに送信したメールが、/var/spool/virtual/domain.ltd/user/new 以下に配信されていればOK
dovecotの設定
postfixAdminで登録した情報を取得するためのクエリを作成。以下の名前で新規作成する。
connect = の部分は改行するとダメ。
#
# for postfixadmin
#
connect = host=localhost dbname=postfix user=postfix password=hogehoge
driver = mysql
# Default password scheme.
# depends on your $CONF['encrypt'] setting:
# md5crypt -> MD5-CRYPT
# md5 -> PLAIN-MD5
# cleartext -> PLAIN
default_pass_scheme = MD5-CRYPT
password_query = SELECT username AS user,password FROM mailbox WHERE username = '%u' AND active='1'
user_query = SELECT CONCAT('/var/spool/virtual/', maildir) AS mail, 10000 AS uid, 10000 AS gid, CONCAT('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active='1'
認証
メールアドレス+パスワードでPOP3,IMAP認証可能にし、PAMでのユーザ認証は無効にする。
/etc/dovecot/conf.d/10-auth.confを変更する。
...
# STARTTLSで暗号化するので、plaintext認証を有効にする
disable_plaintext_auth = no
...
#コメントアウト
#!include auth-system.conf.ext
#コメントアウトを外す
!include auth-sql.conf.ext
...
/etc/dovecot/conf.d/auth-sql.conf.extを変更する
# Authentication for SQL users. Included from auth.conf.
#
# <doc/wiki/AuthDatabase.SQL.txt>
passdb {
driver = sql
# Path for SQL configuration file, see example-config/dovecot-sql.conf.ext
# 先程作成したファイルを指定
args = /etc/dovecot/dovecot-sql.conf.ext
}
# "prefetch" user database means that the passdb already provided the
# needed information and there's no need to do a separate userdb lookup.
# <doc/wiki/UserDatabase.Prefetch.txt>
#userdb {
# driver = prefetch
#}
userdb {
driver = sql
# 先程作成したファイルを指定
args = /etc/dovecot/dovecot-sql.conf.ext
}
# If you don't have any user-specific settings, you can avoid the user_query
# by using userdb static instead of userdb sql, for example:
# <doc/wiki/UserDatabase.Static.txt>
#userdb {
#driver = static
#args = uid=vmail gid=vmail home=/var/vmail/%u
#}
SSL/TLSを使用可能にする
# SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
ssl = yes
ローカルメールの設定
postfixでのメール配送をMaidir形式にしたので、dovecotのデフォルトもMaidir形式にする。
mail_locationはローカルユーザ向けの設定なので、各ユーザのホームディレクトリを指定。
mail_location = maildir:~/Maildir
ここまで設定すれば、pop3,imapは使用できるようになるが、
MUAがThunderBirdの場合、送信サーバの認証ができないとメールアカウント登録でエラーとなる。
Postfix用のSMTP認証用設定
PostfixでDovecotの認証を使用するための設定を記載。
設定後、dovecotを再起動し /var/spool/postfix/private/auth が作成されている事を確認する。
dovecot側の設定
# Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
postfix側の設定
myhostname = mail.example.jp
myorigin = $myhostname
// 外部からのメールを受信可能にする
inet_interfaces = all
#
# SASL(SMTP認証) 有効化
#
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination
# 認証にdovecotを使用
smtpd_sasl_type = dovecot
# 認証用ソケット。/var/spool/postfix からの相対パス
smtpd_sasl_path = private/auth
# 一部MUAもサポート
broken_sasl_auth_clients = yes
#
# TLS(STARTTLS) 有効化
#
smtpd_use_tls = yes
smtld_tls_loglevel = 1
# dovecotの証明書を流用.正式な証明書があるならそちらを指定する。
smtpd_tls_cert_file = /etc/pki/dovecot/certs/dovecot.pem
smtpd_tls_key_file = /etc/pki/dovecot/private/dovecot.pem
smtpd_tls_session_cache_database = btree:/etc/postfix/smtpd_scache
smtpd_tls_session_cache_timeout = 3600s
通常、メールを受信するドメインは、$mydestinationに指定するが、
バーチャルドメインで使用するドメインは、$mydestination に追加してはいけない。
OB25対策
プロバイダによってはOB25により、25番ポートでのメール送信ができないのでサブミッションポートを使用可能にする。
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
SASL認証を有効にし、サブミッションポートを利用しての送信は認証成功以外は送信拒否とする。