Fixing MOR-bit set when efi var is immutable, improving some parts and taking improved configs from CIS hardening guide

This commit is contained in:
2025-12-21 18:47:04 +00:00
parent 4b476e8782
commit bae5c65794
2 changed files with 344 additions and 203 deletions

View File

@@ -1,14 +1,22 @@
#!/bin/bash #!/bin/bash
log() {
echo "[$(date --rfc-3339=seconds)] $*" >&2
}
# Update system
log "Updating system packages..."
sudo pacman -Syu --noconfirm
# [STRG-1846] Disable drivers like firewire # [STRG-1846] Disable drivers like firewire
sudo tee /etc/modprobe.d/firewire-disable.conf > /dev/null <<EOL log "Disabling FireWire kernel modules..."
sudo tee /etc/modprobe.d/90-firewire-disable.conf >/dev/null <<EOL
# Disable FireWire kernel modules to prevent unauthorized DMA access # Disable FireWire kernel modules to prevent unauthorized DMA access
blacklist firewire-core blacklist firewire-core
install firewire-core /bin/false install firewire-core /bin/false
# Optional additional modules to blacklist
blacklist firewire-ohci blacklist firewire-ohci
blacklist firewire-sbp2
install firewire-ohci /bin/false install firewire-ohci /bin/false
blacklist firewire-sbp2
install firewire-sbp2 /bin/false install firewire-sbp2 /bin/false
EOL EOL
@@ -17,12 +25,12 @@ sudo pacman -S --noconfirm --needed syslog-ng
sudo systemctl enable --now syslog-ng@default.service sudo systemctl enable --now syslog-ng@default.service
# [NETW-2706] Ensure DNSSEC validation is enabled # [NETW-2706] Ensure DNSSEC validation is enabled
echo 'DNSSEC=yes' | sudo tee -a /etc/systemd/resolved.conf > /dev/null echo 'DNSSEC=yes' | sudo tee -a /etc/systemd/resolved.conf >/dev/null
sudo systemctl restart systemd-resolved sudo systemctl restart systemd-resolved
# [USB-3000] Ensure USBGUARD is installed and configured # [USB-3000] Ensure USBGUARD is installed and configured
sudo pacman -S --noconfirm --needed usbguard sudo pacman -S --noconfirm --needed usbguard
sudo usbguard generate-policy | sudo tee /etc/usbguard/rules.conf > /dev/null 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 sudo sed -i 's/^PresentControllerPolicy=.*/PresentControllerPolicy=apply-policy/' /etc/usbguard/usbguard-daemon.conf
sudo systemctl enable --now usbguard sudo systemctl enable --now usbguard
@@ -31,13 +39,14 @@ sudo pacman -S --noconfirm --needed arpwatch
# Find first non-loopback, non-virbr/vmbr interface and enable arpwatch on it # Find first non-loopback, non-virbr/vmbr interface and enable arpwatch on it
iface=$(ip -o link show | awk -F': ' '{print $2}' | sed 's/@.*$//' | grep -Ev '^(lo|virbr|vmbr)' | head -n1) iface=$(ip -o link show | awk -F': ' '{print $2}' | sed 's/@.*$//' | grep -Ev '^(lo|virbr|vmbr)' | head -n1)
if [ -n "$iface" ]; then if [ -n "$iface" ]; then
sudo systemctl enable --now "arpwatch@${iface}.service" sudo systemctl enable --now "arpwatch@${iface}.service"
else else
echo "No suitable network interface found for arpwatch; service not enabled." >&2 echo "No suitable network interface found for arpwatch; service not enabled." >&2
fi fi
# [NETW-3200] Disable unused network protocols # [NETW-3200] Disable unused network protocols
sudo tee /etc/modprobe.d/network-protocols-disable.conf > /dev/null <<EOL log "Disabling unused network protocol modules..."
sudo tee /etc/modprobe.d/90-network-protocols-disable.conf >/dev/null <<EOL
# Disable unnecessary network protocols to reduce attack surface # Disable unnecessary network protocols to reduce attack surface
blacklist dccp blacklist dccp
install dccp /bin/false install dccp /bin/false
@@ -53,19 +62,17 @@ install tipc /bin/false
EOL EOL
# [MALW-3276] Ensure rkhunter is installed # [MALW-3276] Ensure rkhunter is installed
sudo pacman -S --noconfirm --needed rkhunter #sudo pacman -S --noconfirm --needed rkhunter
sudo rkhunter --propupd #sudo rkhunter --propupd
sudo echo 'SCRIPTWHITELIST=/usr/bin/egrep' | sudo tee -a /etc/rkhunter.conf > /dev/null #sudo echo 'SCRIPTWHITELIST=/usr/bin/egrep' | sudo tee -a /etc/rkhunter.conf >/dev/null
sudo echo 'SCRIPTWHITELIST=/usr/bin/fgrep' | sudo tee -a /etc/rkhunter.conf > /dev/null #sudo echo 'SCRIPTWHITELIST=/usr/bin/fgrep' | sudo tee -a /etc/rkhunter.conf >/dev/null
sudo echo 'SCRIPTWHITELIST=/usr/bin/ldd' | sudo tee -a /etc/rkhunter.conf > /dev/null #sudo echo 'SCRIPTWHITELIST=/usr/bin/ldd' | sudo tee -a /etc/rkhunter.conf >/dev/null
sudo echo 'SCRIPTWHITELIST=/usr/bin/rkhunter' | sudo tee -a /etc/rkhunter.conf > /dev/null #sudo echo 'SCRIPTWHITELIST=/usr/bin/rkhunter' | sudo tee -a /etc/rkhunter.conf >/dev/null
# [MALW-3282] Ensure ClamAV is installed # [MALW-3282] Ensure ClamAV is installed
sudo pacman -S --noconfirm --needed clamav sudo pacman -S --noconfirm --needed clamav
sudo systemctl enable --now clamav-daemon clamav-freshclam
sudo freshclam sudo freshclam
sudo systemctl enable --now clamav-freshclam
sleep 5
sudo systemctl enable --now clamav-daemon
# [FINT-4350] Install a file integrity tool # [FINT-4350] Install a file integrity tool
sudo pacman -S --noconfirm --needed aide sudo pacman -S --noconfirm --needed aide
@@ -75,12 +82,10 @@ sudo systemctl enable --now aidecheck.timer
# [FIRE-45XX] Firewall configuration # [FIRE-45XX] Firewall configuration
# remove iptables if installed # remove iptables if installed
if pacman -Qi iptables &> /dev/null; then log "Installing nftables and iptables-nft..."
sudo pacman -R --noconfirm iptables sudo pacman -S --noconfirm --needed nftables iptables-nft
fi log "Disabling iptables to prevent conflicts with nftables (default on debian since Buster)..."
sudo pacman -S --noconfirm --needed nftables sudo tee /etc/modprobe.d/90-ip_tables-disable.conf >/dev/null <<EOL
sudo tee /etc/modprobe.d/ip_tables-disable.conf > /dev/null <<EOL
# Disable ip_tables to prevent conflicts with nftables # Disable ip_tables to prevent conflicts with nftables
blacklist ip_tables blacklist ip_tables
install ip_tables /bin/false install ip_tables /bin/false
@@ -91,10 +96,9 @@ sudo pacman -S --noconfirm --needed snort
sudo systemctl enable --now snort sudo systemctl enable --now snort
# [KRNL-5820] Disable core dumps # [KRNL-5820] Disable core dumps
log "Disabling core dumps via systemd and limits..."
# Disable coredump handling in systemd's coredump configuration and mask units
sudo mkdir -p /etc/systemd/coredump.conf.d sudo mkdir -p /etc/systemd/coredump.conf.d
sudo tee /etc/systemd/coredump.conf.d/99-disable-coredumps.conf > /dev/null <<'EOL' sudo tee /etc/systemd/coredump.conf.d/99-disable-coredumps.conf >/dev/null <<'EOL'
[Coredump] [Coredump]
# Prevent any core file data being stored and limit accepted size to 0 # Prevent any core file data being stored and limit accepted size to 0
ProcessSizeMax=0 ProcessSizeMax=0
@@ -103,22 +107,22 @@ EOL
sudo systemctl daemon-reload sudo systemctl daemon-reload
sudo mkdir -p /etc/security/limits.d/ sudo mkdir -p /etc/security/limits.d/
sudo tee /etc/security/limits.d/20-disable-core-dumps.conf > /dev/null <<EOL sudo tee /etc/security/limits.d/20-disable-core-dumps.conf >/dev/null <<EOL
# Disable core dumps for ALL users # Disable core dumps for ALL users
# The format is: <domain> <type> <item> <value> # The format is: <domain> <type> <item> <value>
* hard core 0 * hard core 0
* soft core 0 * soft core 0
EOL EOL
# Append to /etc/profile to enforce core dump restriction system-wide # Append to /etc/profile to enforce core dump restriction system-wide
echo '# Disable core dumps system-wide' | sudo tee -a /etc/profile > /dev/null if ! grep -q "ulimit -c 0" /etc/profile 2>/dev/null; then
echo 'ulimit -c 0 > /dev/null 2>&1' | sudo tee -a /etc/profile > /dev/null echo '# Disable core dumps system-wide' | sudo tee -a /etc/profile >/dev/null
echo '# Set the core dump soft limit to 0 (current enforceable limit)' | 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 -S -c 0 > /dev/null 2>&1' | sudo tee -a /etc/profile >/dev/null
echo '# Set the hard limit to 0 (absolute maximum limit)' | sudo tee -a /etc/profile > /dev/null echo 'ulimit -H -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] Check sysctl settings for kernel hardening # [KRNL-6000] Check sysctl settings for kernel hardening
sudo tee /etc/sysctl.d/99-hardened.conf > /dev/null <<'EOL' sudo tee /etc/sysctl.d/99-hardened.conf >/dev/null <<'EOL'
# Kernel and filesystem hardening settings # Kernel and filesystem hardening settings
kernel.randomize_va_space = 2 kernel.randomize_va_space = 2
kernel.kptr_restrict = 2 kernel.kptr_restrict = 2
@@ -140,22 +144,30 @@ net.core.bpf_jit_harden = 2
net.ipv4.conf.all.forwarding = 0 net.ipv4.conf.all.forwarding = 0
net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.log_martians = 1 net.ipv4.conf.default.log_martians = 1
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv6.conf.all.accept_redirects = 0 net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0 net.ipv6.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_ra = 0
net.ipv6.conf.default.accept_ra = 0
EOL EOL
sudo sysctl --system sudo sysctl --system
# [SHLL-6220] Idle session handling # [SHLL-6220] Idle session handling
echo 'TMOUT=900' | sudo tee -a /etc/profile > /dev/null echo 'TMOUT=900' | sudo tee -a /etc/profile >/dev/null
echo 'readonly TMOUT' | 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 echo 'export TMOUT' | sudo tee -a /etc/profile >/dev/null
# [MACF-6290] Enable MAC framework (AppArmor) # [MACF-6290] Enable MAC framework (AppArmor)
sudo pacman -S --noconfirm --needed apparmor apparmor.d-git sudo pacman -S --noconfirm --needed apparmor apparmor.d-git
@@ -164,46 +176,57 @@ sudo systemctl enable --now apparmor
# [FILE-6344] Restricting process details to users # [FILE-6344] Restricting process details to users
## Editing fstab ## Editing fstab
if ! grep -q '^proc\s\+/proc\s\+proc\s\+' /etc/fstab; then if ! grep -q '^proc\s\+/proc\s\+proc\s\+' /etc/fstab; then
echo '# /proc' | sudo tee -a /etc/fstab > /dev/null 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 echo 'proc /proc proc defaults,hidepid=2,gid=wheel 0 0' | sudo tee -a /etc/fstab >/dev/null
else else
sudo sed -i 's|^proc[[:space:]]\+/proc[[:space:]]\+proc[[:space:]]\+.*$|proc /proc proc defaults,hidepid=1,gid=wheel 0 0|' /etc/fstab sudo sed -i 's|^proc[[:space:]]\+/proc[[:space:]]\+proc[[:space:]]\+.*$|proc /proc proc defaults,hidepid=1,gid=wheel 0 0|' /etc/fstab
fi fi
## Remount /proc to apply changes immediately ## Remount /proc to apply changes immediately
sudo systemctl daemon-reload sudo systemctl daemon-reload
sudo mount -o remount /proc sudo mount -o remount /proc
# [FILE-6374] Check mount options # [FILE-6374] Check /dev, /dev/shm and /tmp mount options
# if /dev/shm is not in /etc/fstab, add it with the correct options log "Ensuring /dev, /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 if ! grep -q '^devtmpfs\s\+/dev\s\+devtmpfs\s\+' /etc/fstab; then
echo 'tmpfs /dev/shm tmpfs rw,nosuid,nodev,noexec 0 0' | sudo tee -a /etc/fstab > /dev/null echo '# /dev' | sudo tee -a /etc/fstab >/dev/null
echo 'devtmpfs /dev devtmpfs rw,nosuid,noexec,relatime,size=10%,mode=755 0 0' | sudo tee -a /etc/fstab >/dev/null
else else
sudo sed -i 's|^tmpfs[[:space:]]\+/dev/shm[[:space:]]\+tmpfs[[:space:]]\+.*$|tmpfs /dev/shm tmpfs rw,nosuid,nodev,noexec 0 0|' /etc/fstab sudo sed -i 's|^devtmpfs[[:space:]]\+/dev[[:space:]]\+devtmpfs[[:space:]]\+.*$|devtmpfs /dev devtmpfs rw,nosuid,noexec,relatime,size=10%,mode=755 0 0|' /etc/fstab
fi
sudo systemctl daemon-reload
sudo mount -o remount /dev
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 fi
# Remount /dev/shm to apply changes immediately
sudo systemctl daemon-reload sudo systemctl daemon-reload
sudo mount -o remount /dev/shm sudo mount -o remount /dev/shm
# Replace /tmp mount
if ! grep -q '^tmpfs\s\+/tmp\s\+tmpfs\s\+' /etc/fstab; then if ! grep -q '^tmpfs\s\+/tmp\s\+tmpfs\s\+' /etc/fstab; then
echo '# /tmp' | sudo tee -a /etc/fstab > /dev/null 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 echo 'tmpfs /tmp tmpfs rw,nosuid,nodev,noexec 0 0' | sudo tee -a /etc/fstab >/dev/null
else else
sudo sed -i 's|^tmpfs[[:space:]]\+/tmp[[:space:]]\+tmpfs[[:space:]]\+.*$|tmpfs /tmp tmpfs rw,nosuid,nodev,noexec 0 0|' /etc/fstab sudo sed -i 's|^tmpfs[[:space:]]\+/tmp[[:space:]]\+tmpfs[[:space:]]\+.*$|tmpfs /tmp tmpfs rw,nosuid,nodev,noexec 0 0|' /etc/fstab
fi fi
# Remount /tmp to apply changes immediately
sudo systemctl daemon-reload sudo systemctl daemon-reload
sudo mount -o remount /tmp sudo mount -o remount /tmp
# [FILE-6430] Disable mounting of some filesystems # [FILE-6430] Disable mounting of some filesystems
sudo tee /etc/modprobe.d/fs_blacklist.conf > /dev/null <<EOL sudo tee /etc/modprobe.d/fs_blacklist.conf >/dev/null <<EOL
# Blacklist unnecessary filesystem modules to reduce attack surface # Blacklist unnecessary filesystem modules to reduce attack surface
# Cramfs (Compressed ROM filesystem) # Cramfs (Compressed ROM filesystem)
blacklist cramfs blacklist cramfs
install cramfs /bin/false install cramfs /bin/false
# FreeVXFS (Veritas filesystem)
blacklist freevxfs
install freevxfs /bin/false
# HFS and HFS+ (Apple filesystems) # HFS and HFS+ (Apple filesystems)
blacklist hfs blacklist hfs
install hfs /bin/false install hfs /bin/false
@@ -225,7 +248,9 @@ install udf /bin/false
EOL EOL
# [BANN-7126] Add legal banner to /etc/issue # [BANN-7126] Add legal banner to /etc/issue
sudo tee /etc/issue > /dev/null <<EOL log "Adding legal banner to /etc/issue..."
sudo systemctl disable --now pvebanner || true
sudo tee /etc/issue >/dev/null <<EOL
******************************************************************** ********************************************************************
* WARNING - UNAUTHORIZED ACCESS * * WARNING - UNAUTHORIZED ACCESS *
* * * *
@@ -241,17 +266,38 @@ sudo tee /etc/issue > /dev/null <<EOL
\n - \l \n - \l
EOL EOL
# [BANN-7130] Check issue.net banner file contents
log "Checking /etc/issue.net banner file contents..."
if ! sudo grep -q "WARNING - UNAUTHORIZED ACCESS" /etc/issue.net; then
log "Adding legal banner to /etc/issue.net..."
sudo tee /etc/issue.net >/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
fi
# [HRDN-7220] Don't install /usr/bin/as by adding it to NoExtract # [HRDN-7220] Don't install /usr/bin/as by adding it to NoExtract
if sudo grep -q 'usr/bin/as' /etc/pacman.conf; then if sudo grep -q 'usr/bin/as' /etc/pacman.conf; then
: # already present : # already present
else else
if sudo grep -qE '^[[:space:]]*NoExtract' /etc/pacman.conf; then if sudo grep -qE '^[[:space:]]*NoExtract' /etc/pacman.conf; then
sudo sed -i '0,/^[[:space:]]*NoExtract/ s|^\([[:space:]]*NoExtract[[:space:]]*=[[:space:]]*\)\(.*\)$|\1\2 usr/bin/as|' /etc/pacman.conf sudo sed -i '0,/^[[:space:]]*NoExtract/ s|^\([[:space:]]*NoExtract[[:space:]]*=[[:space:]]*\)\(.*\)$|\1\2 usr/bin/as|' /etc/pacman.conf
elif sudo grep -qE '^[[:space:]]*#[[:space:]]*NoExtract' /etc/pacman.conf; then elif sudo grep -qE '^[[:space:]]*#[[:space:]]*NoExtract' /etc/pacman.conf; then
sudo sed -i '/^[[:space:]]*#[[:space:]]*NoExtract/ a NoExtract = usr/bin/as' /etc/pacman.conf sudo sed -i '/^[[:space:]]*#[[:space:]]*NoExtract/ a NoExtract = usr/bin/as' /etc/pacman.conf
else else
sudo bash -c 'printf "\n# NoExtract added by hardening script\nNoExtract = usr/bin/as\n" >> /etc/pacman.conf' sudo bash -c 'printf "\n# NoExtract added by hardening script\nNoExtract = usr/bin/as\n" >> /etc/pacman.conf'
fi fi
fi fi
# [HRDN-7222] Restricting compilator access to root user only # [HRDN-7222] Restricting compilator access to root user only
@@ -280,7 +326,7 @@ sudo systemctl enable --now rngd
#sudo systemctl enable --now haveged #sudo systemctl enable --now haveged
# [CRYP-8006] Ensure MemoryOverwriteRequest-bit set # [CRYP-8006] Ensure MemoryOverwriteRequest-bit set
sudo tee /usr/lib/systemd/system-shutdown/mor-bit-wipe.shutdown > /dev/null <<'EOL' sudo tee /usr/lib/systemd/system-shutdown/mor-bit-wipe.shutdown >/dev/null <<'EOL'
#!/bin/bash #!/bin/bash
# Path to the MemoryOverwriteRequestControl UEFI variable # Path to the MemoryOverwriteRequestControl UEFI variable
@@ -288,8 +334,11 @@ MOR_VAR_PATH="/sys/firmware/efi/efivars/MemoryOverwriteRequestControl-e20939be-3
# Check if the UEFI variable path exists # Check if the UEFI variable path exists
if [ -e "$MOR_VAR_PATH" ]; then if [ -e "$MOR_VAR_PATH" ]; then
# The expected format is: Attributes (4 bytes) + Value (1 byte for MOR state) # The expected format is: Attributes (4 bytes) + Value (1 byte for MOR state)
# We need to write 5 bytes in total: 0x07 0x00 0x00 0x00 (Attributes) + 0x01 (MOR-bit set) # We need to write 5 bytes in total: 0x07 0x00 0x00 0x00 (Attributes) + 0x01 (MOR-bit set)
# Removing immutable on the efi variable
chattr -i "$MOR_VAR" 2>/dev/null
# Use printf to create the necessary 5-byte data and write it to the variable # Use printf to create the necessary 5-byte data and write it to the variable
# 0x01 means MOR is SET (request memory wipe) # 0x01 means MOR is SET (request memory wipe)
@@ -310,16 +359,26 @@ sudo sed -i 's/^#SHA_CRYPT_MAX_ROUNDS .*/SHA_CRYPT_MAX_ROUNDS 5000000/' /etc/log
# [AUTH-9262] Password strength checking tool is installed # [AUTH-9262] Password strength checking tool is installed
sudo pacman -S --noconfirm --needed libpwquality sudo pacman -S --noconfirm --needed libpwquality
sudo tee /etc/security/pwquality.conf > /dev/null <<EOL set_pwq() {
# PAM pwquality configuration file local key="$1"
retry = 3 local val="$2"
difok = 6 if sudo grep -Eq "^[[:space:]]*${key}[[:space:]]*=" /etc/security/pwquality.conf 2>/dev/null; then
minlen = 14 sudo sed -ri "s|^[[:space:]]*${key}[[:space:]]*=.*|${key} = ${val}|" /etc/security/pwquality.conf
dcredit = -1 else
ucredit = -1 sudo sh -c "printf '%s = %s\n' '${key}' '${val}' >> /etc/security/pwquality.conf"
ocredit = -1 fi
lcredit = -1 }
EOL
set_pwq "retry" 3
set_pwq "difok" 6
set_pwq "minlen" 14
set_pwq "dcredit" -1
set_pwq "ucredit" -1
set_pwq "ocredit" -1
set_pwq "lcredit" -1
set_pwq "minclass" 4
set_pwq "usercheck" 1
set_pwq "enforcing" 1
sudo sed -i '/^password\s*required\s*pam_unix.so\s*try_first_pass\s*nullok\s*shadow/i password required pam_pwquality.so' /etc/pam.d/system-auth sudo sed -i '/^password\s*required\s*pam_unix.so\s*try_first_pass\s*nullok\s*shadow/i password required pam_pwquality.so' /etc/pam.d/system-auth
@@ -328,23 +387,27 @@ sudo sed -i 's/^PASS_MIN_DAYS.*/PASS_MIN_DAYS 7/' /etc/login.defs
sudo sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' /etc/login.defs sudo sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' /etc/login.defs
# [AUTH-9328] Ensure default user umask is 027 or more restrictive # [AUTH-9328] Ensure default user umask is 027 or more restrictive
sudo sed -i 's/^UMASK.*/UMASK 027/' /etc/login.defs if sudo grep -Eq '^[[:space:]]*#?[[:space:]]*UMASK\b' /etc/login.defs 2>/dev/null; then
if sudo grep -qE '^[[:space:]]*#?[[:space:]]*umask' /etc/bash.bashrc; then sudo sed -ri "s|^[[:space:]]*#?[[:space:]]*UMASK[[:space:]]+.*|UMASK 027|" /etc/login.defs || true
sudo sed -i 's/^[[:space:]]*#\?[[:space:]]*umask.*/umask 027/' /etc/bash.bashrc
else else
echo 'umask 027' | sudo tee -a /etc/bash.bashrc > /dev/null echo 'UMASK 027' | sudo tee -a /etc/login.defs >/dev/null
fi
if sudo grep -qE '^[[:space:]]*#?[[:space:]]*umask' /etc/bash.bashrc; then
sudo sed -i 's/^[[:space:]]*#\?[[:space:]]*umask.*/umask 027/' /etc/bash.bashrc
else
echo 'umask 027' | sudo tee -a /etc/bash.bashrc >/dev/null
fi fi
if sudo grep -qE '^[[:space:]]*#?[[:space:]]*umask' /etc/profile; then if sudo grep -qE '^[[:space:]]*#?[[:space:]]*umask' /etc/profile; then
sudo sed -i 's/^[[:space:]]*#\?[[:space:]]*umask.*/umask 027/' /etc/profile sudo sed -i 's/^[[:space:]]*#\?[[:space:]]*umask.*/umask 027/' /etc/profile
else else
echo 'umask 027' | sudo tee -a /etc/profile > /dev/null echo 'umask 027' | sudo tee -a /etc/profile >/dev/null
fi fi
# [AUTH-9408] Logging of failed login attempts is enabled # [AUTH-9408] Logging of failed login attempts is enabled
if sudo grep FAILLOG_ENAB /etc/login.defs; then if sudo grep FAILLOG_ENAB /etc/login.defs; then
sudo sed -i 's/^FAILLOG_ENAB .*/FAILLOG_ENAB yes/' /etc/login.defs sudo sed -i 's/^FAILLOG_ENAB .*/FAILLOG_ENAB yes/' /etc/login.defs
else else
echo 'FAILLOG_ENAB yes' | sudo tee -a /etc/login.defs > /dev/null echo 'FAILLOG_ENAB yes' | sudo tee -a /etc/login.defs >/dev/null
fi fi
# [ACCT-9622] Enable process accounting # [ACCT-9622] Enable process accounting
@@ -353,21 +416,98 @@ sudo systemctl enable --now acct
# [ACCT-9626] Enable sysstat to collect accounting data # [ACCT-9626] Enable sysstat to collect accounting data
sudo pacman -S --noconfirm --needed sysstat sudo pacman -S --noconfirm --needed sysstat
sudo systemctl enable --now sysstat-collect.timer sysstat-rotate.timer sudo systemctl enable --now sysstat.service sysstat-collect.timer sysstat-rotate.timer
# [ACCT-9628] Enable auditd to collect audit data # [ACCT-9628] Enable auditd to collect audit data
sudo systemctl enable --now auditd audit-rules sudo systemctl enable --now auditd audit-rules
# [ACCT-9630] Configure auditd rules # [ACCT-9630] Configure auditd rules
sudo tee /etc/audit/rules.d/10-harden.rules > /dev/null <<EOL sudo tee /etc/audit/rules.d/10-harden.rules >/dev/null <<EOL
# Monitor attempts to change system time -a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change
-w /etc/localtime -p wa -k time-change -a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change
-a always,exit -F arch=b64 -S clock_settime -k time-change
-a always,exit -F arch=b32 -S clock_settime -k time-change
# Monitor attempts to change user/group info (password changes) -w /etc/group -p wa -k identity
-w /etc/passwd -p wa -k user-info -w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k user-info -w /etc/gshadow -p wa -k identity
-w /etc/group -p wa -k user-info -w /etc/shadow -p wa -k identity
-w /etc/gshadow -p wa -k user-info -w /etc/security/opasswd -p wa -k identity
-a exit,always -F arch=b64 -S sethostname -S setdomainname -k system-locale
-a exit,always -F arch=b32 -S sethostname -S setdomainname -k system-locale
-w /etc/issue -p wa -k system-locale
-w /etc/issue.net -p wa -k system-locale
-w /etc/hosts -p wa -k system-locale
-w /etc/network -p wa -k system-locale
-w /etc/apparmor/ -p wa -k MAC-policy
-w /etc/apparmor.d/ -p wa -k MAC-policy
-w /var/log/faillog -p wa -k logins
-w /var/log/lastlog -p wa -k logins
-w /var/log/tallylog -p wa -k logins
-w /var/run/utmp -p wa -k session
-w /var/log/wtmp -p wa -k session
-w /var/log/btmp -p wa -k session
-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b64 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod
-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access
-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access
-a always,exit -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access
-a always,exit -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access
-a always,exit -F path=/usr/bin/chage -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/chfn -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/chsh -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/expiry -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/gpasswd -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/mount -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/newgrp -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/passwd -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/ssh-agent -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/su -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/umount -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/crontab -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/fusermount3 -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/dotlockfile -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/lockfile -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/procmail -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/newgidmap -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/newuidmap -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/bin/sudo -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/lib/openssh/ssh-keysign -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/lib/dbus-1.0/dbus-daemon-launch-helper -F perm=x -F auid>=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/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
-a always,exit -F path=/usr/sbin/postdrop -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F path=/usr/sbin/postqueue -F perm=x -F auid>=1000 -F auid!=4294967295 -k privileged
-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts
-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts
-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete
-a always,exit -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=1000 -F auid!=4294967295 -k delete
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
-w /var/log/auth.log -p wa -k sudoaction
-w /sbin/insmod -p x -k modules
-w /sbin/rmmod -p x -k modules
-w /sbin/modprobe -p x -k modules
-a always,exit -F arch=b64 -S init_module -S delete_module -k modules
# Make the configuration immutable (must be the last line) # Make the configuration immutable (must be the last line)
-e 2 -e 2
@@ -375,11 +515,11 @@ EOL
# To test # To test
# Function to create basic systemd hardening drop-in # Function to create basic systemd hardening drop-in
create_systemd_hardening () { create_systemd_hardening() {
SERVICE="$1" SERVICE="$1"
DROPIN="/etc/systemd/system/${SERVICE}.d" DROPIN="/etc/systemd/system/${SERVICE}.d"
sudo mkdir -p "$DROPIN" sudo mkdir -p "$DROPIN"
sudo tee "$DROPIN/hardening.conf" > /dev/null <<EOL sudo tee "$DROPIN/hardening.conf" >/dev/null <<EOL
[Service] [Service]
PrivateTmp=true PrivateTmp=true
ProtectSystem=full ProtectSystem=full
@@ -395,54 +535,54 @@ RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
SystemCallFilter=@system-service SystemCallFilter=@system-service
UMask=0077 UMask=0077
EOL EOL
sudo systemctl daemon-reload sudo systemctl daemon-reload
} }
# Add conservative hardening overrides for high-risk services you should review # Add conservative hardening overrides for high-risk services you should review
SERVICES_TO_HARDEN=( SERVICES_TO_HARDEN=(
"NetworkManager" "NetworkManager"
"accounts-daemon" "accounts-daemon"
"aidecheck" "aidecheck"
"auditd" "auditd"
"bluetooth" "bluetooth"
"bolt" "bolt"
"dbus-broker" "dbus-broker"
"dirmngr@etc-pacman.d-gnupg" "dirmngr@etc-pacman.d-gnupg"
"dm-event" "dm-event"
"emergency" "emergency"
"firewalld" "firewalld"
"fprintd" "fprintd"
"getty@tty1" "getty@tty1"
"gpg-agent@etc-pacman.d-gnupg" "gpg-agent@etc-pacman.d-gnupg"
"keyboxd@etc-pacman.d-gnupg" "keyboxd@etc-pacman.d-gnupg"
"lenovo-cfgservice" "lenovo-cfgservice"
"libvirtd" "libvirtd"
"meshagent" "meshagent"
"ollama" "ollama"
"packagekit" "packagekit"
"plymouth-start" "plymouth-start"
"rescue" "rescue"
"rtkit-daemon" "rtkit-daemon"
"sddm" "sddm"
"snapper-cleanup" "snapper-cleanup"
"snapper-timeline" "snapper-timeline"
"syslog-ng@default" "syslog-ng@default"
"systemd-ask-password-console" "systemd-ask-password-console"
"systemd-ask-password-plymouth" "systemd-ask-password-plymouth"
"systemd-ask-password-wall" "systemd-ask-password-wall"
"systemd-bsod" "systemd-bsod"
"systemd-rfkill" "systemd-rfkill"
"systemd-importd" "systemd-importd"
"systemd-machined" "systemd-machined"
"systemd-udevd" "systemd-udevd"
"udisks2" "udisks2"
"user@1000" "user@1000"
"virtlockd" "virtlockd"
"waydroid-container" "waydroid-container"
"wpa_supplicant" "wpa_supplicant"
) )
for S in "${SERVICES_TO_HARDEN[@]}"; do for S in "${SERVICES_TO_HARDEN[@]}"; do
if systemctl list-unit-files | grep -q "$S"; then if systemctl list-unit-files | grep -q "$S"; then
create_systemd_hardening "$S" create_systemd_hardening "$S"
fi fi
done done

View File

@@ -7,15 +7,15 @@ set -euo pipefail
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
log() { log() {
echo "[$(date --rfc-3339=seconds)] $*" >&2 echo "[$(date --rfc-3339=seconds)] $*" >&2
} }
log_warn() { log_warn() {
echo "[$(date --rfc-3339=seconds)] WARNING: $*" >&2 echo "[$(date --rfc-3339=seconds)] WARNING: $*" >&2
} }
log_error() { log_error() {
echo "[$(date --rfc-3339=seconds)] ERROR: $*" >&2 echo "[$(date --rfc-3339=seconds)] ERROR: $*" >&2
} }
# Update system # Update system
@@ -47,7 +47,7 @@ sudo apt-get install -y fail2ban
# [STRG-1846] Disable drivers like firewire # [STRG-1846] Disable drivers like firewire
log "Disabling FireWire kernel modules..." log "Disabling FireWire kernel modules..."
sudo tee /etc/modprobe.d/90-firewire-disable.conf > /dev/null <<EOL sudo tee /etc/modprobe.d/90-firewire-disable.conf >/dev/null <<EOL
# Disable FireWire kernel modules to prevent unauthorized DMA access # Disable FireWire kernel modules to prevent unauthorized DMA access
blacklist firewire-core blacklist firewire-core
install firewire-core /bin/false install firewire-core /bin/false
@@ -66,9 +66,9 @@ sudo systemctl enable --now rsyslog
log "Installing usbguard..." log "Installing usbguard..."
sudo apt-get install -y usbguard sudo apt-get install -y usbguard
if command -v usbguard >/dev/null 2>&1; then if command -v usbguard >/dev/null 2>&1; then
sudo usbguard generate-policy | sudo tee /etc/usbguard/rules.conf > /dev/null 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 sed -i 's/^PresentControllerPolicy=.*/PresentControllerPolicy=apply-policy/' /etc/usbguard/usbguard-daemon.conf || true
sudo systemctl enable --now usbguard sudo systemctl enable --now usbguard
fi fi
# [NETW-3032] Checking for ARP monitoring software # [NETW-3032] Checking for ARP monitoring software
@@ -77,7 +77,7 @@ sudo apt-get install -y arpon
# [NETW-3200] Disable unused network protocols # [NETW-3200] Disable unused network protocols
log "Disabling unused network protocol modules..." log "Disabling unused network protocol modules..."
sudo tee /etc/modprobe.d/90-network-protocols-disable.conf > /dev/null <<EOL sudo tee /etc/modprobe.d/90-network-protocols-disable.conf >/dev/null <<EOL
# Disable unnecessary network protocols to reduce attack surface # Disable unnecessary network protocols to reduce attack surface
blacklist dccp blacklist dccp
install dccp /bin/false install dccp /bin/false
@@ -130,13 +130,13 @@ log "Installing AIDE..."
sudo apt-get install -y aide sudo apt-get install -y aide
sudo aide --init || true sudo aide --init || true
if [ -f /var/lib/aide/aide.db.new.gz ]; then 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 sudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz || true
fi fi
sudo systemctl enable --now aidecheck.timer || true sudo systemctl enable --now aidecheck.timer || true
# [FIRE-45XX] Firewall configuration: ensure nftables is installed and iptables removed if present # [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)..." log "Disabling iptables to prevent conflicts with nftables (default on debian since Buster)..."
sudo tee /etc/modprobe.d/90-ip_tables-disable.conf > /dev/null <<EOL sudo tee /etc/modprobe.d/90-ip_tables-disable.conf >/dev/null <<EOL
# Disable ip_tables to prevent conflicts with nftables # Disable ip_tables to prevent conflicts with nftables
blacklist ip_tables blacklist ip_tables
install ip_tables /bin/false install ip_tables /bin/false
@@ -150,8 +150,8 @@ if ! grep -q "set superusers=" "$GRUB_PW_FILE" 2>/dev/null; then
echo echo
read -s -p "Enter GRUB superuser password: " GRUB_PASS read -s -p "Enter GRUB superuser password: " GRUB_PASS
echo echo
GRUB_PASS_HASH=$(grub-mkpasswd-pbkdf2 <<< "$GRUB_PASS" | awk -F' ' '/PBKDF2 hash of your password is/ {print $7}') 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 <<EOL sudo tee -a "$GRUB_PW_FILE" >/dev/null <<EOL
set superusers="$GRUB_USER" set superusers="$GRUB_USER"
password_pbkdf2 $GRUB_USER $GRUB_PASS_HASH password_pbkdf2 $GRUB_USER $GRUB_PASS_HASH
EOL EOL
@@ -186,7 +186,7 @@ fi
# [KRNL-5820] Disable core dumps # [KRNL-5820] Disable core dumps
log "Disabling core dumps via systemd and limits..." log "Disabling core dumps via systemd and limits..."
sudo mkdir -p /etc/systemd/coredump.conf.d sudo mkdir -p /etc/systemd/coredump.conf.d
sudo tee /etc/systemd/coredump.conf.d/99-disable-coredumps.conf > /dev/null <<'EOL' sudo tee /etc/systemd/coredump.conf.d/99-disable-coredumps.conf >/dev/null <<'EOL'
[Coredump] [Coredump]
ProcessSizeMax=0 ProcessSizeMax=0
Storage=none Storage=none
@@ -194,21 +194,21 @@ EOL
sudo systemctl daemon-reload || true sudo systemctl daemon-reload || true
sudo mkdir -p /etc/security/limits.d/ sudo mkdir -p /etc/security/limits.d/
sudo tee /etc/security/limits.d/20-disable-core-dumps.conf > /dev/null <<EOL sudo tee /etc/security/limits.d/20-disable-core-dumps.conf >/dev/null <<EOL
* hard core 0 * hard core 0
* soft core 0 * soft core 0
EOL EOL
# Append to /etc/profile to enforce core dump restriction system-wide # Append to /etc/profile to enforce core dump restriction system-wide
if ! grep -q "ulimit -c 0" /etc/profile 2>/dev/null; then 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 '# 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 -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 -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 echo 'ulimit -H -c 0 > /dev/null 2>&1' | sudo tee -a /etc/profile >/dev/null
fi fi
# [KRNL-6000] Sysctl settings for kernel hardening # [KRNL-6000] Sysctl settings for kernel hardening
log "Applying sysctl hardened settings..." log "Applying sysctl hardened settings..."
sudo tee /etc/sysctl.d/99-hardened.conf > /dev/null <<'EOL' sudo tee /etc/sysctl.d/99-hardened.conf >/dev/null <<'EOL'
# Kernel and filesystem hardening settings # Kernel and filesystem hardening settings
kernel.randomize_va_space = 2 kernel.randomize_va_space = 2
kernel.kptr_restrict = 2 kernel.kptr_restrict = 2
@@ -251,9 +251,9 @@ sudo sysctl --system
# [SHLL-6220] Idle session handling # [SHLL-6220] Idle session handling
if ! grep -q 'TMOUT' /etc/profile 2>/dev/null; then if ! grep -q 'TMOUT' /etc/profile 2>/dev/null; then
echo 'TMOUT=900' | sudo tee -a /etc/profile > /dev/null echo 'TMOUT=900' | sudo tee -a /etc/profile >/dev/null
echo 'readonly TMOUT' | 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 echo 'export TMOUT' | sudo tee -a /etc/profile >/dev/null
fi fi
# [MACF-6290] Enable MAC framework (AppArmor) # [MACF-6290] Enable MAC framework (AppArmor)
@@ -264,10 +264,10 @@ sudo systemctl enable --now apparmor || true
# [FILE-6344] Restricting process details to users via /proc mount options # [FILE-6344] Restricting process details to users via /proc mount options
log "Configuring /proc to hide process info..." log "Configuring /proc to hide process info..."
if ! grep -q '^proc\s\+/proc\s\+proc\s\+' /etc/fstab; then if ! grep -q '^proc\s\+/proc\s\+proc\s\+' /etc/fstab; then
echo '# /proc' | sudo tee -a /etc/fstab > /dev/null echo '# /proc' | sudo tee -a /etc/fstab >/dev/null
echo 'proc /proc proc defaults,hidepid=2,gid=sudo 0 0' | sudo tee -a /etc/fstab > /dev/null echo 'proc /proc proc defaults,hidepid=2,gid=sudo 0 0' | sudo tee -a /etc/fstab >/dev/null
else else
sudo sed -i 's|^proc[[:space:]]\+/proc[[:space:]]\+proc[[:space:]]\+.*$|proc /proc proc defaults,hidepid=2,gid=sudo 0 0|' /etc/fstab sudo sed -i 's|^proc[[:space:]]\+/proc[[:space:]]\+proc[[:space:]]\+.*$|proc /proc proc defaults,hidepid=2,gid=sudo 0 0|' /etc/fstab
fi fi
sudo systemctl daemon-reload sudo systemctl daemon-reload
sudo mount -o remount /proc sudo mount -o remount /proc
@@ -276,8 +276,8 @@ sudo mount -o remount /proc
log "Ensuring /dev, /dev/shm and /tmp have secure mount options..." log "Ensuring /dev, /dev/shm and /tmp have secure mount options..."
if ! grep -q '^devtmpfs\s\+/dev\s\+devtmpfs\s\+' /etc/fstab; then if ! grep -q '^devtmpfs\s\+/dev\s\+devtmpfs\s\+' /etc/fstab; then
echo '# /dev' | sudo tee -a /etc/fstab > /dev/null echo '# /dev' | sudo tee -a /etc/fstab >/dev/null
echo 'devtmpfs /dev devtmpfs rw,nosuid,noexec,relatime,size=10%,mode=755 0 0' | sudo tee -a /etc/fstab > /dev/null echo 'devtmpfs /dev devtmpfs rw,nosuid,noexec,relatime,size=10%,mode=755 0 0' | sudo tee -a /etc/fstab >/dev/null
else else
sudo sed -i 's|^devtmpfs[[:space:]]\+/dev[[:space:]]\+devtmpfs[[:space:]]\+.*$|devtmpfs /dev devtmpfs rw,nosuid,noexec,relatime,size=10%,mode=755 0 0|' /etc/fstab sudo sed -i 's|^devtmpfs[[:space:]]\+/dev[[:space:]]\+devtmpfs[[:space:]]\+.*$|devtmpfs /dev devtmpfs rw,nosuid,noexec,relatime,size=10%,mode=755 0 0|' /etc/fstab
fi fi
@@ -285,26 +285,26 @@ sudo systemctl daemon-reload
sudo mount -o remount /dev sudo mount -o remount /dev
if ! grep -q '^tmpfs\s\+/dev/shm\s\+tmpfs\s\+' /etc/fstab; then if ! grep -q '^tmpfs\s\+/dev/shm\s\+tmpfs\s\+' /etc/fstab; then
echo '# /dev/shm' | sudo tee -a /etc/fstab > /dev/null 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 echo 'tmpfs /dev/shm tmpfs rw,nosuid,nodev,noexec 0 0' | sudo tee -a /etc/fstab >/dev/null
else else
sudo sed -i 's|^tmpfs[[:space:]]\+/dev/shm[[:space:]]\+tmpfs[[:space:]]\+.*$|tmpfs /dev/shm tmpfs rw,nosuid,nodev,noexec 0 0|' /etc/fstab sudo sed -i 's|^tmpfs[[:space:]]\+/dev/shm[[:space:]]\+tmpfs[[:space:]]\+.*$|tmpfs /dev/shm tmpfs rw,nosuid,nodev,noexec 0 0|' /etc/fstab
fi fi
sudo systemctl daemon-reload sudo systemctl daemon-reload
sudo mount -o remount /dev/shm sudo mount -o remount /dev/shm
if ! grep -q '^tmpfs\s\+/tmp\s\+tmpfs\s\+' /etc/fstab; then if ! grep -q '^tmpfs\s\+/tmp\s\+tmpfs\s\+' /etc/fstab; then
echo '# /tmp' | sudo tee -a /etc/fstab > /dev/null 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 echo 'tmpfs /tmp tmpfs rw,nosuid,nodev,noexec 0 0' | sudo tee -a /etc/fstab >/dev/null
else else
sudo sed -i 's|^tmpfs[[:space:]]\+/tmp[[:space:]]\+tmpfs[[:space:]]\+.*$|tmpfs /tmp tmpfs rw,nosuid,nodev,noexec 0 0|' /etc/fstab sudo sed -i 's|^tmpfs[[:space:]]\+/tmp[[:space:]]\+tmpfs[[:space:]]\+.*$|tmpfs /tmp tmpfs rw,nosuid,nodev,noexec 0 0|' /etc/fstab
fi fi
sudo systemctl daemon-reload sudo systemctl daemon-reload
sudo mount -o remount /tmp sudo mount -o remount /tmp
# [FILE-6430] Disable mounting of some filesystems # [FILE-6430] Disable mounting of some filesystems
log "Disabling unnecessary filesystem modules..." log "Disabling unnecessary filesystem modules..."
sudo tee /etc/modprobe.d/90-fs_blacklist.conf > /dev/null <<EOL sudo tee /etc/modprobe.d/90-fs_blacklist.conf >/dev/null <<EOL
# Blacklist unnecessary filesystem modules to reduce attack surface # Blacklist unnecessary filesystem modules to reduce attack surface
blacklist cramfs blacklist cramfs
install cramfs /bin/false install cramfs /bin/false
@@ -331,7 +331,7 @@ EOL
# [BANN-7126] Add legal banner to /etc/issue # [BANN-7126] Add legal banner to /etc/issue
log "Adding legal banner to /etc/issue..." log "Adding legal banner to /etc/issue..."
sudo systemctl disable --now pvebanner || true sudo systemctl disable --now pvebanner || true
sudo tee /etc/issue > /dev/null <<EOL sudo tee /etc/issue >/dev/null <<EOL
******************************************************************** ********************************************************************
* WARNING - UNAUTHORIZED ACCESS * * WARNING - UNAUTHORIZED ACCESS *
* * * *
@@ -350,8 +350,8 @@ EOL
# [BANN-7130] Check issue.net banner file contents # [BANN-7130] Check issue.net banner file contents
log "Checking /etc/issue.net banner file contents..." log "Checking /etc/issue.net banner file contents..."
if ! sudo grep -q "WARNING - UNAUTHORIZED ACCESS" /etc/issue.net; then if ! sudo grep -q "WARNING - UNAUTHORIZED ACCESS" /etc/issue.net; then
log "Adding legal banner to /etc/issue.net..." log "Adding legal banner to /etc/issue.net..."
sudo tee /etc/issue.net > /dev/null <<EOL sudo tee /etc/issue.net >/dev/null <<EOL
******************************************************************** ********************************************************************
* WARNING - UNAUTHORIZED ACCESS * * WARNING - UNAUTHORIZED ACCESS *
* * * *
@@ -371,7 +371,7 @@ fi
# [HRDN-7220] Check if one or more compilers are installed # [HRDN-7220] Check if one or more compilers are installed
# Disallow apt to extract /usr/bin/as by making a dpkg config # Disallow apt to extract /usr/bin/as by making a dpkg config
log "Checking if as is present and excluding it from installation..." log "Checking if as is present and excluding it from installation..."
sudo tee /etc/dpkg/dpkg.cfg.d/01-exclude-as > /dev/null <<'EOL' sudo tee /etc/dpkg/dpkg.cfg.d/01-exclude-as >/dev/null <<'EOL'
# Exclude as from being installed # Exclude as from being installed
path-exclude /usr/bin/as path-exclude /usr/bin/as
path-exclude /usr/bin/x86_64-linux-gnu-as path-exclude /usr/bin/x86_64-linux-gnu-as
@@ -381,9 +381,9 @@ EOL
# Correcting from chown->chmod to restrict access # Correcting from chown->chmod to restrict access
log "Restricting compiler binaries..." log "Restricting compiler binaries..."
for bin in /usr/bin/as /usr/bin/x86_64-linux-gnu-as; do for bin in /usr/bin/as /usr/bin/x86_64-linux-gnu-as; do
if [ -f "$bin" ]; then if [ -f "$bin" ]; then
sudo chmod 700 "$bin" || true sudo chmod 700 "$bin" || true
fi fi
done done
# [PKGS-7320] Install package auditing tools # [PKGS-7320] Install package auditing tools
@@ -392,23 +392,23 @@ sudo apt-get install -y debsecan || true
# [PKGS-7370] Checking for debsums utility # [PKGS-7370] Checking for debsums utility
if ! dpkg -l | grep -q debsums; then if ! dpkg -l | grep -q debsums; then
sudo apt-get install -y debsums || true sudo apt-get install -y debsums || true
fi fi
# [SSH-7408] Check SSH specific defined options # [SSH-7408] Check SSH specific defined options
log "Checking SSH specific defined options..." log "Checking SSH specific defined options..."
set_sshd_option() { set_sshd_option() {
local opt="$1" local opt="$1"
local val="$2" local val="$2"
# If the option exists (possibly commented), replace the whole line; otherwise append # If the option exists (possibly commented), replace the whole line; otherwise append
if sudo grep -Eq "^[[:space:]]*#?[[:space:]]*${opt}[[:space:]]+" /etc/ssh/sshd_config 2>/dev/null; then if sudo grep -Eq "^[[:space:]]*#?[[:space:]]*${opt}[[:space:]]+" /etc/ssh/sshd_config 2>/dev/null; then
sudo sed -ri "s|^[[:space:]]*#?[[:space:]]*${opt}[[:space:]]+.*|${opt} ${val}|" /etc/ssh/sshd_config sudo sed -ri "s|^[[:space:]]*#?[[:space:]]*${opt}[[:space:]]+.*|${opt} ${val}|" /etc/ssh/sshd_config
else else
echo "${opt} ${val}" | sudo tee -a /etc/ssh/sshd_config > /dev/null echo "${opt} ${val}" | sudo tee -a /etc/ssh/sshd_config >/dev/null
fi fi
} }
set_sshd_option "PermitRootLogin" "no" # Need to setup SSH key and local admin 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 "PasswordAuthentication" "no" # Need to setup SSH key and local admin
set_sshd_option "ChallengeResponseAuthentication" "no" set_sshd_option "ChallengeResponseAuthentication" "no"
set_sshd_option "AllowTcpForwarding" "no" set_sshd_option "AllowTcpForwarding" "no"
@@ -426,7 +426,7 @@ sudo systemctl restart ssh || true
log "Installing unattended-upgrades..." log "Installing unattended-upgrades..."
sudo apt-get install -y unattended-upgrades || true sudo apt-get install -y unattended-upgrades || true
sudo dpkg-reconfigure -f noninteractive unattended-upgrades || true sudo dpkg-reconfigure -f noninteractive unattended-upgrades || true
sudo tee /etc/apt/apt.conf.d/20auto-upgrades > /dev/null <<'EOL' sudo tee /etc/apt/apt.conf.d/20auto-upgrades >/dev/null <<'EOL'
APT::Periodic::Unattended-Upgrade "1"; APT::Periodic::Unattended-Upgrade "1";
EOL EOL
sudo systemctl enable --now unattended-upgrades || true sudo systemctl enable --now unattended-upgrades || true
@@ -452,7 +452,8 @@ sudo sed -i 's/^#SHA_CRYPT_MAX_ROUNDS .*/SHA_CRYPT_MAX_ROUNDS 5000000/' /etc/log
sudo apt-get install -y libpam-pwquality || true sudo apt-get install -y libpam-pwquality || true
set_pwq() { set_pwq() {
local key="$1"; local val="$2" local key="$1"
local val="$2"
if sudo grep -Eq "^[[:space:]]*${key}[[:space:]]*=" /etc/security/pwquality.conf 2>/dev/null; then if sudo grep -Eq "^[[:space:]]*${key}[[:space:]]*=" /etc/security/pwquality.conf 2>/dev/null; then
sudo sed -ri "s|^[[:space:]]*${key}[[:space:]]*=.*|${key} = ${val}|" /etc/security/pwquality.conf sudo sed -ri "s|^[[:space:]]*${key}[[:space:]]*=.*|${key} = ${val}|" /etc/security/pwquality.conf
else else
@@ -473,7 +474,7 @@ set_pwq "enforcing" 1
# Add pam_pwquality to /etc/pam.d/common-password if not present # 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 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" /etc/pam.d/common-password || true sudo sed -i "/pam_unix.so/ i password requisite pam_pwquality.so" /etc/pam.d/common-password || true
fi fi
# [AUTH-9286] Password aging # [AUTH-9286] Password aging
@@ -484,24 +485,24 @@ sudo sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' /etc/login.defs || true
if sudo grep -Eq '^[[:space:]]*#?[[:space:]]*UMASK\b' /etc/login.defs 2>/dev/null; then 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 027|" /etc/login.defs || true
else else
echo 'UMASK 027' | sudo tee -a /etc/login.defs > /dev/null echo 'UMASK 027' | sudo tee -a /etc/login.defs >/dev/null
fi fi
if grep -qE '^[[:space:]]*#?[[:space:]]*umask' /etc/bash.bashrc 2>/dev/null; then 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 027/' /etc/bash.bashrc || true
else else
echo 'umask 027' | sudo tee -a /etc/bash.bashrc > /dev/null echo 'umask 027' | sudo tee -a /etc/bash.bashrc >/dev/null
fi fi
if grep -qE '^[[:space:]]*#?[[:space:]]*umask' /etc/profile 2>/dev/null; then 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 027/' /etc/profile || true
else else
echo 'umask 027' | sudo tee -a /etc/profile > /dev/null echo 'umask 027' | sudo tee -a /etc/profile >/dev/null
fi fi
# [AUTH-9408] Logging of failed login attempts is enabled # [AUTH-9408] Logging of failed login attempts is enabled
if grep -q FAILLOG_ENAB /etc/login.defs 2>/dev/null; then 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 sudo sed -i 's/^FAILLOG_ENAB .*/FAILLOG_ENAB yes/' /etc/login.defs || true
else else
echo 'FAILLOG_ENAB yes' | sudo tee -a /etc/login.defs > /dev/null echo 'FAILLOG_ENAB yes' | sudo tee -a /etc/login.defs >/dev/null
fi fi
# [ACCT-9622] Enable process accounting # [ACCT-9622] Enable process accounting
@@ -535,7 +536,7 @@ if ! grep -q '^max_log_file_action[[:space:]]*=[[:space:]]*keep_logs' /etc/audit
fi fi
# [ACCT-9630] Configure auditd rules # [ACCT-9630] Configure auditd rules
sudo tee /etc/audit/rules.d/10-harden.rules > /dev/null <<EOL sudo tee /etc/audit/rules.d/10-harden.rules >/dev/null <<EOL
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change -a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change
-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change -a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change
-a always,exit -F arch=b64 -S clock_settime -k time-change -a always,exit -F arch=b64 -S clock_settime -k time-change