diff --git a/debian-hardening.sh b/debian-hardening.sh index aa59e52..9f6217d 100644 --- a/debian-hardening.sh +++ b/debian-hardening.sh @@ -44,6 +44,7 @@ sudo apt-get install -y needrestart # [DEB-0880] Ensure fail2ban is installed log "Installing fail2ban..." sudo apt-get install -y fail2ban +sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local || true # [STRG-1846] Disable drivers like firewire log "Disabling FireWire kernel modules..." @@ -58,9 +59,9 @@ install firewire-sbp2 /bin/false EOL # [LOGG-2154] Ensure system log is configured to send logs to a remote log server -log "Installing rsyslog..." -sudo apt-get install -y rsyslog -sudo systemctl enable --now rsyslog +log "Installing syslog-ng..." +sudo apt-get install -y syslog-ng +sudo systemctl enable --now syslog-ng # [USB-3000] Ensure USBGUARD is installed and configured log "Installing usbguard..." @@ -92,35 +93,13 @@ blacklist tipc install tipc /bin/false EOL -# [MALW-3276] Install rkhunter and update properties -# log "Installing and configuring rkhunter (MALW-3276)..." -# sudo apt-get install -y rkhunter || true -# if command -v rkhunter >/dev/null 2>&1; then -# sudo rkhunter --update || true -# sudo rkhunter --propupd || true -# # Add common whitelists (reduce false positives) -# 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 -# fi - -# [MALW-3282] Check for clamscan -# log "Checking for ClamAV installation..." -# if ! command -v clamscan >/dev/null 2>&1; then -# log "Installing ClamAV..." -# sudo apt-get install -y clamdscan -# sudo freshclam || true -# else -# log "Clamscan is already installed." -# fi - # [MALW-3284] Check for clamd # log "Checking for clamd..." # if ! command -v clamd >/dev/null 2>&1; then # log "Installing clamd..." -# sudo apt-get install -y clamav clamav-daemon -# sudo systemctl enable --now clamav-daemon || true +# sudo apt-get install -y clamav clamav-daemon clamav-freshclam clamdscan +# sudo systemctl enable --now clamav-daemon clamav-freshclam || true +# sudo freshclam # else # log "Clamd is already installed." # fi @@ -128,11 +107,12 @@ EOL # [FINT-4350] Install a file integrity tool log "Installing AIDE..." sudo apt-get install -y aide -sudo aide --init || true -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 +sudo sed -i 's/^Checksums = .*/Checksums = sha512+sha256/' /etc/aide/aide.conf || true +sudo sed -i 's|^database_in=file:.*|database_in=file:/var/lib/aide/aide.db.gz|' /etc/aide/aide.conf || true +sudo sed -i 's|^database_out=file:.*|database_out=file:/var/lib/aide/aide.db.new.gz|' /etc/aide/aide.conf || true +sudo sed -i 's|^database_new=file:.*|database_new=file:/var/lib/aide/aide.db.new.gz|' /etc/aide/aide.conf || true +sudo aide --init --config /etc/aide/aide.conf || true +sudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz || true # [FIRE-45XX] Firewall configuration: ensure nftables is installed and iptables removed if present log "Disabling iptables to prevent conflicts with nftables (default on debian since Buster)..." @@ -144,21 +124,35 @@ EOL # [BOOT-5122] Check for GRUB boot password log "Setting GRUB boot password..." -GRUB_PW_FILE="/etc/grub.d/40_custom" -if ! grep -q "set superusers=" "$GRUB_PW_FILE" 2>/dev/null; then - read -s -p "Enter GRUB superuser name: " GRUB_USER - echo - read -s -p "Enter GRUB superuser password: " GRUB_PASS - echo - GRUB_PASS_HASH=$(grub-mkpasswd-pbkdf2 <<<"$GRUB_PASS" | awk -F' ' '/PBKDF2 hash of your password is/ {print $7}') - sudo tee -a "$GRUB_PW_FILE" >/dev/null </dev/null 2>&1; then + openssl rand -base64 $((len * 2)) | tr -dc 'A-Za-z0-9@%_+=!#-' | head -c "$len" + else + tr -dc 'A-Za-z0-9@%_+=!#-' /dev/null </dev/null; then @@ -178,6 +172,15 @@ else log "audit_backlog_limit=8192 already present in GRUB_CMDLINE_LINUX; skipping." fi +# ^GRUB_CMDLINE_LINUX=.*apparmor=1 security=apparmor is not present in /etc/default/grub +if ! grep -q 'apparmor=1 security=apparmor' /etc/default/grub 2>/dev/null; then + log "Enabling AppArmor in GRUB_CMDLINE_LINUX..." + sudo sed -i 's|^GRUB_CMDLINE_LINUX="\(.*\)"|GRUB_CMDLINE_LINUX="\1 apparmor=1 security=apparmor"|' /etc/default/grub + sudo update-grub || true +else + log "AppArmor already present in GRUB_CMDLINE_LINUX; skipping." +fi + # [TOOL-5190] Ensure IDS/IPS tools are installed (suricata) # log "Installing suricata..." # sudo apt-get install -y suricata @@ -216,6 +219,7 @@ 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 +kernel.yama.ptrace_scope = 2 fs.suid_dumpable = 0 fs.protected_fifos = 2 @@ -326,11 +330,22 @@ install squashfs /bin/false blacklist udf install udf /bin/false + +#blacklist vfat +#install vfat /bin/false +EOL + +# [USB-1000] Disable loading of usb-storage module +log "Disabling usb-storage kernel module..." +sudo tee /etc/modprobe.d/90-usb-storage-disable.conf >/dev/null </dev/null 2>&1 || true sudo tee /etc/issue >/dev/null </dev/null </dev/null <<'EOL' path-exclude /usr/bin/as path-exclude /usr/bin/x86_64-linux-gnu-as EOL +log "Done checking if as is present and excluding it from installation." # [HRDN-7222] Restricting compiler access to root user only # Correcting from chown->chmod to restrict access @@ -385,6 +402,7 @@ for bin in /usr/bin/as /usr/bin/x86_64-linux-gnu-as; do sudo chmod 700 "$bin" || true fi done +log "Done restricting compiler binaries." # [PKGS-7320] Install package auditing tools log "Installing package auditing..." @@ -394,6 +412,11 @@ sudo apt-get install -y debsecan || true if ! dpkg -l | grep -q debsums; then sudo apt-get install -y debsums || true fi +# Ensure debsums is run weekly via CRON_CHECK=weekly in /etc/default/debsums +if ! grep -q '^CRON_CHECK=weekly' /etc/default/debsums 2>/dev/null; then + log "Configuring debsums to run weekly..." + sudo sed -i 's|^#\?CRON_CHECK=.*|CRON_CHECK=weekly|' /etc/default/debsums || true +fi # [SSH-7408] Check SSH specific defined options log "Checking SSH specific defined options..." @@ -408,36 +431,86 @@ set_sshd_option() { fi } -set_sshd_option "PermitRootLogin" "no" # Need to setup SSH key and local admin -set_sshd_option "PasswordAuthentication" "no" # Need to setup SSH key and local admin -set_sshd_option "ChallengeResponseAuthentication" "no" -set_sshd_option "AllowTcpForwarding" "no" -set_sshd_option "AllowAgentForwarding" "no" -set_sshd_option "X11Forwarding" "no" -set_sshd_option "TCPKeepAlive" "no" -set_sshd_option "ClientAliveCountMax" "2" -set_sshd_option "MaxAuthTries" "3" -set_sshd_option "MaxSessions" "2" +set_sshd_option "Protocol" "2" set_sshd_option "LogLevel" "VERBOSE" +set_sshd_option "X11Forwarding" "no" +set_sshd_option "MaxAuthTries" "3" +set_sshd_option "IgnoreRhosts" "yes" +set_sshd_option "HostbasedAuthentication" "no" +set_sshd_option "PermitRootLogin" "no" +set_sshd_option "PermitEmptyPasswords" "no" +set_sshd_option "PermitUserEnvironment" "no" +set_sshd_option "Ciphers" "chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr" +set_sshd_option "MACs" "hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256" +set_sshd_option "KexAlgorithms" "mlkem768x25519-sha256,sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com" +set_sshd_option "ClientAliveInterval" "300" +set_sshd_option "ClientAliveCountMax" "0" +set_sshd_option "LoginGraceTime" "60" +set_sshd_option "AllowUsers" "*" +set_sshd_option "AllowGroups" "*" +set_sshd_option "DenyUsers" "nobody" +set_sshd_option "DenyGroups" "nobody" +set_sshd_option "Banner" "/etc/issue.net" +set_sshd_option "MaxStartups" "10:30:60" +set_sshd_option "MaxSessions" "2" +set_sshd_option "PubkeyAuthentication" "yes" +set_sshd_option "PasswordAuthentication" "no" +set_sshd_option "KerberosAuthentication" "no" +set_sshd_option "ChallengeResponseAuthentication" "no" +set_sshd_option "GSSAPIAuthentication" "no" +set_sshd_option "GSSAPIKeyExchange" "no" +set_sshd_option "RekeyLimit" "512M 6h" +set_sshd_option "AllowAgentForwarding" "no" +set_sshd_option "AllowTcpForwarding" "no" +set_sshd_option "AllowStreamLocalForwarding" "no" +set_sshd_option "PermitTunnel" "no" +set_sshd_option "PermitUserRC" "no" +set_sshd_option "GatewayPorts" "no" +set_sshd_option "StrictModes" "yes" +set_sshd_option "TCPKeepAlive" "no" +set_sshd_option "Port" "2222" sudo systemctl restart ssh || true +log "Done checking SSH specific defined options." # [PKGS-7420] Detect toolkit to automatically download and apply upgrades log "Installing unattended-upgrades..." sudo apt-get install -y unattended-upgrades || true sudo dpkg-reconfigure -f noninteractive unattended-upgrades || true -sudo tee /etc/apt/apt.conf.d/20auto-upgrades >/dev/null <<'EOL' -APT::Periodic::Unattended-Upgrade "1"; -EOL +if ! sudo grep -q 'Unattended-Upgrade::Automatic-Reboot "true"' /etc/apt/apt.conf.d/50unattended-upgrades 2>/dev/null; then + log "Enabling automatic reboot for unattended-upgrades..." + if sudo grep -q 'Unattended-Upgrade::Automatic-Reboot ' /etc/apt/apt.conf.d/50unattended-upgrades 2>/dev/null; then + sudo sed -ri 's|^[[:space:]]*(//)?[[:space:]]*Unattended-Upgrade::Automatic-Reboot .*|Unattended-Upgrade::Automatic-Reboot "true";|' /etc/apt/apt.conf.d/50unattended-upgrades || true + else + echo 'Unattended-Upgrade::Automatic-Reboot "true";' | sudo tee -a /etc/apt/apt.conf.d/50unattended-upgrades >/dev/null + fi +fi +if ! sudo grep -q 'Unattended-Upgrade::SyslogEnable "true"' /etc/apt/apt.conf.d/50unattended-upgrades 2>/dev/null; then + log "Enabling syslog logging for unattended-upgrades..." + if sudo grep -q 'Unattended-Upgrade::SyslogEnable' /etc/apt/apt.conf.d/50unattended-upgrades 2>/dev/null; then + sudo sed -ri 's|^[[:space:]]*(//)?[[:space:]]*Unattended-Upgrade::SyslogEnable.*|Unattended-Upgrade::SyslogEnable "true";|' /etc/apt/apt.conf.d/50unattended-upgrades || true + else + echo 'Unattended-Upgrade::SyslogEnable "true";' | sudo tee -a /etc/apt/apt.conf.d/50unattended-upgrades >/dev/null + fi +fi sudo systemctl enable --now unattended-upgrades || true # [FILE-7524] Ensuring file permissions log "Enforcing file permissions for SSH & cron..." -#sudo chmod -R 640 /var/log/ || true +sudo chmod -R 640 /var/log/ || true sudo chmod 600 /etc/crontab || true sudo chmod 700 /etc/cron.* || true +sudo chmod 644 /etc/cron.allow || true sudo chmod -R 700 /etc/cron.d/ || true sudo chmod 600 /etc/ssh/sshd_config || true +sudo sed -i 's/^UMASK=0022/UMASK=0027/' /etc/sysstat/sysstat || true +if ! grep -q 'Dir::Log::Umask' /etc/apt/apt.conf.d/99Hardened 2>/dev/null; then + log "Setting apt log umask to 027..." + sudo tee -a /etc/apt/apt.conf.d/99Hardened >/dev/null </dev/null; then + sudo sed -ri 's|^[[:space:]]*#?[[:space:]]*SHA_CRYPT_MIN_ROUNDS.*|SHA_CRYPT_MIN_ROUNDS 5000|' /etc/login.defs || true +else + echo 'SHA_CRYPT_MIN_ROUNDS 5000' | sudo tee -a /etc/login.defs >/dev/null || true +fi + +if sudo grep -Eq '^[[:space:]]*#?[[:space:]]*SHA_CRYPT_MAX_ROUNDS\b' /etc/login.defs 2>/dev/null; then + sudo sed -ri 's|^[[:space:]]*#?[[:space:]]*SHA_CRYPT_MAX_ROUNDS.*|SHA_CRYPT_MAX_ROUNDS 5000000|' /etc/login.defs || true +else + echo 'SHA_CRYPT_MAX_ROUNDS 5000000' | sudo tee -a /etc/login.defs >/dev/null || true +fi sudo apt-get install -y libpam-pwquality || true set_pwq() { @@ -483,19 +565,19 @@ sudo sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' /etc/login.defs || true # [AUTH-9328] Default umask if sudo grep -Eq '^[[:space:]]*#?[[:space:]]*UMASK\b' /etc/login.defs 2>/dev/null; then - sudo sed -ri "s|^[[:space:]]*#?[[:space:]]*UMASK[[:space:]]+.*|UMASK 027|" /etc/login.defs || true + sudo sed -ri "s|^[[:space:]]*#?[[:space:]]*UMASK[[:space:]]+.*|UMASK 077|" /etc/login.defs || true else - echo 'UMASK 027' | sudo tee -a /etc/login.defs >/dev/null + echo 'UMASK 077' | sudo tee -a /etc/login.defs >/dev/null fi 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 + sudo sed -i 's/^[[:space:]]*#\?[[:space:]]*umask.*/umask 077/' /etc/bash.bashrc || true else - echo 'umask 027' | sudo tee -a /etc/bash.bashrc >/dev/null + echo 'umask 077' | 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 + sudo sed -i 's/^[[:space:]]*#\?[[:space:]]*umask.*/umask 077/' /etc/profile || true else - echo 'umask 027' | sudo tee -a /etc/profile >/dev/null + echo 'umask 077' | sudo tee -a /etc/profile >/dev/null fi # [AUTH-9408] Logging of failed login attempts is enabled @@ -541,6 +623,7 @@ sudo tee /etc/audit/rules.d/10-harden.rules >/dev/null </dev/null <=1000 -F auid!=4294967295 -k privileged -a always,exit -F path=/usr/libexec/proxmox-mail-forward -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged -a always,exit -F path=/usr/libexec/pam-tmpdir/pam-tmpdir-helper -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged +-a always,exit -F path=/usr/sbin/exim4 -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged -a always,exit -F path=/usr/sbin/unix_chkpwd -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged -a always,exit -F path=/usr/sbin/mount.cifs -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged -a always,exit -F path=/usr/sbin/mount.nfs -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged @@ -634,6 +718,103 @@ if ! grep -q '^Storage=persistent' /etc/systemd/journald.conf 2>/dev/null; then sudo systemctl restart systemd-journald || true fi +# Fix tcpd is not installed +sudo apt-get install -y tcpd || true + +# Fix Defaults log file not found in sudoers files +log "Configuring sudo to log to /var/log/sudo.log..." +if ! sudo grep -q '^Defaults[[:space:]]\+logfile=' /etc/sudoers; then + sudo bash -c 'echo "Defaults logfile=\"/var/log/sudo.log\"" >> /etc/sudoers' + log "Configured sudo to log to /var/log/sudo.log." +else + log "sudo logfile already configured in /etc/sudoers; skipping." +fi + +# Fix logrotate permissions are not configured +log "Configuring logrotate 'create 0640 root utmp' in /etc/logrotate.conf..." +if ! grep -q '^create[[:space:]]\+0640[[:space:]]\+root[[:space:]]\+utmp' /etc/logrotate.conf; then + sudo tee -a /etc/logrotate.conf >/dev/null <> /etc/pam.d/common-auth' + sudo bash -c 'echo "auth [success=1 default=ignore] pam_faillock.so authfail" >> /etc/pam.d/common-auth' + sudo bash -c 'echo "auth required pam_faillock.so postauth" >> /etc/pam.d/common-auth' + log "Configured pam_faillock in /etc/pam.d/common-auth." +else + log "pam_faillock is already configured in /etc/pam.d/common-auth; skipping." +fi + +# Fix pam_faillock not found in /etc/pam.d/common-account +log "Ensuring pam_faillock is configured in /etc/pam.d/common-account..." +if ! sudo grep -q '^account.*pam_faillock.so' /etc/pam.d/common-account; then + sudo bash -c 'echo "account required pam_faillock.so" >> /etc/pam.d/common-account' + log "Configured pam_faillock in /etc/pam.d/common-account." +else + log "pam_faillock is already configured in /etc/pam.d/common-account; skipping." +fi + +# Fix ^password.*remember is not present in /etc/pam.d/common-password +log "Ensuring password remember is configured in /etc/pam.d/common-password..." +if ! sudo grep -q '^password.*remember' /etc/pam.d/common-password; then + sudo bash -c 'echo "password required pam_unix.so remember=5" >> /etc/pam.d/common-password' + log "Configured password remember in /etc/pam.d/common-password." +else + log "Password remember is already configured in /etc/pam.d/common-password; skipping." +fi + +# Fix ^auth[[:space:]]*required[[:space:]]*pam_wheel.so is not present in /etc/pam.d/su +log "Ensuring pam_wheel is configured in /etc/pam.d/su..." +if ! sudo grep -q '^auth[[:space:]]*required[[:space:]]*pam_wheel.so' /etc/pam.d/su; then + sudo bash -c 'echo "auth required pam_wheel.so" >> /etc/pam.d/su' + log "Configured pam_wheel in /etc/pam.d/su." +else + log "pam_wheel is already configured in /etc/pam.d/su; skipping." +fi + +# Fix ACTION=="add", SUBSYSTEMS=="usb", TEST=="authorized_default", ATTR{authorized_default}="0" is not present in /etc/udev/rules.d +log "Ensuring USB storage devices are disabled via udev rules..." +if [ ! -f /etc/udev/rules.d/85-usb-storage.rules ]; then + sudo tee /etc/udev/rules.d/85-usb-storage.rules >/dev/null <