SSLメールサーバ構築メモ Let's Encrypt+Postfix+Dovecot

Linux
Linux
スポンサーリンク

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」としていますが、こちらはなんでも構いません。

example.com.      IN MX 10 mail.example.com.
mail.example.com. IN A 192.0.2.1

メールサーバが使用するポートのオープン

メールの送受信に使う以下のポートを開けておきます。

・SMPT(25)
・SMTPS(465)
・IMAPS(993)
・POP3S(995)

firewall-cmd --add-port=25/tcp --permanent
firewall-cmd --add-port=465/tcp --permanent
firewall-cmd --add-port=993/tcp --permanent
firewall-cmd --add-port=995/tcp --permanent
firewall-cmd --reload

ポートオープンの確認

firewall-cmd --list-ports
22/tcp 25/tcp 465/tcp 995/tcp 993/tcp

基本パッケージのインストール

CentOS7.2を「最小限のインストール」でインストールしている場合は、基本パッケージと開発ツールなどをインストールしておきましょう。

yum -y groupinstall base
yum -y groupinstall development
yum -y groupinstall network-tools

Postfix と Dovecot のインストール

※バージョンは 2016年1月31日時点のものです。

Postfix(2.10.1-6)※CentOSの場合は既にインストールされていると思います。

yum -y install postfix

Dovecot(2.2.10-5)

yum -y install dovecot

Let's Encrypt のSSL/TLS証明書の取得

Let's Encrypt の詳細については、こちらの記事をご参照ください。

クライアントのインストール

Let's Encrypt のクライアントソフトをインストールします。

cd /usr/local/
git clone https://github.com/certbot/certbot

Let's Encrypt クライアントが依存するパッケージをインストールします。

cd certbot/
./certbot-auto -n

証明書の取得

Let's Encrypt クライアントの待ち受けポートを開けておきます。

firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --add-port=443/tcp --permanent
firewall-cmd --reload

Let's Encrypt のSSL/TLS証明書を取得します。
取得した証明書や秘密鍵は「/etc/letsencrypt/live/mail.example.com/」以下に保存されます。

./certbot-auto certonly --standalone \
-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

00 05 01 * * /usr/local/certbot/certbot-auto renew --force-renewal && /bin/systemctl reload postfix && /bin/systemctl reload dovecot

証明書の有効期限確認

openssl x509 -in /etc/letsencrypt/live/mail.example.com/fullchain.pem -noout -dates
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」プラグインで証明書を取得します。

./certbot-auto certonly --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

00 05 01 * * /usr/local/certbot/certbot-auto renew --force-renewal && /bin/systemctl reload postfix && /bin/systemctl reload dovecot

Postfix の設定

元の設定ファイルをキープしておきます。

cp -ip /etc/postfix/main.cf /etc/postfix/main.cf.org

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

ルックアップテーブルの作成

postmap /etc/postfix/access

設定に誤りがないかチェック(なにも表示されなければOKです)

postfix check

Postfixの起動

systemctl start postfix

自動起動の設定

systemctl enable 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

ログの出力先作成しておきます

mkdir /var/log/dovecot

Dovecotを起動

systemctl start dovecot

自動起動の設定

systemctl enable dovecot

認証ソケットファイルが作成されているのを確認します
ls -F /var/spool/postfix/private/auth
---(下記表示があればOK)---

/var/spool/postfix/private/auth =

ログのローテーション設定

ログの設定は必須ではありませんが、メールサーバの運用ではログを参照することが多かと思いますので、運用しやすいように設定しておくのをお勧めします。

下の設定では1日ごとにログファイルを分けて、ファイル名に日付が付くように設定しています。ログファイルの保存期間は60日としていますが、運用ルールに合わせて設定してください。

Postfixログの設定

出力先ディレクトリ作成

mkdir /var/log/mail

・出力先の変更
vim /etc/rsyslog.conf

mail.*                                                  -/var/log/maillog
                       ↓
mail.*                                                  -/var/log/mail/maillog

syslog再起動

systemctl restart rsyslog

不要なログを削除

rm -f /var/log/maillog*

・ログローテーション設定
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です)---

rotating pattern: /var/log/mail/maillog after 1 days (60 rotations)
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です)---

rotating pattern: /var/log/dovecot/dovecot.log after 1 days (60 rotations)
empty log files are rotated, old logs are removed

メールアカウントの作成

メールアカウントの作成は、普通に UNIXユーザを作成するだけでOKです。下記はメールアカウント「sample@example.com」を作成しています。シェルは必ず「/sbin/nologin」を指定しましょう。

useradd -s /sbin/nologin sample
passwd sample
ユーザー sample のパスワードを変更。
新しいパスワード: <←パスワードを入力>
新しいパスワードを再入力してください: <←パスワードを入力>
passwd: 全ての認証トークンが正しく更新できました。

メールクライアント(Thunderbird)の設定例

手動設定でメールサーバを設定し「完了」ボタンをクリックします。以下は「apar.jp」ドメインでの設定例です。
メールクライアント(Thunderbird)の設定画面

送受信がうまくいかない場合は、メールサーバのポートが空いていることを確認してみましょう。また、設定箇所がかなり多いため、設定漏れなどもあるかと思います。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規制のない企業向けプロバイダもしくは別のサーバから接続する必要があります。

telnet mail.example.com 25

(CentOS7 などで telnet コマンドがインストールされていない場合は、「yum -y install telnet」でインストールできます)

接続ができたら青文字の部分を入力し、メールサーバに設定したドメイン名(mydomain)以外のメールアドレスに送信できないことを確認します。

Trying 192.0.2.1...
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」(暗号化強制)になる日が来るかもしれませんね。

コメント

  1. 匿名 より:

    自宅や会社からは大丈夫なのに出先などで自鯖からメールが送れない、という事象が発生していて困っていましたが、SPAM対策の設定に入っているzen.spamhaus.orgがドコモのドメインまたはそれの所有IPアドレスをしょっちゅうSPAMのリストに入れているようです。

  2. メールにもLet’s encryptをつかってみた より:

    […] SSLメールサーバ構築メモ Let’s Encrypt+Postfix+Dovecot […]

  3. hibriiiiidge より:

    大変参考にさせていただきました!
    ありがとうございました!

タイトルとURLをコピーしました