Skip to content

Linux service targets

Agent 1.5.0 and later can deploy a renewed certificate to HAProxy, Caddy, Traefik, LiteSpeed, Postfix, Dovecot, PostgreSQL and MySQL on Linux, in addition to the NGINX, Apache httpd and Tomcat types of the terminal interface.

Not run on a real Linux host yet

The starter hooks were tested with generated scripts, golden files and stand-in commands, not run as root on a real Linux host against these services. Read the generated script before the first renewal and try it on a test host.

How it works

The Agent service runs unprivileged: it cannot write into /etc/haproxy or reload a service itself. For these targets it uses the root hook runner:

  1. The Agent saves the certificate as PEM files with an unencrypted key into its own folder (one the service may write; the terminal interface prepares it).
  2. A hook.run step asks the root hook runner to run the starter hook /etc/certintel/hooks.d/certintel-<kind>.sh (owned by root:root, mode 0700).
  3. The hook installs the files where the service reads them, with the service's owner, group and mode, runs the configuration test and reloads the service.

The hook is an ordinary shell script; the paths, owner, group, mode and commands are written into it and you can edit them. The configuration test runs before the reload, so a mistake stops the script and the running service keeps its current certificate. An existing hook is never replaced: to start again, remove it first. Its output is in journalctl -t certintel-agent-hooks.

Targets

$ID stands for the certificate ID ($CERTINTEL_CERTIFICATE_ID). The paths are the defaults the terminal interface fills in; change them to what your service reads.

Kind Installed files (default) Owner:group Key / certificate mode Configuration test Reload
haproxy /etc/haproxy/certs/$ID.pem (one combined file: full chain and key) root:haproxy 0640 haproxy -c -f /etc/haproxy/haproxy.cfg systemctl reload haproxy
caddy /etc/caddy/certs/$ID.crt, $ID.key caddy:caddy 0600 / 0644 caddy validate --config /etc/caddy/Caddyfile systemctl reload caddy
traefik /etc/traefik/certs/$ID.crt, $ID.key root:traefik 0640 / 0640 none none - Traefik's file provider picks up the new files by itself
litespeed /usr/local/lsws/conf/$ID.crt, $ID.key lsadm:lsadm 0600 / 0600 /usr/local/lsws/bin/openlitespeed -t (when present) /usr/local/lsws/bin/lswsctrl restart (graceful)
postfix /etc/postfix/certintel-fullchain.pem, certintel-key.pem root:root 0600 / 0644 postfix check postfix reload
dovecot /etc/dovecot/certintel-fullchain.pem, certintel-key.pem root:root 0600 / 0600 doveconf -n doveadm reload
postgresql /etc/postgresql/certintel-server.crt, certintel-server.key postgres:postgres 0600 / 0644 none systemctl reload postgresql
mysql /etc/mysql/certintel-cert.pem (certificate only), certintel-key.pem, certintel-ca.pem (chain) mysql:mysql 0600 / 0600 none mysql --protocol=socket -e "ALTER INSTANCE RELOAD TLS" (MySQL 8.0.16 and later), or systemctl restart mysql

The files must not be writable by other users; the hook builder refuses such a mode.

Point the service at the files

The hook only installs the files. Configure the service once to read them, for example:

Kind Configuration
haproxy bind :443 ssl crt <file> (or crt <folder>)
caddy tls <certificate> <key> in the site block
traefik tls.certificates certFile/keyFile in a file-provider configuration; the provider watches it
litespeed certFile, keyFile and certChain 1 in the listener or the virtual host's vhssl block
postfix smtpd_tls_chain_files = <key>, <certificate> in main.cf
dovecot ssl_cert = <<certificate> and ssl_key = <<key> in the Dovecot configuration
postgresql ssl_cert_file and ssl_key_file in postgresql.conf
mysql ssl_cert, ssl_key and ssl_ca in the [mysqld] section

Server detection can read the current paths from an existing HAProxy or LiteSpeed configuration and pre-fill them.

In the terminal interface

Run sudo certintel tui, press a on the Workflows screen and choose the service in Type on the deployment page. The page pre-fills the target paths, owner, group, mode and the test and reload commands from the table above; you can change each one. A service type always saves an unencrypted, owner-only key, because the service cannot read a password-protected one. When you save, the terminal interface prepares the Agent's folder and writes the starter hook as root. S (post-renewal scripts) also offers each starter as Install for (certintel-.sh).

From the command line

certintel hooks starter haproxy           # print the script
sudo certintel hooks starter haproxy --write

certintel hooks starter KIND [--write] prints the starter hook certintel-KIND.sh for one of haproxy, caddy, traefik, litespeed, postfix, dovecot, postgresql or mysql, or with --write (as root) writes it to /etc/certintel/hooks.d and prints Wrote … (root:root, mode 0700). Check the paths, owner and commands in it before the first renewal. Exit codes: 0 success, 1 the script could not be written (for example script … already exists; edit it, or remove it first to start again), 2 invalid usage or not root.

Dashboard-assigned workflows

The catalogue templates haproxy-standard, caddy-standard, traefik-standard, litespeed-standard, postfix-standard, dovecot-standard, postgresql-standard and mysql-standard, shown as (starter hook), can be assigned from the dashboard. Their fields are Agent folder (the absolute folder the Agent saves the PEM files in, for example /etc/certintel/certs/haproxy), Filename prefix (default certificate) and, for HAProxy, Caddy, Traefik and LiteSpeed, Verification hostname and Verification port (443) for an endpoint check after the reload.

An assignment cannot create a script. Before you assign one of these templates, on the host:

  1. Install the starter hook: sudo certintel hooks starter KIND --write, or create the workflow once in sudo certintel tui. Until the hook exists the Agent refuses the assignment with starter hook certintel-KIND.sh is not installed; run certintel hooks starter KIND --write as root.
  2. Prepare the Agent folder so the Agent may write it, once, with sudo certintel tui. The Agent does not check this when the assignment arrives; a folder it cannot write makes the first deployment fail.

The existing nginx-standard and apache-standard catalogue templates are unchanged; for NGINX and Apache httpd prefer the terminal interface types, which reload through the hook runner.