Back to Learn

Basic Linux Security Checklist | NOC.org

Why a Security Checklist Matters

The majority of successful attacks against Linux servers exploit misconfigurations and neglected maintenance rather than sophisticated zero-day vulnerabilities. Default installations leave services exposed, firewalls disabled, and logging insufficient. A methodical security checklist ensures that the most common attack vectors are addressed before a server goes into production — and that ongoing maintenance keeps the server hardened over time.

This checklist covers the essential security controls for any internet-facing Linux server, whether it is running Ubuntu, Debian, CentOS, RHEL, or another distribution. Each item is actionable and can be implemented independently, but together they form a comprehensive baseline that significantly reduces your attack surface.

1. Keep the System Updated

Unpatched software is the number one cause of server compromise. Security patches fix known vulnerabilities that attackers are actively exploiting. The time between a vulnerability disclosure and widespread exploitation is shrinking — often measured in days or hours rather than weeks.

# Ubuntu/Debian
sudo apt update && sudo apt upgrade -y

# CentOS/RHEL
sudo yum update -y

# Check for available security updates only (Ubuntu)
sudo apt list --upgradable 2>/dev/null | grep -i security

Establish a patch schedule: apply critical security updates immediately, and perform full system updates at least weekly. For automated patching, see the section on automatic security updates below.

2. Configure a Firewall

A firewall is your first line of defense. It controls which network traffic is allowed to reach your server and which is blocked. Every Linux server should have a firewall enabled with a default-deny policy — meaning all incoming traffic is blocked unless explicitly permitted.

UFW (Uncomplicated Firewall)

UFW is the recommended firewall for Ubuntu and Debian systems:

# Set default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow essential services
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Enable the firewall
sudo ufw enable
sudo ufw status verbose

iptables / nftables

For CentOS, RHEL, or when you need more granular control, iptables or its successor nftables provide lower-level packet filtering. The key principle is the same: deny everything by default, then create specific allow rules for the services you run.

3. Secure SSH

SSH is the most critical service on a Linux server and the most frequently attacked. A complete SSH hardening guide covers this topic in depth. The minimum SSH security measures are:

  • Disable root login (PermitRootLogin no)
  • Use SSH key authentication instead of passwords
  • Disable password authentication once keys are configured
  • Change the default port from 22
  • Install fail2ban to block brute force attempts
  • Restrict SSH access to specific users with AllowUsers or AllowGroups

4. Disable Unused Services

Every running service is a potential attack vector. A minimal installation with only the necessary services dramatically reduces the attack surface. Audit what is currently running and disable anything that is not needed:

# List all running services
sudo systemctl list-units --type=service --state=running

# List all listening ports
sudo ss -tlnp

# Disable an unnecessary service
sudo systemctl stop service_name
sudo systemctl disable service_name

# Remove unnecessary packages entirely
sudo apt remove --purge package_name   # Debian/Ubuntu
sudo yum remove package_name           # CentOS/RHEL

Common services to evaluate for removal: FTP (use SFTP instead), Telnet, rsh/rlogin, NFS (if not needed), CUPS (printing, rarely needed on servers), Avahi (mDNS/DNS-SD), and any default web server or database that you have replaced with your own.

5. Enforce Strong Password Policies

Even if SSH uses key-based authentication, local user accounts still have passwords used for sudo and console access. Configure PAM (Pluggable Authentication Modules) to enforce password complexity:

# Install password quality checking
sudo apt install libpam-pwquality -y

# /etc/security/pwquality.conf
minlen = 14
dcredit = -1
ucredit = -1
ocredit = -1
lcredit = -1
maxrepeat = 3
dictcheck = 1

This requires passwords with at least 14 characters, including at least one digit, one uppercase letter, one special character, and one lowercase letter, with no more than 3 consecutive repeated characters. Passwords are also checked against a dictionary.

6. Set Proper File Permissions

Incorrect file permissions are a common misconfiguration that allows privilege escalation or data exposure. Key permissions to audit:

# Secure SSH configuration
sudo chmod 600 /etc/ssh/sshd_config
sudo chmod 700 ~/.ssh
sudo chmod 600 ~/.ssh/authorized_keys

# Secure /etc/passwd and /etc/shadow
sudo chmod 644 /etc/passwd
sudo chmod 640 /etc/shadow

# Set restrictive umask for new files
# Add to /etc/profile or /etc/bash.bashrc:
umask 027

The umask 027 setting means new files are created with permissions 640 (owner read/write, group read, no other access) and new directories with 750. This prevents "other" users from reading any newly created files by default.

7. Monitor Logs

Log files contain the evidence of both legitimate activity and attacks. Without monitoring, a compromised server can go undetected for months. Critical log files to monitor:

  • /var/log/auth.log (Debian/Ubuntu) or /var/log/secure (CentOS/RHEL) — authentication events, SSH logins, sudo usage
  • /var/log/syslog or /var/log/messages — system events, service start/stop, errors
  • /var/log/kern.log — kernel messages, hardware errors, firewall drops
  • /var/log/fail2ban.log — banned IPs and jail activity
  • Application-specific logs (web server, database, etc.)

Use logwatch or logcheck for daily email summaries, and forward logs to a centralized logging system for retention and correlation:

# Install logwatch
sudo apt install logwatch -y

# Run a summary
sudo logwatch --detail high --range today --output stdout

8. Configure Automatic Security Updates

Manual patching is not reliable for servers that must remain secure 24/7. Configure automatic installation of security updates to ensure critical patches are applied promptly.

Ubuntu/Debian (unattended-upgrades)

sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure -plow unattended-upgrades

# /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Mail "admin@example.com";

CentOS/RHEL (yum-cron or dnf-automatic)

For CentOS 7 and RHEL 7, use yum-cron. For CentOS 8+/RHEL 8+ and newer, use dnf-automatic. Both support security-only updates and email notifications.

9. Install and Configure Fail2ban

Fail2ban monitors authentication logs and automatically blocks IP addresses that show malicious patterns — primarily brute force attacks. It works with SSH, web servers, mail servers, and many other services:

sudo apt install fail2ban -y
sudo systemctl enable fail2ban

# Create /etc/fail2ban/jail.local
[DEFAULT]
bantime  = 3600
findtime = 600
maxretry = 3
banaction = ufw

[sshd]
enabled = true

[apache-auth]
enabled = true

[nginx-http-auth]
enabled = true

The banaction = ufw directive integrates fail2ban with UFW. On CentOS/RHEL, use banaction = firewallcmd-ipset for firewalld integration.

10. Disable the Root Account for Interactive Login

Beyond disabling root SSH login (covered in Step 3), consider locking the root account entirely for interactive use:

# Lock the root account password
sudo passwd -l root

Administrators should use their own named accounts and escalate with sudo. This provides accountability (every privileged action is attributed to a specific user) and reduces the blast radius if one set of credentials is compromised. Configure sudo to log all commands:

# /etc/sudoers.d/logging
Defaults logfile="/var/log/sudo.log"
Defaults log_input, log_output

11. Audit SUID and SGID Binaries

SUID (Set User ID) and SGID (Set Group ID) binaries execute with the privileges of the file owner (often root) rather than the user who runs them. While some SUID binaries are necessary (like passwd and sudo), unexpected SUID binaries can be a sign of compromise or a privilege escalation vector.

# Find all SUID binaries
sudo find / -perm -4000 -type f 2>/dev/null

# Find all SGID binaries
sudo find / -perm -2000 -type f 2>/dev/null

# Remove SUID bit from unnecessary binaries
sudo chmod u-s /path/to/unnecessary/binary

Run this audit regularly and compare the results against a known-good baseline. Any new or unexpected SUID binary should be investigated immediately.

Regular Security Maintenance

A security checklist is not a one-time activity. Schedule these ongoing tasks:

  • Weekly: Review fail2ban logs, check for failed login attempts, verify backups
  • Monthly: Audit user accounts and permissions, review running services, audit SUID binaries, review firewall rules
  • Quarterly: Review and update the security checklist itself, test disaster recovery procedures, rotate credentials

Build a Layered Defense

Server-level hardening is one layer of a complete security strategy. Combine these controls with SSH hardening, a properly configured firewall, and application-layer protection from a web application firewall. NOC.org provides infrastructure security solutions that complement your server hardening efforts. See our pricing plans to get started.

Improve Your Websites Speed and Security

14 days free trial. No credit card required.