Skip to content

How to Secure a CentOS, AlmaLinux or Rocky Linux Server

Updated 8 min read

Updated: 22 October 2026 · Applies to: AlmaLinux 10.2 and Rocky Linux 9.8 (tested), RHEL 9 and 10 (according to Red Hat); notes for servers still on CentOS 7

The steps that make the biggest difference on a CentOS-family server are: keep it updated, log in with SSH keys instead of root passwords, close every port you do not use, block repeated login attempts, and leave SELinux enforcing. Everything else in this guide builds on those five. If the server still runs CentOS Linux 7 or 8, the most important step comes first: move it to a supported system.

Before you start: is your CentOS still supported?

CentOS Linux 8 reached end of life on 31 December 2021 and CentOS Linux 7 on 30 June 2024, so neither gets security updates any more. No setting below can fix an operating system without patches. Move to AlmaLinux or Rocky Linux 9 or 10 (or RHEL); the commands in this guide are the same on all of them. Keep a full backup before any migration.

All commands below run as root or with sudo.

1. Install updates, and install them automatically

dnf upgrade --refresh

To install updates without waiting for you, enable dnf-automatic:

dnf install dnf-automatic
systemctl enable --now dnf-automatic-install.timer

The dnf-automatic-install timer downloads and installs updates once a day (06:00 plus a random delay of up to an hour on our AlmaLinux 10.2 system), even though /etc/dnf/automatic.conf says apply_updates = no, because that timer runs dnf-automatic with --installupdates. It does not reboot by default (reboot = never).

To apply only security fixes, see How to Install Only Security Updates with yum and dnf. Reboot after kernel updates.

2. Create an admin user and use sudo

Work as a normal user and use sudo for admin tasks. Members of the wheel group may use sudo by default:

useradd -m -G wheel alice
passwd alice

Log in as that user in a new session and check that sudo -i works before you change any root login settings.

3. Use SSH keys and turn off root and password logins

Copy your public key to the server from your own computer:

ssh-copy-id alice@203.0.113.10

Replace the address with your server's IP. When key login works, create a settings file in sshd's drop-in folder. sshd uses the first value it reads for each option, and files are read in name order. Our AlmaLinux 10.2 system already had 25-permitrootlogin.conf (with PermitRootLogin yes) and 50-redhat.conf there, so give your file a name that sorts before them:

nano /etc/ssh/sshd_config.d/10-hardening.conf

(If nano is missing, install it with dnf install nano or use vi.) Put these lines in the file:

PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no

Check the configuration and see which values sshd will really use:

sshd -t
sshd -T | grep -E '^(port|permitrootlogin|passwordauthentication|kbdinteractiveauthentication) '

Output on our AlmaLinux 10.2 system (before the file, it showed permitrootlogin yes and passwordauthentication yes; the port line shows 2222 because we also set the port from step 4):

port 2222
permitrootlogin no
passwordauthentication no
kbdinteractiveauthentication no

sshd -t prints nothing when the syntax is correct. On Rocky Linux 9.8 the default was permitrootlogin without-password (root may log in with a key only) and the same file switched it to no.

Then restart SSH, and keep your current session open until you have logged in again from a second window:

systemctl restart sshd

For more sshd options, see Increasing the security of your server: sshd hardening.

4. Change the SSH port (optional)

According to Red Hat, a different port "provides only limited security benefits", because a full port scan still finds it, but it does cut down the automated login noise in your logs. If you change it, three things must agree: sshd, SELinux and the firewall. Add a Port line (for example Port 2222) to your drop-in file, then:

dnf install policycoreutils-python-utils
semanage port -a -t ssh_port_t -p tcp 2222
firewall-cmd --permanent --add-port=2222/tcp
firewall-cmd --reload
systemctl restart sshd

The semanage line tells SELinux that sshd may listen on 2222; without it, sshd cannot use the new port while SELinux is enforcing. Log in on the new port from a second window (ssh -p 2222 alice@203.0.113.10). Only when that works, close the standard SSH service in the firewall:

firewall-cmd --permanent --remove-service=ssh
firewall-cmd --reload

Red Hat's own example removes 22/tcp as a port, but a default AlmaLinux zone allows SSH as the ssh service, so remove the service instead. The SELinux step is according to Red Hat (a container cannot change SELinux policy); we checked the firewall changes in our lab with firewall-offline-cmd.

Full steps, including Ubuntu, are in What Is the Default SSH Port and How to Change It Safely.

5. Close ports you do not use

firewalld is the standard firewall on AlmaLinux, Rocky and RHEL. See what the default zone allows:

firewall-cmd --list-all

Part of the output on a fresh AlmaLinux 10.2 system (our lab, read with firewall-offline-cmd --list-all, which prints the same format):

public (default)
  target: default
  services: cockpit dhcpv6-client ssh
  ports: 

cockpit is the web console on port 9090. If you do not use it, close it, and open only what your server really serves (for example http and https for a web server):

firewall-cmd --permanent --remove-service=cockpit
firewall-cmd --permanent --add-service=http --add-service=https
firewall-cmd --reload

If the server runs cPanel and WHM, use the firewall your panel supports instead of mixing two firewalls. ConfigServer Firewall (CSF) is now maintained by cPanel as the cpanel-csf package, which according to cPanel installs only on cPanel and WHM servers; old guides that download csf.tgz from configserver.com no longer work.

More examples are in firewall-cmd: List All Rules and Useful firewalld Examples.

6. Block repeated login attempts

Fail2Ban reads the logs and blocks an IP address after several failed logins. It comes from EPEL:

dnf install epel-release
dnf install fail2ban

In our AlmaLinux 10.2 test this installed Fail2Ban 1.1.0 and firewalld, with bans going through firewalld. No jail is switched on after installing, so create /etc/fail2ban/jail.local:

nano /etc/fail2ban/jail.local

With this content (use your SSH port; 2222 is the example from step 4):

[sshd]
enabled = true
port = 2222
maxretry = 5
bantime = 1h

Test the configuration, then start the service:

fail2ban-client -t
systemctl enable --now fail2ban

Output of the test:

OK: configuration test is successful

On a cPanel server, use WHM's cPHulk Brute Force Protection instead. According to cPanel, it protects cPanel, WHM, mail (Dovecot and Exim), Pure-FTPd and SSH logins, and you switch it on with the toggle in WHM, Security Center, cPHulk Brute Force Protection.

7. Leave SELinux enforcing

getenforce

It should print Enforcing. Many old guides tell you to disable SELinux when something does not work; fix the label or port instead (as with semanage above), because SELinux limits what an attacker can do through a hacked web application.

8. Remove services and packages you do not need

Every running service is something that can be attacked. List what listens on the network and what starts at boot:

ss -tulpn
systemctl list-unit-files --type=service --state=enabled

For each service you do not need, stop it now and stop it starting at boot (replace SERVICE with the unit name from the list):

systemctl disable --now SERVICE

Then remove packages you never use with dnf remove PACKAGE. Fewer packages also means fewer updates to apply.

9. Scan for malware and rootkits

Linux servers do get malware, usually through weak passwords or outdated web applications. Run a scanner now and then:

10. Back up, and keep the backup somewhere else

Security is never complete, so plan for the day something goes wrong. Back up files and databases daily to a different server or storage, and test a restore now and then. A backup on the same disk is lost together with the server.

A note on network files: ifcfg is gone

Older CentOS 7 guides edit files in /etc/sysconfig/network-scripts/ifcfg-*. Those set network addresses, not security, and on current systems they no longer apply: AlmaLinux, Rocky and RHEL 9 store connections as NetworkManager keyfiles in /etc/NetworkManager/system-connections/, and according to Red Hat, version 10 ignores ifcfg files completely. On version 9 you can convert old files with:

nmcli connection migrate

To change an IP address with nmcli, or on Ubuntu, follow How to Set a Static IP Address from the Linux Command Line (CentOS, AlmaLinux, Rocky Linux, RHEL and Ubuntu).

If you would rather have our team harden the server for you, see Hire an Expert.

Official documentation: Red Hat Enterprise Linux 10: Securing networks.

Related services

KVM VPS hosting

NVMe SSD and full root access, with Free Basic Managed Support.

Unmanaged dedicated servers

full root access and free IPMI KVM, with Free Basic Managed Support.

Linux server management

hardening, patching, monitoring and automation for Ubuntu, Debian, RHEL and AlmaLinux.

Was this answer helpful?

Still stuck? Open a ticket