Tools: Linux Hardening Scripts: Linux Server Security Guide

Tools: Linux Hardening Scripts: Linux Server Security Guide

Linux Server Security Guide

Table of Contents

Security Mindset

Defense in Depth

Attack Surface Reduction

Remove unnecessary packages

Disable unnecessary services

Close unnecessary ports

SSH Security

Why disable password authentication?

Key security settings explained

Before disabling password auth

Firewall Strategy

Default policy

Typical server rules

Rate limiting

Intrusion Detection & Prevention

Fail2Ban: How it works

Progressive ban strategy

Monitoring Fail2Ban

Kernel Hardening

Network stack hardening

Memory protection

Information disclosure prevention

User & Access Management

Password policy rationale

Sudo hardening explained

The principle of least privilege

Audit & Monitoring

Why audit?

Key audit categories

Useful audit commands

Automated Updates

Why auto-update security patches?

What gets auto-updated?

Risks and mitigation

Filesystem Security

Mount options

SUID/SGID explanation

Incident Response Basics

1. Don't panic, don't power off

2. Capture evidence

3. Check audit logs

4. Isolate

5. Investigate and remediate

Ongoing Maintenance

Weekly

Monthly

Quarterly

Annually

Related Articles A comprehensive guide to understanding and implementing Linux server hardening. Security is not a one-time task — it's an ongoing process. Every server is a potential target, regardless of size or perceived importance. Attackers use automated tools that scan the entire internet for vulnerable systems. Our scripts implement multiple security layers: Before hardening, reduce what attackers can target: SSH is the primary remote access method and the #1 attack target on internet-facing servers. Passwords are susceptible to brute-force attacks. An internet-facing SSH server sees thousands of brute-force attempts daily. SSH keys are cryptographically stronger and cannot be brute-forced. Test key-based login in a new terminal before applying hardening Only then run harden-ssh.sh A firewall should implement the principle of default deny — block everything, then explicitly allow only what's needed. SSH rate limiting (via ufw limit) allows 6 connections per 30 seconds per IP. This stops brute-force while allowing normal use. Kernel parameters control fundamental OS behavior. Our sysctl-hardened.conf addresses: Auditing creates a forensic trail. When (not if) a security incident occurs, audit logs tell you: The #1 cause of successful attacks is unpatched vulnerabilities. The average time between vulnerability disclosure and exploitation is decreasing — automated updates close this window. Only security updates are auto-applied. Feature updates and major version changes require manual review. SUID (Set User ID) binaries run with the file owner's privileges, not the caller's. A vulnerable SUID-root binary = instant root access for an attacker. Review each SUID binary and remove the bit if not needed: If you suspect a compromise: Powering off destroys volatile evidence (memory, network connections). Disconnect from the network if active compromise is confirmed. Use logs and forensic evidence to determine the attack vector and scope. Hardening is not one-and-done. Schedule regular reviews: Guide by Datanest Digital | [email protected] This is 1 of 6 resources in the DevOps Toolkit Pro toolkit. Get the complete [Linux Hardening Scripts] with all files, templates, and documentation for $XX. Or grab the entire DevOps Toolkit Pro bundle (6 products) for $178 — save 30%. Get the Complete Bundle → Templates let you quickly answer FAQs or store snippets for re-use. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse

Code Block

Copy

┌──────────────────────────────────────────────┐ │ Layer 7: Application Security │ │ (Your application code, WAF) │ ├──────────────────────────────────────────────┤ │ Layer 6: Authentication & Authorization │ │ (SSH keys, sudo, PAM, fail2ban) │ ├──────────────────────────────────────────────┤ │ Layer 5: Network Security │ │ (Firewall, rate limiting, IP filtering) │ ├──────────────────────────────────────────────┤ │ Layer 4: OS Hardening │ │ (Kernel params, sysctl, module blacklist) │ ├──────────────────────────────────────────────┤ │ Layer 3: Filesystem Security │ │ (Permissions, mount options, SUID cleanup) │ ├──────────────────────────────────────────────┤ │ Layer 2: Monitoring & Auditing │ │ (auditd, logging, alerting) │ ├──────────────────────────────────────────────┤ │ Layer 1: Patch Management │ │ (Automatic security updates) │ └──────────────────────────────────────────────┘ ┌──────────────────────────────────────────────┐ │ Layer 7: Application Security │ │ (Your application code, WAF) │ ├──────────────────────────────────────────────┤ │ Layer 6: Authentication & Authorization │ │ (SSH keys, sudo, PAM, fail2ban) │ ├──────────────────────────────────────────────┤ │ Layer 5: Network Security │ │ (Firewall, rate limiting, IP filtering) │ ├──────────────────────────────────────────────┤ │ Layer 4: OS Hardening │ │ (Kernel params, sysctl, module blacklist) │ ├──────────────────────────────────────────────┤ │ Layer 3: Filesystem Security │ │ (Permissions, mount options, SUID cleanup) │ ├──────────────────────────────────────────────┤ │ Layer 2: Monitoring & Auditing │ │ (auditd, logging, alerting) │ ├──────────────────────────────────────────────┤ │ Layer 1: Patch Management │ │ (Automatic security updates) │ └──────────────────────────────────────────────┘ ┌──────────────────────────────────────────────┐ │ Layer 7: Application Security │ │ (Your application code, WAF) │ ├──────────────────────────────────────────────┤ │ Layer 6: Authentication & Authorization │ │ (SSH keys, sudo, PAM, fail2ban) │ ├──────────────────────────────────────────────┤ │ Layer 5: Network Security │ │ (Firewall, rate limiting, IP filtering) │ ├──────────────────────────────────────────────┤ │ Layer 4: OS Hardening │ │ (Kernel params, sysctl, module blacklist) │ ├──────────────────────────────────────────────┤ │ Layer 3: Filesystem Security │ │ (Permissions, mount options, SUID cleanup) │ ├──────────────────────────────────────────────┤ │ Layer 2: Monitoring & Auditing │ │ (auditd, logging, alerting) │ ├──────────────────────────────────────────────┤ │ Layer 1: Patch Management │ │ (Automatic security updates) │ └──────────────────────────────────────────────┘ # List installed packages dpkg -l # Debian/Ubuntu rpm -qa # RHEL/CentOS # Remove examples apt purge telnet ftp rsh-client # Debian/Ubuntu yum remove telnet ftp rsh # RHEL/CentOS # List installed packages dpkg -l # Debian/Ubuntu rpm -qa # RHEL/CentOS # Remove examples apt purge telnet ftp rsh-client # Debian/Ubuntu yum remove telnet ftp rsh # RHEL/CentOS # List installed packages dpkg -l # Debian/Ubuntu rpm -qa # RHEL/CentOS # Remove examples apt purge telnet ftp rsh-client # Debian/Ubuntu yum remove telnet ftp rsh # RHEL/CentOS # List all enabled services systemctl list-unit-files --state=enabled # Disable services you don't need systemctl disable --now avahi-daemon systemctl disable --now cups # List all enabled services systemctl list-unit-files --state=enabled # Disable services you don't need systemctl disable --now avahi-daemon systemctl disable --now cups # List all enabled services systemctl list-unit-files --state=enabled # Disable services you don't need systemctl disable --now avahi-daemon systemctl disable --now cups # Check open ports ss -tulnp # Shows all listening ports nmap -sT localhost # Port scan yourself # Check open ports ss -tulnp # Shows all listening ports nmap -sT localhost # Port scan yourself # Check open ports ss -tulnp # Shows all listening ports nmap -sT localhost # Port scan yourself ssh-keygen -t ed25519 -C "[email protected]" ssh-keygen -t ed25519 -C "[email protected]" ssh-keygen -t ed25519 -C "[email protected]" ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server Incoming: DENY ALL (then allow specific ports) Outgoing: ALLOW ALL (restrict if possible) Forward: DENY ALL (unless acting as router) Incoming: DENY ALL (then allow specific ports) Outgoing: ALLOW ALL (restrict if possible) Forward: DENY ALL (unless acting as router) Incoming: DENY ALL (then allow specific ports) Outgoing: ALLOW ALL (restrict if possible) Forward: DENY ALL (unless acting as router) First offense: 1 hour ban (sshd jail) DDoS detection: 48 hour ban (sshd-ddos jail) Repeat offender: 1 week ban (recidive jail) First offense: 1 hour ban (sshd jail) DDoS detection: 48 hour ban (sshd-ddos jail) Repeat offender: 1 week ban (recidive jail) First offense: 1 hour ban (sshd jail) DDoS detection: 48 hour ban (sshd-ddos jail) Repeat offender: 1 week ban (recidive jail) # Overall status fail2ban-client status # SSH jail details fail2ban-client status sshd # Currently banned IPs fail2ban-client get sshd banip # Unban a specific IP fail2ban-client set sshd unbanip 192.168.1.100 # Overall status fail2ban-client status # SSH jail details fail2ban-client status sshd # Currently banned IPs fail2ban-client get sshd banip # Unban a specific IP fail2ban-client set sshd unbanip 192.168.1.100 # Overall status fail2ban-client status # SSH jail details fail2ban-client status sshd # Currently banned IPs fail2ban-client get sshd banip # Unban a specific IP fail2ban-client set sshd unbanip 192.168.1.100 root account → Direct login disabled, use sudo Admin accounts → sudo access with password Service accounts → No login shell (/usr/sbin/nologin) Application user → No sudo, limited file access root account → Direct login disabled, use sudo Admin accounts → sudo access with password Service accounts → No login shell (/usr/sbin/nologin) Application user → No sudo, limited file access root account → Direct login disabled, use sudo Admin accounts → sudo access with password Service accounts → No login shell (/usr/sbin/nologin) Application user → No sudo, limited file access # Search by key ausearch -k identity # User/group changes ausearch -k privilege_escalation # Sudo usage # Reports aureport --summary # Overall summary aureport --auth # Authentication report aureport --login --summary # Login summary aureport --failed # Failed operations # Recent events ausearch -ts recent # Last 10 minutes ausearch -ts today # Today's events # Search by key ausearch -k identity # User/group changes ausearch -k privilege_escalation # Sudo usage # Reports aureport --summary # Overall summary aureport --auth # Authentication report aureport --login --summary # Login summary aureport --failed # Failed operations # Recent events ausearch -ts recent # Last 10 minutes ausearch -ts today # Today's events # Search by key ausearch -k identity # User/group changes ausearch -k privilege_escalation # Sudo usage # Reports aureport --summary # Overall summary aureport --auth # Authentication report aureport --login --summary # Login summary aureport --failed # Failed operations # Recent events ausearch -ts recent # Last 10 minutes ausearch -ts today # Today's events # Find all SUID binaries find / -xdev -perm -4000 -type f 2>/dev/null # Common legitimate SUID binaries /usr/bin/sudo # Needed /usr/bin/passwd # Needed /usr/bin/su # Needed (but consider removing) /usr/bin/chsh # Often unnecessary /usr/bin/chfn # Often unnecessary /usr/bin/newgrp # Often unnecessary # Find all SUID binaries find / -xdev -perm -4000 -type f 2>/dev/null # Common legitimate SUID binaries /usr/bin/sudo # Needed /usr/bin/passwd # Needed /usr/bin/su # Needed (but consider removing) /usr/bin/chsh # Often unnecessary /usr/bin/chfn # Often unnecessary /usr/bin/newgrp # Often unnecessary # Find all SUID binaries find / -xdev -perm -4000 -type f 2>/dev/null # Common legitimate SUID binaries /usr/bin/sudo # Needed /usr/bin/passwd # Needed /usr/bin/su # Needed (but consider removing) /usr/bin/chsh # Often unnecessary /usr/bin/chfn # Often unnecessary /usr/bin/newgrp # Often unnecessary chmod u-s /usr/bin/chfn # Remove SUID from chfn chmod u-s /usr/bin/chfn # Remove SUID from chfn chmod u-s /usr/bin/chfn # Remove SUID from chfn # Current connections ss -tulnp > /tmp/connections.txt # Running processes ps auxf > /tmp/processes.txt # Logged-in users w > /tmp/users.txt # Recent logins last -50 > /tmp/logins.txt # Recent file modifications find / -mtime -1 -type f 2>/dev/null > /tmp/modified-files.txt # Current connections ss -tulnp > /tmp/connections.txt # Running processes ps auxf > /tmp/processes.txt # Logged-in users w > /tmp/users.txt # Recent logins last -50 > /tmp/logins.txt # Recent file modifications find / -mtime -1 -type f 2>/dev/null > /tmp/modified-files.txt # Current connections ss -tulnp > /tmp/connections.txt # Running processes ps auxf > /tmp/processes.txt # Logged-in users w > /tmp/users.txt # Recent logins last -50 > /tmp/logins.txt # Recent file modifications find / -mtime -1 -type f 2>/dev/null > /tmp/modified-files.txt # Failed logins aureport --auth --failed # Privilege escalation ausearch -k privilege_escalation -ts today # File modifications ausearch -k perm_mod -ts today # Failed logins aureport --auth --failed # Privilege escalation ausearch -k privilege_escalation -ts today # File modifications ausearch -k perm_mod -ts today # Failed logins aureport --auth --failed # Privilege escalation ausearch -k privilege_escalation -ts today # File modifications ausearch -k perm_mod -ts today - Security Mindset - Defense in Depth - Attack Surface Reduction - SSH Security - Firewall Strategy - Intrusion Detection & Prevention - Kernel Hardening - User & Access Management - Audit & Monitoring - Automated Updates - Filesystem Security - Incident Response Basics - Ongoing Maintenance - Least privilege: Grant only the minimum access needed - Defense in depth: Multiple layers of security, so failure of one layer doesn't compromise the system - Assume breach: Design systems assuming an attacker will get in, then limit what they can do - Monitor and respond: Detection is as important as prevention - Generate an SSH key pair on your workstation: - Copy the public key to the server: - Test key-based login in a new terminal before applying hardening - Only then run harden-ssh.sh - Fail2Ban monitors log files for authentication failures - After maxretry failures within findtime, the IP is banned - Ban lasts for bantime, then the IP is released - Recidive jail catches repeat offenders with escalating bans - SYN cookies (tcp_syncookies=1): Protects against SYN flood DoS attacks - Reverse path filtering (rp_filter=1): Drops packets with impossible source addresses (IP spoofing) - ICMP redirects disabled: Prevents network route poisoning - Source routing disabled: Prevents attackers from choosing packet routes - ASLR (randomize_va_space=2): Randomizes memory layout, making exploits unreliable - Core dump restriction (suid_dumpable=0): Prevents SUID programs from creating memory dumps that might contain secrets - kptr_restrict=2: Hides kernel memory addresses from non-root users - dmesg_restrict=1: Restricts kernel log access to root - perf_event_paranoid=3: Restricts performance monitoring to root - requiretty: Sudo only works from a real terminal (not from cron or scripts, which could be hijacked) - env_reset: Clears dangerous environment variables that could alter program behavior - timestamp_timeout=15: Re-authentication required every 15 minutes - Logging: All sudo commands logged to /var/log/sudo.log - What happened (file modified, command executed) - When it happened (timestamp) - Who did it (user, process) - How it happened (system call, tool used) - [ ] Review failed SSH login attempts: journalctl -u sshd | grep Failed - [ ] Check Fail2Ban bans: fail2ban-client status sshd - [ ] Review sudo usage: cat /var/log/sudo.log - [ ] Run filesystem audit: bash filesystem-hardening.sh --audit-only - [ ] Check for new SUID binaries - [ ] Review user accounts: awk -F: '$3 >= 1000' /etc/passwd - [ ] Verify auto-updates are working - [ ] Re-run the CIS benchmark checklist - [ ] Review and rotate SSH keys - [ ] Test backup restoration - [ ] Review firewall rules - [ ] Full security assessment - [ ] Review and update password policies - [ ] Audit service accounts - [ ] Update hardening scripts to latest version - CIS Benchmarks — Free PDF downloads - NIST 800-123 — Guide to General Server Security - NIST 800-63B — Digital Identity Authentication Guidelines - Mozilla SSH Guidelines — Modern SSH configuration - Container Security Toolkit: Container Security Guide - Backup Disaster Recovery: Backup & Disaster Recovery Kit - Cicd Pipeline Blueprints: CI/CD Patterns & Best Practices Guide