šŸŽ New User? Get 20% off your first purchase with code NEWUSER20 Register Now →
Menu

Categories

Linux Security Audit Checklist: 50-Point Server Hardening Guide (2026)

Linux Security Audit Checklist: 50-Point Server Hardening Guide (2026)

A security audit is a systematic evaluation of your Linux server's security posture. Whether you are preparing for a compliance review, hardening a new server, or conducting a routine check, this 50-point checklist covers every critical security area. Each item includes the verification command and the recommended fix if the check fails.

Section 1: User Access Control (10 Points)

# 1. No empty passwords exist
sudo awk -F: '($2 == "") {print $1}' /etc/shadow
# FIX: sudo passwd -l username (lock account)

# 2. Root login via SSH is disabled
grep "^PermitRootLogin" /etc/ssh/sshd_config
# Expected: PermitRootLogin no

# 3. Password authentication disabled (SSH key only)
grep "^PasswordAuthentication" /etc/ssh/sshd_config
# Expected: PasswordAuthentication no

# 4. No unauthorized users have sudo access
grep -E "^[^#].*ALL=" /etc/sudoers
cat /etc/sudoers.d/*
getent group sudo
# Review: only authorized administrators should be listed

# 5. Inactive accounts are locked or removed
lastlog | grep "Never logged in"
# FIX: sudo usermod -L username (lock inactive accounts)

# 6. Root is the only UID 0 account
grep "x:0:" /etc/passwd
# Expected: Only root should have UID 0

# 7. Password aging policy is configured
grep -E "PASS_MAX_DAYS|PASS_MIN_DAYS|PASS_MIN_LEN" /etc/login.defs
# Recommended: PASS_MAX_DAYS 90, PASS_MIN_DAYS 7, PASS_MIN_LEN 14

# 8. PAM password complexity is enabled
grep pam_pwquality /etc/pam.d/common-password
# FIX: sudo apt install libpam-pwquality

# 9. Login attempt limits (fail2ban or pam_faillock)
systemctl is-active fail2ban
# FIX: sudo apt install fail2ban

# 10. SSH authorized_keys reviewed for unknown keys
find /home -name "authorized_keys" -exec wc -l {} \;

Section 2: SSH Hardening (8 Points)

# 11. SSH on non-default port (reduces automated attacks)
grep "^Port" /etc/ssh/sshd_config

# 12. SSH idle timeout configured
grep -E "ClientAliveInterval|ClientAliveCountMax" /etc/ssh/sshd_config
# Recommended: ClientAliveInterval 300, ClientAliveCountMax 2

# 13. Max auth attempts limited
grep "MaxAuthTries" /etc/ssh/sshd_config
# Recommended: MaxAuthTries 3

# 14. AllowUsers or AllowGroups restricts SSH access
grep -E "AllowUsers|AllowGroups" /etc/ssh/sshd_config

# 15. X11 Forwarding disabled
grep "X11Forwarding" /etc/ssh/sshd_config
# Expected: X11Forwarding no

# 16. Strong ciphers and MACs configured
grep -E "^Ciphers|^MACs|^KexAlgorithms" /etc/ssh/sshd_config

# 17. Host keys use strong algorithms (ed25519, RSA 4096)
ls -la /etc/ssh/ssh_host_*_key

# 18. SSH banner warns unauthorized access
grep "^Banner" /etc/ssh/sshd_config

Section 3: Firewall and Network (8 Points)

# 19. Firewall is active
sudo ufw status || sudo firewall-cmd --state
# Expected: active / running

# 20. Default deny policy for incoming traffic
sudo ufw status verbose | head -5
# Expected: Default: deny (incoming)

# 21. Only necessary ports are open
sudo ss -tuln
# Review each listening port and justify its need

# 22. No unnecessary services running
systemctl list-units --type=service --state=running
# Disable: telnet, rsh, rlogin, finger, etc.

# 23. IP forwarding disabled (unless router/VPN)
sysctl net.ipv4.ip_forward
# Expected: 0

# 24. ICMP redirects disabled
sysctl net.ipv4.conf.all.accept_redirects
# Expected: 0

# 25. SYN flood protection enabled
sysctl net.ipv4.tcp_syncookies
# Expected: 1

# 26. Source routing disabled
sysctl net.ipv4.conf.all.accept_source_route
# Expected: 0

Section 4: System Updates and Patching (5 Points)

# 27. System is fully updated
sudo apt update && apt list --upgradable
# Expected: no security updates pending

# 28. Automatic security updates enabled
dpkg -l | grep unattended-upgrades
# FIX: sudo apt install unattended-upgrades

# 29. Running kernel is current
uname -r
# Compare with latest available kernel

# 30. Reboot pending check
[ -f /var/run/reboot-required ] && echo "REBOOT NEEDED" || echo "OK"

# 31. Package integrity verified
sudo debsums -c 2>/dev/null | head -20

Section 5: Logging and Monitoring (7 Points)

# 32. System logging is active
systemctl status rsyslog || systemctl status systemd-journald

# 33. Auth logs are being recorded
tail -5 /var/log/auth.log

# 34. Log rotation is configured
ls /etc/logrotate.d/

# 35. fail2ban is active and monitoring SSH
sudo fail2ban-client status sshd

# 36. Auditd is running for system call auditing
systemctl status auditd
# FIX: sudo apt install auditd

# 37. Remote log forwarding configured (critical servers)
grep -E "^[^#].*@" /etc/rsyslog.conf

# 38. NTP time synchronization active
timedatectl status | grep "NTP synchronized"
# Expected: NTP synchronized: yes

Section 6: File System Security (7 Points)

# 39. No world-writable files in system directories
find /etc /usr /var -type f -perm -o+w 2>/dev/null | head -10
# Expected: empty

# 40. SUID/SGID files reviewed
find / -perm -4000 -type f 2>/dev/null | sort
# Review: each SUID binary must be justified

# 41. /tmp mounted with noexec
mount | grep /tmp
# Recommended: noexec,nosuid,nodev

# 42. Home directory permissions are restrictive
ls -la /home/
# Expected: drwx------ (700) for each user

# 43. Critical config file permissions correct
stat -c "%a %n" /etc/shadow /etc/gshadow /etc/passwd
# Expected: shadow 640, passwd 644

# 44. No unowned files exist
find / -nouser -o -nogroup 2>/dev/null | head -10

# 45. File integrity monitoring active (AIDE or OSSEC)
aide --check 2>/dev/null || echo "AIDE not configured"
# FIX: sudo apt install aide && sudo aideinit

Section 7: Application Security (5 Points)

# 46. Web server has security headers
curl -sI https://your-site.com | grep -iE "strict-transport|x-frame|content-security"
# Expected: HSTS, X-Frame-Options, CSP present

# 47. Database only accessible from localhost
ss -tuln | grep -E "5432|3306|27017"
# Expected: 127.0.0.1 only, NOT 0.0.0.0

# 48. SSL certificates are valid and not expiring
echo | openssl s_client -connect your-site.com:443 2>/dev/null | openssl x509 -noout -dates
# Expected: notAfter more than 30 days away

# 49. Default/test pages removed
curl -s http://localhost/server-status 2>/dev/null | head -3
# Expected: 404 or 403

# 50. Application runs as non-root user
ps aux | grep -E "nginx|apache|node|php" | head -5
# Expected: www-data or dedicated service user, NOT root

Scoring Guide

ScoreRatingAction Required
45-50ExcellentWell hardened - maintain with regular audits
35-44GoodAddress gaps within 30 days
25-34Needs WorkPrioritize critical fixes immediately
0-24CriticalServer is at high risk - harden before anything else

Automating Your Audit

You can automate this checklist with tools like:

  • Lynis - Comprehensive security auditing tool (sudo apt install lynis && sudo lynis audit system)
  • OpenSCAP - Compliance checking against CIS benchmarks
  • CIS-CAT - Official CIS Benchmark assessment tool
  • Custom scripts - Automate this checklist as a bash script for regular runs

Download our Linux Security Audit Checklist PDF for a printable version you can use during your audits with checkboxes for each item.

Share this article:
Dorian Thorne
About the Author

Dorian Thorne

Cloud Infrastructure, Cloud Architecture, Infrastructure Automation, Technical Documentation

Dorian Thorne is a cloud infrastructure specialist and technical author focused on the design, deployment, and operation of scalable cloud-based systems.

He has extensive experience working with cloud platforms and modern infrastructure practices, including virtualized environments, cloud networking, identity and acces...

Cloud Computing Cloud Networking Identity and Access Management Infrastructure as Code System Reliability

Stay Updated

Subscribe to our newsletter for the latest tutorials, tips, and exclusive offers.