Skip to content
Back to Blog
Security10 min read

Server Security Checklist 2026: What Admins Must Lock Down

A practical server hardening checklist covering SSH, firewall rules, file permissions, user access, SSL/TLS, automated updates, and threat monitoring that every Linux administrator should implement today.

Written by Abdul AbrorTechnical Hosting Support Engineer
Server Security Checklist 2026: What Admins Must Lock Down
On this page

Server breaches happen when administrators skip the fundamentals. A compromised server means stolen data, ransomware, resource hijacking for crypto mining, or your infrastructure used to attack others. This checklist walks through the security controls every Linux administrator should lock down before a server goes into production or after inheriting an existing system.

SSH Hardening

SSH is the primary entry point for remote administration and the most frequently attacked service on internet-facing servers.

Disable Root Login

Never allow direct root SSH access. Attackers target the root account first because it exists on every Linux system.

# Edit SSH daemon config
sudo nano /etc/ssh/sshd_config

# Set this directive
PermitRootLogin no

# Restart SSH
sudo systemctl restart sshd

Create a regular user account with sudo privileges for administrative tasks. This creates an audit trail showing who performed elevated actions.

Use Key-Based Authentication Only

Password authentication is vulnerable to brute force attacks. SSH keys are mathematically infeasible to crack.

# Generate a strong key pair on your local machine
ssh-keygen -t ed25519 -a 100

# Copy public key to server
ssh-copy-id [email protected]

# On server, disable password auth
sudo nano /etc/ssh/sshd_config
PasswordAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes

sudo systemctl restart sshd

Store private keys securely. Use a passphrase on the key itself as a second factor.

Change Default SSH Port (Optional)

Changing SSH from port 22 reduces automated scan noise but provides minimal real security. It's security through obscurity, not a substitute for strong authentication.

# /etc/ssh/sshd_config
Port 2222

# Update firewall rules before restarting
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
sudo systemctl restart sshd

Restrict SSH Access by IP

If your administrative access comes from known IP ranges, whitelist them.

# /etc/ssh/sshd_config
AllowUsers [email protected]/24
# or
Match Address 203.0.113.0/24
    PasswordAuthentication no
    PermitRootLogin no

For dynamic IPs, consider VPN-only SSH access or port knocking.

Firewall Configuration

A firewall denies all traffic except explicitly permitted services. Default-deny is the foundation of perimeter security.

Enable and Configure Firewall

On RHEL/CentOS/Rocky/AlmaLinux:

sudo systemctl enable firewalld
sudo systemctl start firewalld

# Allow only necessary services
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

# Verify
sudo firewall-cmd --list-all

On Ubuntu/Debian (UFW):

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
sudo ufw status verbose

Close Unused Ports

Scan your own server to see what's exposed:

sudo ss -tulpn | grep LISTEN

If you see services you didn't expect, investigate and disable them. Common unnecessary services include cups (printing), rpcbind, or development servers left running.

Rate Limit SSH Connections

Prevent brute force attempts by limiting connection attempts:

# firewalld
sudo firewall-cmd --permanent --add-rich-rule='rule service name=ssh limit value=3/m accept'
sudo firewall-cmd --reload

# UFW
sudo ufw limit ssh

User Access and Privilege Management

Principle of Least Privilege

Grant users and services only the permissions they need. Avoid giving full sudo access when specific commands suffice.

# Create service-specific users with no shell
sudo useradd -r -s /usr/sbin/nologin appuser

# Grant specific sudo commands
# /etc/sudoers.d/developer
developer ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx

Use visudo to edit sudoers files. It validates syntax before saving.

Audit User Accounts

Remove or lock accounts that are no longer needed:

# List all users
cat /etc/passwd

# Lock an account
sudo usermod -L olduser

# Remove an account and home directory
sudo userdel -r olduser

Enforce Password Policies

Even with key-based SSH, local accounts should have strong password requirements:

# Install password quality library
sudo yum install libpwquality  # RHEL/CentOS
sudo apt install libpam-pwquality  # Ubuntu/Debian

# /etc/security/pwquality.conf
minlen = 14
minclass = 3
maxrepeat = 2

# Set password expiration
sudo chage -M 90 username

File System Permissions and Integrity

Secure Critical Files

Restrict access to configuration files containing credentials:

# Database config files
sudo chmod 600 /etc/mysql/my.cnf
sudo chown mysql:mysql /etc/mysql/my.cnf

# Web application configs
sudo chmod 640 /var/www/html/wp-config.php
sudo chown www-data:www-data /var/www/html/wp-config.php

# Private keys
sudo chmod 600 /etc/ssl/private/*.key

Set Secure Umask

The umask controls default permissions for newly created files:

# /etc/profile and /etc/bashrc
umask 027

This creates files with 640 permissions and directories with 750, preventing world-readable files by default.

Enable File Integrity Monitoring

AIDE (Advanced Intrusion Detection Environment) detects unauthorized file changes:

sudo yum install aide  # RHEL/CentOS
sudo apt install aide  # Ubuntu/Debian

# Initialize database
sudo aide --init
sudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz

# Check for changes
sudo aide --check

# Automate with cron
echo "0 5 * * * root /usr/sbin/aide --check | mail -s 'AIDE Report' [email protected]" | sudo tee -a /etc/crontab

Automated Updates and Patching

Unpatched vulnerabilities are the leading cause of server compromise. Automate security updates to close the window of exposure.

Enable Automatic Security Updates

RHEL/CentOS/Rocky/AlmaLinux:

sudo yum install yum-cron
sudo systemctl enable yum-cron
sudo systemctl start yum-cron

# /etc/yum/yum-cron.conf
apply_updates = yes
update_cmd = security

Ubuntu/Debian:

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

# /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Mail "[email protected]";

Schedule a maintenance window for kernel updates and reboots. Use needs-restarting or checkrestart to identify services that need restarting after library updates.

SSL/TLS Configuration

Encrypt all traffic between clients and your server. Outdated TLS configurations expose data to interception.

Obtain and Install Certificates

Use Let's Encrypt for free, automated certificates:

sudo yum install certbot python3-certbot-nginx  # RHEL/CentOS
sudo apt install certbot python3-certbot-nginx  # Ubuntu/Debian

sudo certbot --nginx -d example.com -d www.example.com

# Auto-renewal
sudo systemctl enable certbot-renew.timer

Harden TLS Settings

Disable weak protocols and ciphers in your web server or reverse proxy:

Nginx:

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

Apache:

SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder on

Test your configuration with SSL Labs or similar scanning tools.

Logging and Monitoring

You can't defend against what you can't see. Centralized logging and real-time alerts detect attacks in progress.

Configure Centralized Logging

Ship logs to a dedicated log server or SIEM. Attackers often delete local logs to cover their tracks.

# Basic rsyslog forwarding
echo "*.* @@logserver.example.com:514" | sudo tee -a /etc/rsyslog.conf
sudo systemctl restart rsyslog

Monitor Authentication Logs

Watch for failed login attempts and unusual access patterns:

# Recent failed SSH attempts
sudo grep "Failed password" /var/log/auth.log | tail -20

# Successful logins
sudo last -a

Set up alerts for repeated failures from the same IP or successful logins from unexpected locations.

Install Intrusion Detection

Fail2ban monitors logs and automatically bans IPs showing malicious behavior:

sudo yum install fail2ban  # RHEL/CentOS
sudo apt install fail2ban  # Ubuntu/Debian

sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600

Monitor System Resources

Crypto miners and DDoS bots consume CPU, memory, and bandwidth. Set up monitoring to catch anomalies:

# Install monitoring tools
sudo yum install glances htop iotop  # RHEL/CentOS
sudo apt install glances htop iotop  # Ubuntu/Debian

# Check current resource usage
glances

For production environments, deploy proper monitoring stacks like Prometheus, Grafana, or Netdata.

Application-Specific Hardening

Secure Database Access

Never expose database ports to the public internet:

# MySQL/MariaDB - bind to localhost only
# /etc/my.cnf or /etc/mysql/my.cnf
[mysqld]
bind-address = 127.0.0.1

sudo systemctl restart mariadb

Use strong passwords, remove test databases, and grant privileges narrowly:

DROP DATABASE test;
DELETE FROM mysql.user WHERE User='';
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'strong_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'appuser'@'localhost';
FLUSH PRIVILEGES;

Harden Web Applications

Disable directory listing, server signatures, and unnecessary modules:

Nginx:

autoindex off;
server_tokens off;

Apache:

Options -Indexes
ServerTokens Prod
ServerSignature Off

Run web applications as dedicated users, not root or your personal account.

Keep Application Dependencies Updated

Outdated CMS platforms, plugins, and libraries are common attack vectors. Enable automatic updates where safe or establish a regular update schedule.

Conclusion

Server security is not a one-time checklist but an ongoing discipline. Implement these controls in order of impact: secure SSH first, enable the firewall, automate updates, then layer on monitoring and intrusion detection. Every control you skip is a door left unlocked. Review your server configurations against this checklist quarterly, audit logs weekly, and apply security patches promptly. The effort invested in hardening today prevents the far greater cost of incident response, data breach notification, and reputation damage tomorrow. Lock it down before someone else does it for you.

FAQ

How often should I audit my server security?

Run a basic security audit monthly and a thorough review quarterly. Perform an immediate audit after any suspicious activity, infrastructure changes, or when new vulnerabilities affecting your software are disclosed.

Should I use SELinux or AppArmor?

Yes, use whichever is native to your distribution. SELinux on RHEL-based systems and AppArmor on Ubuntu/Debian provide mandatory access control that limits damage from compromised services. Start in permissive mode, review denials, then switch to enforcing.

What's the most critical step in this checklist?

SSH key-based authentication with password auth disabled. Most server breaches start with compromised SSH access. This single change eliminates the most common attack vector.

Do I need a web application firewall?

For production web applications, yes. A WAF like ModSecurity provides an additional layer filtering common web attacks like SQL injection and XSS that traditional firewalls miss. Cloud-based WAFs like Cloudflare also mitigate DDoS attacks.

How do I know if my server has been compromised?

Look for unexpected processes, unusual network connections, modified system binaries, unauthorized user accounts, log gaps or deletions, and unexplained resource consumption. File integrity monitoring and intrusion detection systems catch many indicators automatically.