System Hardening
Quick Reference
# Kernel hardening
sysctl -w kernel.kptr_restrict=2
sysctl -w kernel.dmesg_restrict=1
sysctl -w kernel.randomize_va_space=2
# Network hardening
sysctl -w net.ipv4.conf.all.send_redirects=0
sysctl -w net.ipv4.conf.all.accept_redirects=0
sysctl -w net.ipv4.tcp_syncookies=1
# File permissions
chmod 600 /etc/shadow
chmod 644 /etc/passwd
chmod 700 /root
# Find SUID/SGID files
find / -perm /6000 -type f 2>/dev/null
# Check listening services
ss -tulnp
systemctl list-unit-files --state=enabled
# Audit configuration
auditctl -l
aureport --summary
Hardening Methodology
Defense in Depth
┌─────────────────────────────────────────────────────────────────┐
│ Perimeter │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Network │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ Host │ │ │
│ │ │ ┌─────────────────────────────────────────┐ │ │ │
│ │ │ │ Application │ │ │ │
│ │ │ │ ┌─────────────────────────────────┐ │ │ │ │
│ │ │ │ │ Data │ │ │ │ │
│ │ │ │ └─────────────────────────────────┘ │ │ │ │
│ │ │ └─────────────────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Hardening Priorities
| Priority | Area | Examples |
|---|---|---|
Critical |
Access control, authentication |
SSH hardening, password policies, sudo |
High |
Network security |
Firewall, service exposure, encryption |
Medium |
Kernel/OS hardening |
sysctl, file permissions, SUID |
Standard |
Auditing and monitoring |
auditd, logging, integrity checking |
User and Access Management
Password Policies
/etc/login.defs
# Password aging
PASS_MAX_DAYS 90
PASS_MIN_DAYS 1
PASS_MIN_LEN 12
PASS_WARN_AGE 14
# Encryption method
ENCRYPT_METHOD SHA512
SHA_CRYPT_MIN_ROUNDS 10000
/etc/security/pwquality.conf
# Password quality requirements
minlen = 12
minclass = 3
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
maxrepeat = 3
maxclassrepeat = 4
gecoscheck = 1
dictcheck = 1
usercheck = 1
enforcing = 1
retry = 3
Account Security
# Lock inactive accounts
useradd -D -f 30
# Set account to expire
chage -E 2024-12-31 username
# Lock account
usermod -L username
passwd -l username
# Unlock account
usermod -U username
# Force password change on next login
chage -d 0 username
# Review account expiry
chage -l username
# Find accounts without passwords
awk -F: '($2 == "") {print $1}' /etc/shadow
# Find UID 0 accounts (should only be root)
awk -F: '($3 == 0) {print $1}' /etc/passwd
sudo Configuration
/etc/sudoers (use visudo)
# Require password always
Defaults timestamp_timeout=0
# Secure PATH
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Log all sudo commands
Defaults logfile="/var/log/sudo.log"
# Require TTY
Defaults requiretty
# Environment restrictions
Defaults env_reset
Defaults env_delete="LD_PRELOAD LD_LIBRARY_PATH"
# Limit specific commands
admin ALL=(ALL) /usr/bin/systemctl restart httpd
backup ALL=(ALL) NOPASSWD: /usr/local/bin/backup.sh
SSH Hardening
/etc/ssh/sshd_config.d/hardening.conf
# Authentication
PermitRootLogin no
PasswordAuthentication no
PermitEmptyPasswords no
PubkeyAuthentication yes
AuthenticationMethods publickey
# Restrict users
AllowUsers admin deploy
# Or: AllowGroups ssh-users
# Protocol settings
Protocol 2
X11Forwarding no
MaxAuthTries 3
MaxSessions 2
ClientAliveInterval 300
ClientAliveCountMax 2
LoginGraceTime 60
# Ciphers and MACs
Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org
# Disable unused features
AllowAgentForwarding no
AllowTcpForwarding no
GatewayPorts no
PermitTunnel no
# Logging
LogLevel VERBOSE
# Apply changes
sshd -t # Test configuration
systemctl reload sshd
# Generate strong host keys
rm /etc/ssh/ssh_host_*
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""
Kernel Hardening
sysctl Security Settings
/etc/sysctl.d/99-security.conf
# === Kernel ===
# Restrict access to kernel pointers
kernel.kptr_restrict = 2
# Restrict dmesg access
kernel.dmesg_restrict = 1
# Enable ASLR
kernel.randomize_va_space = 2
# Restrict ptrace
kernel.yama.ptrace_scope = 1
# Disable SysRq
kernel.sysrq = 0
# Disable unprivileged user namespaces
kernel.unprivileged_userns_clone = 0
# Disable core dumps
kernel.core_pattern = |/bin/false
fs.suid_dumpable = 0
# Restrict BPF JIT
net.core.bpf_jit_harden = 2
# === Filesystem ===
# Restrict symlinks and hardlinks
fs.protected_symlinks = 1
fs.protected_hardlinks = 1
fs.protected_fifos = 2
fs.protected_regular = 2
# === Network: IPv4 ===
# Disable IP forwarding
net.ipv4.ip_forward = 0
# Disable ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# Disable source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Enable reverse path filtering
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Ignore ICMP broadcast requests
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Ignore bogus ICMP errors
net.ipv4.icmp_ignore_bogus_error_responses = 1
# Log Martian packets
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# Enable SYN cookies (DoS protection)
net.ipv4.tcp_syncookies = 1
# Disable TCP timestamps (privacy)
net.ipv4.tcp_timestamps = 0
# === Network: IPv6 ===
# Disable IPv6 if not needed
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
# Or if IPv6 is needed, harden it:
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_ra = 0
net.ipv6.conf.default.accept_ra = 0
# Apply settings
sysctl -p /etc/sysctl.d/99-security.conf
# Verify settings
sysctl kernel.kptr_restrict
sysctl net.ipv4.tcp_syncookies
Kernel Module Restrictions
/etc/modprobe.d/blacklist-security.conf
# Disable unused filesystems
install cramfs /bin/true
install freevxfs /bin/true
install jffs2 /bin/true
install hfs /bin/true
install hfsplus /bin/true
install squashfs /bin/true
install udf /bin/true
# Disable unused network protocols
install dccp /bin/true
install sctp /bin/true
install rds /bin/true
install tipc /bin/true
# Disable USB storage (if not needed)
install usb-storage /bin/true
# Disable Firewire (if not needed)
install firewire-core /bin/true
install firewire-ohci /bin/true
File System Security
File Permissions
# Critical system files
chmod 600 /etc/shadow
chmod 600 /etc/gshadow
chmod 644 /etc/passwd
chmod 644 /etc/group
# SSH
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/*.pub
# Cron
chmod 600 /etc/crontab
chmod 700 /etc/cron.d
chmod 700 /etc/cron.daily
chmod 700 /etc/cron.hourly
chmod 700 /etc/cron.monthly
chmod 700 /etc/cron.weekly
# Root directory
chmod 700 /root
# Log files
chmod 640 /var/log/*.log
chmod 600 /var/log/audit/audit.log
# Verify no world-writable files
find /etc -type f -perm -002 -ls
find /var -type f -perm -002 -ls
SUID/SGID Files
# Find SUID files
find / -perm -4000 -type f 2>/dev/null
# Find SGID files
find / -perm -2000 -type f 2>/dev/null
# Find both
find / -perm /6000 -type f 2>/dev/null
# Remove SUID/SGID if not needed
chmod u-s /path/to/file
chmod g-s /path/to/file
# Common SUID files to review:
# /usr/bin/passwd - Required
# /usr/bin/sudo - Required
# /usr/bin/su - Required
# /usr/bin/mount - Often not needed for users
# /usr/bin/umount - Often not needed for users
# /usr/bin/chfn - Often not needed
# /usr/bin/chsh - Often not needed
Mount Options
/etc/fstab
# /tmp with restrictions
tmpfs /tmp tmpfs defaults,nodev,nosuid,noexec,size=2G 0 0
# /var/tmp with restrictions
/tmp /var/tmp none bind 0 0
# /home with nosuid
/dev/sda3 /home ext4 defaults,nodev,nosuid 0 2
# /var with nosuid
/dev/sda4 /var ext4 defaults,nodev,nosuid 0 2
# Separate /var/log
/dev/sda5 /var/log ext4 defaults,nodev,nosuid,noexec 0 2
# Separate /var/log/audit
/dev/sda6 /var/log/audit ext4 defaults,nodev,nosuid,noexec 0 2
# /dev/shm restrictions
none /dev/shm tmpfs defaults,nodev,nosuid,noexec 0 0
# Apply without reboot
mount -o remount,nodev,nosuid,noexec /tmp
mount -o remount,nodev,nosuid,noexec /dev/shm
Service Hardening
Minimize Services
# List enabled services
systemctl list-unit-files --state=enabled
# Disable unnecessary services
systemctl disable --now bluetooth.service
systemctl disable --now cups.service
systemctl disable --now avahi-daemon.service
# Mask services to prevent starting
systemctl mask ctrl-alt-del.target
systemctl mask debug-shell.service
# List listening ports
ss -tulnp
# Remove unused packages
dnf remove telnet rsh xinetd tftp-server
apt purge telnet rsh-server xinetd tftpd
systemd Service Hardening
/etc/systemd/system/myservice.service.d/hardening.conf
[Service]
# Filesystem restrictions
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/var/lib/myservice
# Network restrictions
PrivateNetwork=false
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
# Capabilities
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
# User/Group
User=myservice
Group=myservice
DynamicUser=true
# System call filtering
SystemCallFilter=@system-service
SystemCallArchitectures=native
# Memory
MemoryDenyWriteExecute=true
# Proc/Device restrictions
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true
ProtectClock=true
ProtectHostname=true
ProtectProc=invisible
# Misc
LockPersonality=true
RestrictRealtime=true
RestrictSUIDSGID=true
RemoveIPC=true
PrivateDevices=true
# Analyze service security
systemd-analyze security myservice
Network Hardening
Firewall Configuration
# Enable firewall
systemctl enable --now firewalld
# Or: systemctl enable --now nftables
# Default deny incoming
firewall-cmd --set-default-zone=drop
# Allow only necessary services
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
# Rate limiting for SSH
firewall-cmd --permanent --add-rich-rule='rule service name="ssh" limit value="10/m" accept'
TCP Wrappers
/etc/hosts.allow
# Allow SSH from specific networks
sshd: 192.168.1.0/24
sshd: 10.0.0.0/8
/etc/hosts.deny
# Deny all by default
ALL: ALL
fail2ban
/etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
banaction = nftables-multiport
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
[sshd-ddos]
enabled = true
port = ssh
filter = sshd-ddos
logpath = /var/log/auth.log
maxretry = 10
findtime = 60
bantime = 86400
# Enable fail2ban
systemctl enable --now fail2ban
# Check status
fail2ban-client status
fail2ban-client status sshd
# Unban IP
fail2ban-client set sshd unbanip 192.168.1.100
Integrity Checking
AIDE (Advanced Intrusion Detection Environment)
# Install AIDE
dnf install aide
apt install aide
# Initialize database
aide --init
mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
# Check for changes
aide --check
# Update database after legitimate changes
aide --update
mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
/etc/aide.conf (example additions)
# Monitor additional paths
/etc/passwd$ CONTENT_EX
/etc/shadow$ CONTENT_EX
/etc/ssh/sshd_config$ CONTENT_EX
/root/.ssh$ PERMS
/root/.bashrc$ CONTENT_EX
# Exclude frequently changing
!/var/log
!/var/cache
!/proc
!/sys
Package Verification
# Verify installed packages (RPM)
rpm -Va
# Verify specific package
rpm -V openssh-server
# Output meanings:
# S = Size differs
# M = Mode differs
# 5 = MD5 sum differs
# D = Device differs
# L = Link path differs
# U = User differs
# G = Group differs
# T = Time differs
# Verify packages (Debian)
debsums -c
# Verify specific package
debsums openssh-server
Security Auditing
auditd Configuration
/etc/audit/rules.d/security.rules
# Delete all existing rules
-D
# Buffer size
-b 8192
# Failure mode
-f 1
# Monitor authentication
-w /etc/pam.d/ -p wa -k pam
-w /etc/login.defs -p wa -k login
-w /var/log/faillog -p wa -k logins
-w /var/log/lastlog -p wa -k logins
# Monitor sudo
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
# Monitor system files
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/gshadow -p wa -k identity
# Monitor SSH
-w /etc/ssh/sshd_config -p wa -k sshd
# Monitor privilege escalation
-a always,exit -F arch=b64 -S setuid -S setgid -k priv_esc
# Monitor file deletions
-a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -k delete
# Module loading
-w /sbin/insmod -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 immutable
-e 2
# Load rules
augenrules --load
# Check for violations
ausearch -k identity -ts today
aureport --summary
Security Scanning
# OpenSCAP security scan
oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_cis \
--results results.xml \
--report report.html \
/usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml
# Lynis security audit
lynis audit system
# Generate report
lynis audit system --report-file /tmp/lynis-report.log
# Check specific controls
lynis audit --tests CORE-1000,SSH-7408
Quick Hardening Checklist
□ Set strong password policies
□ Configure sudo properly
□ Harden SSH (keys only, no root login)
□ Apply kernel sysctl hardening
□ Disable unnecessary services
□ Configure firewall (default deny)
□ Set restrictive file permissions
□ Remove/restrict SUID/SGID binaries
□ Use restrictive mount options
□ Enable and configure auditd
□ Install and configure AIDE
□ Configure fail2ban
□ Enable SELinux/AppArmor
□ Apply security updates
□ Review and minimize installed packages
Quick Command Reference
# === User Security ===
chage -l username # Check account expiry
passwd -l username # Lock account
usermod -s /sbin/nologin user # Disable login
# === File Permissions ===
find / -perm /6000 -type f # Find SUID/SGID
find / -perm -002 -type f # Find world-writable
chmod u-s /path/file # Remove SUID
# === Service Management ===
systemctl list-unit-files --state=enabled
systemctl disable --now service
systemctl mask service
# === Network ===
ss -tulnp # Listening ports
firewall-cmd --list-all # Firewall rules
# === Auditing ===
auditctl -l # List audit rules
ausearch -k key -ts today # Search audit logs
aureport --summary # Audit summary
# === Integrity ===
aide --check # Check file integrity
rpm -Va # Verify packages (RPM)
debsums -c # Verify packages (Debian)
# === Security Scanning ===
lynis audit system # Security audit
oscap xccdf eval ... # SCAP evaluation