# Certificates, ACME providers and renewal Certificates are managed under **Certificates**. You can import a PEM pair, reference accessible external certificate files or request a managed ACME certificate. Issuing a certificate does **not** automatically assign it to a Vhost; choose the certificate in the intended frontend/Vhost afterwards. ## Supported certificate methods | Mode | Requirements | |---|---| | **HTTP-01 (Let's Encrypt)** | DNS for every name and a public TCP port **80** reaching a plaintext RustProxy listener; HTTP challenge endpoint is handled by RustProxy. | | **Cloudflare DNS-01** | A zone-limited `Zone:DNS:Edit` API token and functioning Certbot Cloudflare plugin. | | **OVH DNS-01** | Correct regional API endpoint plus application key/secret and consumer key scoped to the DNS zone. | | **RFC2136 DNS-01** | DNS server, TSIG name/secret/algorithm and an update policy restricted to the requested records. | | **PEM import** | A matching certificate chain and private key, validated before activation. | | **Existing local files** | Trusted absolute certificate/key paths accessible to the RustProxy service account. Suitable for a separately managed Certbot lineage. | HTTP-01 cannot create wildcard certificates; use DNS-01. A staging certificate is for testing and is not generally trusted by browsers. Production issuance requires explicit confirmation of the production operation and provider terms. ## First issuance and assignment 1. Open **Certificates → Add certificate** and choose the provider/import method. 2. Enter DNS names, a unique certificate ID, contact email where requested and provider-specific credentials or files. 3. For HTTP-01, confirm public DNS and HTTP port 80 reach RustProxy even when a separate public HTTPS port is active. For DNS-01, validate authoritative DNS provider and propagation permissions. 4. Run staging first when testing new credentials/DNS, then confirm production issuance deliberately. 5. Wait for the job result; inspect errors under Certificates and the service logs. 6. Assign the issued/imported certificate to the intended Vhost/listener and verify a real TLS handshake with the public hostname. In 0.34.1 DEV, expand a certificate in the Certificates inventory and use **Assign Vhosts** to check/uncheck multiple Vhosts before applying one revisioned Vhost-section save. This updates Vhost certificate mappings, not the PEM files themselves. Verify frontend listener and certificate hostname coverage separately. The reserved HTTP-01 challenge path is available only during eligible issuance/renewal work. It is not a generic public file server and does not bypass authentication for unrelated URLs. ## Managed ACME runtime RustProxy prefers a **private Certbot/Python environment** under the application data directory (typically `/var/lib/rustproxy/acme-python`), with support for the Cloudflare, OVH and RFC2136 plugins. A working system Certbot may be used as fallback; systems without a usable runtime can still import or reference PEM files. The application does not run system-wide `sudo` to install plugins or modify distribution-owned Python packages. Provider tokens and TSIG secrets are security credentials: use least privilege, protect files and the data directory, rotate compromised values and restrict backups. ACME DNS credentials may be stored in private provider/Certbot files; do not assume they are stored in the same way as RustProxy administration Secret Store records. ## Automatic renewal Managed certificates have configurable automatic renewal. RustProxy runs the scheduler while the service is active; this is **not** a separate cron service. Certificate status and next checks are visible in Certificates. The scheduler uses spaced checks and retry/backoff on failure, without automatically forcing a CA reissue on every check. After successful renewal, RustProxy validates the new pair and publishes it to new TLS handshakes without interrupting existing connections. Invalid/rejected material should leave the previous active pair in place. Keep room for archived ACME generations and monitor expiry; this is not an independent external expiry-alert service. **Do not run an overlapping system Certbot timer** against the RustProxy-managed ACME profiles. ## Externally managed Certbot / PEM files When another service owns the certificate, add a manual certificate with the actual certificate and key paths, for example: ```text /etc/letsencrypt/live/example.com/fullchain.pem /etc/letsencrypt/live/example.com/privkey.pem ``` Keep the original Certbot renewal system and use the RustProxy certificate reload/deploy API or local CLI after rotation. RustProxy resolves relevant symlinks again during reload. The service account must have directory traverse and narrow read permissions to the **current** key file; `ReadOnlyPaths` alone does not grant filesystem permission. Renewal hooks may need to reapply ACLs to replaced target files. ### Restricted certificate API Create an appropriately scoped credential in **Settings → Certificate API**. Its allowed certificate IDs and action permissions control **reload** or **deploy**; it is not a general administration token. A caller supplies both a Bearer credential and its configured `X-RustProxy-Certificate-Key` ID. Use HTTPS outside local/trusted transport and never store the clear token in the repository. See [Administration API](API.md). ## Problems to check - **HTTP-01 validation fails:** public TCP 80, all A/AAAA DNS answers, Host forwarding and challenge path handling through any CDN/router. - **DNS-01 fails:** authoritative DNS provider, correct zone, TSIG/API scope and propagation interval. - **Certificate available but wrong site certificate displayed:** Vhost assignment, listener binding, hostname and restart/reload state. - **Renewal stops:** Certbot runtime, private profile files, DNS secrets, clock skew, permissions and CA limits. - **External file reload fails:** rotated symlink targets, certificate/key match, SAN coverage and read permissions. Keep a private encrypted application backup and a separate copy of any external certificate/key material. See [Backup and recovery](BACKUP.md) and [Security](SECURITY.md).