mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-08-03 22:36:44 +00:00
Update security_manager.py
This commit is contained in:
@@ -137,6 +137,25 @@ def _run_cmd(cmd, timeout=10):
|
|||||||
return -1, "", str(e)
|
return -1, "", str(e)
|
||||||
|
|
||||||
|
|
||||||
|
def _pve_firewall_apply():
|
||||||
|
"""
|
||||||
|
Recompile and apply pending firewall changes.
|
||||||
|
|
||||||
|
pve-firewall 6.x (shipped with PVE 9) dropped the `reload`
|
||||||
|
subcommand — only `restart` recompiles the ruleset and re-applies
|
||||||
|
it to iptables/nftables. Older releases accepted `reload`. Try
|
||||||
|
`reload` first for the cheap path; fall back to `restart` when
|
||||||
|
the subcommand is missing or returns an error. Without this
|
||||||
|
fallback, every mutating firewall call in this module was silently
|
||||||
|
a no-op on PVE 9 (the config file was updated but the kernel
|
||||||
|
ruleset never picked up the change until an unrelated restart).
|
||||||
|
"""
|
||||||
|
rc, out, err = _run_cmd(["pve-firewall", "reload"])
|
||||||
|
if rc == 0:
|
||||||
|
return rc, out, err
|
||||||
|
return _run_cmd(["pve-firewall", "restart"])
|
||||||
|
|
||||||
|
|
||||||
def get_firewall_status():
|
def get_firewall_status():
|
||||||
"""
|
"""
|
||||||
Get the overall Proxmox firewall status.
|
Get the overall Proxmox firewall status.
|
||||||
@@ -392,7 +411,7 @@ def add_firewall_rule(direction="IN", action="ACCEPT", protocol="tcp", dport="",
|
|||||||
with open(fw_file, 'w') as f:
|
with open(fw_file, 'w') as f:
|
||||||
f.write(content)
|
f.write(content)
|
||||||
|
|
||||||
_run_cmd(["pve-firewall", "reload"])
|
_pve_firewall_apply()
|
||||||
|
|
||||||
return True, f"Firewall rule added: {direction} {action} {protocol}{':' + dport if dport else ''}"
|
return True, f"Firewall rule added: {direction} {action} {protocol}{':' + dport if dport else ''}"
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
@@ -509,7 +528,7 @@ def edit_firewall_rule(rule_index, level="host", direction="IN", action="ACCEPT"
|
|||||||
with open(fw_file, 'w') as f:
|
with open(fw_file, 'w') as f:
|
||||||
f.write("\n".join(new_lines) + "\n")
|
f.write("\n".join(new_lines) + "\n")
|
||||||
|
|
||||||
_run_cmd(["pve-firewall", "reload"])
|
_pve_firewall_apply()
|
||||||
|
|
||||||
return True, f"Firewall rule updated: {direction} {action} {protocol}{':' + dport if dport else ''}"
|
return True, f"Firewall rule updated: {direction} {action} {protocol}{':' + dport if dport else ''}"
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
@@ -571,7 +590,7 @@ def delete_firewall_rule(rule_index, level="host"):
|
|||||||
with open(fw_file, 'w') as f:
|
with open(fw_file, 'w') as f:
|
||||||
f.write("\n".join(new_lines) + "\n")
|
f.write("\n".join(new_lines) + "\n")
|
||||||
|
|
||||||
_run_cmd(["pve-firewall", "reload"])
|
_pve_firewall_apply()
|
||||||
|
|
||||||
return True, f"Firewall rule deleted: {removed_rule}"
|
return True, f"Firewall rule deleted: {removed_rule}"
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
@@ -625,7 +644,7 @@ def add_monitor_port_rule():
|
|||||||
f.write(content)
|
f.write(content)
|
||||||
|
|
||||||
# Reload firewall
|
# Reload firewall
|
||||||
_run_cmd(["pve-firewall", "reload"])
|
_pve_firewall_apply()
|
||||||
|
|
||||||
return True, "Firewall rule added: port 8008 (TCP) allowed for ProxMenux Monitor"
|
return True, "Firewall rule added: port 8008 (TCP) allowed for ProxMenux Monitor"
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
@@ -662,7 +681,7 @@ def remove_monitor_port_rule():
|
|||||||
with open(host_fw, 'w') as f:
|
with open(host_fw, 'w') as f:
|
||||||
f.writelines(new_lines)
|
f.writelines(new_lines)
|
||||||
|
|
||||||
_run_cmd(["pve-firewall", "reload"])
|
_pve_firewall_apply()
|
||||||
|
|
||||||
return True, "ProxMenux Monitor firewall rule removed"
|
return True, "ProxMenux Monitor firewall rule removed"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -673,9 +692,25 @@ def enable_firewall(level="host"):
|
|||||||
"""
|
"""
|
||||||
Enable the Proxmox firewall at host or cluster level.
|
Enable the Proxmox firewall at host or cluster level.
|
||||||
Returns (success, message)
|
Returns (success, message)
|
||||||
|
|
||||||
|
Safety net: whoever is calling this endpoint is reaching the Monitor
|
||||||
|
through port 8008. Enabling the firewall without an explicit ACCEPT
|
||||||
|
rule for that port drops the caller's own connection the instant
|
||||||
|
`pve-firewall reload` runs, and they lose the UI they need to fix it.
|
||||||
|
Ensure the rule is in host.fw first; if we can't place it, refuse
|
||||||
|
to enable rather than risk a lock-out.
|
||||||
"""
|
"""
|
||||||
if level not in _FIREWALL_LEVELS:
|
if level not in _FIREWALL_LEVELS:
|
||||||
return False, f"Invalid level: {level}. Must be one of {_FIREWALL_LEVELS}"
|
return False, f"Invalid level: {level}. Must be one of {_FIREWALL_LEVELS}"
|
||||||
|
|
||||||
|
rule_ok, rule_msg = add_monitor_port_rule()
|
||||||
|
if not rule_ok:
|
||||||
|
return False, (
|
||||||
|
f"Refused to enable firewall: could not ensure port 8008 "
|
||||||
|
f"(ProxMenux Monitor) rule in host.fw — {rule_msg}. "
|
||||||
|
f"Add the rule manually and try again."
|
||||||
|
)
|
||||||
|
|
||||||
if level == "cluster":
|
if level == "cluster":
|
||||||
return _set_firewall_enabled(CLUSTER_FW, True)
|
return _set_firewall_enabled(CLUSTER_FW, True)
|
||||||
else:
|
else:
|
||||||
@@ -750,7 +785,7 @@ def _set_firewall_enabled(fw_file, enabled):
|
|||||||
_run_cmd(["systemctl", "enable", "pve-firewall"])
|
_run_cmd(["systemctl", "enable", "pve-firewall"])
|
||||||
_run_cmd(["systemctl", "start", "pve-firewall"])
|
_run_cmd(["systemctl", "start", "pve-firewall"])
|
||||||
|
|
||||||
_run_cmd(["pve-firewall", "reload"])
|
_pve_firewall_apply()
|
||||||
|
|
||||||
state = "enabled" if enabled else "disabled"
|
state = "enabled" if enabled else "disabled"
|
||||||
level = "cluster" if fw_file == CLUSTER_FW else "host"
|
level = "cluster" if fw_file == CLUSTER_FW else "host"
|
||||||
|
|||||||
Reference in New Issue
Block a user