SSL/TLS暗号化を利用した、メールサーバを構築した時のメモです。今回は、正規のSSL/TLS証明書を無料で発行してくれる認証局 Let's Encrypt の証明書を使って設定してみました。証明書が無料なので、お財布にやさしいのはもちろん、Let's Encrypt には証明書を自動更新してくれる仕組みがあるので、一度設定してしまえば、証明書更新にかかる手間が無くなるのも大きな魅力です。
メールサーバの設定概要
ドメイン名やIPアドレスは、ご自分の環境に読替えてください。
送信サーバ:Postfix(SMTP-Auth over SSL)
受信サーバ:Dovecot(IMAPS,POP3S)
サーバOS:CentOS7.2 (1511)
ドメイン名:example.com
サーバIPアドレス:192.0.2.1
MXレコードをDNSサーバに登録
メールサーバを設定する前に、メールアドレスに使用するドメイン名のMXレコードと、メールサーバのAレコードを、DNSサーバに登録しておきます。メールサーバのサブドメインを、今回は「mail」としていますが、こちらはなんでも構いません。
mail.example.com. IN A 192.0.2.1
メールサーバが使用するポートのオープン
メールの送受信に使う以下のポートを開けておきます。
・SMPT(25)
・SMTPS(465)
・IMAPS(993)
・POP3S(995)
firewall-cmd --add-port=465/tcp --permanent
firewall-cmd --add-port=993/tcp --permanent
firewall-cmd --add-port=995/tcp --permanent
firewall-cmd --reload
ポートオープンの確認
22/tcp 25/tcp 465/tcp 995/tcp 993/tcp
基本パッケージのインストール
CentOS7.2を「最小限のインストール」でインストールしている場合は、基本パッケージと開発ツールなどをインストールしておきましょう。
yum -y groupinstall development
yum -y groupinstall network-tools
Postfix と Dovecot のインストール
※バージョンは 2016年1月31日時点のものです。
Postfix(2.10.1-6)※CentOSの場合は既にインストールされていると思います。
Dovecot(2.2.10-5)
Let's Encrypt のSSL/TLS証明書の取得
Let's Encrypt の詳細については、こちらの記事をご参照ください。
クライアントのインストール
Let's Encrypt のクライアントソフトをインストールします。
git clone https://github.com/certbot/certbot
Let's Encrypt クライアントが依存するパッケージをインストールします。
./certbot-auto -n
証明書の取得
Let's Encrypt クライアントの待ち受けポートを開けておきます。
firewall-cmd --add-port=443/tcp --permanent
firewall-cmd --reload
Let's Encrypt のSSL/TLS証明書を取得します。
取得した証明書や秘密鍵は「/etc/letsencrypt/live/mail.example.com/」以下に保存されます。
-d mail.example.com \
-m sample@example.com \
--agree-tos -n
・オプションについて
certonly
証明書の取得のみを行います。デフォルト値は「run」で、WEBサーバの設定なども行ってくれるそうです。
--standalone
プラグインの指定です。standalone プラグインは Let's Encrypt クライアントに内蔵されているWEBサーバを使って、証明書の取得を行います。
-d
証明書を取得するドメイン名を指定します。
-m
ご自分のメールアドレスを指定します。なにかトラブルがあった場合などに Let's Encrypt との連絡用に使用されます。
--agree-tos
Let's Encrypt の利用規約に同意します。事前に利用規約「https://letsencrypt.org/repository/」を確認しておきましょう。
-n
--non-interactive の省略オプションです。対話メッセージの表示や入力を求められないようにできます。
証明書の自動更新設定
cronにて、毎月1日の朝5時に証明書を自動更新し Postfix と Dovecot をリロードします。更新日時はお好みで設定してください。更新時は「renew --force-renewal」オプションを付けて実行します。
crontab -u root -e
証明書の有効期限確認
notBefore=Jan 30 16:01:00 2016 GMT
notAfter=Apr 29 16:01:00 2016 GMT
WEBサーバが同居している場合
standaloneプラグインで起動するWEBサーバの待ち受けポートを変更できればいいのですが、現在のところ出来ないようなので、メールサーバに Apache などのWEBサーバが同居している場合は、mail.example.com のバーチャルホストを設定して「webroot」プラグインで証明書を取得します。
-w /var/www/example -d mail.example.com \
-m sample@example.com \
--agree-tos -n
オプションの指定は「-w /var/www/example」で、ドキュメントルートを指定する以外は、standaloneプラグインと同じです。
証明書の自動更新設定
crontab -u root -e
Postfix の設定
元の設定ファイルをキープしておきます。
Postfixの設定ファイルを編集(なかなか沢山あります)
vim /etc/postfix/main.cf
# このメールサーバのホスト名(FQDN)を指定 #myhostname = host.domain.tld ↓ myhostname = mail.example.com # このメールサーバのドメイン名を指定 #mydomain = domain.tld ↓ mydomain = example.com # メールアドレスを「ユーザ名@ドメイン名」の形式にする #myorigin = $mydomain ↓ myorigin = $mydomain # 全てのホストからメールを受信する inet_interfaces = localhost ↓ inet_interfaces = all # mydomain = で指定したドメイン宛のメールを受信する mydestination = $myhostname, localhost.$mydomain, localhost ↓ mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain # 存在しないメールアドレス(ユーザ)宛のメールの受信を拒否する #local_recipient_maps = proxy:unix:passwd.byname $alias_maps ↓ local_recipient_maps = proxy:unix:passwd.byname $alias_maps # 中継を許可する宛先ドメインを指定 #relay_domains = $mydestination ↓ relay_domains = $mydestination # 転送サーバを使わない #relayhost = [an.ip.add.ress] ↓ relayhost = # メールの格納フォーマットの指定 #home_mailbox = Maildir/ ↓ home_mailbox = Maildir/ # 不要な情報を公開しない #smtpd_banner = $myhostname ESMTP $mail_name ↓ smtpd_banner = $myhostname ESMTP ---(下記を最終行に追加)--------------------------- # VRFYコマンドの使用を禁止する disable_vrfy_command = yes # MailBoxの最大サイズの指定 # メールボックスがMaildir形式のためこの設定は無視されますが「message_size_limit」との兼ね合いのため設定しておきます mailbox_size_limit = 204800000 # 受信メールサイズの制限「mailbox_size_limit」より少ない値を設定してください message_size_limit = 5120000 # 接続元の制限(スパムメール対策) smtpd_client_restrictions = check_client_access hash:/etc/postfix/access reject_rbl_client zen.spamhaus.org reject_non_fqdn_sender reject_unknown_sender_domain # エンベロープアドレス(MAIL FROM)による制限(スパムメール対策) smtpd_sender_restrictions = reject_rhsbl_sender zen.spamhaus.org reject_unknown_sender_domain ########## SMTP-Auth関連 ########## # SASL認証を有効化 smtpd_sasl_auth_enable = yes # Dovecot SASL ライブラリを指定 smtpd_sasl_type = dovecot # Dovecot SASL ライブラリの認証ソケットファイル /var/spool/postfix/ からの相対パスで記述 smtpd_sasl_path = private/auth # 古いバージョンの AUTH コマンド (RFC 2554) を実装した SMTP クライアントとの相互運用性を有効にする broken_sasl_auth_clients = yes ########## TLS/SSL関連 ########## # TLSを有効化 smtpd_use_tls = yes # 宛先のメールサーバがTLSに対応していれば、通信を暗号化する smtp_tls_security_level = may # サーバ証明書と秘密鍵を指定 smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem # TLSログレベルの設定 # 0:出力しない 1:TLSハンドシェイクと証明書情報 2:TLSネゴシエーションの全て smtpd_tls_loglevel = 1 # 暗号に関する情報を "Received:" メッセージヘッダに含める smtpd_tls_received_header = yes # 接続キャッシュファイルの指定 smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache # キャッシュの保持時間の指定 smtpd_tls_session_cache_timeout = 3600s # 認証を通過したものはリレーを許可する(permit_sasl_authenticated) smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated reject_unauth_destination
(2016年6月24日追記)接続元の制限(smtpd_client_restrictions)の所で、「zen.spamhaus.org」を指定していますが、ドコモのドメインやIPアドレスを、SPAMリストに入れることがあるようです。(匿名さんより)
(2017年9月17日追記)RBL.JP が 2017年9月末日を持って終了されるため(これまで本当にありがとうございました!)、接続元の制限(smtpd_client_restrictions)から「reject_rbl_client all.rbl.jp」を削除いたしました。
smtps(SMTP-Auth over SSL)を有効化
vim /etc/postfix/master.cf
#smtps inet n - n - - smtpd # -o syslog_name=postfix/smtps # -o smtpd_tls_wrappermode=yes # -o smtpd_sasl_auth_enable=yes # -o smtpd_reject_unlisted_recipient=no # -o smtpd_client_restrictions=$mua_client_restrictions # -o smtpd_helo_restrictions=$mua_helo_restrictions # -o smtpd_sender_restrictions=$mua_sender_restrictions # -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject # -o milter_macro_daemon_name=ORIGINATING ↓ smtps inet n - n - - smtpd # -o syslog_name=postfix/smtps -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes # -o smtpd_reject_unlisted_recipient=no # -o smtpd_client_restrictions=$mua_client_restrictions # -o smtpd_helo_restrictions=$mua_helo_restrictions # -o smtpd_sender_restrictions=$mua_sender_restrictions -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject # -o milter_macro_daemon_name=ORIGINATING
ルックアップテーブルの作成
設定に誤りがないかチェック(なにも表示されなければOKです)
Postfixの起動
自動起動の設定
Dovecot の設定
・受信プロトコルの設定
vim /etc/dovecot/dovecot.conf
#protocols = imap pop3 lmtp ↓ protocols = imap pop3
・暗号化を使う imaps と pop3s を有効にして、平文で通信する imap と pop3 は「port = 0」を設定し無効にします。
vim /etc/dovecot/conf.d/10-master.conf
service imap-login { inet_listener imap { #port = 143 ↓ port = 0 } inet_listener imaps { #port = 993 #ssl = yes ↓ port = 993 ssl = yes } } service pop3-login { inet_listener pop3 { #port = 110 ↓ port = 0 } inet_listener pop3s { #port = 995 #ssl = yes ↓ port = 995 ssl = yes } }
・Dovecot SASL ライブラリの認証ソケットファイルを指定(97行目あたりです)
vim /etc/dovecot/conf.d/10-master.conf
service auth { (略) # Postfix smtp-auth #unix_listener /var/spool/postfix/private/auth { # mode = 0666 #} ↓ unix_listener /var/spool/postfix/private/auth { mode = 0660 user = postfix group = postfix } }
・認証方式の設定 ※平文パスワードを許可していますが、SSL/TLSで暗号化されますので問題ありません。
vim /etc/dovecot/conf.d/10-auth.conf
#disable_plaintext_auth = yes ↓ disable_plaintext_auth = no auth_mechanisms = plain ↓ auth_mechanisms = plain login
・SSL/TLSの有効化とサーバ証明書と秘密鍵を指定
vim /etc/dovecot/conf.d/10-ssl.conf
ssl = required ↓ ssl = yes #ssl_cert = </etc/pki/dovecot/certs/dovecot.pem #ssl_key = </etc/pki/dovecot/private/dovecot.pem ↓ ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem
・メールボックスの場所を指定
vim /etc/dovecot/conf.d/10-mail.conf
#mail_location = ↓ mail_location = maildir:~/Maildir
・ログの出力先を変更
vim /etc/dovecot/conf.d/10-logging.conf
#log_path = syslog ↓ log_path = /var/log/dovecot/dovecot.log
ログの出力先作成しておきます
Dovecotを起動
自動起動の設定
認証ソケットファイルが作成されているのを確認します
ls -F /var/spool/postfix/private/auth
---(下記表示があればOK)---
ログのローテーション設定
ログの設定は必須ではありませんが、メールサーバの運用ではログを参照することが多かと思いますので、運用しやすいように設定しておくのをお勧めします。
下の設定では1日ごとにログファイルを分けて、ファイル名に日付が付くように設定しています。ログファイルの保存期間は60日としていますが、運用ルールに合わせて設定してください。
Postfixログの設定
出力先ディレクトリ作成
・出力先の変更
vim /etc/rsyslog.conf
mail.* -/var/log/maillog ↓ mail.* -/var/log/mail/maillog
syslog再起動
不要なログを削除
・ログローテーション設定
vim /etc/logrotate.d/syslog
---(下記を削除)---
/var/log/maillog
vim /etc/logrotate.d/maillog
---(下記を追加)---
/var/log/mail/maillog { daily missingok dateext rotate 60 sharedscripts postrotate /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true endscript }
・確認します
logrotate -dv /etc/logrotate.d/maillog
---(下記のような表示があればOKです)---
empty log files are rotated, old logs are removed
Dovecotログの設定
vim /etc/logrotate.d/dovecot
---(下記を追加)---
/var/log/dovecot/dovecot.log { daily missingok dateext rotate 60 sharedscripts postrotate /bin/kill -USR1 `cat /var/run/dovecot/master.pid 2>/dev/null` 2> /dev/null || true endscript }
・確認します
logrotate -dv /etc/logrotate.d/dovecot
---(下記のような表示があればOKです)---
empty log files are rotated, old logs are removed
メールアカウントの作成
メールアカウントの作成は、普通に UNIXユーザを作成するだけでOKです。下記はメールアカウント「sample@example.com」を作成しています。シェルは必ず「/sbin/nologin」を指定しましょう。
passwd sample
ユーザー sample のパスワードを変更。
新しいパスワード: <←パスワードを入力>
新しいパスワードを再入力してください: <←パスワードを入力>
passwd: 全ての認証トークンが正しく更新できました。
メールクライアント(Thunderbird)の設定例
手動設定でメールサーバを設定し「完了」ボタンをクリックします。以下は「apar.jp」ドメインでの設定例です。
送受信がうまくいかない場合は、メールサーバのポートが空いていることを確認してみましょう。また、設定箇所がかなり多いため、設定漏れなどもあるかと思います。Postfix、Dovecotのログを確認してみてください。
メールサーバ間暗号化通信の確認
SSL/TLSに対応しているGmail等とメールを送受信してみると、メールサーバ間でSSL/TLS暗号化通信が行われていることが確認できると思います。
Gamilへ送信したメールのヘッダ
Received: from mail.apar.jp (blog.apar.jp. [160.16.110.50]) by mx.google.com with ESMTPS id cx6si12642323pad.130.2016.01.30.16.31.40 for <XXX@gmail.com> (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 30 Jan 2016 16:31:40 -0800 (PST)
Gmailから受信したメールのヘッダ
Received: from mail-pf0-f181.google.com (mail-pf0-f181.google.com [209.85.192.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested)
第三者中継チェック
メールサーバが誰にでも送信に使われてしまうと、迷惑メールやフィッシングメールの温床になります。メール送信サーバ(Postfix)の設定が終わったら必ず第三者中継チェックを行いましょう。
メールサーバ以外のホストから、telnet コマンドでメールサーバの25番ポート(SMTP)に接続します。※ほとんどの家庭向けプロバイダはOP25B規制(迷惑メール対策のため25番ポートへの接続を禁止)を実施していますので、OP25B規制のない企業向けプロバイダもしくは別のサーバから接続する必要があります。
(CentOS7 などで telnet コマンドがインストールされていない場合は、「yum -y install telnet」でインストールできます)
接続ができたら青文字の部分を入力し、メールサーバに設定したドメイン名(mydomain)以外のメールアドレスに送信できないことを確認します。
Connected to mail.example.com.
Escape character is '^]'.
220 mail.example.com. ESMTP
mail from: sample@example.com ←送信元メールアドレス
250 2.1.0 Ok
rcpt to: test@example.org ←送信先の別ドメインのメールアドレス
454 4.7.1 <test@example.org>: Relay access denied ←この表示がされればOKです、第三者中継が拒否されています。
quit ← 接続終了
送信ドメイン認証の設定(SPF/DKIM)
今や必須になりつつある送信ドメイン認証の SPF と DKIM の設定もあわせて行うことをおすすめします。
▽ SPFレコードを Amazon Route 53 に登録する
https://blog.apar.jp/linux/737/
▽ Postfix SPF 認証 設定メモ(postfix-policyd-spf-python)
https://blog.apar.jp/linux/766/
▽ Postfix DKIM 認証 設定メモ(CentOS6.5+OpenDKIM)
https://blog.apar.jp/linux/856/
終わりに
仕事のコミュニケーションツールとして、広く普及している電子メールですが、メールサーバー間の通信は、今だに暗号化されずに送受信されていることが多いようです。メールサーバの暗号化設定をしない原因の一つに、SSL/TLS証明書発行の費用や更新の手間があるかと思います。Let's Encrypt が普及し一般的になれば、この問題も解決し、Postfixのデフォルト値が「smtpd_tls_security_level=encrypt」(暗号化強制)になる日が来るかもしれませんね。
コメント
自宅や会社からは大丈夫なのに出先などで自鯖からメールが送れない、という事象が発生していて困っていましたが、SPAM対策の設定に入っているzen.spamhaus.orgがドコモのドメインまたはそれの所有IPアドレスをしょっちゅうSPAMのリストに入れているようです。
>匿名さん
情報ありがとうございます。
記事に追記させて頂きました。
[…] SSLメールサーバ構築メモ Let’s Encrypt+Postfix+Dovecot […]
大変参考にさせていただきました!
ありがとうございました!
>hibriiiiidgeさん
コメントありがとうございます。
この記事が参考になってよかったです。