From 0dd6b28d1a5fae072a5d6b61a3c4b3d64f86a5aa Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Sat, 31 Jan 2026 16:17:29 +0100 Subject: [PATCH] fix(mitmproxy): Fix HAProxy backend route sync for new-style UCI configs The sync-routes command was failing to generate routes for most vhosts due to: - Subshell bug: pipe in while loop caused variable changes to be lost - Only supported old-style backends (inline .server field) - Did not support new-style backends with separate =server sections Changes: - Rewrite sync-routes to avoid subshell by using temp file - Add support for both backend styles (inline and separate server sections) - Use original_backend field when vhosts are in inspection mode - Skip luci/fallback/mitmproxy_inspector backends in route generation Now properly generates 13+ routes for HAProxy backend inspection. Co-Authored-By: Claude Opus 4.5 --- .../root/www/secubox-feed/Packages | 138 +++++++++--------- .../root/www/secubox-feed/Packages.gz | Bin 8369 -> 8376 bytes .../secubox-app-mitmproxy_0.5.0-r19_all.ipk | Bin 0 -> 22113 bytes .../secubox/secubox-app-mitmproxy/Makefile | 2 +- .../files/usr/sbin/mitmproxyctl | 65 +++++++-- 5 files changed, 121 insertions(+), 84 deletions(-) create mode 100644 package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mitmproxy_0.5.0-r19_all.ipk diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/Packages b/package/secubox/secubox-app-bonus/root/www/secubox-feed/Packages index 11f08d06..adac9d81 100644 --- a/package/secubox/secubox-app-bonus/root/www/secubox-feed/Packages +++ b/package/secubox/secubox-app-bonus/root/www/secubox-feed/Packages @@ -8,7 +8,7 @@ Architecture: all Installed-Size: 71680 Description: Comprehensive authentication and session management with captive portal, OAuth2/OIDC integration, voucher system, and time-based access control Filename: luci-app-auth-guardian_0.4.0-r3_all.ipk -Size: 12078 +Size: 12079 Package: luci-app-bandwidth-manager Version: 0.5.0-r2 @@ -44,7 +44,7 @@ Architecture: all Installed-Size: 307200 Description: Network Access Control with client monitoring, zone management, captive portal, parental controls, and SMS/email alerts Filename: luci-app-client-guardian_0.4.0-r7_all.ipk -Size: 57044 +Size: 57042 Package: luci-app-crowdsec-dashboard Version: 0.7.0-r29 @@ -56,7 +56,7 @@ Architecture: all Installed-Size: 296960 Description: Real-time security monitoring dashboard for CrowdSec on OpenWrt Filename: luci-app-crowdsec-dashboard_0.7.0-r29_all.ipk -Size: 55583 +Size: 55585 Package: luci-app-cyberfeed Version: 0.1.1-r1 @@ -80,7 +80,7 @@ Architecture: all Installed-Size: 153600 Description: LuCI SecuBox Service Exposure Manager Filename: luci-app-exposure_1.0.0-r3_all.ipk -Size: 20535 +Size: 20532 Package: luci-app-gitea Version: 1.0.0-r2 @@ -92,7 +92,7 @@ Architecture: all Installed-Size: 92160 Description: Modern dashboard for Gitea Platform management on OpenWrt Filename: luci-app-gitea_1.0.0-r2_all.ipk -Size: 15585 +Size: 15584 Package: luci-app-glances Version: 1.0.0-r2 @@ -104,7 +104,7 @@ Architecture: all Installed-Size: 40960 Description: Modern dashboard for Glances system monitoring with SecuBox theme Filename: luci-app-glances_1.0.0-r2_all.ipk -Size: 6969 +Size: 6967 Package: luci-app-haproxy Version: 1.0.0-r8 @@ -116,7 +116,7 @@ Architecture: all Installed-Size: 204800 Description: Web interface for managing HAProxy load balancer with vhosts, SSL certificates, and backend routing Filename: luci-app-haproxy_1.0.0-r8_all.ipk -Size: 34169 +Size: 34166 Package: luci-app-hexojs Version: 1.0.0-r3 @@ -128,7 +128,7 @@ Architecture: all Installed-Size: 215040 Description: Modern dashboard for Hexo static site generator on OpenWrt Filename: luci-app-hexojs_1.0.0-r3_all.ipk -Size: 32976 +Size: 32981 Package: luci-app-jitsi Version: 1.0.0-r1 @@ -140,7 +140,7 @@ Architecture: all Installed-Size: 30720 Description: LuCI Jitsi Meet Configuration Filename: luci-app-jitsi_1.0.0-r1_all.ipk -Size: 5135 +Size: 5137 Package: luci-app-ksm-manager Version: 0.4.0-r2 @@ -152,7 +152,7 @@ Architecture: all Installed-Size: 112640 Description: Centralized cryptographic key management with hardware security module (HSM) support for Nitrokey and YubiKey devices. Provides secure key storage, certificate management, SSH key handling, and secret storage with audit logging. Filename: luci-app-ksm-manager_0.4.0-r2_all.ipk -Size: 18721 +Size: 18720 Package: luci-app-localai Version: 0.1.0-r15 @@ -164,7 +164,7 @@ Architecture: all Installed-Size: 81920 Description: Modern dashboard for LocalAI LLM management on OpenWrt Filename: luci-app-localai_0.1.0-r15_all.ipk -Size: 14361 +Size: 14362 Package: luci-app-lyrion Version: 1.0.0-r1 @@ -176,7 +176,7 @@ Architecture: all Installed-Size: 40960 Description: LuCI support for Lyrion Music Server Filename: luci-app-lyrion_1.0.0-r1_all.ipk -Size: 6726 +Size: 6724 Package: luci-app-magicmirror2 Version: 0.4.0-r6 @@ -188,7 +188,7 @@ Architecture: all Installed-Size: 71680 Description: Modern dashboard for MagicMirror2 smart display platform with module manager and SecuBox theme Filename: luci-app-magicmirror2_0.4.0-r6_all.ipk -Size: 12278 +Size: 12273 Package: luci-app-mailinabox Version: 1.0.0-r1 @@ -200,7 +200,7 @@ Architecture: all Installed-Size: 30720 Description: LuCI support for Mail-in-a-Box Filename: luci-app-mailinabox_1.0.0-r1_all.ipk -Size: 5482 +Size: 5480 Package: luci-app-media-flow Version: 0.6.4-r1 @@ -212,7 +212,7 @@ Architecture: all Installed-Size: 102400 Description: Real-time detection and monitoring of streaming services (Netflix, YouTube, Spotify, etc.) with quality estimation, history tracking, and alerts. Supports nDPId local DPI and netifyd. Filename: luci-app-media-flow_0.6.4-r1_all.ipk -Size: 19126 +Size: 19113 Package: luci-app-metablogizer Version: 1.0.0-r3 @@ -224,7 +224,7 @@ Architecture: all Installed-Size: 112640 Description: LuCI support for MetaBlogizer Static Site Publisher Filename: luci-app-metablogizer_1.0.0-r3_all.ipk -Size: 23506 +Size: 23503 Package: luci-app-metabolizer Version: 1.0.0-r2 @@ -236,7 +236,7 @@ Architecture: all Installed-Size: 30720 Description: LuCI support for Metabolizer CMS Filename: luci-app-metabolizer_1.0.0-r2_all.ipk -Size: 4760 +Size: 4755 Package: luci-app-mitmproxy Version: 0.5.0-r1 @@ -245,10 +245,10 @@ License: Apache-2.0 Section: luci Maintainer: OpenWrt LuCI community Architecture: all -Installed-Size: 112640 +Installed-Size: 51200 Description: Modern dashboard for mitmproxy HTTPS traffic inspection with SecuBox theme Filename: luci-app-mitmproxy_0.5.0-r1_all.ipk -Size: 20408 +Size: 8555 Package: luci-app-mmpm Version: 0.2.0-r3 @@ -260,7 +260,7 @@ Architecture: all Installed-Size: 51200 Description: Web interface for MMPM - MagicMirror Package Manager Filename: luci-app-mmpm_0.2.0-r3_all.ipk -Size: 7903 +Size: 7902 Package: luci-app-mqtt-bridge Version: 0.4.0-r4 @@ -272,7 +272,7 @@ Architecture: all Installed-Size: 122880 Description: USB-to-MQTT IoT hub with SecuBox theme Filename: luci-app-mqtt-bridge_0.4.0-r4_all.ipk -Size: 22780 +Size: 22777 Package: luci-app-ndpid Version: 1.1.2-r2 @@ -284,7 +284,7 @@ Architecture: all Installed-Size: 122880 Description: Modern dashboard for nDPId deep packet inspection on OpenWrt Filename: luci-app-ndpid_1.1.2-r2_all.ipk -Size: 22455 +Size: 22454 Package: luci-app-netdata-dashboard Version: 0.5.0-r2 @@ -308,7 +308,7 @@ Architecture: all Installed-Size: 307200 Description: Configure OpenWrt for different network modes: Sniffer, Access Point, Relay, Router Filename: luci-app-network-modes_0.5.0-r3_all.ipk -Size: 55610 +Size: 55609 Package: luci-app-network-tweaks Version: 1.0.0-r7 @@ -320,7 +320,7 @@ Architecture: all Installed-Size: 81920 Description: Unified network services dashboard with DNS/hosts sync, CDN cache control, and WPAD auto-proxy configuration Filename: luci-app-network-tweaks_1.0.0-r7_all.ipk -Size: 15461 +Size: 15457 Package: luci-app-nextcloud Version: 1.0.0-r1 @@ -344,7 +344,7 @@ Architecture: all Installed-Size: 71680 Description: Modern dashboard for Ollama LLM management on OpenWrt Filename: luci-app-ollama_0.1.0-r1_all.ipk -Size: 11994 +Size: 11993 Package: luci-app-picobrew Version: 1.0.0-r1 @@ -356,7 +356,7 @@ Architecture: all Installed-Size: 51200 Description: Modern dashboard for PicoBrew Server management on OpenWrt Filename: luci-app-picobrew_1.0.0-r1_all.ipk -Size: 9975 +Size: 9979 Package: luci-app-secubox Version: 0.7.1-r4 @@ -368,7 +368,7 @@ Architecture: all Installed-Size: 266240 Description: Central control hub for all SecuBox modules. Provides unified dashboard, module status, system health monitoring, and quick actions. Filename: luci-app-secubox_0.7.1-r4_all.ipk -Size: 49902 +Size: 49900 Package: luci-app-secubox-admin Version: 1.0.0-r19 @@ -379,7 +379,7 @@ Architecture: all Installed-Size: 337920 Description: Unified admin control center for SecuBox appstore plugins with system monitoring Filename: luci-app-secubox-admin_1.0.0-r19_all.ipk -Size: 57096 +Size: 57097 Package: luci-app-secubox-crowdsec Version: 1.0.0-r3 @@ -391,7 +391,7 @@ Architecture: all Installed-Size: 81920 Description: LuCI SecuBox CrowdSec Dashboard Filename: luci-app-secubox-crowdsec_1.0.0-r3_all.ipk -Size: 13920 +Size: 13919 Package: luci-app-secubox-netdiag Version: 1.0.0-r1 @@ -415,7 +415,7 @@ Architecture: all Installed-Size: 215040 Description: Complete LuCI interface for netifyd DPI engine with real-time flow monitoring, application detection, network analytics, and flow action plugins Filename: luci-app-secubox-netifyd_1.2.1-r1_all.ipk -Size: 39499 +Size: 39498 Package: luci-app-secubox-p2p Version: 0.1.0-r1 @@ -427,7 +427,7 @@ Architecture: all Installed-Size: 215040 Description: LuCI SecuBox P2P Hub Filename: luci-app-secubox-p2p_0.1.0-r1_all.ipk -Size: 39256 +Size: 39257 Package: luci-app-secubox-portal Version: 0.7.0-r2 @@ -439,7 +439,7 @@ Architecture: all Installed-Size: 122880 Description: Unified entry point for all SecuBox applications with tabbed navigation Filename: luci-app-secubox-portal_0.7.0-r2_all.ipk -Size: 24555 +Size: 24554 Package: luci-app-secubox-security-threats Version: 1.0.0-r4 @@ -451,7 +451,7 @@ Architecture: all Installed-Size: 71680 Description: Unified dashboard integrating netifyd DPI threats with CrowdSec intelligence for real-time threat monitoring and automated blocking Filename: luci-app-secubox-security-threats_1.0.0-r4_all.ipk -Size: 13908 +Size: 13906 Package: luci-app-service-registry Version: 1.0.0-r1 @@ -475,7 +475,7 @@ Architecture: all Installed-Size: 122880 Description: Modern dashboard for Streamlit Platform management on OpenWrt Filename: luci-app-streamlit_1.0.0-r9_all.ipk -Size: 20470 +Size: 20469 Package: luci-app-system-hub Version: 0.5.1-r4 @@ -487,7 +487,7 @@ Architecture: all Installed-Size: 358400 Description: Central system control with monitoring, services, logs, and backup Filename: luci-app-system-hub_0.5.1-r4_all.ipk -Size: 66348 +Size: 66347 Package: luci-app-tor-shield Version: 1.0.0-r10 @@ -499,7 +499,7 @@ Architecture: all Installed-Size: 133120 Description: Modern dashboard for Tor anonymization on OpenWrt Filename: luci-app-tor-shield_1.0.0-r10_all.ipk -Size: 24537 +Size: 24532 Package: luci-app-traffic-shaper Version: 0.4.0-r2 @@ -511,7 +511,7 @@ Architecture: all Installed-Size: 92160 Description: Advanced traffic shaping with TC/CAKE for precise bandwidth control Filename: luci-app-traffic-shaper_0.4.0-r2_all.ipk -Size: 15637 +Size: 15631 Package: luci-app-vhost-manager Version: 0.5.0-r5 @@ -523,7 +523,7 @@ Architecture: all Installed-Size: 153600 Description: Nginx reverse proxy manager with Let's Encrypt SSL certificates, authentication, and WebSocket support Filename: luci-app-vhost-manager_0.5.0-r5_all.ipk -Size: 26201 +Size: 26198 Package: luci-app-wireguard-dashboard Version: 0.7.0-r5 @@ -535,7 +535,7 @@ Architecture: all Installed-Size: 235520 Description: Modern dashboard for WireGuard VPN monitoring on OpenWrt Filename: luci-app-wireguard-dashboard_0.7.0-r5_all.ipk -Size: 45371 +Size: 45369 Package: luci-app-zigbee2mqtt Version: 1.0.0-r2 @@ -547,7 +547,7 @@ Architecture: all Installed-Size: 40960 Description: Graphical interface for managing the Zigbee2MQTT docker application. Filename: luci-app-zigbee2mqtt_1.0.0-r2_all.ipk -Size: 7091 +Size: 7087 Package: luci-theme-secubox Version: 0.4.7-r1 @@ -559,7 +559,7 @@ Architecture: all Installed-Size: 460800 Description: Global CyberMood design system (CSS/JS/i18n) shared by all SecuBox dashboards. Filename: luci-theme-secubox_0.4.7-r1_all.ipk -Size: 111796 +Size: 111794 Package: secubox-app Version: 1.0.0-r2 @@ -570,7 +570,7 @@ Installed-Size: 92160 Description: Command line helper for SecuBox App Store manifests. Installs /usr/sbin/secubox-app and ships the default manifests under /usr/share/secubox/plugins/. Filename: secubox-app_1.0.0-r2_all.ipk -Size: 11183 +Size: 11181 Package: secubox-app-adguardhome Version: 1.0.0-r2 @@ -602,7 +602,7 @@ Description: Logs authentication failures from LuCI/rpcd and Dropbear SSH - JavaScript hook to intercept login failures - CrowdSec parser and bruteforce scenario Filename: secubox-app-auth-logger_1.2.2-r1_all.ipk -Size: 9379 +Size: 9376 Package: secubox-app-crowdsec-custom Version: 1.1.0-r1 @@ -625,7 +625,7 @@ Description: Custom CrowdSec configurations for SecuBox web interface protectio - Webapp generic auth bruteforce protection - Whitelist for trusted networks Filename: secubox-app-crowdsec-custom_1.1.0-r1_all.ipk -Size: 5762 +Size: 5759 Package: secubox-app-cs-firewall-bouncer Version: 0.0.31-r4 @@ -652,7 +652,7 @@ Description: SecuBox CrowdSec Firewall Bouncer for OpenWrt. - Automatic restart on firewall reload - procd service management Filename: secubox-app-cs-firewall-bouncer_0.0.31-r4_aarch64_cortex-a72.ipk -Size: 5049320 +Size: 5049323 Package: secubox-app-cyberfeed Version: 0.2.1-r1 @@ -679,7 +679,7 @@ Installed-Size: 10240 Description: Installer, configuration, and service manager for running Domoticz inside Docker on SecuBox-powered OpenWrt systems. Filename: secubox-app-domoticz_1.0.0-r2_all.ipk -Size: 2546 +Size: 2547 Package: secubox-app-exposure Version: 1.0.0-r1 @@ -694,7 +694,7 @@ Description: Unified service exposure manager for SecuBox. - Dynamic Tor hidden service management - HAProxy SSL reverse proxy configuration Filename: secubox-app-exposure_1.0.0-r1_all.ipk -Size: 6834 +Size: 6831 Package: secubox-app-gitea Version: 1.0.0-r5 @@ -717,7 +717,7 @@ Description: Gitea Git Platform - Self-hosted lightweight Git service Runs in LXC container with Alpine Linux. Configure in /etc/config/gitea. Filename: secubox-app-gitea_1.0.0-r5_all.ipk -Size: 9406 +Size: 9405 Package: secubox-app-glances Version: 1.0.0-r1 @@ -740,7 +740,7 @@ Description: Glances - Cross-platform system monitoring tool for SecuBox. Runs in LXC container for isolation and security. Configure in /etc/config/glances. Filename: secubox-app-glances_1.0.0-r1_all.ipk -Size: 5537 +Size: 5538 Package: secubox-app-haproxy Version: 1.0.0-r23 @@ -760,7 +760,7 @@ Description: HAProxy load balancer and reverse proxy running in an LXC containe - Stats dashboard - Rate limiting and ACLs Filename: secubox-app-haproxy_1.0.0-r23_all.ipk -Size: 15681 +Size: 15682 Package: secubox-app-hexojs Version: 1.0.0-r8 @@ -784,7 +784,7 @@ Description: Hexo CMS - Self-hosted static blog generator for OpenWrt Runs in LXC container with Alpine Linux. Configure in /etc/config/hexojs. Filename: secubox-app-hexojs_1.0.0-r8_all.ipk -Size: 94937 +Size: 94939 Package: secubox-app-jitsi Version: 1.0.0-r1 @@ -809,7 +809,7 @@ Description: Jitsi Meet - Secure, fully featured video conferencing for SecuBox Integrates with HAProxy for SSL termination. Configure in /etc/config/jitsi. Filename: secubox-app-jitsi_1.0.0-r1_all.ipk -Size: 8916 +Size: 8918 Package: secubox-app-localai Version: 2.25.0-r1 @@ -831,7 +831,7 @@ Description: LocalAI native binary package for OpenWrt. API: http://:8081/v1 Filename: secubox-app-localai_2.25.0-r1_all.ipk -Size: 5726 +Size: 5719 Package: secubox-app-localai-wb Version: 2.25.0-r1 @@ -855,7 +855,7 @@ Description: LocalAI native binary package for OpenWrt. API: http://:8080/v1 Filename: secubox-app-localai-wb_2.25.0-r1_all.ipk -Size: 7953 +Size: 7957 Package: secubox-app-lyrion Version: 2.0.2-r1 @@ -875,7 +875,7 @@ Description: Lyrion Media Server (formerly Logitech Media Server / Squeezebox S Auto-detects available runtime, preferring LXC for lower resource usage. Configure runtime in /etc/config/lyrion. Filename: secubox-app-lyrion_2.0.2-r1_all.ipk -Size: 7285 +Size: 7293 Package: secubox-app-magicmirror2 Version: 0.4.0-r8 @@ -897,7 +897,7 @@ Description: MagicMirror² - Open source modular smart mirror platform for Secu Runs in LXC container for isolation and security. Configure in /etc/config/magicmirror2. Filename: secubox-app-magicmirror2_0.4.0-r8_all.ipk -Size: 9254 +Size: 9248 Package: secubox-app-mailinabox Version: 2.0.0-r1 @@ -922,7 +922,7 @@ Description: Complete email server solution using docker-mailserver for SecuBox Commands: mailinaboxctl --help Filename: secubox-app-mailinabox_2.0.0-r1_all.ipk -Size: 7571 +Size: 7573 Package: secubox-app-metabolizer Version: 1.0.0-r3 @@ -943,16 +943,16 @@ Description: Metabolizer Blog Pipeline - Integrated CMS with Git-based workflow Pipeline: Edit in Streamlit -> Push to Gitea -> Build with Hexo -> Publish Filename: secubox-app-metabolizer_1.0.0-r3_all.ipk -Size: 13979 +Size: 13976 Package: secubox-app-mitmproxy -Version: 0.5.0-r17 +Version: 0.5.0-r19 Depends: wget, tar License: Apache-2.0 Section: utils Maintainer: CyberMind Studio Architecture: all -Installed-Size: 71680 +Installed-Size: 92160 Description: mitmproxy - Interactive HTTPS proxy for SecuBox-powered OpenWrt systems. Features: @@ -969,8 +969,8 @@ Description: mitmproxy - Interactive HTTPS proxy for SecuBox-powered OpenWrt sy Runs in LXC container for isolation and security. Configure in /etc/config/mitmproxy. -Filename: secubox-app-mitmproxy_0.5.0-r17_all.ipk -Size: 18508 +Filename: secubox-app-mitmproxy_0.5.0-r19_all.ipk +Size: 22113 Package: secubox-app-mmpm Version: 0.2.0-r5 @@ -1005,7 +1005,7 @@ Description: Installer, configuration, and service manager for running Nextclou inside Docker on SecuBox-powered OpenWrt systems. Self-hosted file sync and share with calendar, contacts, and collaboration. Filename: secubox-app-nextcloud_1.0.0-r2_all.ipk -Size: 2956 +Size: 2962 Package: secubox-app-ollama Version: 0.1.0-r1 @@ -1027,7 +1027,7 @@ Description: Ollama - Simple local LLM runtime for SecuBox-powered OpenWrt syst Runs in Docker/Podman container. Configure in /etc/config/ollama. Filename: secubox-app-ollama_0.1.0-r1_all.ipk -Size: 5735 +Size: 5740 Package: secubox-app-picobrew Version: 1.0.0-r7 @@ -1049,7 +1049,7 @@ Description: PicoBrew Server - Self-hosted brewing controller for PicoBrew devi Runs in LXC container with Python/Flask backend. Configure in /etc/config/picobrew. Filename: secubox-app-picobrew_1.0.0-r7_all.ipk -Size: 5543 +Size: 5542 Package: secubox-app-streamlit Version: 1.0.0-r5 @@ -1099,7 +1099,7 @@ Description: SecuBox Tor Shield - One-click Tor anonymization for OpenWrt Configure in /etc/config/tor-shield. Filename: secubox-app-tor_1.0.0-r1_all.ipk -Size: 7377 +Size: 7379 Package: secubox-app-webapp Version: 1.5.0-r7 @@ -1130,7 +1130,7 @@ Installed-Size: 20480 Description: Installer, configuration, and service manager for running Zigbee2MQTT inside Docker on SecuBox-powered OpenWrt systems. Filename: secubox-app-zigbee2mqtt_1.0.0-r3_all.ipk -Size: 3542 +Size: 3544 Package: secubox-core Version: 0.10.0-r11 @@ -1150,7 +1150,7 @@ Description: SecuBox Core Framework provides the foundational infrastructure fo - Unified CLI interface - ubus RPC backend Filename: secubox-core_0.10.0-r11_all.ipk -Size: 87809 +Size: 87811 Package: secubox-p2p Version: 0.6.0-r1 @@ -1169,5 +1169,5 @@ Description: SecuBox P2P Hub backend providing peer discovery, mesh networking and MirrorBox NetMesh Catalog for cross-chain distributed service registry with HAProxy vhost discovery and multi-endpoint access URLs. Filename: secubox-p2p_0.6.0-r1_all.ipk -Size: 40190 +Size: 40191 diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/Packages.gz b/package/secubox/secubox-app-bonus/root/www/secubox-feed/Packages.gz index 97f569056a0f81801042e9081725397351b0d785..c64bb707815a4f7c15d6da208bb780668ac8a389 100644 GIT binary patch literal 8376 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 Ocl-mK<%#TvjQ{}Y7+6LC literal 8369 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 diff --git a/package/secubox/secubox-app-mitmproxy/files/usr/sbin/mitmproxyctl b/package/secubox/secubox-app-mitmproxy/files/usr/sbin/mitmproxyctl index ff775b28..6874fd4b 100755 --- a/package/secubox/secubox-app-mitmproxy/files/usr/sbin/mitmproxyctl +++ b/package/secubox/secubox-app-mitmproxy/files/usr/sbin/mitmproxyctl @@ -921,43 +921,80 @@ cmd_sync_routes() { local routes_file="$data_path/haproxy-routes.json" local tmp_file="/tmp/haproxy-routes.tmp" + local count=0 # Start JSON echo "{" > "$tmp_file" - local first=1 - local count=0 + # Get all vhosts - avoid subshell by using temp file + local vhosts_file="/tmp/haproxy-vhosts.tmp" + uci show haproxy 2>/dev/null | grep "=vhost" | cut -d'=' -f1 | cut -d'.' -f2 > "$vhosts_file" + + while read vhost; do + [ -z "$vhost" ] && continue - # Get all vhosts and their backends - uci show haproxy 2>/dev/null | grep "=vhost" | while read line; do - local vhost=$(echo "$line" | cut -d'=' -f1 | cut -d'.' -f2) local domain=$(uci -q get haproxy.$vhost.domain) local backend=$(uci -q get haproxy.$vhost.backend) + # If currently using mitmproxy_inspector, use the stored original backend + if [ "$backend" = "mitmproxy_inspector" ]; then + backend=$(uci -q get haproxy.$vhost.original_backend) + fi + + # Skip fallback, luci, and mitmproxy backends + case "$backend" in + fallback|luci|luci_default|mitmproxy_inspector|"") continue ;; + esac + if [ -n "$domain" ] && [ -n "$backend" ]; then - # Get backend server details + local ip="" + local port="" + + # Method 1: Check for inline server field (old style) local server=$(uci -q get haproxy.$backend.server) if [ -n "$server" ]; then # Parse server spec: "name ip:port check [options]" local addr=$(echo "$server" | awk '{print $2}') - local ip=$(echo "$addr" | cut -d':' -f1) - local port=$(echo "$addr" | cut -d':' -f2) - + ip=$(echo "$addr" | cut -d':' -f1) + port=$(echo "$addr" | cut -d':' -f2) # Handle backends without explicit port [ "$ip" = "$port" ] && port="80" + fi - if [ $first -eq 0 ]; then + # Method 2: Check for separate server section (new style) + if [ -z "$ip" ]; then + # Find server section that references this backend + local server_section=$(uci show haproxy 2>/dev/null | grep "\.backend='$backend'" | grep "=server" | head -1 | cut -d'=' -f1 | cut -d'.' -f2) + if [ -z "$server_section" ]; then + # Try pattern: backend_name_servername=server + server_section=$(uci show haproxy 2>/dev/null | grep "^haproxy\.${backend}_.*=server" | head -1 | cut -d'=' -f1 | cut -d'.' -f2) + fi + + if [ -n "$server_section" ]; then + ip=$(uci -q get haproxy.$server_section.address) + port=$(uci -q get haproxy.$server_section.port) + fi + fi + + # Only add route if we found valid ip:port + if [ -n "$ip" ] && [ -n "$port" ]; then + if [ $count -gt 0 ]; then echo "," >> "$tmp_file" fi - first=0 count=$((count + 1)) - echo " \"$domain\": [\"$ip\", $port]" >> "$tmp_file" - log_info " $domain -> $ip:$port" + printf ' "%s": ["%s", %s]' "$domain" "$ip" "$port" >> "$tmp_file" + log_info " $domain -> $ip:$port (backend: $backend)" + else + log_warn " $domain: could not resolve backend '$backend'" fi fi - done + done < "$vhosts_file" + rm -f "$vhosts_file" + + # Close JSON + echo "" >> "$tmp_file" echo "}" >> "$tmp_file" # Move to final location