TLS / HTTPS
Configuration

TLS / HTTPS

Put a reverse proxy in front of Drevnix to terminate TLS. Examples for nginx, Caddy, and Traefik.

Using an AI assistant? Give it this file.

/llms.md is a single Markdown file covering installation, configuration, quickstart, clients, upstreams, permissions, TLS, and production deployment. Copy it and paste it into your AI chat, or tell the AI to fetch https://drevnix.tech/llms.md.

TLS / HTTPS

Drevnix does not terminate TLS itself. Run a reverse proxy in front of it to handle certificates and HTTPS.

Only the proxy port (:8000) typically needs to be public-facing. The portal (:8001) and REST API (:8002) should be accessible via VPN or internal network only.

nginx

server {
    listen 443 ssl;
    server_name drevnix.company.com;

    ssl_certificate     /etc/ssl/certs/drevnix.crt;
    ssl_certificate_key /etc/ssl/private/drevnix.key;

    # Docker layer downloads can be very large — disable buffering
    proxy_buffering         off;
    proxy_request_buffering off;
    client_max_body_size    0;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

# Redirect HTTP to HTTPS
server {
    listen 80;
    server_name drevnix.company.com;
    return 301 https://$host$request_uri;
}

The proxy_buffering off and client_max_body_size 0 settings are important. Docker image layers can be gigabytes in size and will time out or fail if buffered.

Caddy

drevnix.company.com {
    reverse_proxy localhost:8000 {
        header_up X-Forwarded-For {remote_host}
        flush_interval -1
    }
}

Caddy automatically obtains and renews TLS certificates from Let’s Encrypt. The flush_interval -1 setting disables response buffering, which is required for large layer downloads.

Traefik (Docker labels)

labels:
  - "traefik.enable=true"
  - "traefik.http.routers.drevnix.rule=Host(`drevnix.company.com`)"
  - "traefik.http.routers.drevnix.entrypoints=websecure"
  - "traefik.http.routers.drevnix.tls.certresolver=letsencrypt"
  - "traefik.http.services.drevnix.loadbalancer.server.port=8000"
  - "traefik.http.services.drevnix.loadbalancer.responseForwarding.flushInterval=1ms"

X-Forwarded-For and real client IPs

When Drevnix runs behind a reverse proxy, the TCP remote address it sees is the proxy’s IP, not the original client. This affects audit log client_ip entries and rate limiting buckets (five failed logins from “the proxy IP” is not useful).

TRUSTED_PROXIES controls how Drevnix resolves the real client IP. Getting this wrong means audit logs show proxy IPs instead of real clients, and rate limiting misfires. Set it correctly before going to production.

Which value should I use?

  1. Is Drevnix directly reachable from the internet — no firewall, load balancer, or proxy in front of it? → Yes: leave TRUSTED_PROXIES unset. Done. → No: continue.

  2. Do you need to restrict which specific proxy IPs are trusted?No (most deployments): set TRUSTED_PROXIES=* — correct for nginx, Traefik, Caddy, AWS ALB, GCP LB, Hetzner LB, Cloudflare, or any chain of proxies, as long as Drevnix is not directly internet-reachable. → Yes: set TRUSTED_PROXIES to a comma-separated list of your proxy CIDRs.

ValueWhen to use
unsetApp exposed directly to the internet, no proxy
*App behind any proxy/LB, not directly internet-reachable
10.0.0.0/8,...You need precise per-CIDR proxy trust

Unset (default)X-Forwarded-For is ignored. remote-addr is always used as the client IP. Safe for direct deployments — no configuration needed, spoofed headers have no effect.

Wildcard (*)X-Forwarded-For is always trusted. The leftmost token is used as the client IP, falling back to remote-addr if the header is absent.

TRUSTED_PROXIES=*

Only use * when Drevnix is not directly reachable from the internet. If it is, any client can forge their IP via X-Forwarded-For. Enforce this at the network level: firewall or security group should only allow inbound traffic from your proxy.

CIDR listX-Forwarded-For is trusted only when remote-addr falls within one of the specified ranges. Otherwise remote-addr is used directly. Accepts a comma-separated list of IPv4 or IPv6 CIDR ranges. A single host is /32 (IPv4) or /128 (IPv6).

TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12

Whitespace around entries is ignored. A malformed CIDR causes a startup error rather than silently failing mid-request.

Behavior matrix:

ScenarioTRUSTED_PROXIESTCP remote addrX-Forwarded-ForIP used
Direct deploymentunset1.2.3.49.9.9.9 (spoofed)1.2.3.4
Direct deploymentunset1.2.3.4absent1.2.3.4
Behind proxy (wildcard)*10.0.0.1 (proxy)1.2.3.4 (client)1.2.3.4
Behind proxy (wildcard), no XFF*10.0.0.1absent10.0.0.1
Behind proxy (CIDR)10.0.0.0/810.0.0.1 (proxy)1.2.3.4 (client)1.2.3.4
Behind proxy, multi-hop10.0.0.0/810.0.0.11.2.3.4, 10.0.0.21.2.3.4
Behind proxy, no XFF header10.0.0.0/810.0.0.1absent10.0.0.1
Untrusted remote10.0.0.0/85.5.5.59.9.9.9 (spoofed)5.5.5.5

TRUSTED_PROXIES applies to portal login, proxy auth, and REST API auth — all three use the same IP resolution, so one setting covers the entire application.

Exposing portal and API over HTTPS

If you need remote access to the portal or REST API, put them behind the same reverse proxy on a separate subdomain or path, and restrict access with IP allowlisting or mTLS at the proxy level.