Automatic copy of certificates from Caddy

Started by likkyss, October 22, 2025, 06:21:07 PM

Previous topic - Next topic
Hi there, newbie here :) I am trying to setup Mailcow (on second server), I already configured port forwarding, Caddy, DNS, installed Mailcow and got it running. I am using Caddy as reverse proxy with Auto HTTPS certificate - this is working. Then I wrote script to copy certificate from OPNSense to my mail server - this works too (skript bellow). Last thing to setup is to automatically run this script after certificate renewal.

When I was browsing through Caddy UI I didn't find any option to "do something after it gets new certificate", so after some digging I wanted to add hook into Caddy File. Problem is the first line in Caddy file: # DO NOT EDIT THIS FILE -- OPNsense auto-generated file

I already spent more then 30 hours to get it running but now I am on a dead end. Can anybody here please help me find the way to do it automatically so I don't need to run this script everytime certificate changes?

Thank you very much.

#!/bin/sh

#path and details
CERT_NAME="mail.domain.com"
CADDY_CERT_DIR="/var/db/caddy/data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/${CERT_NAME}/"

#login
MAILCOW_USER="mailserveruser"
MAILCOW_HOST="XXX.XXX.XXX.XXX"
MAILCOW_SSL_DIR="/opt/mailcow-dockerized/data/assets/ssl/"

#SSH path (for OPNSense root user)
SSH_KEY_PATH="/root/.ssh/opnsense_mailcow_cert_key"

#timestamp into log
echo "$(date) - Sync of certificates start."

#private key copy (key.pem)
echo "Private key copy."
scp -i "$SSH_KEY_PATH" "$CADDY_CERT_DIR/${CERT_NAME}.key" "$MAILCOW_USER@$MAILCOW_HOST:/tmp/key.pem.new"

#full chain certificate copy (cert.pem)
echo "Certificate copy (Full Chain)."
scp -i "$SSH_KEY_PATH" "$CADDY_CERT_DIR/${CERT_NAME}.crt" "$MAILCOW_USER@$MAILCOW_HOST:/tmp/cert.pem.new"

#is copy ok?
if [ $? -eq 0 ]; then
    echo "Copy to /tmp succeeded. Deploying Mailcow."

    #move files and restart Docker
    #the suffix .new is used for replacement to prevent failure due to a missing file
    SSH_COMMAND="
    sudo cp /tmp/cert.pem.new ${MAILCOW_SSL_DIR}cert.pem;
    sudo cp /tmp/key.pem.new ${MAILCOW_SSL_DIR}key.pem;
    rm /tmp/cert.pem.new /tmp/key.pem.new;
    sudo docker compose -f /opt/mailcow-dockerized/docker-compose.yml restart dovecot-mailcow postfix-mailcow sogo-mailcow
    "

    ssh -t -i "$SSH_KEY_PATH" "$MAILCOW_USER@$MAILCOW_HOST" "${SSH_COMMAND}"
    if [ $? -eq 0 ]; then
        echo "Mailcow restart successful."
    else
        echo "ERROR: Restart Mailcow failed. Check sudo permissions"
    fi
else
    echo "ERROR: Copy failed."
fi

Versions
OPNsense 25.7.6-amd64
FreeBSD 14.3-RELEASE-p4
OpenSSL 3.0.18
os-caddy 2.0.4_1
mailserver OS Ubuntu 24.04.3 LTS
mailcow 2025-10

You probably want to use the ACME client plugin and the DNS-01 method for your certificates. ACME client can run automations whenever a certificate is reissued and Caddy can use the certificates provided by ACME client.
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

Hi, thank you for fast reply :) Do you mean to download os-acme-client from plugins? And then I should change Auto HTTPS to get certificate from this plugin?

Exactly. Some assembly required - ACME client is best used with the DNS-01 authentication protocol.
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

If you do http01 and tls01 challenge in caddy you could also enable http01 challenge in mailcow and use the reverse proxy function to forward the challenge from caddy.

That way caddy and mailcow generate their own certs, no copy jank needed.

https://docs.opnsense.org/manual/how-tos/caddy.html#redirect-acme-http-01-challenge
Hardware:
DEC740


Ok, it did not do the job... I am just dumb :D

I thougt it is ok, but when I try to connect to Mailcow, it did not work through domain, but not IP adress (internal network) - no certificate.

So I am still on start line and don't know, how to continue. I am not complete sure with ACME client too, but I will give it a try...

I know for sure this works with mailcow because the feature was implemented from feedback of a guy who uses mailcow with caddy.

Maybe contact them for help?
https://community.mailcow.email/u/pleibling

Hardware:
DEC740