He he, Postfix Autocert hack :)

If you happen to maintain Postfix and Caddy at the same time, it’s actually super easy to get a cert for Postfix.

I am running a bunch of instances that uses this Docker Caddy setup.

Add following to your Caddyfile, or in the setup above in the conf/caddyfile_optional.conf file:

    mail.yourdomain.org {
        respond "Hello"
        log
    }

When Caddy is reloaded you’ll get a cert. Again, in the example tutorial above the cert will end up in:
.caddy_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.yourdomain.org

Symlink the crt/key files to your Postfix conf. I have added a symlink to the ordinary /etc folder:

    mkdir -p /etc/letsencrypt/from-caddy
    cd /etc/letsencrypt/from-caddy
    ln -s /path/to/docker/.caddy_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.yourdomain.org/mail.yourdomain.org.crt
    ln -s /path/to/docker/.caddy_data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.yourdomain.org/mail.yourdomain.org.key

Then in the TLS-part of /etc/postfix/main.cf:

    smtpd_tls_cert_file = /etc/letsencrypt/from-caddy/mail.yourdomain.org.crt
    smtpd_tls_key_file = /etc/letsencrypt/from-caddy/mail.yourdomain.org.key

To make sure Postfix always uses the latest cert, reload the conf with crontab:

    0 0 * * 0 bash -lc '/etc/init.d/postfix reload'

That’s it. Butt ugly and works a charm! :grin:

If someone finds this thread that is now closed, same setup should work too.

You can also directly trigger the reload of postfix when the cert is renewed using this plugin:

{
	events {
		on cert_obtained exec /etc/init.d/postfix reload
	}
}

Actually that triggers a reload for any cert that gets obtained (including renewals), but in the future we may make it possible to filter by event data.

2 Likes

Yes, that works too!
In my case the Caddy instances are isolated from Postfix as they are running in Docker containers. Hence the reload with crontab.

Keep in mind that if Caddy uses ZeroSSL to issue a cert instead of Let’s Encrypt, your approach will break because the path to the files will be different. You can use events to get the correct path every time (it gets passed as input to the event handler)

1 Like