Certificates
Configure certificates for GoDoxy
TL;DR
- Main certificate covers all domains in
autocert.domains - Extra certificates can be configured for additional domains
- SNI selection: exact match > wildcard match, main cert > extra cert
- Managed by
lego(ACME) with DNS-01; auto-issued and auto-renewed - Bring your own certificate with
provider: local - Short alias vs FQDN determines how domains match
match_domainsrestricts which base domains are valid- TCP on HTTPS: stream routes listening on the configured
HTTPS_ADDRare matched by TLS SNI (same rules as HTTP). Withouttls_termination, bytes are forwarded unchanged; withtls_termination: trueandautocert, Godoxy terminates TLS and proxies plaintext to the upstream TCP port. Registration rejects TLS termination when no autocert provider is configured
Certificates
-
Main certificate covers every domain in
autocert.domains -
Extra certificates can be added via the
extrafield for additional domains -
Based on SNI (Server Name Indication) from the client's TLS handshake
- Exact match > wildcard match (e.g.,
app.example.comexact beats*.example.comwildcard) - Main cert > extra certificates when both match
- Falls back to main cert if no match
- Exact match > wildcard match (e.g.,
-
Issued/managed by
legousing ACME, typically Let's Encrypt via DNS-01 -
Auto-issue/renew with 1-hour cooldown after failures. Renewal happens when:
autocertis enabled but no certs are present- The set of
autocert.domainsno longer matches the loaded certificate - The certificate will expire within 30 days
TCP stream routes on the HTTPS listener
TCP routes whose listen address is the HTTPS entrypoint share the same TLS socket as the web UI and reverse proxies. GoDoxy inspects the ClientHello SNI to pick the stream route, using the same naming rules as HTTP routes:
- Short alias: if SNI is
mqtt.example.comand the route key ismqtt, the first label (mqtt) can select that route when it is registered under that name. - FQDN: the full normalized hostname can match the route when that is how the route is keyed.
Passthrough (default) — After SNI matching, the encrypted stream is forwarded as-is to host:port. Use this when the upstream speaks TLS (for example the upstream terminates HTTPS).
Termination — Set tls_termination: true only on a TCP route listening on the configured shared HTTPS_ADDR. Route validation rejects other listeners, and SNI route registration rejects TLS termination unless an operational autocert provider exists. GoDoxy matches ClientHello SNI, completes the TLS handshake using autocert, then proxies a plaintext TCP connection to the configured upstream. Leave tls_termination disabled for SNI passthrough when autocert is absent or when the upstream should serve its own certificate.
Extra Certificates
-
Must specify unique
cert_pathandkey_path(no duplicates) -
Inherit all configuration from the main config (except
extra) -
Participate in ACME cycles independently
-
Selected via SNI when the client's requested domain matches (exact or wildcard)
-
Main certificate takes precedence when both match
Autocert Configuration
| Field | Type | Default | Required | Description |
|---|---|---|---|---|
provider | string | local | Yes | Certificate / DNS-01 provider |
email | string | - | Yes | ACME email |
domains | array | - | Yes | Certificate domains |
options | object | - | provider != local | Provider-specific options |
resolvers | array | - | No | DNS resolvers |
cert_path | string | certs/cert.crt | No | Certificate file path |
key_path | string | certs/priv.key | No | Private key file path |
extra | array | - | No | Additional certificates |
ca_dir_url | string | - | No | CA directory URL |
ca_certs | array | - | No | CA certificates to use |
eab_kid | string | - | No | EAB Key ID |
eab_hmac | string | - | No | Base64 encoded EAB¹ HMAC |
certificate_key_type | string | EC256 | No | Private key algorithm for ACME-issued leaf certs (lego Certificate.KeyType) |
- EAB refers to External Account Binding.
certificate_key_type applies only when GoDoxy obtains or renews the certificate via ACME (not for provider: local static files). Default is elliptic curve P-256 (EC256). Allowed values: EC256, EC384, RSA2048, RSA3072, RSA4096, RSA8192 (case-insensitive). Aliases: P256 / P384 for EC, and bare sizes 2048, 3072, 4096, 8192 for RSA. Invalid values are rejected during config validation. On an extra entry, a non-empty certificate_key_type overrides the main autocert setting for that certificate’s lego config.
Using Existing SSL Certificate
autocert:
provider: local
# path relative to /app
cert_path: certs/cert.crt
key_path: certs/priv.keyAutocert with Cloudflare
Use certificate_key_type when you need an RSA leaf (for example clients without ECDSA, such as some IoT TLS stacks). See the table above for all allowed values.
autocert:
provider: cloudflare
email: your-email@example.com
domains:
- "*.yourdomain.com"
# certificate_key_type: RSA2048
options:
auth_token: your-zone-api-tokenAutocert with a Custom Internal CA
You may use internal CA like step-ca for issuing certificates.
Use step-ca as an example:
export ACME_URL=https://acme.internal
# get root certs and save to `certs/roots.pem`
# assume that `certs/` is mounted to `/app/certs` (by default)
curl -k https://${ACME_URL}/roots.pem > certs/roots.pemautocert:
provider: custom
email: your-email@example.com
domains:
- "*.yourdomain.com"
ca_dir_url: https://acme.internal/acme/acme/directory
ca_certs:
- certs/roots.pemEAB
If using EAB (External Account Binding), set eab_kid and eab_hmac in autocert. Also works with custom ACME CAs.
autocert:
provider: custom
email: your-email@example.com
domains:
- "*.yourdomain.com"
eab_kid: your-eab-kid
eab_hmac: base64-encoded-hmacMultiple Certificates with SNI
Configure multiple certificates for different domains. GoDoxy uses SNI to select the appropriate certificate during TLS handshake.
domains is ignored for local provider.Example: Multiple certificates with different providers
autocert:
provider: cloudflare
email: your-email@example.com
domains:
- "*.example.com"
options:
auth_token: your-zone-api-token
extra:
# Extra cert 1: Same provider, different domain
- cert_path: certs/other.crt
key_path: certs/other.key
domains:
- "*.other.com"
# Inherits provider, email, options from main config
# Extra cert 2: Different provider (custom CA)
- cert_path: certs/internal.crt
key_path: certs/internal.key
provider: custom
# certificate_key_type: RSA2048 # optional; overrides main autocert when set
domains:
- "*.internal.local"
ca_dir_url: https://ca.internal/acme/directory
# Extra cert 3: Local/static certificate
- cert_path: certs/static.crt
key_path: certs/static.key
provider: local
domains:
- "*.services.internal"
# Static certificate, no ACME obtain/renewSNI Selection Behavior:
Based on the example above, certificate selection works as follows:
| Hostname | Selected Certificate | Match Type |
|---|---|---|
app.example.com | Main cert | Exact match (*.example.com) |
sub.example.com | Main cert | Wildcard match (*.example.com) |
api.other.com | Extra cert 1 | Wildcard match (*.other.com) |
service.internal.local | Extra cert 2 | Wildcard match (*.internal.local) |
db.services.internal | Extra cert 3 | Wildcard match (*.services.internal) |
unknown.com | Main cert (fallback) | No match |
Selection Precedence:
- Exact match > wildcard match
- Main cert > extra certificates when both match
- Falls back to main cert if no match
Other DNS providers
Check DNS-01 Providers
Troubleshooting
If you encounter issues:
- Set
LEGO_DISABLE_CNAME_SUPPORT=1if your domain has a CNAME record - Try different DNS resolvers via
autocert.resolvers