Skip to content

Server Configuration

FlagDefaultDescription
-http0.0.0.0:8080Bind address and port for the admin web UI
-tcp0.0.0.0:9000Bind address and port for client TCP connections
-db./woho.dbPath to the SQLite database file
FlagDefaultDescription
-rp-idlocalhostRelying Party ID — the domain where Woho is hosted
-rp-origin(derived)Full origin URL including protocol, e.g. https://admin.example.com

The client tunnel on port 9000 has no default transport. The server must start with either TLS or explicit plaintext mode.

FlagDefaultDescription
-tls-certWOHO_TLS_CERTPEM certificate for the agent tunnel
-tls-keyWOHO_TLS_KEYPEM private key for the agent tunnel
-tunnel-insecurefalseRun the agent tunnel without TLS; clients must also use -insecure
FlagDescription
-versionPrint version information and exit
-helpPrint help message and exit
Terminal window
# Minimal (development / local use)
woho-server -http :8080 -tcp :9000 -db /var/lib/woho/woho.db -tunnel-insecure
# Full production configuration
woho-server \
-http 0.0.0.0:8080 \
-tcp 0.0.0.0:9000 \
-db /var/lib/woho/woho.db \
-rp-id admin.example.com \
-rp-origin https://admin.example.com \
-tls-cert /etc/letsencrypt/live/admin.example.com/fullchain.pem \
-tls-key /etc/letsencrypt/live/admin.example.com/privkey.pem
# Listen on a specific interface only
woho-server -http 192.168.1.100:8080 -tcp 192.168.1.100:9000 -tunnel-insecure

VariableValuesDescription
DEV_MODEtrue, 1Enable development mode
TRUSTED_PROXY_CIDRSComma-separated CIDRsTrust X-Forwarded-For and X-Real-IP only from these direct proxy IP ranges
WOHO_TLS_CERTFile pathDefault value for -tls-cert
WOHO_TLS_KEYFile pathDefault value for -tls-key
WOHO_TUNNEL_INSECUREtrueDefault value for -tunnel-insecure

Development mode effects:

  • Disables minified asset bundles (uses individual JS files)
  • Enables source maps
  • Verbose logging
  • Disables secure cookies (allows HTTP)
Terminal window
DEV_MODE=true woho-server -http :8080 -tcp :9000 -tunnel-insecure

For a local nginx proxy, trust only the loopback peer. Add ::1/128 if nginx connects over IPv6.

Terminal window
TRUSTED_PROXY_CIDRS=127.0.0.1/32 woho-server -http 127.0.0.1:8080 -tcp :9000

The admin web UI and the client tunnel are separate. HTTPS for the admin UI is usually handled by nginx. The tunnel on port 9000 is configured directly in Woho.

Use a certificate that matches the hostname clients connect to:

Terminal window
woho-server \
-http 127.0.0.1:8080 \
-tcp 0.0.0.0:9000 \
-db /var/lib/woho/woho.db \
-tls-cert /etc/letsencrypt/live/admin.example.com/fullchain.pem \
-tls-key /etc/letsencrypt/live/admin.example.com/privkey.pem

Clients need no extra TLS option when the certificate is publicly trusted.

Use plaintext only for local testing or a fully trusted private network:

Terminal window
woho-server -http :8080 -tcp :9000 -db /var/lib/woho/woho.db -tunnel-insecure

Every client must also use -insecure when connecting to this server. Without -tunnel-insecure, the server exits instead of silently running an unencrypted tunnel.


Passwordless authentication using hardware security keys, platform authenticators (Windows Hello, Touch ID), or passkeys.

  1. -rp-id must be a domain name — IP addresses are not supported.
  2. -rp-id must match (or be a parent of) the origin domain.
  3. HTTPS is required in production — WebAuthn only works in a secure context.
Terminal window
# Domain matches exactly
-rp-id admin.example.com -rp-origin https://admin.example.com
# Parent domain (credentials work on all subdomains)
-rp-id example.com -rp-origin https://admin.example.com
# Non-standard port
-rp-id admin.example.com -rp-origin https://admin.example.com:8443
Terminal window
# ❌ IP address not allowed
-rp-id 192.168.1.100 -rp-origin https://192.168.1.100
# ❌ Domain mismatch
-rp-id other.com -rp-origin https://admin.example.com

Woho uses SQLite (woho.db). The database is created automatically on first start with schema migrations and a bootstrap admin user. The generated password is printed once in the server log.

Terminal window
# Backup while the server is running
sqlite3 /var/lib/woho/woho.db ".backup /backup/woho-$(date +%Y%m%d).db"
# Recover space after bulk deletes
sqlite3 /var/lib/woho/woho.db "VACUUM;"
# Check integrity
sqlite3 /var/lib/woho/woho.db "PRAGMA integrity_check;"

To expose Woho over HTTPS, place it behind nginx:

server {
listen 443 ssl;
server_name admin.example.com;
ssl_certificate /etc/letsencrypt/live/admin.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/admin.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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_read_timeout 3600s;
}
}

Set TRUSTED_PROXY_CIDRS to the IP range of your reverse proxy. Woho then uses proxy headers for login rate limits and the activity log. For X-Forwarded-For, it reads from the right and uses the first address that is not a trusted proxy, so client-supplied prefixes are ignored.

If TRUSTED_PROXY_CIDRS is empty, Woho ignores proxy headers and uses the direct TCP peer address.

The TCP client port (9000) must stay directly accessible; it cannot go through a standard HTTP reverse proxy.


  • Change the generated admin password immediately after first login
  • Configure tunnel TLS with -tls-cert and -tls-key, or explicitly choose -tunnel-insecure for local testing
  • Use HTTPS (nginx + Let’s Encrypt) for the admin panel
  • Bind TCP to a specific interface if clients are on a private network
  • Enable Pre-Shared Keys when deploying to untrusted networks
  • Register a passkey / WebAuthn credential for your admin account
  • Set TRUSTED_PROXY_CIDRS when the admin panel is behind a reverse proxy
  • Restrict access to port 8080 via firewall (allow only trusted IPs)