diff --git a/package/secubox/luci-app-client-guardian/htdocs/luci-static/resources/view/client-guardian/autozoning.js b/package/secubox/luci-app-client-guardian/htdocs/luci-static/resources/view/client-guardian/autozoning.js index 89c115fc..04a67a6e 100644 --- a/package/secubox/luci-app-client-guardian/htdocs/luci-static/resources/view/client-guardian/autozoning.js +++ b/package/secubox/luci-app-client-guardian/htdocs/luci-static/resources/view/client-guardian/autozoning.js @@ -27,17 +27,17 @@ return view.extend({ s = m.section(form.NamedSection, 'config', 'client-guardian', _('Auto-Zoning Settings')); o = s.option(form.Flag, 'auto_zoning_enabled', _('Enable Auto-Zoning'), - _('Automatically assign clients to zones using matching rules')); - o.default = '1'; + _('Automatically assign clients to zones using matching rules. WARNING: May restrict network access for new devices!')); + o.default = '0'; o.rmempty = false; o = s.option(form.ListValue, 'auto_parking_zone', _('Auto-Parking Zone'), _('Default zone for clients that don\'t match any rule')); - o.value('guest', _('Guest')); - o.value('quarantine', _('Quarantine')); - o.value('iot', _('IoT')); - o.value('lan_private', _('LAN Private')); - o.default = 'guest'; + o.value('lan_private', _('LAN Private (Full Access)')); + o.value('guest', _('Guest (Internet Only)')); + o.value('iot', _('IoT (Isolated)')); + o.value('quarantine', _('Quarantine (No Access - Dangerous!)')); + o.default = 'lan_private'; o.depends('auto_zoning_enabled', '1'); o = s.option(form.Flag, 'auto_parking_approve', _('Auto-Approve Parked Clients'), diff --git a/package/secubox/luci-app-client-guardian/htdocs/luci-static/resources/view/client-guardian/settings.js b/package/secubox/luci-app-client-guardian/htdocs/luci-static/resources/view/client-guardian/settings.js index bff19236..135077b5 100644 --- a/package/secubox/luci-app-client-guardian/htdocs/luci-static/resources/view/client-guardian/settings.js +++ b/package/secubox/luci-app-client-guardian/htdocs/luci-static/resources/view/client-guardian/settings.js @@ -29,17 +29,17 @@ return view.extend({ s = m.section(form.NamedSection, 'config', 'client-guardian', _('General Settings')); o = s.option(form.Flag, 'enabled', _('Enable Client Guardian')); - o.default = '1'; + o.default = '0'; o.rmempty = false; - o.description = _('Enable or disable the Client Guardian access control system'); + o.description = _('Enable or disable the Client Guardian access control system. WARNING: Enabling with restrictive policies may block network access!'); o = s.option(form.ListValue, 'default_policy', _('Default Policy')); - o.value('open', _('Open - Allow all clients')); - o.value('quarantine', _('Quarantine - Require approval')); - o.value('whitelist', _('Whitelist Only - Allow only approved clients')); - o.default = 'quarantine'; + o.value('open', _('Open - Allow all clients (Recommended)')); + o.value('quarantine', _('Quarantine - Require approval (Restrictive)')); + o.value('whitelist', _('Whitelist Only - Block unknown clients (Very Restrictive)')); + o.default = 'open'; o.rmempty = false; - o.description = _('Default behavior for new/unknown clients'); + o.description = _('Default behavior for new/unknown clients. WARNING: Quarantine and Whitelist modes will block new devices from accessing the network!'); o = s.option(form.Flag, 'auto_approve', _('Auto-Approve Known Devices')); o.default = '0'; diff --git a/package/secubox/luci-app-client-guardian/root/etc/config/client-guardian b/package/secubox/luci-app-client-guardian/root/etc/config/client-guardian index c47aead7..9b8970f7 100644 --- a/package/secubox/luci-app-client-guardian/root/etc/config/client-guardian +++ b/package/secubox/luci-app-client-guardian/root/etc/config/client-guardian @@ -1,9 +1,9 @@ config client-guardian 'config' - option enabled '1' - option default_policy 'quarantine' + option enabled '0' + option default_policy 'open' option quarantine_zone 'quarantine' option scan_interval '30' - option auto_approve '0' + option auto_approve '1' option log_level 'info' # Dashboard Reactiveness option auto_refresh '1' @@ -11,11 +11,11 @@ config client-guardian 'config' # Debug Mode option debug_enabled '0' option debug_level 'INFO' - option enable_active_scan '1' - # Auto-Zoning / Auto-Parking - option auto_zoning_enabled '1' - option auto_parking_zone 'guest' - option auto_parking_approve '0' + option enable_active_scan '0' + # Auto-Zoning / Auto-Parking - DISABLED BY DEFAULT for safety + option auto_zoning_enabled '0' + option auto_parking_zone 'lan_private' + option auto_parking_approve '1' # Alert Configuration config alerts 'alerts' @@ -196,7 +196,7 @@ config schedule 'school_hours' config schedule 'night_block' option name 'Blocage Nocturne' - option enabled '1' + option enabled '0' option action 'block' option start_time '22:00' option end_time '07:00' @@ -216,11 +216,11 @@ config schedule 'weekend_limit' list days 'sat' list days 'sun' -# Threat Intelligence Integration +# Threat Intelligence Integration - DISABLED by default for safety config threat_policy 'threat_policy' - option enabled '1' - option auto_ban_threshold '80' - option auto_quarantine_threshold '60' + option enabled '0' + option auto_ban_threshold '95' + option auto_quarantine_threshold '90' option threat_check_interval '60' # Auto-Zoning Rules diff --git a/package/secubox/luci-app-client-guardian/root/usr/libexec/rpcd/luci.client-guardian b/package/secubox/luci-app-client-guardian/root/usr/libexec/rpcd/luci.client-guardian index 9c72c1e7..3c13f8f7 100755 --- a/package/secubox/luci-app-client-guardian/root/usr/libexec/rpcd/luci.client-guardian +++ b/package/secubox/luci-app-client-guardian/root/usr/libexec/rpcd/luci.client-guardian @@ -11,6 +11,49 @@ LOG_FILE="/var/log/client-guardian.log" CLIENTS_DB="/tmp/client-guardian-clients.json" ALERTS_QUEUE="/tmp/client-guardian-alerts.json" +# SAFETY LIMITS - prevent accidental mass blocking +MAX_BLOCKED_DEVICES=10 +SAFETY_BYPASS_FILE="/tmp/client-guardian-safety-bypass" + +# Count currently blocked devices (CG_NOLAN, CG_BLOCK, CG_QUARANTINE rules) +count_blocked_devices() { + uci show firewall 2>/dev/null | grep -c "\.name='CG_NOLAN_\|CG_BLOCK_\|CG_QUARANTINE_'" 2>/dev/null || echo "0" +} + +# Check if safety limit is reached +check_safety_limit() { + local force="$1" + + # If safety bypass file exists (set by admin), skip check + [ -f "$SAFETY_BYPASS_FILE" ] && return 0 + + # If force flag is set, skip check + [ "$force" = "1" ] && return 0 + + local blocked_count=$(count_blocked_devices) + if [ "$blocked_count" -ge "$MAX_BLOCKED_DEVICES" ]; then + log_event "warn" "SAFETY LIMIT: Already $blocked_count devices blocked (max: $MAX_BLOCKED_DEVICES)" + return 1 + fi + return 0 +} + +# Clear all CG firewall rules (emergency restore) +clear_all_cg_rules() { + log_event "warn" "EMERGENCY: Clearing all Client Guardian firewall rules" + + # Find and delete all CG rules + local rules=$(uci show firewall 2>/dev/null | grep "\.name='CG_" | cut -d. -f2 | cut -d= -f1 | sort -ru) + for rule in $rules; do + uci delete firewall.$rule 2>/dev/null + done + uci commit firewall + /etc/init.d/firewall reload >/dev/null 2>&1 + + log_event "info" "All Client Guardian rules cleared" + echo '{"success":true,"message":"All CG rules cleared"}' +} + # Logging function with debug support log_event() { local level="$1" @@ -1051,9 +1094,18 @@ create_firewall_zone() { apply_client_rules() { local mac="$1" local zone="$2" + local force="${3:-0}" log_event "info" "Applying rules for MAC: $mac -> Zone: $zone" + # SAFETY CHECK: If zone would block/quarantine and safety limit reached, skip + if [ "$zone" = "blocked" ] || [ "$zone" = "quarantine" ]; then + if ! check_safety_limit "$force"; then + log_event "error" "SAFETY LIMIT REACHED: Refusing to block MAC $mac. Use force=1 or clear existing rules." + return 1 + fi + fi + # Normalize MAC to uppercase for firewall rules local mac_upper=$(echo "$mac" | tr 'a-f' 'A-F') @@ -1649,7 +1701,7 @@ get_client() { # Main dispatcher case "$1" in list) - echo '{"status":{},"clients":{},"zones":{},"parental":{},"alerts":{},"logs":{"limit":"int","level":"str"},"approve_client":{"mac":"str","name":"str","zone":"str","notes":"str"},"ban_client":{"mac":"str","reason":"str"},"quarantine_client":{"mac":"str"},"update_client":{"section":"str","name":"str","zone":"str","notes":"str","daily_quota":"int","static_ip":"str"},"update_zone":{"id":"str","name":"str","bandwidth_limit":"int","content_filter":"str"},"send_test_alert":{"type":"str"},"get_policy":{},"set_policy":{"policy":"str","auto_approve":"bool","session_timeout":"int"},"get_client":{"mac":"str"},"sync_zones":{},"list_profiles":{},"apply_profile":{"profile_id":"str","auto_refresh":"str","refresh_interval":"str","threat_enabled":"str","auto_ban_threshold":"str","auto_quarantine_threshold":"str"}}' + echo '{"status":{},"clients":{},"zones":{},"parental":{},"alerts":{},"logs":{"limit":"int","level":"str"},"approve_client":{"mac":"str","name":"str","zone":"str","notes":"str"},"ban_client":{"mac":"str","reason":"str"},"quarantine_client":{"mac":"str"},"update_client":{"section":"str","name":"str","zone":"str","notes":"str","daily_quota":"int","static_ip":"str"},"update_zone":{"id":"str","name":"str","bandwidth_limit":"int","content_filter":"str"},"send_test_alert":{"type":"str"},"get_policy":{},"set_policy":{"policy":"str","auto_approve":"bool","session_timeout":"int"},"get_client":{"mac":"str"},"sync_zones":{},"list_profiles":{},"apply_profile":{"profile_id":"str","auto_refresh":"str","refresh_interval":"str","threat_enabled":"str","auto_ban_threshold":"str","auto_quarantine_threshold":"str"},"clear_rules":{},"safety_status":{}}' ;; call) case "$2" in @@ -1677,6 +1729,15 @@ case "$1" in ;; list_profiles) list_profiles ;; apply_profile) apply_profile ;; + clear_rules) clear_all_cg_rules ;; + safety_status) + json_init + local blocked=$(count_blocked_devices) + json_add_int "blocked_devices" "$blocked" + json_add_int "max_allowed" "$MAX_BLOCKED_DEVICES" + json_add_boolean "safety_limit_reached" $([ "$blocked" -ge "$MAX_BLOCKED_DEVICES" ] && echo 1 || echo 0) + json_dump + ;; *) echo '{"error": "Unknown method"}' ;; esac ;;