Files
RustProxy/docs/ACME_PROVIDERS.md
2026-10-23 13:07:11 +02:00

89 lines
9.4 KiB
Markdown

# 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.
On Linux, the updated DEB/RPM service allows **read-only** access to
external certificate paths according to the `rustproxy` user's Unix group/
ACL permissions, including paths inside `/home`. A separate safety rule still
requires the actual PEM files and real parent directories to be owned by root
or `rustproxy`; user-owned `/home/alice` is therefore unsuitable as a PEM
ancestor even though it can host a Web Server document root. See
[Installation: external paths](INSTALL.md#linux-debrpm-read-only-access-to-external-paths)
for scoped ACLs and Certbot renewal handling.
## 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
```
### Permission commands and automatic SNI names
Select **External files (absolute paths)** and enter both paths. A permission-command block is generated **below the certificate and private-key fields** and changes as the paths change. It uses the supplied paths, resolves symlink targets on the server when run, removes group/other write permission on the resolved PEM files and other-user read permission on the private key, then grants traversal of the relevant parent directories and read access to the files for `rustproxy`. Install the Linux `acl` tools if needed and review/run the commands as an administrator on that server. The panel generates commands; it does not execute them or change filesystem ownership.
The paths must be absolute, without `.`/`..` components or control characters, and resolve to existing regular files when the commands run. For a custom deployment, change **Service user** under **Options and help** before copying the commands; the default is `rustproxy`. This field only changes the generated instructions, not RustProxy's process identity or saved configuration.
The existing trusted-path rules still apply: real PEM files and ancestors must be owned by root or the RustProxy service user, ancestors must not be group/world-writable, and a private key must not be world-readable or group/world-writable. ACLs alone do not make an untrusted path acceptable. Container mounts and mandatory access-control rules need matching deployment settings; see [Installation](INSTALL.md#linux-debrpm-read-only-access-to-external-paths).
After a public certificate becomes readable, the editor automatically fills **Legacy SNI names** from its DNS Subject Alternative Name (SAN) entries. Wildcard SANs are retained; filenames and a certificate's Common Name are not used to invent DNS names. Inspection applies to managed certificate filenames and external paths, reads only the public PEM, and does not activate or save the certificate. The certificate/key pair is still validated when applied.
Automatic reads preserve manually edited names, intentional clearing and existing saved mappings. Results from an earlier path or form are ignored. Use **Read names from certificate** to retry after fixing filesystem permissions or to deliberately replace the current field with the certificate's names. Prefer explicit certificate assignment in the intended Vhost; auto-filled legacy SNI names do not create Vhosts or replace their assignments.
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.
- **SNI field does not auto-fill:** check the read status below the paths, grant access to the public certificate, then use **Read names from certificate**. A manually edited/cleared field is intentionally preserved until this explicit action; a certificate without DNS SAN entries supplies no names.
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).