Advertisement
Intermediate Time: 2 weeks IT & Networking

Linux Server Hardening

Implement comprehensive Linux server hardening following CIS Benchmark, DISA STIG, and security best practices with automated audit.

LinuxSecurityHardeningSSHAuditCIS Benchmark
DifficultyIntermediate
Duration2 weeks
Components10 items
Steps6 steps

Introduction

Implement comprehensive Linux server hardening following CIS Benchmark, DISA STIG, and security best practices with automated audit. This comprehensive guide covers everything from design through implementation, testing, and deployment.

Theory & Background

Edit /etc/ssh/sshd_config: PasswordAuthentication no, PermitRootLogin no, PubkeyAuthentication yes, AllowUsers your_username, Port 2222 (non-default), MaxAuthTries 3, LoginGraceTime 30, ClientAliveInterval 300, ClientAliveCountMax 0, Protocol 2, Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com (remove weak ciphers), MACs hmac-sha2-512,hmac-sha2-256. Generate Ed25519 key pair for authentication (stronger than RSA 2048). Disable X11Forwarding unless needed.

Advertisement

Components & Requirements

10 components required for this project.

#ComponentPurposeQty
1Ubuntu 22.04 LTS or RHEL 9Production server OSx1
2Lynis (security auditing tool)Automated security assessmentx1
3AIDE (file integrity monitor)Detecting unauthorized file changesx1
4Fail2BanBrute force protectionx1
5auditdSystem call and file access auditingx1
6AppArmor/SELinuxMandatory access control (MAC)x1
7ClamAVMalware scanningx1
8OpenSCAPCIS Benchmark compliance checkingx1
9Tripwire (optional)Commercial-grade file integrityx1
10Logwatch + GraylogLog management and alertingx1

Step-by-Step Implementation

Follow these 6 steps carefully.

1
SSH Hardening (Most Critical)

Edit /etc/ssh/sshd_config: PasswordAuthentication no, PermitRootLogin no, PubkeyAuthentication yes, AllowUsers your_username, Port 2222 (non-default), MaxAuthTries 3, LoginGraceTime 30, ClientAliveInterval 300, ClientAliveCountMax 0, Protocol 2, Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com (remove weak ciphers), MACs hmac-sha2-512,hmac-sha2-256. Generate Ed25519 key pair for authentication (stronger than RSA 2048). Disable X11Forwarding unless needed.

2
Kernel Security Parameters (sysctl)

Key kernel hardening parameters in /etc/sysctl.d/99-security.conf: net.ipv4.conf.all.accept_redirects=0 (block ICMP redirects), net.ipv4.conf.all.send_redirects=0, net.ipv4.tcp_syncookies=1 (SYN flood protection), kernel.randomize_va_space=2 (full ASLR), kernel.dmesg_restrict=1 (hide kernel info from users), net.ipv4.conf.all.rp_filter=1 (reverse path filtering), fs.suid_dumpable=0 (no core dumps for SUID programs), kernel.sysrq=0 (disable magic SysRq).

3
User Account Security

Lock unused accounts: passwd -l username. Remove unnecessary packages: apt autoremove. Implement strong password policy using /etc/security/pwquality.conf: minlen=14, dcredit=-1, ucredit=-1, lcredit=-1, ocredit=-1. PAM configuration: set FAILDELAY=3000000 (3s delay after failed auth). Set password expiration: chage -M 90 username. Use sudo instead of root: visudo, configure specific commands per user. Check for users with UID 0: awk -F: '$3==0' /etc/passwd.

4
File System Security

Restrict mount options in /etc/fstab: /tmp nodev,nosuid,noexec. /var/tmp nodev,nosuid,noexec. Verify file permissions: find / -perm -4000 (SUID files — investigate any unexpected ones), find / -nouser -nogroup 2>/dev/null (orphaned files). Set umask to 027 in /etc/profile. Install AIDE: aide --init creates baseline database. Weekly cron: aide --check compares current vs baseline, alerts on changes (potential intrusion indicator).

5
Network Security and Firewall

UFW firewall: ufw default deny incoming, ufw default allow outgoing, ufw allow 2222/tcp (SSH), ufw enable. Install and configure fail2ban for SSH: maxretry=3, bantime=3600s, findtime=600s. Disable unnecessary services: systemctl disable avahi-daemon bluetooth cups. Check open ports: ss -tulnp — investigate anything unexpected. Install ClamAV for malware scanning: clamscan -r /home /var/www weekly. Verify no listening services on unintended interfaces.

6
Audit and Compliance

Run Lynis audit: lynis audit system — provides a score (0–100) and prioritized recommendations. Run OpenSCAP against CIS Benchmark: oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_cis --report report.html /usr/share/xml/scap/ssg/ubuntu2204-ds.xml. Configure auditd rules: watch /etc/passwd, /etc/shadow, /etc/sudoers for writes (-w /etc/passwd -p wa -k passwd_changes). Log retention: set logrotate to keep 90 days. Forward logs to centralized SIEM.

Code & Implementation

Core code for harden_server.sh:

harden_server.sh Shell
#!/bin/bash # Linux Server Hardening Checklist Script  # Colors RED='\033[0;31m'; GREEN='\033[0;32m'; NC='\033[0m'  check() { [ "$2" = "PASS" ] && echo -e "✓ PASS: $1" || echo -e "✗ FAIL: $1 - $2"; }  echo "=== SSH Configuration Checks ===" SSH_CFG="/etc/ssh/sshd_config" check "PasswordAuthentication disabled" "$(grep -i '^PasswordAuthentication no' $SSH_CFG 2>/dev/null && echo PASS || echo 'NOT DISABLED')" check "Root login disabled"             "$(grep -i '^PermitRootLogin no' $SSH_CFG && echo PASS || echo 'ENABLED')" check "Protocol 2 only"                 "$(grep -i '^Protocol 2' $SSH_CFG && echo PASS || echo 'CHECK OPENSSH VERSION >=7')"  echo "=== Kernel Security ===" check "ASLR enabled"     "$([ $(sysctl -n kernel.randomize_va_space) -eq 2 ] && echo PASS || echo $(sysctl -n kernel.randomize_va_space))" check "SYN cookies on"   "$([ $(sysctl -n net.ipv4.tcp_syncookies) -eq 1 ] && echo PASS || echo DISABLED)"  echo "=== Firewall Status ===" check "UFW active"       "$(ufw status | grep -q 'active' && echo PASS || echo 'INACTIVE')"  echo "=== Services ===" check "Fail2ban running" "$(systemctl is-active fail2ban 2>/dev/null | grep -q 'active' && echo PASS || echo 'NOT RUNNING')" check "auditd running"   "$(systemctl is-active auditd 2>/dev/null | grep -q 'active' && echo PASS || echo 'NOT RUNNING')"  echo "=== Accounts ===" check "No empty passwords" "$(awk -F: '($2 == \"\") {print $1}' /etc/shadow | grep -q . && echo 'EMPTY PASS FOUND' || echo PASS)"

Testing & Troubleshooting

Test Linux Server Hardening by verifying each subsystem individually before full integration.

!
Troubleshooting Tips

Verify power voltages, check ground connections, use serial monitor for debug.

Real-World Applications

*Production web server security baseline
*Database server hardening
*Financial system compliance
*Healthcare HIPAA server requirements
*Government server security standards
*DevOps CI/CD pipeline server security
*IoT gateway device hardening
*Container host OS security

Extensions & Next Steps

  • Implement automatic CIS benchmark compliance checking with alerts
  • Build an Infrastructure-as-Code hardening playbook with Ansible
  • Add SELinux policy writing for custom application confinement
  • Implement log analysis for threat hunting
  • Build an automated security testing pipeline for new deployments

Interactive Playground

Coming Soon

An interactive simulator will be available here — simulate circuits and run code in-browser without hardware.

Frequently Asked Questions

What is the difference between DAC, MAC, and RBAC?
DAC (Discretionary Access Control): owner controls permissions. Traditional Unix file permissions (rwx) — owner decides who can read/write/execute. Any user can share their files with others. MAC (Mandatory Access Control): system enforces policy overriding user wishes — SELinux and AppArmor. A web server process in SELinux confinement cannot read /etc/shadow even if run as root. RBAC (Role-Based Access Control): permissions assigned to roles, users assigned to roles. Used in databases, cloud IAM, Kubernetes. Sudo is a simple RBAC — users have specific command permissions.
How do I keep a hardened server updated without breaking things?
Strategy: enable unattended-upgrades for security patches only (not all updates — prevents breaking changes). Test major updates in staging before production. Before any update: create a VM snapshot (if virtualized) or system backup. Enable dpkg-statoverride to preserve custom permissions. Monitor: subscribe to Ubuntu Security Notices (USN) or RHEL errata mailing list. After update: run Lynis and check that hardening settings are still in place (packages sometimes reset configuration files).
Advertisement