Skip to content

SSL/TLS Configuration

Ingress supports SSL/TLS termination, allowing you to serve HTTPS traffic and terminate TLS connections at the proxy level.

HTTPS Configuration

To enable HTTPS, configure the https section in your configuration file:

yaml
version: v1
port: 8080

https:
  port: 8443
  ssl:
    - domain: example.com
      cert:
        certificate: /path/to/certificate.pem
        certificate_key: /path/to/private-key.pem
    - domain: api.example.com
      cert:
        certificate: /path/to/api-certificate.pem
        certificate_key: /path/to/api-private-key.pem

Configuration Fields

FieldTypeDescription
portintHTTPS port to listen on (default: 8443)
enable_http3boolEnable HTTP/3 (QUIC) on UDP when TLS is configured
http3_portintUDP port for HTTP/3; omit or 0 to use the same port as HTTPS (TCP and UDP)
http3_altsvc_max_ageintAlt-Svc response header ma= in seconds; 0 uses a server default; negative omits Alt-Svc
redirect_from_http.disabledboolDisable forced HTTP -> HTTPS redirect (false by default, which means enabled when HTTPS is configured)
redirect_from_http.permanentboolUse 301 when true, 302 when false
redirect_from_http.exclude_pathsarrayExact request paths that should skip forced redirect
sslarrayArray of SSL certificate configurations

SSL Certificate Configuration

Each SSL entry requires:

FieldTypeDescription
domainstringDomain name for the certificate
cert.certificatestringPath to the certificate file (PEM format)
cert.certificate_keystringPath to the private key file (PEM format)

HTTP/2 and HTTP/3

  • HTTP/2 over TLS: When HTTPS is enabled, the server negotiates HTTP/2 via ALPN (h2) where the client supports it. No extra YAML is required.
  • Cleartext HTTP/2 (h2c): Set top-level enable_h2c: true to serve HTTP/2 without TLS on the plain HTTP port. Use only on trusted networks (for example behind a terminating proxy that speaks h2c to the backend).
  • HTTP/3: Set https.enable_http3: true. The process listens for QUIC on UDP (same port as HTTPS by default, or https.http3_port). HTTPS responses can include an Alt-Svc header so clients upgrade to HTTP/3; tune or disable with https.http3_altsvc_max_age. Ensure firewalls allow UDP to the chosen port.

Example with HTTP/3:

yaml
port: 8080

https:
  port: 443
  enable_http3: true
  # http3_port: 443
  # http3_altsvc_max_age: 86400
  ssl:
    - domain: example.com
      cert:
        certificate: /path/to/fullchain.pem
        certificate_key: /path/to/privkey.pem

Zoox may also apply ENABLE_H2C, ENABLE_HTTP3, HTTP3_PORT, and HTTP3_ALTSVC_MAX_AGE from the environment when the corresponding config fields are unset.

Certificate Formats

Ingress expects certificates in PEM format. Both the certificate and private key should be in PEM format:

-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----

Multiple Domains

You can configure multiple SSL certificates for different domains:

yaml
https:
  port: 8443
  ssl:
    - domain: example.com
      cert:
        certificate: /etc/ssl/example.com/fullchain.pem
        certificate_key: /etc/ssl/example.com/privkey.pem
    - domain: api.example.com
      cert:
        certificate: /etc/ssl/api.example.com/fullchain.pem
        certificate_key: /etc/ssl/api.example.com/privkey.pem
    - domain: admin.example.com
      cert:
        certificate: /etc/ssl/admin.example.com/fullchain.pem
        certificate_key: /etc/ssl/admin.example.com/privkey.pem

Certificate File Paths

Certificate files can be specified using:

  • Absolute paths: /etc/ssl/example.com/cert.pem
  • Relative paths: Relative to the working directory when Ingress starts

Make sure Ingress has read permissions for the certificate files.

Using Let's Encrypt

You can use certificates from Let's Encrypt. Typically, Let's Encrypt certificates are stored in locations like:

yaml
https:
  port: 8443
  ssl:
    - domain: example.com
      cert:
        certificate: /etc/letsencrypt/live/example.com/fullchain.pem
        certificate_key: /etc/letsencrypt/live/example.com/privkey.pem

Certificate Reloading

When you update certificate files, you can reload the configuration without restarting:

bash
# Send SIGHUP signal
kill -HUP $(cat /tmp/gozoox.ingress.pid)

# Or use the reload command
ingress reload

Ingress will reload the certificates from the configured paths.

HTTP to HTTPS Redirect

To force global HTTP -> HTTPS redirects, configure https.redirect_from_http:

yaml
https:
  port: 443
  redirect_from_http:
    # disabled: false
    permanent: true
    # exclude_paths:
    #   - /healthz
  ssl:
    - domain: example.com
      cert:
        certificate: /path/to/fullchain.pem
        certificate_key: /path/to/privkey.pem

Behavior:

  • Redirect applies before route matching.
  • Redirect is enabled by default when https.port is configured (unless redirect_from_http.disabled: true).
  • The redirect keeps original host/path/query by default.
  • When https.port is not 443, the redirect URL includes that port.
  • Requests already identified as HTTPS (TLS or X-Forwarded-Proto: https) are not redirected.
  • Paths listed in exclude_paths are matched exactly and skip forced redirect.

For route-specific redirects, continue using rules[].backend.redirect.

SNI (Server Name Indication)

Ingress supports SNI, allowing it to serve different certificates for different domains on the same port. The certificate is selected based on the domain name in the TLS handshake.

Backend Communication

When Ingress terminates TLS and forwards to backend services:

  • Backend services can use HTTP (no TLS required)
  • The original protocol information is preserved in headers like X-Forwarded-Proto: https
  • Backend services can still use HTTPS if needed

Example configuration:

yaml
https:
  port: 8443
  ssl:
    - domain: example.com
      cert:
        certificate: /path/to/cert.pem
        certificate_key: /path/to/key.pem

rules:
  - host: example.com
    backend:
      service:
        name: backend-service
        port: 8080
        protocol: http  # Backend uses HTTP, TLS terminated at Ingress

Security Best Practices

  1. Use Strong Cipher Suites: Ensure your certificates use strong encryption
  2. Keep Certificates Updated: Regularly renew certificates before expiration
  3. Use Valid Certificates: Avoid self-signed certificates in production
  4. Secure Private Keys: Protect private key files with appropriate permissions (e.g., 600)
  5. TLS Version: Use TLS 1.2 or higher
  6. Certificate Chain: Include the full certificate chain in the certificate file
  7. Monitor Expiration: Set up alerts for certificate expiration

Troubleshooting

Certificate Not Loading

  • Verify certificate file paths are correct
  • Check file permissions (Ingress needs read access)
  • Ensure certificates are in PEM format
  • Check certificate file syntax

Certificate Mismatch

  • Verify the domain in the certificate matches the request domain
  • Check that SNI is working correctly
  • Ensure the certificate hasn't expired

Connection Refused

  • Verify the HTTPS port is not already in use
  • Check firewall rules allow traffic on the HTTPS port
  • Ensure Ingress is listening on the correct port

Released under the MIT License.