Filemaker Server 2024, Letsencrypt, lego, Hetzner Api

Mac mini M1, macOS Sequoia 15.3, Filemaker Server 2024.

Ich möchte über die Hetzner-Api mittels lego ein Zertifikat von Letsencrypt holen ohne dafür am Filemaker Server den Port 80 zu öffnen. Das funktioniert auch mit vielen anderen DNS-Providern, eine Liste gibt es auf der lego Webseite.

Quellen

Lego: https://go-acme.github.io/lego/dns/hetzner/index.html

Hetzner-Api: https://dns.hetzner.com/api-docs

Claris: https://help.claris.com/en/server-installation-configuration-guide/content/using-certificate-command.html

lego installieren

brew update
==> Updating Homebrew...
Already up-to-date.

brew upgrade

brew install lego

Zertifikat holen

Ich habe mir für meine Domain ein Shell-Script geschrieben. Den Api-Key muss man sich bei Hetzner in seinem Account anlegen.

nano ~/lego-run.sh
#!/bin/sh

PATH="/Users/ICH"
DOMAIN="FilemakerServer.domain.com"
EMAIL="email@domain.com"
# mein Hetzner Api-Key
KEY="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

cd ${PATH}
HETZNER_API_KEY=${KEY} /opt/homebrew/bin/lego --email ${EMAIL} --dns hetzner -d ${DOMAIN} run
chmod 750 ~/lego-run.sh

Und dann ausgeführt.

./lego-run.sh

2025/02/08 17:08:59 No key found for account email@domain.com. Generating a P256 key.
2025/02/08 17:08:59 Saved key to /Users/ICH/.lego/accounts/acme-v02.api.letsencrypt.org/email@domain.com/keys/email@domain.com.key
2025/02/08 17:08:59 [DEBUG] GET https://acme-v02.api.letsencrypt.org/directory
2025/02/08 17:09:00 Please review the TOS at https://letsencrypt.org/documents/LE-SA-v1.4-April-3-2024.pdf
Do you accept the TOS? Y/n
Y
2025/02/08 17:09:03 [INFO] acme: Registering account for email@domain.com
2025/02/08 17:09:03 [DEBUG] HEAD https://acme-v02.api.letsencrypt.org/acme/new-nonce
2025/02/08 17:09:04 [DEBUG] POST https://acme-v02.api.letsencrypt.org/acme/new-acct
!!!! HEADS UP !!!!

Your account credentials have been saved in your Let's Encrypt
configuration directory at "/Users/ICH/.lego/accounts".

You should make a secure backup of this folder now. This
configuration directory will also contain certificates and
private keys obtained from Let's Encrypt so making regular
backups of this folder is ideal.
2025/02/08 17:09:04 [INFO] [FilemakerServer.domain.com] acme: Obtaining bundled SAN certificate
2025/02/08 17:09:04 [DEBUG] POST https://acme-v02.api.letsencrypt.org/acme/new-order
2025/02/08 17:09:04 [DEBUG] POST https://acme-v02.api.letsencrypt.org/acme/authz/22165/472925
2025/02/08 17:09:04 [INFO] [FilemakerServer.domain.com] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz/225/4725
2025/02/08 17:09:04 [INFO] [FilemakerServer.domain.com] acme: Could not find solver for: tls-alpn-01
2025/02/08 17:09:04 [INFO] [FilemakerServer.domain.com] acme: Could not find solver for: http-01
2025/02/08 17:09:04 [INFO] [FilemakerServer.domain.com] acme: use dns-01 solver
2025/02/08 17:09:04 [INFO] [FilemakerServer.domain.com] acme: Preparing to solve DNS-01
2025/02/08 17:09:05 [INFO] [FilemakerServer.domain.com] acme: Trying to solve DNS-01
2025/02/08 17:09:05 [INFO] [FilemakerServer.domain.com] acme: Checking DNS record propagation. [nameservers=1.1.1.1:53,9.9.9.9:53]
2025/02/08 17:09:07 [INFO] Wait for propagation [timeout: 2m0s, interval: 2s]
2025/02/08 17:09:07 [INFO] [FilemakerServer.domain.com] acme: Waiting for DNS record propagation.
2025/02/08 17:09:10 [INFO] [FilemakerServer.domain.com] acme: Waiting for DNS record propagation.
2025/02/08 17:09:12 [INFO] [FilemakerServer.domain.com] acme: Waiting for DNS record propagation.
2025/02/08 17:09:14 [INFO] [FilemakerServer.domain.com] acme: Waiting for DNS record propagation.
2025/02/08 17:09:16 [INFO] [FilemakerServer.domain.com] acme: Waiting for DNS record propagation.
2025/02/08 17:09:18 [INFO] [FilemakerServer.domain.com] acme: Waiting for DNS record propagation.
2025/02/08 17:09:20 [DEBUG] POST https://acme-v02.api.letsencrypt.org/acme/chall/2265/425/0EHnPw
2025/02/08 17:09:20 [DEBUG] POST https://acme-v02.api.letsencrypt.org/acme/authz/225/47725
2025/02/08 17:09:24 [DEBUG] POST https://acme-v02.api.letsencrypt.org/acme/authz/2217165/47293725
2025/02/08 17:09:24 [INFO] [FilemakerServer.domain.com] The server validated our request
2025/02/08 17:09:24 [INFO] [FilemakerServer.domain.com] acme: Cleaning DNS-01 challenge
2025/02/08 17:09:25 [INFO] [FilemakerServer.domain.com] acme: Validations succeeded; requesting certificates
2025/02/08 17:09:25 [DEBUG] POST https://acme-v02.api.letsencrypt.org/acme/finalize/225/3525
2025/02/08 17:09:27 [DEBUG] POST https://acme-v02.api.letsencrypt.org/acme/cert/03c4c0
2025/02/08 17:09:27 [DEBUG] POST https://acme-v02.api.letsencrypt.org/acme/cert/03c4c0/1
2025/02/08 17:09:27 [INFO] [FilemakerServer.domain.com] Server responded with a certificate.

Das Zertifikat muss für den Import in den Ordner des Filemaker Servers kopiert werden und die Rechte müssen gesetzt werden, sonst klappt auch der Import von der Admin-Console nicht.

cp ~/.lego/certificates/*.crt /Library/FileMaker\ Server/CStore/
cp ~/.lego/certificates/*.key /Library/FileMaker\ Server/CStore/
chmod 640 /Library/FileMaker\ Server/CStore/*.crt
chmod 640 /Library/FileMaker\ Server/CStore/*.key
chown fmserver:fmsadmin /Library/FileMaker\ Server/CStore/*.crt
chown fmserver:fmsadmin /Library/FileMaker\ Server/CStore/*.key

Zertifikat automatisch erneuern

nano ~/lego-renew.sh

Dieses Script wird bei mir 1x / Woche ausgeführt. Es prüft, ob das Zertifikat erneuert werden muss. Wenn es erneuter wird, dann wird im Anschluss das Script lego-hook.sh ausgeführt.

#!/bin/sh

PATH="/Users/ICH"
DOMAIN="FilemakerServer.domain.com"
EMAIL="email@domain.com"
# mein Hetzner Api-Key
KEY="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
LOGFILE="/tmp/legorenew.log"

cd ${PATH}
HETZNER_API_KEY=${KEY} /opt/homebrew/bin/lego --email ${EMAIL} --dns hetzner -d ${DOMAIN} renew --renew-hook=${PATH}/lego-hook.sh

So sieht die Ausgabe aus, wenn das Zertifikat nicht erneuert werden muss.

./lego-renew.sh
2025/02/08 17:23:59 [DEBUG] GET https://acme-v02.api.letsencrypt.org/directory
2025/02/08 17:23:59 [DEBUG] GET https://acme-v02.api.letsencrypt.org/draft-ietf-acme-ari-03/renewalInfo/ky....._TA
2025/02/08 17:24:00 [INFO] [FilemakerServer.domain.com] acme: renewalInfo endpoint indicates that renewal is not needed
2025/02/08 17:24:00 [FilemakerServer.domain.com] The certificate expires in 89 days, the number of days defined to perform the renewal is 30: no renewal.
das Skript für den Hook
nano ~/lego-hook.sh
#!/bin/sh

# Dieses Skript wird nur ausgeführt, wenn das Skript
# lego-renew.sh die Zertifikate erneuert hat.

DOMAIN="FilemakerServer.domain.com"
SERVER_PATH="/Library/FileMaker Server/"
# Benutzername/Pass vom Filemaker-Admin
USER="ICH"
PASS="xxxxxx-xxxxx-xxxxxx"
LOGFILE="/tmp/legorenew.log"
# der Ort wo lego das Zertifikat abgelegt hat
certfile="/Users/ICH/.lego/certificates/${DOMAIN}.crt"
keyfile="/Users/ICH/.lego/certificates/${DOMAIN}.key"

# Das Zertifikat in den Order für Filemaker Server kopieren
cp "/Users/ICH/.lego/certificates/${DOMAIN}.crt" "${SERVER_PATH}CStore/${DOMAIN}.crt"
cp "/Users/ICH/.lego/certificates/${DOMAIN}.key" "${SERVER_PATH}CStore/${DOMAIN}.key"

# Die Rechte für den Filemaker Server setzen
chmod 640 "${SERVER_PATH}CStore/${DOMAIN}.crt"
chmod 640 "${SERVER_PATH}CStore/${DOMAIN}.key"
chown fmserver:fmsadmin "${SERVER_PATH}CStore/${DOMAIN}.crt"
chown fmserver:fmsadmin "${SERVER_PATH}CStore/${DOMAIN}.key"

# Das Zertifikat in den Filemaker Server importieren
fmsadmin certificate delete -y -u "${USER}" -p "${PASS}"
fmsadmin certificate import "${SERVER_PATH}CStore/${DOMAIN}.crt" --keyfile "${SERVER_PATH}CStore/${DOMAIN}.key" -y -u "${USER}" -p "${PASS}"  >> "${LOGFILE}"

# Den Filemaker Server neustarten
launchctl stop com.filemaker.fms
sleep 60
launchctl start com.filemaker.fms

Die Skripte bewegen und Rechte setzen

cd ~/
sudo mv lego-*.sh /usr/local/bin/
sudo chown root:wheel /usr/local/bin/lego-*.sh
sudo chmod 750 /usr/local/bin/lego-*.sh

ln -s /usr/local/bin/lego-hook.sh
ln -s /usr/local/bin/lego-renew.sh

LaunchDaemon

Jeden Samstag früh um 4:29 Uhr soll lego-renew.sh das Zertifikat prüfen, ggf. erneuern und mittels lego-hook.sh das Zertifikat in den Filemaker Server laden und diesen dann neu starten.

sudo nano /Library/LaunchDaemons/com.filemaker.fmcertrenew.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>EnvironmentVariables</key>
    <dict>
        <key>PATH</key>
        <string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin</string>
    </dict>
    <key>Label</key>
    <string>com.filemaker.fmcertrenew</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/sh</string>
        <string>/usr/local/bin/lego-renew.sh</string>
    </array>
    <key>RunAtLoad</key>
    <false/>
    <key>AbandonProcessGroup</key>
    <true/>
    <key>StartCalendarInterval</key>
    <array>
        <dict>
            <key>Hour</key>
            <integer>4</integer>
            <key>Minute</key>
            <integer>29</integer>
            <key>Weekday</key>
            <integer>6</integer>
        </dict>
    </array>
</dict>
</plist>