#!/usr/bin/env python3 """ SecuBox Control Panel - Grand-Mamy KISS Edition v4 FIXED: Reads service status from cache files (works inside LXC) """ import streamlit as st import json import time from datetime import datetime st.set_page_config(page_title="SecuBox Control", page_icon="🛡️", layout="wide", initial_sidebar_state="collapsed") PRIORITY_LEVELS = { 0: ("DESACTIVE", "#404050"), 3: ("NORMAL", "#00d4aa"), 6: ("CRITIQUE", "#ffa500"), 7: ("URGENT", "#ff8c00"), 8: ("ALERTE", "#ff6b6b"), 9: ("DANGER", "#ff4d4d"), 10: ("PERMANENT", "#ff0000"), } st.markdown(""" """, unsafe_allow_html=True) def read_cache(path): try: with open(path, "r") as f: return json.load(f) except: return {} def rgb_hex(r, g, b): return f"#{r:02x}{g:02x}{b:02x}" def badge(level): name, color = PRIORITY_LEVELS.get(level, ("NORMAL", "#00d4aa")) return f'{name}' def progress(val): pct = min(100, int(val)) c = "progress-green" if pct < 60 else "progress-yellow" if pct < 85 else "progress-red" return f'
{pct}%
' @st.cache_data(ttl=5) def get_data(): d = {"time": datetime.now().strftime("%H:%M:%S"), "date": datetime.now().strftime("%d/%m/%Y")} health = read_cache("/tmp/secubox/health.json") threat = read_cache("/tmp/secubox/threat.json") capacity = read_cache("/tmp/secubox/capacity.json") status = read_cache("/tmp/secubox/health-status.json") cs = read_cache("/tmp/secubox/crowdsec.json") mitm = read_cache("/tmp/secubox/mitmproxy.json") netif = read_cache("/tmp/secubox/netifyd.json") waf = read_cache("/tmp/secubox/waf-stats.json") cs_detail = read_cache("/tmp/secubox/crowdsec-overview.json") modules = status.get("modules", {}) resources = status.get("resources", {}) d["score"] = health.get("score", 100) d["svc_ok"] = modules.get("active", health.get("services_ok", 0)) d["svc_total"] = modules.get("enabled", health.get("services_total", 0)) d["threat"] = threat.get("level", 0) d["cpu"] = capacity.get("cpu_pct", 0) d["mem"] = resources.get("memory_percent", 50) d["disk"] = resources.get("storage_percent", 0) d["load"] = resources.get("cpu_load", "0") d["haproxy"] = modules.get("active", 0) > 0 d["crowdsec"] = cs.get("running", 0) == 1 d["cs_alerts"] = cs.get("alerts", 0) d["cs_bans"] = cs.get("bans", 0) d["mitmproxy"] = mitm.get("running", 0) == 1 d["mitm_threats"] = mitm.get("threats_today", 0) d["netifyd"] = netif.get("running", 0) == 1 # Enhanced WAF/threat stats d["waf_threats"] = waf.get("threats_today", 0) d["waf_autobans"] = waf.get("autobans_total", 0) d["waf_pending"] = waf.get("autobans_pending", 0) d["active_bans"] = cs_detail.get("active_bans", 0) d["total_decisions"] = cs_detail.get("total_decisions", 0) # DPI Dual-Stream stats dpi_buffer = read_cache("/tmp/secubox/dpi-buffer.json") dpi_flows = read_cache("/tmp/secubox/dpi-flows.json") d["dpi_buffer_entries"] = dpi_buffer.get("entries", 0) d["dpi_threats"] = dpi_buffer.get("threats_detected", 0) d["dpi_blocked"] = dpi_buffer.get("blocked_count", 0) d["dpi_flows"] = dpi_flows.get("flows_1min", 0) d["dpi_rx"] = dpi_flows.get("rx_bytes", 0) d["dpi_tx"] = dpi_flows.get("tx_bytes", 0) d["p_haproxy"] = 3 if d["haproxy"] else 10 d["p_crowdsec"] = 3 if d["crowdsec"] and d["cs_alerts"] == 0 else 7 if d["cs_alerts"] > 0 else 10 d["p_mitmproxy"] = 3 if d["mitmproxy"] else 6 d["led1"] = rgb_hex(0, 255 if d["score"] > 50 else 0, 0) if d["score"] > 80 else rgb_hex(255, 165, 0) if d["score"] > 50 else rgb_hex(255, 0, 0) d["led2"] = rgb_hex(0, 255, 0) if d["threat"] < 10 else rgb_hex(255, 165, 0) if d["threat"] < 50 else rgb_hex(255, 0, 0) d["led3"] = rgb_hex(0, 255, 0) if d["cpu"] < 60 else rgb_hex(255, 165, 0) if d["cpu"] < 85 else rgb_hex(255, 0, 0) # LED4: Bans indicator d["led4"] = rgb_hex(255, 0, 0) if d["active_bans"] > 5 else rgb_hex(255, 165, 0) if d["active_bans"] > 0 else rgb_hex(0, 255, 0) return d def main(): d = get_data() st.markdown('

SecuBox Control Panel

', unsafe_allow_html=True) st.markdown(f'
💚 {d["time"]} - {d["date"]} 💚
', unsafe_allow_html=True) st.markdown(f'''
💡 LED Status
Health
Score: {d['score']}
Threat
Level: {d['threat']}
{d['cpu']}%
CPU
🚫
Bans: {d['active_bans']}
''', unsafe_allow_html=True) st.markdown('
SERVICES
', unsafe_allow_html=True) c1, c2, c3, c4 = st.columns(4) with c1: st.markdown(f'''
⚡ HAProxy{badge(d['p_haproxy'])}
{'ON' if d['haproxy'] else 'OFF'}
Status
''', unsafe_allow_html=True) with c2: st.markdown(f'''
🛡️ CrowdSec{badge(d['p_crowdsec'])}
{d['cs_alerts']}
Alerts
{d['cs_bans']}
Bans
''', unsafe_allow_html=True) with c3: st.markdown(f'''
🔍 WAF/MITM{badge(d['p_mitmproxy'])}
{d['waf_threats']}
Threats
{d['waf_autobans']}
AutoBans
''', unsafe_allow_html=True) dpi_color = "#00d4aa" if d["dpi_buffer_entries"] > 0 else "#808090" with c4: st.markdown(f'''
📡 DPI Dual
{d['dpi_flows']}
Flows/min
{d['dpi_threats']}
Threats
{d['dpi_blocked']}
Blocked
''', unsafe_allow_html=True) st.markdown('
SYSTEM
', unsafe_allow_html=True) c1, c2, c3, c4 = st.columns(4) with c1: st.markdown(f'
🖥️ CPU
{progress(d["cpu"])}
', unsafe_allow_html=True) with c2: st.markdown(f'
🧠 Memory
{progress(d["mem"])}
', unsafe_allow_html=True) with c3: st.markdown(f'
💾 Disk
{progress(d["disk"])}
', unsafe_allow_html=True) with c4: st.markdown(f'''
⚙️ Services
{d['svc_ok']}/{d['svc_total']}
Running
''', unsafe_allow_html=True) score_color = "#00d4aa" if d["score"] >= 80 else "#ffa500" if d["score"] >= 50 else "#ff4d4d" st.markdown(f'''
{d['score']}
SECURITY SCORE
''', unsafe_allow_html=True) time.sleep(10) st.rerun() if __name__ == "__main__": main()