それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

mailcowにcertbot の証明書を使ってもらう。

mailcow には lets encrypt (LE) が内蔵だが、オフにしたい。

mailcow に添付されてる LE acme クライアントは、port 80/443 (http/https)で ドメインをVerifyする。

うちの環境では、狙われやすいメール環境にIP接続制限を掛けていて、海外IPからの接続を拒否している。そのため、http/s を用いたドメインの確認ができない。http に接続が来ても、USAからの接続になりLEが検証に失敗した

Certbotなら外部から接続を受け入れなくても、ドメイン名の検証はDNSのTXTレコードで可能であるが、軽量版のacme-tiny ではIPへ接続する方法のみ提供になる。

そのため mailcow 添付 の LE 関連機能を諦めCertbotで生成した証明書を使うことにした。

certbot で作った証明書を食わせる。

#!/bin/bash
## 証明書を移動
cert_name=my.domain.tld.name
cp /etc/letsencrypt/live/cert_name/fullchain.pem   /opt/mailcow-dockerized/data/assets/ssl/cert.pem
cp /etc/letsencrypt/live/cert_name/privkey.pem     /opt/mailcow-dockerized/data/assets/ssl/key.pem
## restart
postfix_c=$(docker ps -qaf name=postfix-mailcow)
dovecot_c=$(docker ps -qaf name=dovecot-mailcow)
nginx_c=$(docker ps -qaf name=nginx-mailcow)
docker restart ${postfix_c} ${dovecot_c} ${nginx_c}

これで、mailcow がcertbot で作ったSSLを読んでくれる。

注意点 mailcow-dockerized/data/assets/ssl/

これをやってハマった点。 SKIP_LETS_ENCRYPT=y を初期設定前に追加してしまうと、 mailcow-dockerized/data/assets/ssl/ の内部のディレクトリが初期設定されないので、いったん SKIP_LETS_ENCRYPT=n で初回起動して動作しているのを見てから、SKIP_LETS_ENCRYPT=n に変えて、証明書を突っ込む必要があった。

注意点 domain verify

証明書をちゃんと有効にしていると、外部からサブミッションポート(578)・SMTPSポート(465) で接続ができるが、接続はTLSになる。当然ながらドメイン名のVerify が走る。

そのため、IPアドレスの直接指定ではTLS証明書の検証に失敗し接続ができなくなる。接続テスト時には、/etc/hosts や dnsmasq / unbound などを駆使するか、ヘアピンNATでうまくドメイン名とIPアドレスを解決して上げる必要があった。

参考資料

公式にちゃんとドキュメントがあって素晴らしい。

https://mailcow.github.io/mailcow-dockerized-docs/post_installation/firststeps-rp/#optional-post-hook-script-for-non-mailcow-acme-clients

https://mailcow.github.io/mailcow-dockerized-docs/post_installation/firststeps-ssl/#additional-domain-names