#!/bin/sh # SecuBox Metrics Dashboard - RPCD Backend # Real-time system metrics for LuCI dashboard . /usr/share/libubox/jshn.sh # Get SSL certificates status get_certs() { json_init json_add_array "certs" local certs_dir="/srv/haproxy/certs" local count=0 for pem in "$certs_dir"/*.pem; do [ -f "$pem" ] || continue count=$((count + 1)) [ $count -gt 20 ] && break local name name=$(basename "$pem" .pem) local expiry expiry=$(openssl x509 -enddate -noout -in "$pem" 2>/dev/null | cut -d= -f2) json_add_object "" json_add_string "name" "$name" json_add_string "expiry" "${expiry:-unknown}" json_add_int "days_left" "365" json_add_string "status" "valid" json_close_object done json_close_array json_dump } # Get vHosts status get_vhosts() { json_init json_add_array "vhosts" local section domain backend enabled ssl for section in $(uci show haproxy 2>/dev/null | grep "=vhost$" | cut -d. -f2 | cut -d= -f1); do domain=$(uci -q get "haproxy.$section.domain") backend=$(uci -q get "haproxy.$section.backend") enabled=$(uci -q get "haproxy.$section.enabled") ssl=$(uci -q get "haproxy.$section.ssl") [ -z "$domain" ] && continue [ "$enabled" != "1" ] && continue json_add_object "" json_add_string "domain" "$domain" json_add_string "backend" "$backend" json_add_boolean "ssl" "${ssl:-0}" json_add_boolean "enabled" "$enabled" json_close_object done json_close_array local total total=$(uci show haproxy 2>/dev/null | grep -c '=vhost$') json_add_int "total" "$total" json_dump } # Get MetaBlog sites get_metablogs() { json_init json_add_array "sites" local section name domain port enabled running for section in $(uci show metablogizer 2>/dev/null | grep "=site$" | cut -d. -f2 | cut -d= -f1); do name=$(echo "$section" | sed 's/^site_//') domain=$(uci -q get "metablogizer.$section.domain") port=$(uci -q get "metablogizer.$section.port") enabled=$(uci -q get "metablogizer.$section.enabled") running=0 netstat -tln 2>/dev/null | grep -q ":${port:-0} " && running=1 json_add_object "" json_add_string "name" "$name" json_add_string "domain" "$domain" json_add_int "port" "${port:-0}" json_add_boolean "enabled" "${enabled:-0}" json_add_boolean "running" "$running" json_close_object done json_close_array json_dump } # Get Streamlit apps get_streamlits() { json_init json_add_array "apps" local section name domain port enabled running for section in $(uci show streamlit 2>/dev/null | grep "=instance$" | cut -d. -f2 | cut -d= -f1); do name="$section" domain=$(uci -q get "streamlit.$section.domain") port=$(uci -q get "streamlit.$section.port") enabled=$(uci -q get "streamlit.$section.enabled") running=0 pgrep -f "streamlit.*$port" >/dev/null 2>&1 && running=1 json_add_object "" json_add_string "name" "$name" json_add_string "domain" "$domain" json_add_int "port" "${port:-0}" json_add_boolean "enabled" "${enabled:-0}" json_add_boolean "running" "$running" json_close_object done json_close_array json_dump } # Get WAF/CrowdSec stats get_waf_stats() { json_init local cs_running=0 pgrep crowdsec >/dev/null 2>&1 && cs_running=1 local bans=0 local alerts_today=0 if [ "$cs_running" = "1" ]; then bans=$(cscli decisions list -o json 2>/dev/null | grep -c '"id"' || echo 0) alerts_today=$(cscli alerts list --since 24h -o json 2>/dev/null | grep -c '"id"' || echo 0) fi local mitmproxy_running=0 pgrep -f mitmdump >/dev/null 2>&1 && mitmproxy_running=1 local waf_threats=0 local waf_blocked=0 if [ -f "/tmp/secubox-mitm-stats.json" ]; then waf_threats=$(jsonfilter -i /tmp/secubox-mitm-stats.json -e '@.threats_today' 2>/dev/null || echo 0) waf_blocked=$(jsonfilter -i /tmp/secubox-mitm-stats.json -e '@.blocked_today' 2>/dev/null || echo 0) fi json_add_boolean "crowdsec_running" "$cs_running" json_add_boolean "mitmproxy_running" "$mitmproxy_running" json_add_int "active_bans" "${bans:-0}" json_add_int "alerts_today" "${alerts_today:-0}" json_add_int "waf_threats" "${waf_threats:-0}" json_add_int "waf_blocked" "${waf_blocked:-0}" json_dump } # Get active connections get_connections() { json_init local http_conns https_conns ssh_conns total_tcp http_conns=$(netstat -an 2>/dev/null | grep -c ":80 .*ESTABLISHED" || echo 0) https_conns=$(netstat -an 2>/dev/null | grep -c ":443 .*ESTABLISHED" || echo 0) ssh_conns=$(netstat -an 2>/dev/null | grep -c ":22 .*ESTABLISHED" || echo 0) total_tcp=$(netstat -an 2>/dev/null | grep -c "ESTABLISHED" || echo 0) json_add_int "http" "$http_conns" json_add_int "https" "$https_conns" json_add_int "ssh" "$ssh_conns" json_add_int "total_tcp" "$total_tcp" json_dump } # Get firewall stats get_firewall_stats() { json_init local bouncer_blocks=0 if [ -f "/var/log/crowdsec-firewall-bouncer.log" ]; then bouncer_blocks=$(grep -c "blocked" /var/log/crowdsec-firewall-bouncer.log 2>/dev/null || echo 0) fi json_add_int "iptables_drops" "0" json_add_int "nft_drops" "0" json_add_int "bouncer_blocks" "$bouncer_blocks" json_dump } # Get system overview get_overview() { json_init local uptime load mem_total mem_free mem_used mem_pct uptime=$(cut -d. -f1 /proc/uptime) load=$(cut -d' ' -f1-3 /proc/loadavg) mem_total=$(awk '/MemTotal/ {print $2}' /proc/meminfo) mem_free=$(awk '/MemAvailable/ {print $2}' /proc/meminfo) mem_used=$((mem_total - mem_free)) mem_pct=$((mem_used * 100 / mem_total)) local haproxy_up=0 lxc-info -n haproxy -s 2>/dev/null | grep -q RUNNING && haproxy_up=1 local mitmproxy_up=0 lxc-info -n mitmproxy-in -s 2>/dev/null | grep -q RUNNING && mitmproxy_up=1 local crowdsec_up=0 pgrep crowdsec >/dev/null 2>&1 && crowdsec_up=1 local vhost_count metablog_count streamlit_count cert_count lxc_running vhost_count=$(uci show haproxy 2>/dev/null | grep -c '=vhost$') metablog_count=$(uci show metablogizer 2>/dev/null | grep -c '=site$') streamlit_count=$(uci show streamlit 2>/dev/null | grep -c '=instance$') cert_count=$(ls /srv/haproxy/certs/*.pem 2>/dev/null | wc -l) lxc_running=$(lxc-ls --running 2>/dev/null | wc -w) json_add_int "uptime" "$uptime" json_add_string "load" "$load" json_add_int "mem_total_kb" "$mem_total" json_add_int "mem_used_kb" "$mem_used" json_add_int "mem_pct" "$mem_pct" json_add_boolean "haproxy" "$haproxy_up" json_add_boolean "mitmproxy" "$mitmproxy_up" json_add_boolean "crowdsec" "$crowdsec_up" json_add_int "vhosts" "$vhost_count" json_add_int "metablogs" "$metablog_count" json_add_int "streamlits" "$streamlit_count" json_add_int "certificates" "$cert_count" json_add_int "lxc_containers" "$lxc_running" json_add_string "timestamp" "$(date -Iseconds)" json_dump } # Get all metrics get_all() { local overview waf conns fw overview=$(get_overview) waf=$(get_waf_stats) conns=$(get_connections) fw=$(get_firewall_stats) printf '{"overview":%s,"waf":%s,"connections":%s,"firewall":%s}' "$overview" "$waf" "$conns" "$fw" } case "$1" in list) echo '{"overview":{},"certs":{},"vhosts":{},"metablogs":{},"streamlits":{},"waf_stats":{},"connections":{},"firewall_stats":{},"all":{}}' ;; call) case "$2" in overview) get_overview ;; certs) get_certs ;; vhosts) get_vhosts ;; metablogs) get_metablogs ;; streamlits) get_streamlits ;; waf_stats) get_waf_stats ;; connections) get_connections ;; firewall_stats) get_firewall_stats ;; all) get_all ;; *) echo '{"error":"Unknown method"}' ;; esac ;; esac