CERMM/wiki>

Deploy

Behind a reverse proxy

A proxy with a real certificate (Let's Encrypt) in front of CERMM for browsers, while CERMM keeps its own HTTPS for the LAN and the agents.

How it fits together

  • People open https://cermm.example.com, served by the proxy (Nginx Proxy Manager, Caddy, Traefik, nginx) with its own certificate.
  • The proxy forwards to CERMM's port, over http:// or https://.
  • Agents keep talking to CERMM directly on its LAN address, with the key they pinned. Nothing changes for them.

Set it up in CERMM

Settings → Security → Connection → Reverse proxy. Two things:

  1. Its public address, like https://cermm.example.com. Links in notifications use it.
  2. The proxy's IP addresses, as CERMM sees them connect.

Only requests from those addresses are believed when they say, through X-Forwarded-Proto, X-Forwarded-For and X-Forwarded-Host, that they came over HTTPS, from whom and to which name. Anyone else could write those headers to get round the sign-in limits. If an address you haven't trusted sends them, the setting shows it with Trust: most likely that's your proxy.

Until the proxy is trusted, sign-in limits count the proxy instead of each person, and a proxy forwarding to plain HTTP loops back to the HTTPS address.

Proxy examples

A starting point; change the names and addresses. The proxy must send X-Forwarded-Proto and X-Forwarded-For (Nginx Proxy Manager, Caddy and Traefik do by default).

Caddy

cermm.example.com {
	reverse_proxy 192.168.1.10:4800
}

nginx

server {
    listen 443 ssl;
    server_name cermm.example.com;
    # ssl_certificate and ssl_certificate_key: your Let's Encrypt files

    location / {
        proxy_pass http://192.168.1.10:4800;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_read_timeout 1h;   # live output and the terminal keep a request open
    }
}

Every CERMM response says X-Accel-Buffering: no, so nginx doesn't hold back live job output.

The wiki and the website

CERMM serves this wiki on port 8471 and the website (cermm.it) on port 8470, so a proxy can put each at its own name with nothing else installed. In Caddy, with CERMM at 192.168.0.74:

wiki.cermm.it {
	encode zstd gzip
	reverse_proxy 192.168.0.74:8471
	header {
		Strict-Transport-Security "max-age=31536000"
		-Server
	}
}

cermm.it {
	encode zstd gzip
	reverse_proxy 192.168.0.74:8470
	header {
		Strict-Transport-Security "max-age=31536000"
		-Server
	}
}

A git pull in the checkout updates both; nothing to restart.

CERMM_TRUST_PROXY=1

The older, blunter way: set CERMM_TRUST_PROXY=1 (and CERMM_URL to the public address) in /etc/default/cermm. It believes those headers from every address and turns CERMM's own HTTPS off, so agents then talk to the proxy and check its certificate the usual way. Use it only when nothing but the proxy can reach CERMM's port.

# /etc/default/cermm
CERMM_TRUST_PROXY=1
CERMM_URL=https://cermm.example.com

CERMM is in development. Something here wrong or out of date? Tell us or fix it.