From 5b5533553ccd47cc61098f3a5ea6eade04ed3ec5 Mon Sep 17 00:00:00 2001 From: Lightemerald Date: Sat, 13 Dec 2025 17:02:57 +0100 Subject: [PATCH] Adding [WIP] debian hardening script --- debian-hardening.sh | 387 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 387 insertions(+) create mode 100644 debian-hardening.sh diff --git a/debian-hardening.sh b/debian-hardening.sh new file mode 100644 index 0000000..5b3506b --- /dev/null +++ b/debian-hardening.sh @@ -0,0 +1,387 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Debian Hardening Script +# Adapted from the Arch Linux hardening script (arch-hardening.sh) +# Run as root or via sudo + +export DEBIAN_FRONTEND=noninteractive + +log() { + echo "[$(date --rfc-3339=seconds)] $*" >&2 +} + +log_warn() { + echo "[$(date --rfc-3339=seconds)] WARNING: $*" >&2 +} + +log_error() { + echo "[$(date --rfc-3339=seconds)] ERROR: $*" >&2 +} + +# Update system +log "Updating packages..." +sudo apt-get update +sudo apt-get upgrade -y + +# [STRG-1846] Disable drivers like firewire +log "Disabling FireWire kernel modules..." +sudo tee /etc/modprobe.d/firewire-disable.conf > /dev/null < /dev/null + sudo systemctl restart systemd-resolved +fi + +# [USB-3000] Ensure USBGUARD is installed and configured +log "Installing usbguard..." +sudo apt-get install -y usbguard +if command -v usbguard >/dev/null 2>&1; then + sudo usbguard generate-policy | sudo tee /etc/usbguard/rules.conf > /dev/null + sudo sed -i 's/^PresentControllerPolicy=.*/PresentControllerPolicy=apply-policy/' /etc/usbguard/usbguard-daemon.conf || true + sudo systemctl enable --now usbguard +fi + +# [NETW-3032] Ensure arpwatch is installed and enabled +log "Installing arpwatch..." +sudo apt-get install -y arpwatch +iface=$(ip -o link show | awk -F': ' '{print $2}' | sed 's/@.*$//' | grep -Ev '^(lo|virbr|vmbr)' | head -n1 || true) +if [ -n "$iface" ]; then + sudo systemctl enable --now "arpwatch@${iface}.service" || true +else + log_warn "No suitable network interface found for arpwatch; service not enabled." +fi + +# [NETW-3200] Disable unused network protocols +log "Disabling unused network protocol modules..." +sudo tee /etc/modprobe.d/network-protocols-disable.conf > /dev/null </dev/null 2>&1; then + sudo apt-get remove -y iptables || true +fi +sudo apt-get install -y nftables + +sudo tee /etc/modprobe.d/ip_tables-disable.conf > /dev/null < /dev/null <<'EOL' +[Coredump] +ProcessSizeMax=0 +Storage=none +EOL +sudo systemctl daemon-reload || true + +sudo mkdir -p /etc/security/limits.d/ +sudo tee /etc/security/limits.d/20-disable-core-dumps.conf > /dev/null </dev/null; then + echo '# Disable core dumps system-wide' | sudo tee -a /etc/profile > /dev/null + echo 'ulimit -c 0 > /dev/null 2>&1' | sudo tee -a /etc/profile > /dev/null + echo 'ulimit -S -c 0 > /dev/null 2>&1' | sudo tee -a /etc/profile > /dev/null + echo 'ulimit -H -c 0 > /dev/null 2>&1' | sudo tee -a /etc/profile > /dev/null +fi + +# [KRNL-6000] Sysctl settings for kernel hardening +log "Applying sysctl hardened settings..." +sudo tee /etc/sysctl.d/99-hardened.conf > /dev/null <<'EOL' +# Kernel and filesystem hardening settings +kernel.randomize_va_space = 2 +kernel.kptr_restrict = 2 +kernel.unprivileged_bpf_disabled = 1 +#kernel.modules_disabled = 1 # Uncomment to disable module loading entirely at your own risk +kernel.sysrq = 0 +kernel.core_uses_pid = 1 + +fs.suid_dumpable = 0 +fs.protected_fifos = 2 +fs.protected_hardlinks = 1 +fs.protected_regular = 2 +fs.protected_symlinks = 1 + +dev.tty.ldisc_autoload = 0 + +net.core.bpf_jit_harden = 2 + +net.ipv4.conf.all.forwarding = 0 +net.ipv4.conf.all.accept_redirects = 0 +net.ipv4.conf.all.send_redirects = 0 +net.ipv4.conf.all.log_martians = 1 +net.ipv4.conf.all.rp_filter = 1 + +net.ipv4.conf.default.accept_redirects = 0 +net.ipv4.conf.default.log_martians = 1 + +net.ipv6.conf.all.accept_redirects = 0 +net.ipv6.conf.default.accept_redirects = 0 +EOL +sudo sysctl --system + +# [SHLL-6220] Idle session handling +if ! grep -q 'TMOUT' /etc/profile 2>/dev/null; then + echo 'TMOUT=900' | sudo tee -a /etc/profile > /dev/null + echo 'readonly TMOUT' | sudo tee -a /etc/profile > /dev/null + echo 'export TMOUT' | sudo tee -a /etc/profile > /dev/null +fi + +# [MACF-6290] Enable AppArmor +log "Installing and enabling AppArmor..." +sudo apt-get install -y apparmor apparmor-utils +sudo systemctl enable --now apparmor || true + +# [FILE-6344] Restricting process details to users via /proc mount options +log "Configuring /proc to hide process info..." +if ! grep -q '^proc\s\+/proc\s\+proc\s\+' /etc/fstab; then + echo '# /proc' | sudo tee -a /etc/fstab > /dev/null + echo 'proc /proc proc defaults,hidepid=2,gid=wheel 0 0' | sudo tee -a /etc/fstab > /dev/null +else + sudo sed -i 's|^proc[[:space:]]\+/proc[[:space:]]\+proc[[:space:]]\+.*$|proc /proc proc defaults,hidepid=1,gid=wheel 0 0|' /etc/fstab +fi +sudo systemctl daemon-reload +sudo mount -o remount /proc + +# [FILE-6374] Check /dev/shm and /tmp mount options +log "Ensuring /dev/shm and /tmp have secure mount options..." +if ! grep -q '^tmpfs\s\+/dev/shm\s\+tmpfs\s\+' /etc/fstab; then + echo '# /dev/shm' | sudo tee -a /etc/fstab > /dev/null + echo 'tmpfs /dev/shm tmpfs rw,nosuid,nodev,noexec 0 0' | sudo tee -a /etc/fstab > /dev/null +else + sudo sed -i 's|^tmpfs[[:space:]]\+/dev/shm[[:space:]]\+tmpfs[[:space:]]\+.*$|tmpfs /dev/shm tmpfs rw,nosuid,nodev,noexec 0 0|' /etc/fstab +fi +sudo systemctl daemon-reload +sudo mount -o remount /dev/shm + +if ! grep -q '^tmpfs\s\+/tmp\s\+tmpfs\s\+' /etc/fstab; then + echo '# /tmp' | sudo tee -a /etc/fstab > /dev/null + echo 'tmpfs /tmp tmpfs rw,nosuid,nodev,noexec 0 0' | sudo tee -a /etc/fstab > /dev/null +else + sudo sed -i 's|^tmpfs[[:space:]]\+/tmp[[:space:]]\+tmpfs[[:space:]]\+.*$|tmpfs /tmp tmpfs rw,nosuid,nodev,noexec 0 0|' /etc/fstab +fi +sudo systemctl daemon-reload +sudo mount -o remount /tmp + +# [FILE-6430] Disable mounting of some filesystems +log "Disabling unnecessary filesystem modules..." +sudo tee /etc/modprobe.d/fs_blacklist.conf > /dev/null < /dev/null <chmod to restrict access +log "Restricting compiler binaries..." +for bin in /usr/bin/as /usr/bin/gcc /usr/bin/g++ /usr/bin/cc /usr/bin/c++ /usr/bin/ld /usr/bin/lld /usr/bin/clang; do + if [ -f "$bin" ]; then + sudo chmod 700 "$bin" || true + fi +done + +# [PKGS-7320] Install package auditing tools +log "Installing arch-audit equivalent packages..." +# Debian doesn't have arch-audit; install debsecan for security audits +sudo apt-get install -y debsecan || true + +# [FILE-7524] Ensuring file permissions +log "Enforcing file permissions for SSH & cron..." +sudo chmod 600 /etc/ssh/sshd_config || true +sudo chmod 700 /etc/cron.hourly || true + +# [CRYP-8004] Presence of hardware RNG and software PRNG +log "Installing rng-tools and haveged..." +sudo apt-get install -y rng-tools haveged || true +sudo systemctl enable --now rng-tools haveged || true + +# [CRYP-8006] Ensure MemoryOverwriteRequest-bit set (UEFI) using system-shutdown script +sudo tee /usr/lib/systemd/system-shutdown/mor-bit-wipe.sh > /dev/null <<'EOL' +#!/bin/bash +MOR_VAR_PATH="/sys/firmware/efi/efivars/MemoryOverwriteRequestControl-e20939be-32d4-41be-a150-897f85d49829" +if [ -e "$MOR_VAR_PATH" ]; then + printf "\x07\x00\x00\x00\x01" | dd of="$MOR_VAR_PATH" bs=5 count=1 conv=notrunc >/dev/null 2>&1 || true + echo "$(date) - Successfully set MOR-bit for next boot memory wipe." >> /var/log/mor-wipe.log || true +fi +exit 0 +EOL +sudo chmod +x /usr/lib/systemd/system-shutdown/mor-bit-wipe.sh || true + +# [AUTH-*] Password and PAM related settings +log "Configuring password hashing and pam pwquality..." +sudo sed -i 's/^ENCRYPT_METHOD .*/ENCRYPT_METHOD YESCRYPT/' /etc/login.defs || true +sudo sed -i 's/^#SHA_CRYPT_MIN_ROUNDS .*/SHA_CRYPT_MIN_ROUNDS 5000/' /etc/login.defs || true +sudo sed -i 's/^#SHA_CRYPT_MAX_ROUNDS .*/SHA_CRYPT_MAX_ROUNDS 5000000/' /etc/login.defs || true + +sudo apt-get install -y libpam-pwquality || true +sudo tee /etc/security/pwquality.conf > /dev/null </dev/null; then + sudo sed -i "/pam_unix.so/ i password requisite pam_pwquality.so retry=3" /etc/pam.d/common-password || true +fi + +# [AUTH-9286] Password change days +sudo sed -i 's/^PASS_MIN_DAYS.*/PASS_MIN_DAYS 7/' /etc/login.defs || true +sudo sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' /etc/login.defs || true + +# [AUTH-9328] Default umask +sudo sed -i 's/^UMASK.*/UMASK 027/' /etc/login.defs || true +if grep -qE '^[[:space:]]*#?[[:space:]]*umask' /etc/bash.bashrc 2>/dev/null; then + sudo sed -i 's/^[[:space:]]*#\?[[:space:]]*umask.*/umask 027/' /etc/bash.bashrc || true +else + echo 'umask 027' | sudo tee -a /etc/bash.bashrc > /dev/null +fi +if grep -qE '^[[:space:]]*#?[[:space:]]*umask' /etc/profile 2>/dev/null; then + sudo sed -i 's/^[[:space:]]*#\?[[:space:]]*umask.*/umask 027/' /etc/profile || true +else + echo 'umask 027' | sudo tee -a /etc/profile > /dev/null +fi + +# [AUTH-9408] Logging of failed login attempts is enabled +if grep -q FAILLOG_ENAB /etc/login.defs 2>/dev/null; then + sudo sed -i 's/^FAILLOG_ENAB .*/FAILLOG_ENAB yes/' /etc/login.defs || true +else + echo 'FAILLOG_ENAB yes' | sudo tee -a /etc/login.defs > /dev/null +fi + +# [ACCT-9622] Enable process accounting +sudo apt-get install -y acct || true +sudo systemctl enable --now acct || true + +# [ACCT-9626] Enable sysstat +sudo apt-get install -y sysstat || true +sudo systemctl enable --now sysstat || true + +# [ACCT-9628] Enable auditd +sudo apt-get install -y auditd || true +sudo systemctl enable --now auditd || true + +# [ACCT-9630] Configure auditd rules +sudo tee /etc/audit/rules.d/10-harden.rules > /dev/null <