Handling TLS certs on Fedora IoT with acme.sh
If you're running Fedora IoT (or Fedora CoreOS outside of Kubenetes) then you'll need to run your ACME client within a container if you want free auto-updating TLS certificates.
One option for doing this is acme.sh. It wasn't obvious to me how this was expected to work, hence these notes. My primary resources were:
Note that I perform all of the following as the root user (see Shortcomings of Rootless Podman), because one of my uses for the certs is nginx bound to port 443.
Firstly we'll need to create a volume that acme.sh can write to and any certificate-consuming applications can read from:
  podman volume create acme-certs
…then we can run acme.sh and point it at our volume (the :z option when specifying the volume applies an SELinux label denoting shared content):
    # Only needed for the first run:
  podman run --rm -it -v acme-certs:/acme.sh:z \
    docker.io/neilpang/acme.sh --register-account -m inbox@example.comOnce the initial registration is done you should be able to issue certs:
  podman run --rm -it -v acme-certs:/acme.sh:z \
    -e GANDI_LIVEDNS_KEY=api-key-gibberish \
    docker.io/neilpang/acme.sh \
    --issue --dns dns_gandi_livedns -d host.example.comIn this example I'm using Gandi LiveDNS for verification, the acme.sh DNS API supports many providers so probably yours is in there.
Assuming the certificate issue operation succeeds you will see output like this:
  Your cert is in: /acme.sh/host.example.com/host.example.com.cer
  Your cert key is in: /acme.sh/host.example.com/host.example.com.key
  The intermediate CA cert is in: /acme.sh/host.example.com/ca.cer
  And the full chain certs is there: /acme.sh/host.example.com/fullchain.cerTake note of the names/paths as you'll need them when configuring whichever consuming applications you'll use.
Now all that's left is to automate certificate renewal. I've done this with a systemd timer because everything in Fedora IoT is unit files already, but it works just as well via cron.
  cat <<EOF > /etc/systemd/system/acme-certs.service
  [Unit]
  Description=Renew TLS certificates via acme.sh
  After=network.target
  [Service]
  Type=simple
  ExecStart=podman run --rm -it -v acme-certs:/acme.sh:z \
      -e GANDI_LIVEDNS_KEY=api-key-gibberish \
      docker.io/neilpang/acme.sh --cron
  EOF
  cat <<EOF > /etc/systemd/system/acme-certs.timer
  [Unit]
  Description=Check and renew TLS certificates daily
  [Timer]
  OnCalendar=daily
  Persistent=true
  [Install]
  WantedBy=timers.target
  EOF
  systemctl daemon-reload
  # test manually
  systemctl start acme-certs.service
  journalctl --unit acme-certs.service
  # enable the timer
  systemctl enable acme-certs.timer
  systemctl start acme-certs.timer
  systemctl status acme-certs.timer acme-certs.service