From 2637fb516b9d768293e9eb0e59cd33c984925233 Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Sat, 14 Feb 2026 08:03:27 +0100 Subject: [PATCH] fix(haproxy): Add waf_bypass option for WebSocket-heavy apps Streamlit apps require WebSocket connections that mitmproxy WAF doesn't handle properly. Added waf_bypass UCI option to allow specific vhosts to route directly to backends while other services still get WAF protection. - Add waf_bypass option check in haproxyctl - Vhosts with waf_bypass=1 skip mitmproxy_inspector - Fixes blank page issue with Streamlit apps Co-Authored-By: Claude Opus 4.5 --- .claude/HISTORY.md | 29 +++++++++++++++++++ .../files/usr/sbin/haproxyctl | 6 ++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/.claude/HISTORY.md b/.claude/HISTORY.md index b9e10f76..44f3dad2 100644 --- a/.claude/HISTORY.md +++ b/.claude/HISTORY.md @@ -1420,3 +1420,32 @@ _Last updated: 2026-02-11_ - **Login Issue Resolution**: - Form field is `username` not `email` (GoToSocial quirk) - Admin user: `admin@secubox.in` / `TestAdmin123!` + +## 2026-02-14: Fixed Streamlit apps + WAF compatibility + +### Problem +- Streamlit apps showing blank page with loading spinner when accessed via public URLs +- Direct access to backends (192.168.255.1:xxxx) worked fine +- Issue was mitmproxy WAF not handling WebSocket connections properly + +### Root Cause +- HAProxy `waf_enabled=1` routed ALL vhosts through `mitmproxy_inspector` backend +- mitmproxy's `haproxy_router` addon wasn't properly handling WebSocket upgrade connections +- WebSocket connections disconnected immediately, breaking Streamlit's real-time UI + +### Solution +1. Added `waf_bypass` option to `/usr/sbin/haproxyctl`: + - Vhosts with `waf_bypass=1` route directly to their backends + - Other vhosts still go through mitmproxy WAF +2. Set `waf_bypass=1` for Streamlit vhosts (yling, bazi, bweep, bweek, wuyun, pix, hermes, evolution, control) +3. Updated haproxy_router.py addon with WebSocket event handlers (for future improvement) + +### Files Modified +- `/usr/sbin/haproxyctl` - Added waf_bypass option check +- `/srv/mitmproxy-in/addons/haproxy_router.py` - Added WebSocket handlers +- `/srv/lxc/mitmproxy-in/config` - Enabled HAPROXY_ROUTER_ENABLED=1 + +### Result +- Streamlit apps work with full WebSocket support +- Other services still protected by mitmproxy WAF +- Hybrid approach balances security and functionality diff --git a/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxyctl b/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxyctl index 4134d843..571e9f35 100644 --- a/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxyctl +++ b/package/secubox/secubox-app-haproxy/files/usr/sbin/haproxyctl @@ -723,7 +723,8 @@ _emit_sorted_path_acls() { # Generate use_backend rule (use WAF backend if enabled) local effective_backend="$backend" - [ "$waf_enabled" = "1" ] && effective_backend="$waf_backend" + config_get waf_bypass "$section" waf_bypass "0" + [ "$waf_enabled" = "1" ] && [ "$waf_bypass" != "1" ] && effective_backend="$waf_backend" if [ -n "$host_acl_name" ]; then echo " use_backend $effective_backend if host_${host_acl_name} ${acl_name}" else @@ -788,7 +789,8 @@ _add_vhost_acl() { esac # Use WAF backend if enabled, otherwise use original backend local effective_backend="$backend" - [ "$waf_enabled" = "1" ] && effective_backend="$waf_backend" + config_get waf_bypass "$section" waf_bypass "0" + [ "$waf_enabled" = "1" ] && [ "$waf_bypass" != "1" ] && effective_backend="$waf_backend" echo " use_backend $effective_backend if host_${acl_name}" }