SSH module

The SSH module copies the certificate + private key + chain to a target host using SCP/SFTP, then runs post-deployment actions (typically systemctl reload nginx or equivalent). It is the most-used distribution module and the only one with full rollback — every file we overwrite is first saved as .bak, so a rollback restores the exact previous state.

01Overview

  • Transport: SSH v2 (SCP for writes).
  • Auth: username + password, SSH private key (with or without passphrase), or TLS client certificate.
  • Path set: defines where each file goes (cert, key, chain) with ownership + mode.
  • Action set: shell commands run after writes, typically to reload the consuming service.
  • Rollback: full. Previous cert/key are kept as <path>.bak; rollback swaps them back and re-runs the action set.
  • Concurrency: per-target-group batch concurrency is capped by DistributionSSHMaxConcurrency (Settings → General).

02Prerequisites

  • An SSH module credential (key or password) saved under Settings → Distribution → Credentials.
  • Target hosts reachable from the backend. The backend's pod or VM must have SSH egress to every target.
  • A user account on each target with write permission to the cert/key directories, plus sudo (NOPASSWD) for the action set if it uses privileged commands.
  • A path set and an optional action set.

03Create an SSH target

  1. Settings → Distribution → TargetsNew.
  2. Module type: SSH.
  3. Hostname + port (default 22).
  4. Username: the account on the remote host.
  5. Credential: pick the SSH key credential you created.
  6. Host-key strategy:
    • Trust on first use (TOFU) (default) — accept the first host key seen and pin it thereafter.
    • Pinned — paste a known-good host key fingerprint. The module refuses to connect if it changes.
  7. Save → health check runs a connect + echo ok.

04Path set

A path set defines the files you want CertAutoPilot to write, with ownership and mode. Example for nginx:

/etc/nginx/ssl/{{ .cn }}.crt    root:root   0644   <cert+chain>
/etc/nginx/ssl/{{ .cn }}.key    root:root   0600   <private key>
/etc/nginx/ssl/{{ .cn }}.ca     root:root   0644   <chain only>

{{ .cn }} is a Go template variable expanded from the cert's common name. You can reference project variables (Variables) the same way. Typical practice is one path set per service template (nginx, haproxy, apache, postgres, dovecot, etc.) and reuse it across many targets.

05Action set

Actions run over SSH in sequence after every file has been written. Example:

sudo nginx -t
sudo systemctl reload nginx

Use nginx -t-style preflight to fail fast before reloading. A non-zero exit status marks the target as failed and triggers rollback if it's enabled for the distribution.

06Execute a distribution

  1. On the cert detail page → Distribution tab → Add distribution.
  2. Pick the SSH module, a target or target group, a path set, and an action set.
  3. Optionally enable validation endpoints so we confirm the cert is live post-deploy (see Validation).
  4. Click Dry-run first. The module returns the exact list of files it will write and commands it will execute, per target. Review.
  5. Execute. Progress shows per target; a green tick means files written + action set returned 0. Red means failure — open the target's log to see whether it was transport (network), credential (auth), or post-action (validation) failure.

07Rollback

SSH rollback is the gold standard:

  1. Before any overwrite, the module copies the existing file to <path>.bak.
  2. On rollback, the module swaps: <path> becomes <path>.rollback-tmp, <path>.bak becomes <path>, the temp file is deleted.
  3. The action set re-runs (most services expect a reload after cert change).

Rollback metadata is stored on the distribution (LastRollbackMeta). The UI surfaces a Rollback button when this metadata is present.

Rollback on a first-ever deploy

If a distribution was the first one to put a cert at the configured path (no prior file), rollback will delete the cert rather than restore — there is no .bak to swap in. The service's reload will then fail, which is usually what you want (it surfaces the rollback clearly).

08Troubleshooting

SSH auth fails despite a valid key

Permission issue on the remote side. The user needs write on the path-set directories and passwordless sudo on the action-set commands. Check ~/.ssh/authorized_keys contains the right public key and the sudoers entry is specific enough.

Host key mismatch after a rebuild

You rebuilt the target VM and the host key changed. If you were using TOFU, clear the pinned fingerprint on the target detail page; if pinned, paste the new fingerprint (and verify it out-of-band).

Action set times out

Long-running reload (systemd's default is 90 s). Edit the action set timeout on the distribution; the action will be killed and the target marked failed if it exceeds.