courier-imap + postfix からなるメールサーバの SSL 証明書を certbot と Let’s Encrypt で自動更新化

プロバイダのメールや仕事上のメールなどのもろもろのメールは、プロバイダのメールが IMAP 未対応なことなどから、別途 IMAP でメールサーバを立てて、そこに転送したり、fetchmail で取ってきたりして集約。IMAP でいろんなデバイスからメールを確認できるようにしている。

また、そのサーバではもろもろのメールを集約するほか、仮にそのメールサーバのドメインを mail.example.com とすると、〜@example.com のメールも送受信できるようにしています。

んで、そのもろもろのメールを集約しているメールサーバの SSL 証明書はこれまで年1回、格安のところで購入して手動でインストールしてきました(当初はオレオレ証明書でやっていたけど、いろいろすんなり行かなくなって、ちゃんと SSL 証明書を購入してインストールしてきた)。

ところが、SSL 証明書の有効期限が2026年3月から最長200日になり、その後は最終的に47日になることが決定したようで、VPS で運用しているお客さんのサイトの SSL 証明書の更新も自動化しないと仕方がないなぁ、ということで、SSL 証明書の自動更新化を決意。いろいろわからないので、とりあえず手始めに、この手元のメールサーバを自動更新化しようと思い立ったのである。

お客さんのサイトは Let’s Encrypt は使用しないつもりだが、このメールサーバについては Let’s Encrypt でいいだろうということで以下やってみました。

メールサーバの構成

当該のサーバは Conoha で VPS を借りて、Ubuntu 24.04.3 LTS を構築。IMAP サーバは courier-imap で、smtp サーバは postfix で運用している。

IMAP サーバは Dovecot に変更したほうがいいかなと思いつつ、courier-imap のまま。今回もそのまま courier-imap を引き続き使用することにする。

まずはウェブサーバを certbot と Let’s Encrypt で SSL 化

これまでこのサーバではウェブサーバを立てていなかったんだけど、Let’s Encrypt では「HTTP-01 チャレンジ」「DNS-01 チャレンジ」の2通りのチャレンジ(まさわたくしがドメイン mail.example.com を管理していることを検証すること)の仕方があるけど、まあ「HTTP-01 チャレンジ」が一般的ということで今回はこちらの方法でやっていく。

そのためにはウェブサーバを立てて80番ポートを開放してやる必要がある(参考)ということで、今回 nginx でウェブサーバを立てて、80 番ポートとついでに 443 番ポートを開放してやった。まあ普通に nginx を入れて https でも接続できるようにして、Ubuntu なので ufw でポートを開放してやる。

次に certbot をインストールしてウェブサーバを SSL 化

んで確認したら、certbot は入っていなかったので、インストールすることに。いろいろ調べてみたら、nginx 用のプラグインもあるということで、それも同時に次のようにして入れてやる。

$ sudo apt install certbot python3-certbot-nginx

それで nginx に設定するには

$ sudo certbot --nginx

としてやるだけでよいようだ(今回の場合、必ずしも nginx に証明書を設定してやる必要はないのだが、まあこれが簡単かなと)。

すると、メールアドレスを聞かれるので入力。同意を求められるので、Y (2番目は N でもいいんでしょう) と答えてやると、以下のようになる。

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): ginchan@mail.example.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.6-August-18-2025.pdf. You must agree
in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:
(Y)es/(N)o: Y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
Account registered.

Which names would you like to activate HTTPS for?
We recommend selecting either all domains, or all domains in a VirtualHost/server block.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: mail.example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):
Requesting a certificate for mail.example.com

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/mail.example.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/mail.example.com/privkey.pem
This certificate expires on 2026-03-18.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

Deploying certificate
Successfully deployed certificate for mail.example.com to /etc/nginx/sites-enabled/default
Congratulations! You have successfully enabled HTTPS on https://mail.example.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

これで nginx の設定を見てやると、

server {

        server_name mail.example.com;

        root /var/www/html;
        index index.html;

        location / {
                try_files $uri $uri/ =404;
        }

        listen [::]:443 ssl ipv6only=on; # managed by Certbot
        listen 443 ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/mail.example.com/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/mail.example.com/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
        if ($host = mail.example.com) {
                  return 301 https://$host$request_uri;
        } # managed by Certbot

        listen 80;
        listen [::]:80;

        server_name mail.example.com;
        return 404; # managed by Certbot
}

てな感じで、いい塩梅で設定をしてくれている。

メール関係の設定

それであとは courier-imap と postfix のほうの設定だ。まずは postfix のほうは、/etc/postfix/main.cf を編集。 courier-imap に設定していた証明書などを指定してあるところを以下のように変更して、Let’s Encrypt で生成された証明書と秘密鍵を指定してやる。

変更前)
smtpd_tls_cert_file=/etc/courier/imapd.pem
smtpd_tls_key_file=/etc/courier/imapd.pem
smtpd_tls_CAfile=/etc/courier/ca-bundle.ca
↓
変更後)
smtpd_tls_cert_file=/etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/mail.example.com/privkey.pem

これで sudo service postfix restart でpostfix を再起動してやる。

んで問題は courier-imap 。/etc/courier/imapd-ssl を編集してやればいいのだが、問題は

TLS_CERTFILE=/etc/courier/imapd.pem

となっているところなんだが、この imapd.pem は秘密鍵と証明書をまとめたやつなのだ。上記のfullchain.pem と privkey.pem をまとめてやればいいのだが、自動更新する対応するためには更新されるごとにファイルをまとめてやらなければならない。まあスクリプトを書けばいいんだが、ちょっと探してみたら、もろもろ作っておられるのを発見

Let’s IMAP https://github.com/mohsenie/lets-encrypt-imap

上記にしたがって、まず /etc/courier/imapd-ssl のなかの TLS_CERTFILE と TLS_TRUSTCERTS の設定を以下のように変更

変更前)
TLS_CERTFILE=/etc/courier/imapd.pem
TLS_TRUSTCERTS=/etc/ssl/certs/ca-certificates.crt
↓
変更後)
TLS_CERTFILE=/etc/letsencrypt/live/mail.example.com/imapd.pem
TLS_TRUSTCERTS=/etc/letsencrypt/live/mail.example.com/fullchain.pem

そのうえで上記の Let’s IMAP を

$ git clone https://github.com/nicolas-dutertry/letsimap.git
$ cd letsimap
$ sudo ./install

でインストールしてやる。これで、/etc/letsencrypt/live/mail.example.com/imapd.pem が生成される。これで sudo service courier-imap-ssl restart で再起動

これでメール関係の設定が終わったので、

openssl s_client -connect mail.example.com:993 | openssl x509 -text | grep 'Not'

などとして、Let’s Encrypt の証明書がインストールされているのを確認する。

自動更新について

ネット上の情報では、これで自動更新するために cron に登録する必要があるというのが散見されるが、/etc/cron.d/ 内に certbot がすでに登録されていた。その中身は、

0 */12 * * * root test -x /usr/bin/certbot -a ! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew --no-random-sleep-on-renew

となっていて、12時間ごとに確認して、更新できる場合は更新を行うようだ。それで courier-imap のほうは上記の Let’s IMAP が /etc/cron.d/ 内に letsimap を生成してくれており、中身は

30 */12 * * * root test -x /usr/local/bin/letsimap && letsimap

cerbot のほうが12時間ごとに確認するわけだが、その30分に letsimap も確認&生成をしてくれるわけだ。

これで問題なく、自動更新していってくれるはず。めでたしめでたし。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です