Kalzit is in early development. These pages describe what exists today and change as the milestones progress.
HTTPS and reverse proxies
Kalzit can serve HTTPS itself, or it can sit behind a reverse proxy that handles TLS. Both work the same on Windows and Linux.
HTTPS with your own certificate
Kalzit uses rustls, so no OpenSSL is involved. Give it a certificate chain and a private key as PEM files and an HTTPS address:
[server]
http_addr = "0.0.0.0:80"
https_addr = "0.0.0.0:443"
public_url = "https://kalzit.example.com"
[tls]
cert_file = "/etc/kalzit/tls/fullchain.pem"
key_file = "/etc/kalzit/tls/privkey.pem"
What happens then:
- HTTPS offers TLS 1.2 and 1.3 (
tls.min_version = "1.3"allows only 1.3) and HTTP/2. - Plain HTTP on
http_addrredirects to HTTPS, except/healthzand/readyz. Setserver.redirect_http_to_https = falseto serve the app on both, or sethttp_addr = ""to turn plain HTTP off. - Every 60 seconds Kalzit checks whether the files changed and loads a renewed certificate without a restart. If a new file cannot be read, the old certificate stays in use and the log says why.
- HTTPS responses carry
Strict-Transport-Securityfor one year.
Automatic certificates through ACME (Let’s Encrypt) are planned for M5. Until then, renew the files with the tool of your choice; Kalzit picks them up.
HSTS is sticky. Once a browser has seen the header, it refuses plain HTTP for that host for the whole duration. While you try things out, set
security.hsts_max_age_secsto a few minutes, orsecurity.hsts = false.
Behind a reverse proxy
Let the proxy terminate TLS and keep Kalzit on plain HTTP on the loopback interface:
[server]
http_addr = "127.0.0.1:3000"
public_url = "https://kalzit.example.com"
[security]
trusted_proxies = ["127.0.0.1/32", "::1/128"]
trusted_proxies matters. Kalzit reads X-Forwarded-For, X-Forwarded-Proto and
X-Forwarded-Host only from these addresses; from everyone else the headers are ignored, so a
client cannot pretend to come from somewhere else. Without it, Kalzit sees every request as plain
HTTP from the proxy: session cookies lose the Secure flag, HSTS is not sent and the sign-in
limit counts all users as one address.
The client address is the first address in X-Forwarded-For, read from the right, that is not a
trusted proxy. Serve Kalzit at the root of its own host name; a sub-path such as /kalzit is
not supported yet.
If the proxy already sends HSTS, set security.hsts = false so the header is not sent twice.
Caddy
Caddy gets a certificate on its own and sets the forwarded headers by default:
kalzit.example.com {
reverse_proxy 127.0.0.1:3000
}
nginx
server {
listen 443 ssl;
http2 on;
server_name kalzit.example.com;
ssl_certificate /etc/ssl/kalzit/fullchain.pem;
ssl_certificate_key /etc/ssl/kalzit/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
}
}
Headers Kalzit always sends
Every response carries a Content Security Policy without inline scripts or styles,
X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, a
Permissions-Policy that turns off camera, microphone and location, and
Cross-Origin-Opener-Policy: same-origin. Requests that change data from a foreign origin are
rejected.