LoginSignup
183

More than 5 years have passed since last update.

EC2にメールサーバを構築(複数ドメイン)

Last updated at Posted at 2015-03-10

要件

  • 複数ドメインのメールが受信できる。
  • メールアドレス毎に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の読み込み部分を消さないと無限ループする。

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に以下の行を追加する。

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形式への変更

/etc/postfix/main.cf
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 ディレクトリを作成し、以下のファイルを新規作成

/etc/postfix/sql/mysql_virtual_domains_maps.cf
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
/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf
# 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'
/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
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'
/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf
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'
/etc/postfix/sql/mysql_virtual_alias_maps.cf
user = postfix
password = hogehoge
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
#expansion_limit = 100
/etc/postfix/sql/mysql_virtual_mailbox_maps.cf
user = postfix
password = hogehoge
hosts = localhost
dbname = postfix
query           = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
#expansion_limit = 100

メール容量制限取得。容量制限を行わないなら不要

/etc/postfix/sql/mysql_virtual_mailbox_limit_maps.cf
user = postfix
password = hogehoge
hosts = localhost
dbname = postfix
query = SELECT quota FROM mailbox WHERE username='%s' AND active = '1'

バーチャルドメイン用メールボックスの設定

以下の設定を追記し、バーチャルドメインのメールを配送できるようにする

/etc/postfix/main.cf
# 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 = の部分は改行するとダメ。

/etc/dovecot/dovecot-sql.conf.ext
#
# 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を変更する。

/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を変更する

/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を使用可能にする

/etc/dovecot/conf.d/10-ssl.conf
 # SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
 ssl = yes

ローカルメールの設定

postfixでのメール配送をMaidir形式にしたので、dovecotのデフォルトもMaidir形式にする。
mail_locationはローカルユーザ向けの設定なので、各ユーザのホームディレクトリを指定。

/etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:~/Maildir

ここまで設定すれば、pop3,imapは使用できるようになるが、
MUAがThunderBirdの場合、送信サーバの認証ができないとメールアカウント登録でエラーとなる。

Postfix用のSMTP認証用設定

PostfixでDovecotの認証を使用するための設定を記載。
設定後、dovecotを再起動し /var/spool/postfix/private/auth が作成されている事を確認する。

dovecot側の設定

/etc/dovecot/conf.d/10-master.conf
   # Postfix smtp-auth
   unix_listener /var/spool/postfix/private/auth {
      mode = 0666
      user = postfix
      group = postfix
   }

postfix側の設定

/etc/postfix/main.cf

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番ポートでのメール送信ができないのでサブミッションポートを使用可能にする。

/etc/postfix/master.cf
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認証を有効にし、サブミッションポートを利用しての送信は認証成功以外は送信拒否とする。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
183