Adding [WIP] debian hardening script

This commit is contained in:
2025-12-13 17:02:57 +01:00
parent fbfe26f8d7
commit 5b5533553c

387
debian-hardening.sh Normal file
View File

@@ -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 <<EOL
# Disable FireWire kernel modules to prevent unauthorized DMA access
blacklist firewire-core
install firewire-core /bin/false
blacklist firewire-ohci
install firewire-ohci /bin/false
blacklist firewire-sbp2
install firewire-sbp2 /bin/false
EOL
# [LOGG-2154] Ensure system log is configured to send logs to a remote log server
# Debian uses rsyslog by default; install rsyslog to match standard Debian setups
log "Installing rsyslog..."
sudo apt-get install -y rsyslog
sudo systemctl enable --now rsyslog
# [NETW-2706] Ensure DNSSEC validation is enabled (systemd-resolved)
log "Enabling DNSSEC in systemd-resolved..."
if [ -f /etc/systemd/resolved.conf ]; then
sudo sed -i '/^DNSSEC=/d' /etc/systemd/resolved.conf || true
echo 'DNSSEC=yes' | sudo tee -a /etc/systemd/resolved.conf > /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 <<EOL
# Disable unnecessary network protocols to reduce attack surface
blacklist dccp
install dccp /bin/false
blacklist sctp
install sctp /bin/false
blacklist rds
install rds /bin/false
blacklist tipc
install tipc /bin/false
EOL
# [MALW-3276] Ensure rkhunter is installed
log "Installing rkhunter..."
sudo apt-get install -y rkhunter
sudo rkhunter --propupd || true
# Add common whitelists
sudo sed -i "$ a SCRIPTWHITELIST=/usr/bin/egrep" /etc/rkhunter.conf || true
sudo sed -i "$ a SCRIPTWHITELIST=/usr/bin/fgrep" /etc/rkhunter.conf || true
sudo sed -i "$ a SCRIPTWHITELIST=/usr/bin/ldd" /etc/rkhunter.conf || true
sudo sed -i "$ a SCRIPTWHITELIST=/usr/bin/rkhunter" /etc/rkhunter.conf || true
# [MALW-3282] Ensure ClamAV is installed
log "Installing ClamAV..."
sudo apt-get install -y clamav clamav-freshclam
sudo freshclam || true
sudo systemctl enable --now clamav-freshclam || true
sleep 2
sudo systemctl enable --now clamav-daemon || true
# [FINT-4350] Install a file integrity tool
log "Installing AIDE..."
sudo apt-get install -y aide
if [ -f /var/lib/aide/aide.db.new.gz ]; then
sudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz || true
fi
sudo systemctl enable --now aidecheck.timer || true
# [FIRE-45XX] Firewall configuration: ensure nftables is installed and iptables removed if present
log "Installing nftables and removing iptables (if installed)..."
if dpkg -s iptables >/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 <<EOL
# Disable ip_tables to prevent conflicts with nftables
blacklist ip_tables
install ip_tables /bin/false
EOL
# [TOOL-5190] Ensure IDS/IPS tools are installed (snort)
log "Installing snort..."
sudo apt-get install -y snort
sudo systemctl enable --now snort || true
# [KRNL-5820] Disable core dumps
log "Disabling core dumps via systemd and limits..."
sudo mkdir -p /etc/systemd/coredump.conf.d
sudo tee /etc/systemd/coredump.conf.d/99-disable-coredumps.conf > /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 <<EOL
* hard core 0
* soft core 0
EOL
# Append to /etc/profile to enforce core dump restriction system-wide
if ! grep -q "ulimit -c 0" /etc/profile 2>/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 <<EOL
# Blacklist unnecessary filesystem modules to reduce attack surface
blacklist cramfs
install cramfs /bin/false
blacklist hfs
install hfs /bin/false
blacklist hfsplus
install hfsplus /bin/false
blacklist jffs2
install jffs2 /bin/false
blacklist squashfs
install squashfs /bin/false
blacklist udf
install udf /bin/false
EOL
# [BANN-7126] Add legal banner to /etc/issue
log "Adding legal banner to /etc/issue..."
sudo tee /etc/issue > /dev/null <<EOL
********************************************************************
* WARNING - UNAUTHORIZED ACCESS *
* *
* Unauthorized access to this computer system is strictly *
* prohibited. Individuals accessing, using, or modifying this *
* system without explicit authorization will be subject to legal *
* action and prosecuted to the fullest extent of the law. *
* *
* Authorized users should have no expectation of privacy. All *
* activity on this system is monitored, recorded, and may be used *
* as evidence in criminal or civil proceedings. *
********************************************************************
\n - \l
EOL
# [HRDN-7222] Restricting compiler access to root user only
# Correcting from chown->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 <<EOL
# PAM pwquality configuration file
retry = 3
difok = 6
minlen = 14
dcredit = -1
ucredit = -1
ocredit = -1
lcredit = -1
EOL
# Add pam_pwquality to /etc/pam.d/common-password if not present
if ! grep -q "pam_pwquality.so" /etc/pam.d/common-password 2>/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 <<EOL
# Monitor attempts to change system time
-w /etc/localtime -p wa -k time-change
# Monitor attempts to change user/group info
-w /etc/passwd -p wa -k user-info
-w /etc/shadow -p wa -k user-info
-w /etc/group -p wa -k user-info
-w /etc/gshadow -p wa -k user-info
# Make the configuration immutable (must be the last line)
-e 2
EOL
log "Debian hardening completed. Review the log above for applied steps and check for any package/service variations on your system."
exit 0