Initial commit — SETEC LABS Manager (Setec_CDM)
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>
This commit is contained in:
220
setec-web/hardening.py
Normal file
220
setec-web/hardening.py
Normal file
@@ -0,0 +1,220 @@
|
||||
# Security hardening commands for Linux VPS
|
||||
# Each function returns a bash command string that app.py executes via ssh_run()
|
||||
|
||||
|
||||
def ssh_harden_cmd(port=22, disable_root=True, disable_password=True):
|
||||
"""Return bash command to harden SSH config. Backs up sshd_config first."""
|
||||
root_login = "no" if disable_root else "yes"
|
||||
password_auth = "no" if disable_password else "yes"
|
||||
return (
|
||||
"cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d_%H%M%S) && "
|
||||
f"sed -i 's/^#\\?Port .*/Port {port}/' /etc/ssh/sshd_config && "
|
||||
f"sed -i 's/^#\\?PermitRootLogin .*/PermitRootLogin {root_login}/' /etc/ssh/sshd_config && "
|
||||
f"sed -i 's/^#\\?PasswordAuthentication .*/PasswordAuthentication {password_auth}/' /etc/ssh/sshd_config && "
|
||||
"sed -i 's/^#\\?PubkeyAuthentication .*/PubkeyAuthentication yes/' /etc/ssh/sshd_config && "
|
||||
"sed -i 's/^#\\?X11Forwarding .*/X11Forwarding no/' /etc/ssh/sshd_config && "
|
||||
"sed -i 's/^#\\?MaxAuthTries .*/MaxAuthTries 3/' /etc/ssh/sshd_config && "
|
||||
"sed -i 's/^#\\?AllowAgentForwarding .*/AllowAgentForwarding no/' /etc/ssh/sshd_config && "
|
||||
"grep -q '^Port ' /etc/ssh/sshd_config || echo 'Port {port}' >> /etc/ssh/sshd_config && ".format(port=port) +
|
||||
"grep -q '^PermitRootLogin ' /etc/ssh/sshd_config || echo 'PermitRootLogin {root}' >> /etc/ssh/sshd_config && ".format(root=root_login) +
|
||||
"grep -q '^PasswordAuthentication ' /etc/ssh/sshd_config || echo 'PasswordAuthentication {pw}' >> /etc/ssh/sshd_config && ".format(pw=password_auth) +
|
||||
"grep -q '^PubkeyAuthentication ' /etc/ssh/sshd_config || echo 'PubkeyAuthentication yes' >> /etc/ssh/sshd_config && "
|
||||
"sshd -t 2>&1 && "
|
||||
"systemctl restart sshd 2>&1 && "
|
||||
"echo 'SSH hardened: Port={port}, RootLogin={root}, PasswordAuth={pw}'".format(
|
||||
port=port, root=root_login, pw=password_auth
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def kernel_harden_cmd():
|
||||
"""Return bash command to apply kernel hardening via sysctl."""
|
||||
sysctl_conf = (
|
||||
"# Setec Labs kernel hardening\\n"
|
||||
"net.ipv4.tcp_syncookies = 1\\n"
|
||||
"net.ipv4.conf.all.rp_filter = 1\\n"
|
||||
"net.ipv4.icmp_echo_ignore_broadcasts = 1\\n"
|
||||
"net.ipv4.conf.all.accept_redirects = 0\\n"
|
||||
"net.ipv4.conf.all.send_redirects = 0\\n"
|
||||
"net.ipv4.conf.all.accept_source_route = 0\\n"
|
||||
"net.ipv6.conf.all.accept_redirects = 0\\n"
|
||||
"kernel.randomize_va_space = 2\\n"
|
||||
"net.ipv4.tcp_max_syn_backlog = 2048\\n"
|
||||
"net.ipv4.tcp_synack_retries = 2\\n"
|
||||
"fs.protected_hardlinks = 1\\n"
|
||||
"fs.protected_symlinks = 1"
|
||||
)
|
||||
return (
|
||||
"cp /etc/sysctl.d/99-hardening.conf /etc/sysctl.d/99-hardening.conf.bak.$(date +%Y%m%d_%H%M%S) 2>/dev/null; "
|
||||
f"echo -e '{sysctl_conf}' > /etc/sysctl.d/99-hardening.conf && "
|
||||
"sysctl --system 2>&1 && "
|
||||
"echo 'Kernel hardening applied via /etc/sysctl.d/99-hardening.conf'"
|
||||
)
|
||||
|
||||
|
||||
def auto_updates_cmd():
|
||||
"""Return bash cmd to install and configure unattended-upgrades."""
|
||||
return (
|
||||
"DEBIAN_FRONTEND=noninteractive apt-get install -y unattended-upgrades apt-listchanges 2>&1 && "
|
||||
"cat > /etc/apt/apt.conf.d/20auto-upgrades << 'EOF'\n"
|
||||
'APT::Periodic::Update-Package-Lists "1";\n'
|
||||
'APT::Periodic::Unattended-Upgrade "1";\n'
|
||||
'APT::Periodic::AutocleanInterval "7";\n'
|
||||
"EOF\n"
|
||||
"cat > /etc/apt/apt.conf.d/50unattended-upgrades << 'EOF'\n"
|
||||
"Unattended-Upgrade::Allowed-Origins {\n"
|
||||
' \"${distro_id}:${distro_codename}\";\n'
|
||||
' \"${distro_id}:${distro_codename}-security\";\n'
|
||||
' \"${distro_id}ESMApps:${distro_codename}-apps-security\";\n'
|
||||
' \"${distro_id}ESM:${distro_codename}-infra-security\";\n'
|
||||
"};\n"
|
||||
'Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";\n'
|
||||
'Unattended-Upgrade::Remove-Unused-Dependencies "true";\n'
|
||||
'Unattended-Upgrade::Automatic-Reboot "false";\n'
|
||||
"EOF\n"
|
||||
"systemctl enable unattended-upgrades 2>&1 && "
|
||||
"systemctl restart unattended-upgrades 2>&1 && "
|
||||
"echo 'Unattended upgrades configured and enabled'"
|
||||
)
|
||||
|
||||
|
||||
def firewall_status_cmd():
|
||||
"""Return bash cmd to get UFW status verbose."""
|
||||
return "ufw status verbose 2>&1"
|
||||
|
||||
|
||||
def firewall_enable_cmd(ssh_port=22):
|
||||
"""Return bash cmd to enable UFW with sensible defaults."""
|
||||
return (
|
||||
"apt-get install -y ufw 2>&1 && "
|
||||
"ufw default deny incoming 2>&1 && "
|
||||
"ufw default allow outgoing 2>&1 && "
|
||||
f"ufw allow {ssh_port}/tcp comment 'SSH' 2>&1 && "
|
||||
"ufw allow 80/tcp comment 'HTTP' 2>&1 && "
|
||||
"ufw allow 443/tcp comment 'HTTPS' 2>&1 && "
|
||||
"echo 'y' | ufw enable 2>&1 && "
|
||||
"ufw status verbose 2>&1"
|
||||
)
|
||||
|
||||
|
||||
def firewall_add_rule_cmd(rule):
|
||||
"""Return bash cmd to add a UFW rule (e.g. 'allow 8080/tcp')."""
|
||||
return f"ufw {rule} 2>&1 && ufw status numbered 2>&1"
|
||||
|
||||
|
||||
def firewall_delete_rule_cmd(rule):
|
||||
"""Return bash cmd to delete a UFW rule."""
|
||||
return f"echo 'y' | ufw delete {rule} 2>&1 && ufw status numbered 2>&1"
|
||||
|
||||
|
||||
def firewall_preset_cmd(preset):
|
||||
"""Return bash cmd for common firewall presets."""
|
||||
presets = {
|
||||
"webserver": (
|
||||
"ufw default deny incoming 2>&1 && "
|
||||
"ufw default allow outgoing 2>&1 && "
|
||||
"ufw allow 22/tcp comment 'SSH' 2>&1 && "
|
||||
"ufw allow 80/tcp comment 'HTTP' 2>&1 && "
|
||||
"ufw allow 443/tcp comment 'HTTPS' 2>&1 && "
|
||||
"echo 'y' | ufw enable 2>&1 && "
|
||||
"echo 'Webserver preset applied' && ufw status verbose 2>&1"
|
||||
),
|
||||
"mailserver": (
|
||||
"ufw default deny incoming 2>&1 && "
|
||||
"ufw default allow outgoing 2>&1 && "
|
||||
"ufw allow 22/tcp comment 'SSH' 2>&1 && "
|
||||
"ufw allow 25/tcp comment 'SMTP' 2>&1 && "
|
||||
"ufw allow 80/tcp comment 'HTTP' 2>&1 && "
|
||||
"ufw allow 443/tcp comment 'HTTPS' 2>&1 && "
|
||||
"ufw allow 465/tcp comment 'SMTPS' 2>&1 && "
|
||||
"ufw allow 587/tcp comment 'Submission' 2>&1 && "
|
||||
"ufw allow 993/tcp comment 'IMAPS' 2>&1 && "
|
||||
"echo 'y' | ufw enable 2>&1 && "
|
||||
"echo 'Mailserver preset applied' && ufw status verbose 2>&1"
|
||||
),
|
||||
"lockdown": (
|
||||
"ufw default deny incoming 2>&1 && "
|
||||
"ufw default deny outgoing 2>&1 && "
|
||||
"ufw allow out 53 comment 'DNS' 2>&1 && "
|
||||
"ufw allow out 80/tcp comment 'HTTP out' 2>&1 && "
|
||||
"ufw allow out 443/tcp comment 'HTTPS out' 2>&1 && "
|
||||
"ufw allow 22/tcp comment 'SSH' 2>&1 && "
|
||||
"echo 'y' | ufw enable 2>&1 && "
|
||||
"echo 'Lockdown preset applied - SSH only inbound' && ufw status verbose 2>&1"
|
||||
),
|
||||
}
|
||||
if preset not in presets:
|
||||
return f"echo 'Unknown preset: {preset}. Available: webserver, mailserver, lockdown'"
|
||||
return presets[preset]
|
||||
|
||||
|
||||
def user_audit_cmd():
|
||||
"""Return bash cmd to audit users, SUID binaries, world-writable files, sudoers, recent logins."""
|
||||
return (
|
||||
"echo '=== USERS WITH SHELLS ===' && "
|
||||
"grep -v '/nologin\\|/false\\|/sync' /etc/passwd | cut -d: -f1,6,7 && "
|
||||
"echo '' && echo '=== SUDOERS ===' && "
|
||||
"getent group sudo 2>/dev/null | cut -d: -f4 && "
|
||||
"cat /etc/sudoers.d/* 2>/dev/null | grep -v '^#' | grep -v '^$' && "
|
||||
"echo '' && echo '=== UID 0 ACCOUNTS ===' && "
|
||||
"awk -F: '$3 == 0 {print $1}' /etc/passwd && "
|
||||
"echo '' && echo '=== SUID BINARIES ===' && "
|
||||
"find / -perm -4000 -type f 2>/dev/null | head -30 && "
|
||||
"echo '' && echo '=== WORLD-WRITABLE FILES (non /proc /sys /dev) ===' && "
|
||||
"find / -xdev -type f -perm -0002 2>/dev/null | head -20 && "
|
||||
"echo '' && echo '=== RECENT LOGINS ===' && "
|
||||
"last -n 15 2>/dev/null && "
|
||||
"echo '' && echo '=== FAILED LOGIN ATTEMPTS ===' && "
|
||||
"lastb -n 15 2>/dev/null || journalctl _SYSTEMD_UNIT=sshd.service --no-pager -n 15 2>/dev/null"
|
||||
)
|
||||
|
||||
|
||||
def port_scan_cmd():
|
||||
"""Return bash cmd to scan open ports with ss."""
|
||||
return (
|
||||
"echo '=== LISTENING PORTS ===' && "
|
||||
"ss -tlnp 2>&1 && "
|
||||
"echo '' && echo '=== UDP LISTENERS ===' && "
|
||||
"ss -ulnp 2>&1 && "
|
||||
"echo '' && echo '=== ESTABLISHED CONNECTIONS ===' && "
|
||||
"ss -tnp state established 2>&1 | head -30"
|
||||
)
|
||||
|
||||
|
||||
def ssh_status_cmd():
|
||||
"""Return bash cmd to show current SSH config settings."""
|
||||
return (
|
||||
"echo '=== SSHD CONFIG ===' && "
|
||||
"grep -E '^(Port|PermitRootLogin|PasswordAuthentication|PubkeyAuthentication|"
|
||||
"X11Forwarding|MaxAuthTries|AllowUsers|AllowGroups|Protocol|LoginGraceTime)' "
|
||||
"/etc/ssh/sshd_config 2>/dev/null && "
|
||||
"echo '' && echo '=== SSHD STATUS ===' && "
|
||||
"systemctl status sshd --no-pager -l 2>&1 | head -15 && "
|
||||
"echo '' && echo '=== AUTHORIZED KEYS ===' && "
|
||||
"for u in $(awk -F: '$3>=1000{print $1}' /etc/passwd) root; do "
|
||||
" f=\"/home/$u/.ssh/authorized_keys\"; "
|
||||
" [ \"$u\" = 'root' ] && f='/root/.ssh/authorized_keys'; "
|
||||
" if [ -f \"$f\" ]; then echo \"$u: $(wc -l < \"$f\") keys\"; fi; "
|
||||
"done"
|
||||
)
|
||||
|
||||
|
||||
def kernel_status_cmd():
|
||||
"""Return bash cmd to show current sysctl security settings."""
|
||||
return (
|
||||
"echo '=== SYSCTL SECURITY SETTINGS ===' && "
|
||||
"sysctl net.ipv4.tcp_syncookies "
|
||||
"net.ipv4.conf.all.rp_filter "
|
||||
"net.ipv4.icmp_echo_ignore_broadcasts "
|
||||
"net.ipv4.conf.all.accept_redirects "
|
||||
"net.ipv4.conf.all.send_redirects "
|
||||
"net.ipv4.conf.all.accept_source_route "
|
||||
"net.ipv6.conf.all.accept_redirects "
|
||||
"kernel.randomize_va_space "
|
||||
"net.ipv4.tcp_max_syn_backlog "
|
||||
"net.ipv4.tcp_synack_retries "
|
||||
"fs.protected_hardlinks "
|
||||
"fs.protected_symlinks 2>&1 && "
|
||||
"echo '' && echo '=== HARDENING CONFIG FILE ===' && "
|
||||
"cat /etc/sysctl.d/99-hardening.conf 2>/dev/null || echo 'No hardening config found'"
|
||||
)
|
||||
Reference in New Issue
Block a user