#!/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") 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 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) 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
''', unsafe_allow_html=True) st.markdown('
SERVICES
', unsafe_allow_html=True) c1, c2, c3 = st.columns(3) 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'''
🔍 MITM{badge(d['p_mitmproxy'])}
{d['mitm_threats']}
Threats
''', 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()