2026年8月16日
2026年8月16日
メールサーバーのSSL証明書をLet’s Encryptで自動更新する(Postfix・Dovecot)
メールサーバー(Postfix・Dovecot)の SSL/TLS 証明書は、Web サーバーと同じく Let's Encrypt の証明書を certbot で取得・更新できます。ただし、certbot には Postfix や Dovecot の設定を自動で書き換える機能は無いので、証明書の取得と更新は certbot に任せ、メールソフトにはファイルの場所を設定し、更新のあとに再読み込みさせる、という分担にします。
この記事のコマンドは Ubuntu 24.04 を例にしています。certbot の動作は2026年11月時点の certbot の公式ドキュメント、証明書の有効期間は Let's Encrypt の公式発表で確認しています。
前提
- メールサーバーのホスト名(例:
mail.example.com)の A レコード(IPv6 を使うなら AAAA レコード)が、このサーバーを指していること - 証明書の取得に HTTP の確認を使う場合は、インターネットからこのサーバーの 80 番ポートに接続できること
- Postfix と Dovecot が入っていること
ステップ1:certbot を入れる
sudo apt update
sudo apt install certbot
certbot の公式サイトは snap での導入を案内しています。どちらで入れても、使うコマンドは同じです。
ステップ2:証明書を取得する
メールサーバーで使う方法は、サーバーで Web サーバーが動いているかで選びます。
| サーバーの状態 | 使う方法 |
|---|---|
| Web サーバーが動いていない | --standalone(certbot が一時的に 80 番ポートで待ち受ける) |
| 同じサーバーで Web サーバーが動いている | --webroot(Web サーバーの公開ディレクトリに確認用のファイルを置く) |
| 80 番ポートを開けられない | DNS で確認する方法(DNS 事業者ごとのプラグインが必要) |
# Web サーバーが動いていない場合
sudo certbot certonly --standalone -d mail.example.com
# 同じサーバーで Web サーバーが動いている場合(公開ディレクトリが /var/www/html の例)
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 |
秘密鍵 |
live のファイルは更新のたびに新しい証明書を指すように切り替わります。コピーせず、このパスをそのまま設定に書きます。
--standalone の場合、更新のときにも certbot が 80 番ポートで待ち受けます。ファイアウォールで 80 番ポートを閉じると更新に失敗するので注意します。
ステップ3:Postfix に証明書を設定する
sudo postconf -e 'smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem'
sudo postconf -e 'smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem'
sudo postconf -e 'smtpd_tls_security_level = may'
sudo postfix check
sudo systemctl reload postfix
postconf -e は /etc/postfix/main.cf の該当する行を書き換えます。smtpd_tls_security_level = may は、相手が対応していれば STARTTLS で暗号化する設定です(25番ポートで受けるメールサーバーでは、TLS に対応しない相手からも受け取れるよう may にします)。587番ポート(submission)で認証して送信させる設定は、/etc/postfix/master.cf の submission の行で行います。
ステップ4:Dovecot に証明書を設定する
Dovecot は、2.3 系と 2.4 系で設定の名前が違います。dovecot --version で確かめます。Ubuntu 24.04 の Dovecot は 2.3 系、Debian 13 の Dovecot は 2.4 系です。
Dovecot 2.3 系(/etc/dovecot/conf.d/10-ssl.conf)
ssl = required
ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem
< はファイルの中身を読み込む記号で、省くと動きません。
Dovecot 2.4 系(Debian 13 では同じ /etc/dovecot/conf.d/10-ssl.conf に既定の値の行があるので、その行を書き換えます)
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
設定を確かめて反映します。
sudo doveconf -n | grep -i ssl
sudo systemctl reload dovecot
Dovecot は root の権限で証明書と秘密鍵を読むので、秘密鍵の権限を広げる必要はありません。
ステップ5:更新のあとに Postfix と Dovecot を再読み込みさせる
certbot が証明書を更新しても、Postfix と Dovecot は再読み込みするまで古い証明書を使い続けることがあります。certbot のデプロイフックを使い、更新に成功したときだけ再読み込みさせます。
/etc/letsencrypt/renewal-hooks/deploy/ に置いた実行可能なファイルは、証明書の取得・更新に成功するたびに実行されます。
sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-mail.sh
#!/bin/sh
systemctl reload postfix
systemctl reload dovecot
sudo chmod 755 /etc/letsencrypt/renewal-hooks/deploy/reload-mail.sh
同じサーバーにほかの証明書もあり、メールの証明書が更新されたときだけ実行したい場合は、certbot が渡す環境変数 RENEWED_LINEAGE(更新された証明書の live のディレクトリ)で判定します。
#!/bin/sh
case "$RENEWED_LINEAGE" in
*/mail.example.com)
systemctl reload postfix
systemctl reload dovecot
;;
esac
ステップ6:自動更新が動いているかを確かめる
apt や snap で入れた certbot は、certbot renew を定期的に実行するタイマーを用意します。certbot renew は、期限が近づいた証明書だけを更新します。自分で cron に certbot renew を書き足す必要は通常ありません。
# 更新のタイマーがあるか(apt なら certbot.timer、snap なら snap.certbot.renew.timer)
systemctl list-timers | grep -i certbot
# 取得済みの証明書と有効期限の一覧
sudo certbot certificates
# 更新の予行演習(本番の証明書は変わらない)
sudo certbot renew --dry-run
--dry-run ではデプロイフックは実行されません。フックも含めて試すには --run-deploy-hooks を付けます(実際に Postfix と Dovecot が再読み込みされます)。
sudo certbot renew --dry-run --run-deploy-hooks
更新の記録は /var/log/letsencrypt/letsencrypt.log に残ります。失敗したときは、まずこのログを見ます。
ステップ7:メールソフトが新しい証明書を使っているかを確かめる
openssl s_client で各ポートに接続し、証明書の名前と有効期限を表示します。
# IMAPS(993番)
openssl s_client -connect mail.example.com:993 -servername mail.example.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -enddate
# SMTP の submission(587番、STARTTLS)
openssl s_client -connect mail.example.com:587 -starttls smtp -servername mail.example.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -enddate
# SMTP(25番、STARTTLS)
openssl s_client -connect mail.example.com:25 -starttls smtp -servername mail.example.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -enddate
notAfter= の日付が sudo certbot certificates の有効期限と同じなら、新しい証明書が使われています。古い日付のままなら、再読み込みができていません。
有効期間と期限切れの通知についての注意
- 2026年11月時点で、Let's Encrypt の通常の証明書の有効期間は90日です。Let's Encrypt は有効期間を段階的に短くすると発表しており、2027年2月10日から64日、2028年2月16日から45日になる予定です。更新を自動にし、決まった日数ごとに更新するような独自の仕組みに頼らないようにします。
- Let's Encrypt は、期限切れが近いことを知らせるメールの送信を2025年6月4日に終了しています。期限の監視は自分で用意します。上の
opensslのコマンドで残り日数を調べる、監視ツールで証明書の期限をチェックする、などの方法があります。
Web サーバー側の自動更新については Let's EncryptのSSL証明書を自動更新する方法、メールの暗号化の設定については メールサーバーのSTARTTLSの設定 も参照してください。
まとめ
certbot certonlyで、メールサーバーのホスト名の証明書を取得します(--standaloneか--webroot)。- Postfix は
smtpd_tls_cert_file・smtpd_tls_key_file、Dovecot は 2.3 系ならssl_cert・ssl_key、2.4 系ならssl_server_cert_file・ssl_server_key_fileにliveのパスを設定します。 /etc/letsencrypt/renewal-hooks/deploy/にフックを置き、更新のたびに Postfix と Dovecot を再読み込みさせます。systemctl list-timersとcertbot renew --dry-runで自動更新を確かめ、openssl s_clientで実際に使われている証明書の期限を確かめます。