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 とログで暗号化を確かめる

お気軽にご相談ください

お見積りへ お問い合わせへ
▲