Server Configuration

Complete server configuration reference.

Configuration File

Server configuration is stored in config.yaml. The default location is /etc/drip/config.yaml.

Configuration Options

OptionTypeDefaultDescription
portint-Server listen port (required)
domainstring-Domain for client connections (required)
tunnel_domainstringsame as domainDomain for tunnel URLs
tls_enabledbooltrueEnable TLS. When false, MUST use reverse proxy
tls_certstring-Path to TLS certificate (required if tls_enabled)
tls_keystring-Path to TLS private key (required if tls_enabled)
tokenstring-Authentication token (strongly recommended)
tcp_port_minint20000TCP tunnel port range start
tcp_port_maxint20100TCP tunnel port range end
public_portintsame as portPort displayed in URLs (for reverse proxy)
metrics_tokenstring-Token for /metrics endpoint
debugboolfalseEnable debug logging
pprof_portint-Enable pprof profiling on this port
transportslist[tcp, wss]Allowed transport protocols
tunnel_typeslist[http, https, tcp]Allowed tunnel types

Security Best Practices

Generate Strong Authentication Token

Always use a cryptographically secure random token:

bash
# Generate a 32-byte (256-bit) random token
openssl rand -hex 32

Never use:

  • Simple passwords like your-secret-token
  • Dictionary words or predictable patterns
  • Tokens shorter than 32 characters

Protect Configuration Files

bash
# Set secure permissions on config file
sudo chmod 600 /etc/drip/config.yaml
sudo chown root:root /etc/drip/config.yaml

# Or if using a dedicated user
sudo chown drip:drip /etc/drip/config.yaml

Use Separate Metrics Token

Always use a different token for metrics access:

bash
# Generate separate metrics token
openssl rand -hex 32

Restrict Tunnel Types (Production)

For production environments, consider restricting tunnel types:

yaml
# Only allow HTTP/HTTPS tunnels (no raw TCP)
tunnel_types:
  - http
  - https

Example Configurations

Minimal Secure Configuration

yaml
# /etc/drip/config.yaml
port: 443
domain: tunnel.example.com
token: a1b2c3d4e5f6...  # Use: openssl rand -hex 32
tls_enabled: true
tls_cert: /etc/letsencrypt/live/tunnel.example.com/fullchain.pem
tls_key: /etc/letsencrypt/live/tunnel.example.com/privkey.pem
tcp_port_min: 20000
tcp_port_max: 20100
metrics_token: m1e2t3r4i5c6...  # Use: openssl rand -hex 32

Production Configuration (Direct TLS)

yaml
# /etc/drip/config.yaml
# Production server with direct TLS termination

# Network
port: 443
domain: tunnel.example.com
# tunnel_domain: example.com  # Optional: use different domain for tunnel URLs

# TLS - Required for direct mode
tls_enabled: true
tls_cert: /etc/letsencrypt/live/tunnel.example.com/fullchain.pem
tls_key: /etc/letsencrypt/live/tunnel.example.com/privkey.pem

# Authentication - REQUIRED for production
# Generate with: openssl rand -hex 32
token: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6

# TCP tunnel port range
tcp_port_min: 20000
tcp_port_max: 20100

# Monitoring - Use separate token
# Generate with: openssl rand -hex 32
metrics_token: m1e2t3r4i5c6s7t8o9k0e1n2h3e4r5e6

# Security restrictions
transports:
  - tcp
  - wss
tunnel_types:
  - http
  - https
  - tcp

# Logging - disable in production unless debugging
debug: false

Production Configuration (Behind Reverse Proxy)

yaml
# /etc/drip/config.yaml
# Production server behind Caddy/Nginx reverse proxy

# Network - Internal port, Caddy/Nginx handles 443
port: 8443
domain: tunnel.example.com
public_port: 443  # Port shown in tunnel URLs

# TLS disabled - Reverse proxy handles TLS termination
# WARNING: Only use behind a trusted reverse proxy!
tls_enabled: false

# Authentication - REQUIRED
# Generate with: openssl rand -hex 32
token: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6

# TCP tunnel port range (exposed directly, not through proxy)
tcp_port_min: 20000
tcp_port_max: 20100

# Monitoring
metrics_token: m1e2t3r4i5c6s7t8o9k0e1n2h3e4r5e6

# Security restrictions
transports:
  - tcp
  - wss
tunnel_types:
  - http
  - https
  - tcp

debug: false

High-Security Configuration

yaml
# /etc/drip/config.yaml
# Maximum security configuration

port: 443
domain: tunnel.example.com

tls_enabled: true
tls_cert: /etc/letsencrypt/live/tunnel.example.com/fullchain.pem
tls_key: /etc/letsencrypt/live/tunnel.example.com/privkey.pem

# Strong authentication token (64 chars recommended)
token: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a1b2c3d4e5f6g7h8

# Minimal TCP port range
tcp_port_min: 20000
tcp_port_max: 20100

# Separate metrics token
metrics_token: m1e2t3r4i5c6s7t8o9k0e1n2h3e4r5e6m1e2t3r4i5c6s7t8o9k0

# Restrict to HTTP/HTTPS only (no raw TCP tunnels)
tunnel_types:
  - http
  - https

# Allow both transports
transports:
  - tcp
  - wss

debug: false
# pprof_port: 6060  # Only enable for debugging, never in production

Separate Domain Configuration

When you want the client connection domain and tunnel URL domain to be different, use the tunnel_domain configuration.

Use cases:

  • Clients connect to the server via tunnel.example.com
  • Tunnel URLs use a shorter domain like *.example.com
yaml
# /etc/drip/config.yaml
# Separate domain configuration example

port: 443

# Client connection domain - clients use this address to connect to the server
# Client config: drip config set --server tunnel.example.com:443
domain: tunnel.example.com

# Tunnel URL domain - public access address for tunnels
# Generated tunnel URLs will be: https://myapp.example.com
tunnel_domain: example.com

tls_enabled: true
tls_cert: /etc/letsencrypt/live/example.com/fullchain.pem
tls_key: /etc/letsencrypt/live/example.com/privkey.pem

token: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6

tcp_port_min: 20000
tcp_port_max: 20100

DNS Configuration Requirements:

# Client connection domain
tunnel.example.com    A    your-server-ip

# Tunnel URL domain (wildcard)
*.example.com         A    your-server-ip

SSL Certificate Requirements:

The certificate must cover both domains:

bash
sudo certbot certonly --manual --preferred-challenges dns \
  -d "example.com" -d "*.example.com" -d "tunnel.example.com"

Workflow:

  1. Client connects to tunnel.example.com:443
  2. When creating a tunnel, requests subdomain myapp
  3. Server returns tunnel URL: https://myapp.example.com
  4. External users access the tunnel via https://myapp.example.com

URL Routing Behavior:

URL AccessedResult
tunnel.example.comShows Drip home page
myapp.example.comProxies to registered tunnel myapp
unknown.example.comShows 404 - Tunnel Not Found
example.comShows 404 - Tunnel Not Found
other.comShows 404 - Tunnel Not Found

Environment Variables

All configuration options can be set via environment variables with the DRIP_ prefix:

VariableDescription
DRIP_PORTServer port
DRIP_PUBLIC_PORTPublic port for URLs
DRIP_DOMAINServer domain
DRIP_TUNNEL_DOMAINTunnel domain
DRIP_TOKENAuthentication token
DRIP_TLS_ENABLEDEnable TLS (true/false)
DRIP_TLS_CERTTLS certificate path
DRIP_TLS_KEYTLS private key path
DRIP_TCP_PORT_MINMin TCP port
DRIP_TCP_PORT_MAXMax TCP port
DRIP_METRICS_TOKENMetrics endpoint token
DRIP_DEBUGEnable debug logging
DRIP_PPROF_PORTPprof profiling port

Priority: Command flags > Environment variables > Config file

Using Environment File (Recommended for Secrets)

Create /etc/drip/server.env:

bash
# /etc/drip/server.env
DRIP_TOKEN=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6
DRIP_METRICS_TOKEN=m1e2t3r4i5c6s7t8o9k0e1n2h3e4r5e6

Secure the file:

bash
sudo chmod 600 /etc/drip/server.env
sudo chown drip:drip /etc/drip/server.env

Reference in systemd service:

ini
[Service]
EnvironmentFile=/etc/drip/server.env

Server Endpoints

EndpointPurposeAuth Required
/healthHealth check (returns 200 OK)No
/statsServer statistics (JSON)Yes (metrics-token)
/metricsPrometheus metricsYes (metrics-token)

Accessing Metrics

bash
# Health check (no auth)
curl https://tunnel.example.com/health

# Server stats (requires metrics token)
curl -H "Authorization: Bearer YOUR_METRICS_TOKEN" \
  https://tunnel.example.com/stats

# Prometheus metrics (requires metrics token)
curl -H "Authorization: Bearer YOUR_METRICS_TOKEN" \
  https://tunnel.example.com/metrics

Rate Limiting

The server enforces rate limits to prevent abuse:

LimitDefault
Tunnel registrations per IP per minute10
Maximum tunnels per IP10
Maximum total tunnels1000

TLS Configuration

When tls_enabled: true, Drip uses TLS 1.3 exclusively with modern cipher suites:

  • TLS_AES_128_GCM_SHA256
  • TLS_AES_256_GCM_SHA384
  • TLS_CHACHA20_POLY1305_SHA256

Legacy TLS versions (1.0, 1.1, 1.2) are not supported.


Security Checklist

Before deploying to production, verify:

  • [ ] Authentication token is randomly generated (32+ chars)
  • [ ] Metrics token is different from auth token
  • [ ] Config file permissions are 600 (owner read/write only)
  • [ ] TLS is enabled OR server is behind a trusted reverse proxy
  • [ ] Firewall only allows necessary ports (443, TCP range)
  • [ ] Debug mode is disabled
  • [ ] pprof is disabled (or restricted to localhost)
  • [ ] Tunnel types are restricted if raw TCP is not needed