Guides

HTTPS

How hostnames reach apps, and where TLS is terminated.

[proxy.http] in config.toml is the host's one HTTP listener. It routes each request by the hostname it carries to the httpPort of the app that names that hostname:

"hostnames": [{ "hostname": "app-1.example.com", "kind": "platform" }]

kind is platform or custom: a label for whatever writes the document, routed the same. An app nothing outside needs to reach by name has an empty hostnames.

A request for a sleeping app wakes it. A document that names a hostname on a host with no [proxy.http] is refused by name, and the instance is reported failed saying so. The reference is every key under [proxy].

Behind an edge

The installer writes plain HTTP, which is what a host behind an edge that terminates TLS — Cloudflare, a load balancer, a reverse proxy of your own — wants:

[proxy.http]
listen_address = "0.0.0.0"
port = 80

TLS on this host

Add [proxy.http.tls] with a certificate and key, both PEM:

[proxy.http]
listen_address = "0.0.0.0"
port = 443

[proxy.http.tls]
certificate = "/etc/nibrunner/tls/origin.crt"
key = "/etc/nibrunner/tls/origin.key"
  • One certificate covers the whole host. There is no SNI selection, so every hostname an app holds must be covered by it — a wildcard, in practice, which matches one label deep: app.example.com but not a.b.example.com.
  • The daemon does not obtain certificates. ACME and renewal belong to certbot or to the edge. The files are read once, at startup, so a renewed certificate needs systemctl restart nibrunnerd — which stops no app.
  • There is one listener, not a plain one and a TLS one. Nothing redirects, so two would serve every app both ways forever.

Only through the edge

Add [proxy.http.tls.client_ca] to require a client certificate on every handshake. On an origin whose IP is discoverable, this is what keeps it reachable only through the edge:

[proxy.http.tls.client_ca]
certificate = "/etc/nibrunner/tls/origin-pull-ca.pem"

certificate is a PEM holding every certificate the pool trusts. You cannot reach the host yourself without one, so turn this on after the plain path is proven.

Good to know

A connection whose handshake named one app and whose request names another gets a 421. That is what keeps two apps that share a certificate apart.

On this page