2026年5月22日
2026年5月22日
メールサーバーのSSL/TLS設定方法|PostfixとDovecotでSTARTTLSを有効にする手順
メールサーバーの通信を暗号化するには、送信を受け持つ Postfix と、受信(IMAP)を受け持つ Dovecot の両方にサーバー証明書を設定します。この記事では、Let's Encrypt の証明書を取得し、Postfix で STARTTLS と 465番ポートの TLS を、Dovecot で IMAP の TLS を有効にするまでを説明します。
手順は Ubuntu 24.04(Postfix 3.8、Dovecot 2.3)と Debian 13(Postfix 3.10、Dovecot 2.4)の標準パッケージで確認しています(2026年10月時点)。Dovecot は 2.3 と 2.4 で設定の書き方が違うため、両方を載せています。
STARTTLS と最初から TLS の違い
メールの暗号化には2つの方式があります。
- STARTTLS:平文で接続したあと、
STARTTLSコマンドで暗号化に切り替える方式 - 最初から TLS(暗黙の TLS):接続した直後から TLS で通信する方式
ポートごとの使い分けは次のとおりです。
| ポート | 用途 | 方式 |
|---|---|---|
| 25 | メールサーバー同士の配送(SMTP) | STARTTLS(相手が対応していれば暗号化) |
| 587 | メールソフトからの送信(submission) | STARTTLS(暗号化を必須にする) |
| 465 | メールソフトからの送信(submissions) | 最初から TLS |
| 143 | IMAP | STARTTLS |
| 993 | IMAPS | 最初から TLS |
メールソフトとサーバーの間では、RFC 8314 が最初から TLS を使う方式(465・993)を推奨しています。25番ポートは、相手のサーバーが暗号化に対応していない場合も配送できるよう、暗号化を「任意」にしておくのが一般的です。
前提
- メールサーバーのホスト名(この記事では
mail.example.com)の A レコードが、そのサーバーの IP アドレスを指していること - 証明書の名前は、MX レコードに書いたホスト名と、メールソフトに設定するサーバー名に合わせること
- Postfix と Dovecot が動いていて、587・465番で使う SMTP 認証(Dovecot SASL など)が設定済みであること。まだの場合はPostfixとDovecotでメールサーバーを構築する手順を先に済ませてください
- ファイアウォールで 25・587・465・993 番(必要なら 143 番)を開けていること
手順1:証明書を取得する
certbot で mail.example.com の証明書を取得します。証明書の取得には、そのホスト名の 80 番ポートで HTTP の応答を返せることが必要です。
sudo apt update
sudo apt install certbot
# 80番ポートを使うWebサーバーが動いていない場合(certbot が一時的に80番で待ち受ける)
sudo certbot certonly --standalone -d mail.example.com
# 同じサーバーのWebサーバーが mail.example.com を配信している場合(ドキュメントルートを指定)
sudo certbot certonly --webroot -w /var/www/html -d mail.example.com
取得できると、次のファイルができます。
- 証明書(中間証明書を含む):
/etc/letsencrypt/live/mail.example.com/fullchain.pem - 秘密鍵:
/etc/letsencrypt/live/mail.example.com/privkey.pem
Postfix と Dovecot は起動時に root 権限でこれらのファイルを読むため、権限を変える必要はありません。
手順2:Postfix の main.cf を設定する
/etc/postfix/main.cf に次の設定を書きます。同じ名前の設定がすでにある場合は、その行を書き換えます(同じ設定が2回あると、後に書いたほうが使われます)。
# 受け付ける側(他のサーバーやメールソフトから接続されるとき)
smtpd_tls_chain_files = /etc/letsencrypt/live/mail.example.com/privkey.pem, /etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_mandatory_protocols = >=TLSv1.2
smtpd_tls_loglevel = 1
# 送る側(他のサーバーへ配送するとき)
smtp_tls_security_level = may
smtp_tls_loglevel = 1
各設定の意味は次のとおりです。
| 設定 | 意味 |
|---|---|
smtpd_tls_chain_files |
秘密鍵と証明書のファイル。秘密鍵を先に書く(Postfix 3.4 以降) |
smtpd_tls_security_level = may |
STARTTLS を提供するが、暗号化は必須にしない(25番ポート向け) |
smtpd_tls_auth_only = yes |
暗号化していない接続では SMTP 認証を受け付けない |
smtpd_tls_mandatory_protocols |
暗号化を必須にした接続(587番の encrypt など)で使う TLS の最低バージョン。>= の書き方は Postfix 3.6 以降 |
smtp_tls_security_level = may |
配送先が STARTTLS に対応していれば暗号化して送る |
*_tls_loglevel = 1 |
TLS の接続をログに記録する |
Ubuntu・Debian の初期設定には自己署名の証明書を指す smtpd_tls_cert_file と smtpd_tls_key_file の行があります。smtpd_tls_chain_files を書くとこの2つは使われなくなり、警告がログに出るため、2行は削除しておきます。Postfix 3.3 以前を使う場合は、smtpd_tls_chain_files の代わりにこの2つに fullchain.pem と privkey.pem を指定します。
古い記事でよく見る smtpd_use_tls = yes と smtp_use_tls = yes は、Postfix 2.3 以降は smtpd_tls_security_level と smtp_tls_security_level に置き換わっており、Postfix 3.9 で非推奨になりました。残っている場合は削除します。
手順3:Postfix の master.cf で 587番と465番を有効にする
/etc/postfix/master.cf には、587番(submission)と465番(submissions)の設定がコメントアウトされた状態で入っています。行頭の # を外して有効にします。最低限、次の行が有効になっていれば動きます。
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_tls_auth_only=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
submissions inet n - y - - smtpd
-o syslog_name=postfix/submissions
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
smtpd_tls_security_level=encrypt:587番では暗号化しない限りコマンドを受け付けないsmtpd_tls_wrappermode=yes:465番を最初から TLS で待ち受ける
-o で始まる行は、行頭に空白を入れて前の行の続きとして書きます。配布されている master.cf には他にも -o の行がありますが、意味が分からない行は有効にしないでおけば十分です。
設定を確かめて反映します。
sudo postfix check
sudo postconf -n | grep tls
sudo systemctl reload postfix
手順4:Dovecot(IMAP)を設定する
設定ファイルは /etc/dovecot/conf.d/10-ssl.conf です。Dovecot のバージョンは dovecot --version で確認できます。
Dovecot 2.3(Ubuntu 24.04 など)の場合:
ssl = required
ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem
ssl_min_protocol = TLSv1.2
Dovecot 2.3 では、ファイル名の前に < が必要です。< がないと、パスの文字列そのものを証明書の中身として扱うため、証明書を読み込めずエラーになります。
Dovecot 2.4(Debian 13 など)の場合:
ssl = required
ssl_server_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_server_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem
ssl_min_protocol = TLSv1.2
ssl = required にすると、暗号化していない接続ではログインできなくなります(STARTTLS でも 993番でもかまいません)。設定を確かめて反映します。
sudo doveconf -n | grep ssl
sudo systemctl reload dovecot
手順5:証明書の更新時に再読み込みする
Debian・Ubuntu の certbot パッケージには、自動更新のタイマーが入っています。動いているかを確かめます。
systemctl list-timers | grep certbot
証明書が更新されても、Postfix と Dovecot は再読み込みするまで古い証明書を使い続けます。更新されたときだけ再読み込みするよう、certbot の deploy フックを置きます。
sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-mail.sh > /dev/null << 'EOF'
#!/bin/sh
systemctl reload postfix
systemctl reload dovecot
EOF
sudo chmod 755 /etc/letsencrypt/renewal-hooks/deploy/reload-mail.sh
renewal-hooks/deploy/ に置いたスクリプトは、証明書の取得や更新に成功したときに実行されます。sudo certbot renew --post-hook "systemctl reload postfix" を手で実行する方法も見かけますが、これはそのとき1回だけ更新を試すコマンドで、定期実行の設定にはなりません。
更新の流れは次のコマンドで試せます。
sudo certbot renew --dry-run
--dry-run では deploy フックは実行されません。フックも試したい場合は --run-deploy-hooks を付けます。
Let's Encrypt の証明書の有効期間は、2026年10月時点の標準で90日です。2027年2月から64日、2028年2月から45日に短くなると公表されているため、手作業ではなく自動更新で運用してください。詳しくはcertbotで証明書を自動更新する設定も参照してください。
手順6:暗号化できているか確かめる
openssl s_client で各ポートに接続し、TLS で接続できるか、証明書が正しいかを確かめます。最後の < /dev/null は、接続を確かめたらすぐ終了させるためのものです。
# 587番(STARTTLS)
openssl s_client -connect mail.example.com:587 -starttls smtp -servername mail.example.com -brief < /dev/null
# 465番(最初から TLS)
openssl s_client -connect mail.example.com:465 -servername mail.example.com -brief < /dev/null
# 25番(STARTTLS)
openssl s_client -connect mail.example.com:25 -starttls smtp -servername mail.example.com -brief < /dev/null
# 993番(IMAPS)
openssl s_client -connect mail.example.com:993 -servername mail.example.com -brief < /dev/null
成功すると、次のような行が表示されます。
CONNECTION ESTABLISHED
Protocol version: TLSv1.3
Peer certificate: CN=mail.example.com
Verification: OK
Verification が OK でない場合は、証明書のホスト名が接続先の名前と合っているか、fullchain.pem を指定しているか(cert.pem だと中間証明書が足りません)を確かめます。
日本の家庭用回線などでは、外向きの25番ポートがプロバイダーにふさがれていることがあります(OP25B)。25番の確認は、別のサーバーから行ってください。
外部のサーバーとのやり取りが暗号化されているかは、Postfix のログで確かめます。smtpd_tls_loglevel = 1 と smtp_tls_loglevel = 1 にしてあれば、暗号化した接続ごとに TLS connection established を含む行が記録されます。
# rsyslog がある環境(Ubuntu など)
sudo grep "TLS connection established" /var/log/mail.log | tail
# ログが journald だけの環境(Debian 12 以降の初期状態など)
sudo journalctl -t postfix/smtpd -t postfix/smtp --since today | grep "TLS connection established"
注意事項
- 25番ポートの暗号化は「相手が対応していれば」の任意の暗号化です。サーバー間の暗号化を強制したい場合は、MTA-STS(RFC 8461)や DANE(RFC 7672)といった別の仕組みを使います
- 25番ポートに
smtpd_tls_security_level = encryptを設定すると、暗号化に対応していないサーバーからのメールを受け取れなくなります。公開しているメールサーバーの25番では使わないでください(Postfix の説明書でもこの用途では使わないよう書かれています) - 証明書を入れ替えても、送信ドメイン認証(SPF・DKIM・DMARC)には影響しません。到達率の対策は別に行います(SPF・DKIM・DMARCの確認方法)
まとめ
- 証明書はメールサーバーのホスト名(MX とメールソフトの設定に使う名前)で取得する
- Postfix は
smtpd_tls_chain_filesとsmtpd_tls_security_level = mayで25番の STARTTLS を、master.cf で587番(encrypt)と465番(wrappermode)を設定する smtpd_use_tlsなどの古い設定は使わない- Dovecot は 2.3 と 2.4 で証明書の設定名が違う
- 更新時の再読み込みは
renewal-hooks/deploy/のスクリプトで行い、openssl s_clientとログで暗号化を確かめる