-
-
Notifications
You must be signed in to change notification settings - Fork 0
Security and Networking
Kanfei is designed for trusted LAN and self-hosted environments. It includes built-in session and API key authentication (see Authentication Model below), but does not include a TLS termination layer — HTTPS is expected to be provided at the infrastructure level via a reverse proxy. This page covers the authentication design, TLS setup, and hardening guidance.
Kanfei serves HTTP on port 8000 by default. All traffic — including API responses containing configuration values, bot tokens, and API keys — is transmitted in cleartext. On a trusted, isolated LAN segment this may be acceptable, but any of the following situations require TLS:
- The Kanfei host is reachable from untrusted networks
- The LAN segment has untrusted devices or users
- Bot tokens, nowcast API keys, or upload credentials are configured
- Remote access is needed (VPN, Tailscale, Cloudflare Tunnel, etc.)
The recommended approach is a reverse proxy that terminates TLS in front of Kanfei.
Option A: Caddy (automatic TLS)
Caddy automatically obtains and renews Let's Encrypt certificates. This is the simplest path if you have a public domain name pointed at the host. See the Caddy docs for installation and configuration details.
weather.example.com {
reverse_proxy localhost:8000
}
Caddy handles HTTPS redirect, HSTS, certificate renewal, and WebSocket upgrade automatically. No additional configuration needed for /ws/live.
For LAN-only with a self-signed cert:
https://192.168.12.39 {
tls internal
reverse_proxy localhost:8000
}
Option B: nginx
server {
listen 80;
server_name weather.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name weather.example.com;
ssl_certificate /etc/letsencrypt/live/weather.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/weather.example.com/privkey.pem;
# HSTS — enable after confirming HTTPS works
# add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ws/live {
proxy_pass http://127.0.0.1:8000/ws/live;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400s;
}
}Use certbot to obtain and renew Let's Encrypt certificates. See the nginx reverse proxy docs for more on proxying and WebSocket support.
After enabling HTTPS:
- Verify the dashboard loads over
https:// - Verify live data updates work (WebSocket at
wss://) - Verify the session cookie (
knf_session) is emitted with theSecureflag — it is set automatically when the app detects HTTPS (directly or viaX-Forwarded-Protoheader from the proxy) - Enable HSTS once stable (
Strict-Transport-Securityheader) - If using bots, confirm outbound connections (Telegram/Discord) still work — they connect outbound to platform servers, not through the proxy
- Update any bookmarks or integrations that reference
http://
Default app bind is 0.0.0.0:8000.
Recommendations:
- Restrict inbound access at firewall/router to trusted source IPs.
- Use a reverse proxy with TLS (see above).
- Do not expose the raw app port directly to the internet.
- Bind to
127.0.0.1:8000if the reverse proxy runs on the same host — this prevents direct access to the unencrypted port.
Sensitive values include:
- Bot tokens (
bot_telegram_token,bot_discord_token) - API keys (
anthropic_admin_api_key,nowcast_remote_api_key, WU keys) - Station identifiers and callsigns (context-dependent)
Handling guidance:
- Restrict filesystem permissions on
.envand the SQLite database - Avoid sharing full config exports publicly
- Rotate keys immediately if leaked
- Bot tokens are redacted from API error responses, but are stored in plaintext in the database — protect database file access
Kanfei uses a two-tier API model:
| Tier | Auth | Examples |
|---|---|---|
| Public | None |
/api/current, /api/history, /api/forecast, /api/astronomy, /api/nowcast (GET), /api/metar, /api/aprs, /api/public/weather, /api/station (GET), /api/setup/status, /ws/live
|
| Admin | Required |
/api/config, /api/backup/*, /api/db-admin/*, /api/setup/probe, /api/setup/complete, /api/setup/reconnect, /api/telegram/*, /api/discord/*, /api/station/sync-time, /api/logs/*, /api/auth/* (except login/setup-admin) |
Browser-based access uses a session cookie:
-
Cookie name:
knf_session -
Attributes:
HttpOnly,SameSite=Lax,Secure(when HTTPS detected via scheme orX-Forwarded-Proto) - Expiry: 72-hour sliding window (extends on each authenticated request)
- Credentials are bcrypt-hashed; the admin account is created during the setup wizard
For scripts and integrations, generate API keys from the Settings UI:
- Format:
knf_prefix + 43-character token (47 characters total) - Passed via
Authorization: Bearer knf_...header - Full key is shown once at creation and never retrievable again (SHA-256 hash stored)
- Keys can be revoked from the Settings UI
GET /api/config masks sensitive values (bot tokens, API keys, upload credentials). Full values are accepted on write but never echoed back.
For internet-facing deployments, consider layering additional controls at the proxy boundary:
- VPN (WireGuard, Tailscale)
- SSO proxy (Authelia, Authentik, oauth2-proxy)
- IP allowlisting at the firewall
Baseline host hardening:
- Run under a non-root service user
- Keep OS and dependencies patched
- Minimize open ports
- Isolate service account privileges
-
Serial stations: Grant device access via group membership (for example
dialouton Debian/Ubuntu). Do not run broad privileged processes unnecessarily. - Network stations: Ensure the station's network port is accessible from the Kanfei host. Consider isolating IoT/weather station devices on a dedicated VLAN or subnet with appropriate firewall rules.
Primary at-rest data:
- Weather/time-series database (SQLite)
- Configuration values in
station_config(includes bot tokens and API keys) - Optional custom asset uploads
Recommendations:
- Encrypted disk or encrypted backup target
- Regular backup validation restores
- Retention policies to limit unnecessary data growth
- Use service manager restarts for crash recovery
- Keep backup/restore steps documented and tested
- Monitor critical endpoints (
/api/station,/api/current) for freshness