# The Other Dude — Apache reverse proxy example # # Required modules: # a2enmod proxy proxy_http proxy_wstunnel rewrite ssl headers # # This config assumes: # - TOD frontend runs on FRONTEND_HOST:3000 # - TOD API runs on API_HOST:8001 # - WinBox worker Xpra ports are on WORKER_HOST:10100-10119 # # Replace tod.example.com and upstream addresses with your values. ServerName tod.example.com RewriteEngine On RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L] ServerName tod.example.com SSLEngine on SSLCertificateFile /etc/ssl/certs/tod.example.com.pem SSLCertificateKeyFile /etc/ssl/private/tod.example.com.key # ── Security headers ────────────────────────────────────────────── Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Content-Type-Options "nosniff" Header always set X-XSS-Protection "1; mode=block" Header always set Referrer-Policy "strict-origin-when-cross-origin" # ── Xpra (Remote WinBox) ───────────────────────────────────────── # Must appear BEFORE the general proxy rules. # WebSocket upgrade is required. Do NOT enable mod_deflate on this path # — compressing WebSocket binary frames corrupts Xpra mouse/keyboard data. # # ProxyPassMatch uses regex to capture the port and forward to the worker. # Ports 10100-10119 (up to 20 concurrent sessions). RewriteEngine On # WebSocket upgrade for Xpra RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteRule ^/xpra/(\d+)/(.*)$ ws://YOUR_TOD_HOST:$1/$2 [P,L] # Regular HTTP requests for Xpra HTML5 client assets ProxyPassMatch "^/xpra/(\d+)/(.*)" "http://YOUR_TOD_HOST:$1/$2" # Relaxed CSP for Xpra HTML5 client (inline scripts + eval) Header always set Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval' ws: wss: data: blob:; frame-ancestors 'self';" SetEnv no-gzip 1 # ── API ─────────────────────────────────────────────────────────── ProxyPass /api/ http://YOUR_TOD_HOST:8001/api/ ProxyPassReverse /api/ http://YOUR_TOD_HOST:8001/api/ ProxyTimeout 300 RequestHeader set X-Forwarded-Proto "https" # Let the API set its own CSP Header unset Content-Security-Policy # ── Frontend (SPA) ──────────────────────────────────────────────── ProxyPass / http://YOUR_TOD_HOST:3000/ ProxyPassReverse / http://YOUR_TOD_HOST:3000/ ProxyPreserveHost On