[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
| Key | Default | Description |
|---|---|---|
enabledboolean | false | Serve 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. |
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-configreports the same error without starting it. - TLS 1.2 and 1.3 are accepted, and ALPN offers
h2andhttp/1.1. - With TLS on, every response carries
Strict-Transport-Security: max-age=31536000unless[security] hstssays otherwise, requests that reach the server directly have the schemehttps(req.scheme,ctx.scheme), and/_gio/healthreports"tls": true.
Errors
Startup stops with one of these after giojs-server: configuration error::
| Message | Cause |
|---|---|
TLS enabled but cert_path not set in gio.toml | enabled = 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 = trueGood 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
h2andhttp/1.1in ALPN, or onlyhttp/1.1with[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.
Related
[server]-tls_handshake_timeout_secsand the listen address[security] hsts- Proxies, Sizing & Scaling
- Production Checklist
Version history
| Version | Changes |
|---|---|
v0.1.0-beta.8 | The 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.1 | Introduced. |