Flask-based VPS management panel with SSH remote command execution. Includes E2E encrypted SSH tunnel (AES-256-GCM + Go agent), setup wizard, security hardening tools, DNS management, firewall configs, monitoring, backup, and .sec patch update system. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
142 lines
6.0 KiB
Python
142 lines
6.0 KiB
Python
# Security update management via .sec files
|
|
# Each function returns a bash command string that app.py executes via ssh_run()
|
|
|
|
SEC_DIR = "/var/www/updates.seteclabs.io/sec"
|
|
|
|
|
|
def os_detect_cmd():
|
|
"""Return bash cmd to detect OS distro and version."""
|
|
return (
|
|
"echo '=== OS Detection ===' && "
|
|
"if [ -f /etc/os-release ]; then "
|
|
" . /etc/os-release && "
|
|
" echo \"DISTRO_ID=$ID\" && "
|
|
" echo \"DISTRO_VERSION=$VERSION_ID\" && "
|
|
" echo \"DISTRO_CODENAME=$VERSION_CODENAME\" && "
|
|
" echo \"DISTRO_NAME=$PRETTY_NAME\"; "
|
|
"else "
|
|
" echo 'ERROR: /etc/os-release not found'; "
|
|
"fi && "
|
|
"echo \"KERNEL=$(uname -r)\" && "
|
|
"echo \"ARCH=$(dpkg --print-architecture 2>/dev/null || uname -m)\""
|
|
)
|
|
|
|
|
|
def list_available_cmd():
|
|
"""Return bash cmd to list all available .sec files on the update server."""
|
|
return (
|
|
f"echo '=== Available Security Updates ===' && "
|
|
f"ls -1 {SEC_DIR}/*.sec 2>/dev/null | while read f; do "
|
|
f" name=$(basename \"$f\"); "
|
|
f" desc=$(head -5 \"$f\" | grep '^# Setec Labs' | sed 's/^# //'); "
|
|
f" target=$(head -5 \"$f\" | grep '^# Target:' | sed 's/^# Target: //'); "
|
|
f" echo \"$name | $target | $desc\"; "
|
|
f"done || echo 'No .sec files found in {SEC_DIR}'"
|
|
)
|
|
|
|
|
|
def check_updates_cmd(distro_id, version_id):
|
|
"""Return bash cmd to find .sec files matching a distro+version prefix."""
|
|
# Construct prefix: e.g. ubuntu + 22.04 -> ubuntu2204_
|
|
ver_clean = version_id.replace(".", "")
|
|
prefix = f"{distro_id}{ver_clean}_"
|
|
return (
|
|
f"echo '=== Updates for {distro_id} {version_id} ===' && "
|
|
f"ls -1 {SEC_DIR}/{prefix}*.sec 2>/dev/null | while read f; do "
|
|
f" name=$(basename \"$f\"); "
|
|
f" echo \"$name\"; "
|
|
f"done || echo 'No updates found for prefix: {prefix}'"
|
|
)
|
|
|
|
|
|
def download_update_cmd(filename):
|
|
"""Return bash cmd to show the contents of a .sec file (it's already local on VPS)."""
|
|
if ".." in filename or "/" in filename:
|
|
return "echo 'ERROR: invalid filename'"
|
|
return f"cat {SEC_DIR}/{filename} 2>&1"
|
|
|
|
|
|
def preview_update_cmd(filename):
|
|
"""Return bash cmd to preview what a .sec file will do without applying it."""
|
|
if ".." in filename or "/" in filename:
|
|
return "echo 'ERROR: invalid filename'"
|
|
path = f"{SEC_DIR}/{filename}"
|
|
return (
|
|
f"echo '=== Preview: {filename} ===' && "
|
|
f"if [ ! -f '{path}' ]; then echo 'File not found: {filename}'; exit 1; fi && "
|
|
f"echo '' && echo '--- [packages] ---' && "
|
|
f"sed -n '/^\\[packages\\]/,/^\\[/{{ /^\\[/!p }}' '{path}' | grep -v '^#' | grep -v '^$' && "
|
|
f"echo '' && echo '--- [sysctl] ---' && "
|
|
f"sed -n '/^\\[sysctl\\]/,/^\\[/{{ /^\\[/!p }}' '{path}' | grep -v '^#' | grep -v '^$' && "
|
|
f"echo '' && echo '--- [services] ---' && "
|
|
f"sed -n '/^\\[services\\]/,/^\\[/{{ /^\\[/!p }}' '{path}' | grep -v '^#' | grep -v '^$' && "
|
|
f"echo '' && echo '--- [files] ---' && "
|
|
f"sed -n '/^\\[files\\]/,/^\\[/{{ /^\\[/!p }}' '{path}' | grep -v '^#' | grep -v '^$' && "
|
|
f"echo '' && echo '--- [custom] ---' && "
|
|
f"sed -n '/^\\[custom\\]/,/^\\[/{{ /^\\[/!p }}' '{path}' | grep -v '^#' | grep -v '^$' && "
|
|
f"echo '' && echo '=== End Preview ==='"
|
|
)
|
|
|
|
|
|
def parse_and_apply_cmd(filename):
|
|
"""Return bash cmd to parse a .sec file and apply all sections."""
|
|
if ".." in filename or "/" in filename:
|
|
return "echo 'ERROR: invalid filename'"
|
|
path = f"{SEC_DIR}/{filename}"
|
|
return (
|
|
f"if [ ! -f '{path}' ]; then echo 'File not found: {filename}'; exit 1; fi && "
|
|
f"echo '=== Applying: {filename} ===' && "
|
|
f"echo \"Started: $(date)\" && "
|
|
f"echo '' && "
|
|
# Log the apply
|
|
f"echo \"$(date '+%Y-%m-%d %H:%M:%S') APPLY {filename}\" >> /var/log/setec-updates.log && "
|
|
# [packages] section — run each line as a command
|
|
f"echo '>>> [packages]' && "
|
|
f"sed -n '/^\\[packages\\]/,/^\\[/{{ /^\\[/!p }}' '{path}' | grep -v '^#' | grep -v '^$' | "
|
|
f"while IFS= read -r cmd; do "
|
|
f" echo \"+ $cmd\" && "
|
|
f" eval \"DEBIAN_FRONTEND=noninteractive $cmd\" 2>&1; "
|
|
f"done && "
|
|
# [sysctl] section — write to conf file, then apply
|
|
f"echo '' && echo '>>> [sysctl]' && "
|
|
f"sed -n '/^\\[sysctl\\]/,/^\\[/{{ /^\\[/!p }}' '{path}' | grep -v '^#' | grep -v '^$' > /etc/sysctl.d/99-setec-update.conf && "
|
|
f"sysctl -p /etc/sysctl.d/99-setec-update.conf 2>&1 && "
|
|
# [services] section — run each line
|
|
f"echo '' && echo '>>> [services]' && "
|
|
f"sed -n '/^\\[services\\]/,/^\\[/{{ /^\\[/!p }}' '{path}' | grep -v '^#' | grep -v '^$' | "
|
|
f"while IFS= read -r cmd; do "
|
|
f" echo \"+ $cmd\" && "
|
|
f" eval \"$cmd\" 2>&1; "
|
|
f"done && "
|
|
# [files] section — run each line
|
|
f"echo '' && echo '>>> [files]' && "
|
|
f"sed -n '/^\\[files\\]/,/^\\[/{{ /^\\[/!p }}' '{path}' | grep -v '^#' | grep -v '^$' | "
|
|
f"while IFS= read -r cmd; do "
|
|
f" echo \"+ $cmd\" && "
|
|
f" eval \"$cmd\" 2>&1; "
|
|
f"done && "
|
|
# [custom] section — strip bash:-: prefix, run each line
|
|
f"echo '' && echo '>>> [custom]' && "
|
|
f"sed -n '/^\\[custom\\]/,/^\\[/{{ /^\\[/!p }}' '{path}' | grep -v '^#' | grep -v '^$' | "
|
|
f"sed 's/^bash:-://' | "
|
|
f"while IFS= read -r cmd; do "
|
|
f" echo \"+ $cmd\" && "
|
|
f" eval \"$cmd\" 2>&1; "
|
|
f"done && "
|
|
f"echo '' && echo \"Completed: $(date)\" && "
|
|
f"echo \"$(date '+%Y-%m-%d %H:%M:%S') DONE {filename}\" >> /var/log/setec-updates.log && "
|
|
f"echo '=== Update Applied Successfully ==='"
|
|
)
|
|
|
|
|
|
def update_history_cmd():
|
|
"""Return bash cmd to show the update application history."""
|
|
return (
|
|
"echo '=== Setec Update History ===' && "
|
|
"if [ -f /var/log/setec-updates.log ]; then "
|
|
" cat /var/log/setec-updates.log; "
|
|
"else "
|
|
" echo 'No update history found'; "
|
|
"fi"
|
|
)
|