You get root on a fresh Linux server. Now what? Default installs β whether Ubuntu, RHEL, Amazon Linux β are not hardened out of the box. This module is your opinionated checklist: the baseline controls every production Linux server should have before it sees traffic.
The hardening stack
- Network β firewall, SSH, services
- Users & authentication β sudo, SSH keys, lockouts
- Filesystem β permissions, mounts, SELinux / AppArmor
- Logging & audit β journald, auditd
- Updates β unattended security patches
- Kernel β sysctl tunings, module blacklists
1. Firewall baseline (ufw / firewalld)
# Ubuntu / Debian β ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp # SSH (restrict source IP if possible)
ufw allow 80,443/tcp # web
ufw enable
# RHEL / CentOS / Amazon Linux β firewalld
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --remove-service=cockpit
firewall-cmd --reload
Default-deny inbound is non-negotiable. Allow only what’s needed, scoped to source IPs where possible.
2. SSH hardening
Edit /etc/ssh/sshd_config:
Port 22 # consider non-default
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding no
AllowUsers deploy admin # whitelist specific users
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
AllowTcpForwarding no
PermitEmptyPasswords no
Protocol 2
Then systemctl reload sshd. Use fail2ban for brute-force protection, but disabling password auth eliminates most brute-force value anyway.
3. Users and sudo
- Disable root login over SSH (above); require SSH key + sudo
- Create individual user accounts β don’t share the deploy account
- Use
visudoto edit /etc/sudoers; prefer/etc/sudoers.d/*drop-ins - Require password for sudo escalation (NOPASSWD for convenience = audit finding)
- Timeout sudo cache:
Defaults timestamp_timeout=5 - Log sudo commands to /var/log/auth.log (default)
4. Automatic security updates
# Debian / Ubuntu
apt install unattended-upgrades
dpkg-reconfigure --priority=low unattended-upgrades
# RHEL / CentOS
dnf install dnf-automatic
systemctl enable --now dnf-automatic.timer
5. Filesystem permissions + mount hardening
Add restrictive mount options in /etc/fstab:
# /tmp β nodev, nosuid, noexec (prevents malware execution from /tmp)
tmpfs /tmp tmpfs defaults,nodev,nosuid,noexec 0 0
# /var/tmp, /dev/shm β same pattern
tmpfs /dev/shm tmpfs defaults,nodev,nosuid,noexec 0 0
Run find / -perm -4000 2>/dev/null to inventory setuid binaries. Remove any that shouldn’t be setuid (e.g. /usr/bin/pkexec has had multiple CVEs).
6. SELinux / AppArmor
Mandatory Access Control prevents compromised services from accessing resources they’re not supposed to:
- SELinux (RHEL/CentOS/Amazon Linux/Fedora) β keep in Enforcing mode.
getenforceshould return Enforcing. - AppArmor (Ubuntu/Debian/SUSE) β
aa-statusshould show multiple enforced profiles. - Never disable MAC to “make things work” β investigate the denial and write a policy exception instead
7. Logging and audit
# Install auditd
apt install auditd # Debian / Ubuntu
dnf install audit # RHEL
# Add critical audit rules (/etc/audit/rules.d/security.rules)
-w /etc/passwd -p wa -k passwd_changes
-w /etc/shadow -p wa -k shadow_changes
-w /var/log -p rwa -k log_changes
-a always,exit -F arch=b64 -S execve -F uid=0 -k root_commands
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid!=0 -k escalation
service auditd restart
# Ship logs offsite β rsyslog to SIEM
# Local logs can be tampered with; ship immediately
8. Kernel sysctl hardening
# /etc/sysctl.d/99-security.conf
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
kernel.yama.ptrace_scope = 2
kernel.randomize_va_space = 2
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.log_martians = 1
fs.suid_dumpable = 0
# Apply
sysctl --system
9. Disable unused services
systemctl list-unit-files --type=service --state=enabled β disable anything not required. Common wins: cups (printing), avahi-daemon, rpcbind, bluetooth on servers.
10. File integrity monitoring
- AIDE or Tripwire β baseline system file hashes; alert on changes
- Run daily via cron, send report to sec team
- Tune to expected changes (logs, /tmp, /var/run) to reduce noise
CIS Benchmarks
The Center for Internet Security publishes detailed hardening benchmarks for every major Linux distro. Run Lynis for automated scoring, or use CIS-provided hardening scripts. Aim for 80%+ CIS compliance as a minimum production baseline.
Quick reference summary
- Default-deny firewall, SSH with key-only auth, no root SSH
- Individual user accounts + sudo with password + command logging
- Automatic security updates (unattended-upgrades / dnf-automatic)
- Harden /tmp, /var/tmp, /dev/shm mount options (nodev,nosuid,noexec)
- Keep SELinux / AppArmor in Enforcing mode
- auditd with rules for passwd, shadow, privilege escalation
- Sysctl: restrict dmesg, randomise ASLR, drop source-routed packets
- Disable unused services; run Lynis + CIS Benchmark annually
- Ship logs off-host to a SIEM β local logs can be tampered
Module Quiz Β· 20 questions
Pass with 70%+ to mark this module complete. Unlimited retries. Each question shows an explanation.