SSL
Last updated
Operator workflow? See SSL Manager, Panel Certificate. Tenant workflow? See SSL (User). This page covers the underlying certificate model.
Let’s Encrypt is the default. HTTP-01 challenge runs over the domain’s existing port-80 nginx vhost; no DNS-01. Custom (bring-your-own) certificates are supported via the CLI — see below.
Per-domain certificates
Toggle SSL on a domain (admin: Domains → Edit → SSL; user: Domains → Edit → SSL). The reconciler:
- Verifies the domain resolves to one of the server’s IPs (or to the configured listen IP for that domain).
- Calls certbot via the agent with
--webrootagainst the live nginx vhost. - Stores the cert under
/etc/letsencrypt/live/<domain>/. - Reloads nginx.
Issuance latency: ≤60 s typical. Failures retry every 3 hours (reconciler interval).
Renewal
certbot’s own systemd timer renews. The agent’s deploy-hook reloads nginx automatically. No human action.
Panel-hostname certificate
The panel itself runs on a Let’s Encrypt cert for the Panel Hostname (Server Settings → General). Cert lives in the singleton panel_certificate table; the agent’s ssl.panel.issue action handles issuance via the same HTTP-01 path (with a /.well-known/acme-challenge/ location on the panel-hostname nginx vhost). Deploy hook reloads nginx → panel-api → Bulwark in that order.
If issuance fails, the panel falls back to a self-signed cert so the UI stays reachable; the SSL card in Server Settings shows the failure reason. Hit “Retry” or wait for the next reconciler tick.
Cross-user view (admin)
/jabali-admin/ssl lists every cert known to the panel, expiry, last issuance result. Per-row “Retry” forces a fresh attempt.
Common failure modes
| Symptom | Cause | Fix |
|---|---|---|
Failed authorization procedure | Domain does not resolve to this server | Update DNS at the registrar; wait propagation; retry. |
urn:ietf:params:acme:error:rateLimited | Hit LE rate limit | Wait the window (typically 1 hour). |
| Cert issued but browser shows old cert | nginx not reloaded | systemctl reload nginx or trigger reconciler. |
| Panel cert never issues | Bulwark serving on :80 | Reconciler should fix; check journalctl -u jabali-agent -f. |
Custom (bring-your-own) certificates
For domains covered by a wildcard cert issued outside Jabali, or an EV cert from a specific CA, install the certificate manually:
jabali cert set-custom --domain <fqdn> --cert /path/fullchain.pem --key /path/privkey.pem
The reconciler stores the cert alongside Let’s Encrypt-issued certs, updates the nginx vhost, and reloads. Custom certs are not auto-renewed — set a calendar reminder before expiry and re-run set-custom with the new file. To go back to Let’s Encrypt, run jabali ssl renew <domain>; the ACME client will overwrite the custom cert on the next successful issuance.
CLI
jabali ssl list [--user <id>]
jabali ssl enable <domain> # toggle on; reconciler does the rest
jabali ssl disable <domain>
jabali ssl renew <domain> # synchronous renew via agent
jabali cert set-custom # install a bring-your-own certificate