From cc34d330902b68fdde824e071aab3c16967778d9 Mon Sep 17 00:00:00 2001 From: MacRimi Date: Tue, 10 Feb 2026 18:28:43 +0100 Subject: [PATCH] Update security --- AppImage/components/security.tsx | 162 +--------------------- AppImage/scripts/flask_security_routes.py | 16 --- AppImage/scripts/security_manager.py | 66 --------- 3 files changed, 1 insertion(+), 243 deletions(-) diff --git a/AppImage/components/security.tsx b/AppImage/components/security.tsx index 1d23df87..9c0ab6b9 100644 --- a/AppImage/components/security.tsx +++ b/AppImage/components/security.tsx @@ -9,7 +9,7 @@ import { Shield, Lock, User, AlertCircle, CheckCircle, Info, LogOut, Key, Copy, Eye, EyeOff, Trash2, RefreshCw, Clock, ShieldCheck, Globe, FileKey, AlertTriangle, Flame, Bug, Search, Download, Power, PowerOff, Plus, Minus, Activity, Settings, Ban, - FileText, Printer, Play, BarChart3, TriangleAlert, ChevronDown, UserCog, + FileText, Printer, Play, BarChart3, TriangleAlert, ChevronDown, } from "lucide-react" import { getApiUrl, fetchApi } from "../lib/api-config" import { TwoFactorSetup } from "./two-factor-setup" @@ -165,17 +165,6 @@ export function Security() { const [f2bSavingConfig, setF2bSavingConfig] = useState(false) const [f2bApplyingJails, setF2bApplyingJails] = useState(false) - // Root Hardening state - const [rootHardeningLoading, setRootHardeningLoading] = useState(true) - const [rootHardeningData, setRootHardeningData] = useState<{ - hardening_applied: boolean - ssh_root_disabled: boolean - root_web_blocked: boolean - admin_user: string - pve_user_exists: boolean - } | null>(null) - const [showRootHardeningScript, setShowRootHardeningScript] = useState(false) - // SSL/HTTPS state const [sslEnabled, setSslEnabled] = useState(false) const [sslSource, setSslSource] = useState<"none" | "proxmox" | "custom">("none") @@ -195,7 +184,6 @@ export function Security() { loadSslStatus() loadFirewallStatus() loadSecurityTools() - loadRootHardeningStatus() }, []) const loadFirewallStatus = async () => { @@ -235,26 +223,6 @@ export function Security() { } } - const loadRootHardeningStatus = async () => { - try { - setRootHardeningLoading(true) - const data = await fetchApi("/api/security/root-hardening/status") - if (data.success) { - setRootHardeningData({ - hardening_applied: data.hardening_applied, - ssh_root_disabled: data.ssh_root_disabled, - root_web_blocked: data.root_web_blocked, - admin_user: data.admin_user, - pve_user_exists: data.pve_user_exists, - }) - } - } catch { - // Silently fail - } finally { - setRootHardeningLoading(false) - } - } - const loadFail2banDetails = async () => { try { setF2bDetailsLoading(true) @@ -2150,124 +2118,6 @@ ${(report.sections && report.sections.length > 0) ? `
- {/* Root Access Hardening */} - - -
-
- - Root Access Hardening -
- -
- - Restrict root access to SSH and Proxmox web UI by creating a dedicated admin user - -
- - {rootHardeningLoading ? ( -
-
-
- ) : ( -
- {/* Status indicators */} -
-
- SSH Root: - {rootHardeningData?.ssh_root_disabled ? ( - Disabled - ) : ( - Enabled - )} -
-
-
- Root Web: - {rootHardeningData?.root_web_blocked ? ( - Blocked - ) : ( - Active - )} -
- {rootHardeningData?.admin_user && ( - <> -
-
- Admin: - {rootHardeningData.admin_user} - {rootHardeningData.pve_user_exists && ( - - )} -
- - )} -
- - {/* Info/Warning based on state */} - {rootHardeningData?.hardening_applied ? ( -
-
- -
-

Root Access Hardened

-

- Root SSH login is disabled and root web access is blocked. - Use {rootHardeningData.admin_user} for SSH and Proxmox web UI. - For root shell, run sudo -i from the admin user. -

-
-
-
- ) : ( -
-
- -
-

Root Access Not Hardened

-

- Root can access SSH and the Proxmox web UI directly. It is recommended to create a dedicated admin user and disable root remote access. - ProxMenux Monitor will continue working without interruption. -

-
-
-
- )} - - {/* Action buttons */} -
- {!rootHardeningData?.hardening_applied ? ( - - ) : ( - - )} -
-
- )} - - - {/* Proxmox Firewall */} @@ -3688,16 +3538,6 @@ ${(report.sections && report.sections.length > 0) ? ` {/* Script Terminal Modals */} - { - setShowRootHardeningScript(false) - loadRootHardeningStatus() - }} - scriptPath="/usr/local/share/proxmenux/scripts/security/root_hardening.sh" - title="Root Access Hardening" - description="Manage root access hardening for SSH and Proxmox web UI" - /> { diff --git a/AppImage/scripts/flask_security_routes.py b/AppImage/scripts/flask_security_routes.py index 5b2e590a..426145da 100644 --- a/AppImage/scripts/flask_security_routes.py +++ b/AppImage/scripts/flask_security_routes.py @@ -289,19 +289,3 @@ def security_tools(): return jsonify({"success": True, "tools": tools}) except Exception as e: return jsonify({"success": False, "message": str(e)}), 500 - - -# ------------------------------------------------------------------- -# Root Access Hardening -# ------------------------------------------------------------------- - -@security_bp.route('/api/security/root-hardening/status', methods=['GET']) -def root_hardening_status(): - """Get root access hardening status""" - if not security_manager: - return jsonify({"success": False, "message": "Security manager not available"}), 500 - try: - status = security_manager.get_root_hardening_status() - return jsonify({"success": True, **status}) - except Exception as e: - return jsonify({"success": False, "message": str(e)}), 500 diff --git a/AppImage/scripts/security_manager.py b/AppImage/scripts/security_manager.py index 60f96469..b22cafbb 100644 --- a/AppImage/scripts/security_manager.py +++ b/AppImage/scripts/security_manager.py @@ -1855,69 +1855,3 @@ def parse_lynis_report(): report["proxmox_context_applied"] = True return report - - -# ================================================================= -# Root Access Hardening -# ================================================================= - -HARDENING_FLAG = "/root/.proxmenux/root_hardening.json" -SSHD_CONFIG = "/etc/ssh/sshd_config" - -def get_root_hardening_status(): - """ - Check root hardening status: SSH root login, web access, admin user. - Returns dict with current state. - """ - result = { - "hardening_applied": False, - "ssh_root_disabled": False, - "root_web_blocked": False, - "admin_user": "", - "pve_user_exists": False, - } - - # Check SSH root login - try: - if os.path.isfile(SSHD_CONFIG): - with open(SSHD_CONFIG, 'r') as f: - for line in f: - stripped = line.strip() - if stripped and not stripped.startswith('#'): - if stripped.lower().startswith('permitrootlogin'): - val = stripped.split(None, 1)[1].strip().lower() if len(stripped.split(None, 1)) > 1 else "" - result["ssh_root_disabled"] = val == "no" - break - except Exception: - pass - - # Check hardening flag - if os.path.isfile(HARDENING_FLAG): - try: - with open(HARDENING_FLAG, 'r') as f: - data = json.loads(f.read()) - result["hardening_applied"] = True - result["admin_user"] = data.get("admin_user", "") - result["root_web_blocked"] = data.get("root_web_blocked", False) - result["ssh_root_disabled"] = data.get("ssh_root_disabled", result["ssh_root_disabled"]) - - # Verify admin user exists in PVE - if result["admin_user"]: - rc, out, _ = _run_cmd(["pveum", "user", "list", "--output-format", "json"]) - if rc == 0 and out: - try: - users = json.loads(out) - pam_user = f"{result['admin_user']}@pam" - for u in users: - if u.get("userid") == pam_user: - result["pve_user_exists"] = True - break - except json.JSONDecodeError: - # Fallback: grep approach - rc2, out2, _ = _run_cmd(["pveum", "user", "list"]) - if rc2 == 0: - result["pve_user_exists"] = f"{result['admin_user']}@pam" in out2 - except Exception: - pass - - return result