GioJSdocs
On this page

[server.tls]

Terminate TLS in the GioJS server itself, from a PEM certificate chain and private key.

gio.toml
[server]
port = 443

[server.tls]
enabled = true
cert_path = "/etc/letsencrypt/live/example.com/fullchain.pem"
key_path  = "/etc/letsencrypt/live/example.com/privkey.pem"

TLS is off by default: most deployments terminate it in a reverse proxy, load balancer or CDN. Turn it on when the server faces clients directly.

Reference

KeyDefaultDescription
enabledbooleanfalseServe HTTPS on [server] host and port. The listener then speaks only TLS: there is no second port for plain HTTP and no redirect from it.0 / false / empty: Plain HTTP
cert_pathstring-The certificate chain, PEM-encoded: the server certificate first, then the intermediates (a Let's Encrypt fullchain.pem). Required when enabled = true.
key_pathstring-The private key, PEM-encoded: PKCS#8 (BEGIN PRIVATE KEY), PKCS#1 RSA (BEGIN RSA PRIVATE KEY) or SEC1 EC (BEGIN EC PRIVATE KEY). Required when enabled = true.

Relative paths resolve against the directory the server is started from, not the project root; absolute paths avoid surprises. The handshake deadline is [server] tls_handshake_timeout_secs (10 seconds).

Behavior

  • The certificate and key are loaded and checked at startup, before the Node worker starts. Any problem stops the server, and giojs-server --check-config reports the same error without starting it.
  • TLS 1.2 and 1.3 are accepted, and ALPN offers h2 and http/1.1.
  • With TLS on, every response carries Strict-Transport-Security: max-age=31536000 unless [security] hsts says otherwise, requests that reach the server directly have the scheme https (req.scheme, ctx.scheme), and /_gio/health reports "tls": true.

Errors

Startup stops with one of these after giojs-server: configuration error::

MessageCause
TLS enabled but cert_path not set in gio.tomlenabled = true without cert_path (key_path likewise).
TLS enabled but cert not found at <path>The file cannot be opened (key not found for the key).
Failed to parse cert at <path>: ...A PEM block in the certificate file is malformed (Failed to parse key for the key).
No private key found at <path>The key file holds no PKCS#8, PKCS#1 or SEC1 key (a certificate passed as the key, a file that is not PEM).
Invalid TLS certificate/key: ...The key does not match the certificate, the certificate is unusable, or the certificate file holds no certificate at all (Invalid TLS certificate/key: peer sent no certificates).

Examples

A self-signed certificate for local HTTPS

bash
openssl req -x509 -newkey rsa:2048 -nodes -days 30 \
  -keyout certs/key.pem -out certs/cert.pem -subj "/CN=localhost"
gio.toml
[server]
host = "127.0.0.1"
port = 3443

[server.tls]
enabled = true
cert_path = "certs/cert.pem"   # relative to the directory the server starts in
key_path  = "certs/key.pem"
bash
curl -k https://127.0.0.1:3443/_gio/health
# {"cacheEntries":0,...,"status":"ok","tls":true,...}

TLS terminated by a proxy

Leave [server.tls] off, trust the proxy so its X-Forwarded-Proto: https counts, and send HSTS yourself - GioJS cannot see that the site is HTTPS-only:

gio.toml
[server]
trusted_proxies = ["127.0.0.1"]

[security]
hsts = true

Good to know

  • The certificate is read once, at startup. After renewing it (certbot, acme.sh), restart the server.
  • A plain http:// request to the TLS port fails the handshake; nothing redirects it. Put a redirecting proxy on port 80 if you need one.
  • The handshake offers h2 and http/1.1 in ALPN, or only http/1.1 with [server] http2 = false.
  • Binding port 443 needs privileges: run behind a proxy, grant the binary CAP_NET_BIND_SERVICE, or map the port in your container runtime.

Not configurable

  • Protocol versions (TLS 1.2 and 1.3) and cipher suites are rustls' safe defaults.
  • Client certificates (mutual TLS) are not requested.

Version history

VersionChanges
v0.1.0-beta.8The certificate and key are checked at startup before the worker starts, every problem is reported at once, and --check-config runs the same check. HSTS is sent by default while TLS is on. [server] http2 = false drops h2 from ALPN (it used to be offered anyway, and clients that picked it could not connect).
v0.1.0-beta.1Introduced.