kde-redhat.org · all guides

PillarA · RHEL-family servers PublishedJuly 24, 2026 AuthorElton

Initial Server Setup on AlmaLinux 10 and Rocky Linux 10: users, SSH keys, firewalld and SELinux

A tested first-hour checklist for AlmaLinux 10 and Rocky Linux 10: sudo user, SSH key hardening, firewalld zones and SELinux kept on, with expected output.

TL;DR

The first hour on a fresh AlmaLinux 10 or Rocky Linux 10 server, condensed: update, create a sudo user, move SSH to keys only, keep firewalld and SELinux exactly as they are. Every step below has the expected output and the recovery path.

$ sudo dnf -y upgrade
$ sudo useradd -m -G wheel deploy && sudo passwd deploy
$ ssh-copy-id [email protected]
$ printf 'PermitRootLogin no\nPasswordAuthentication no\n' | sudo tee /etc/ssh/sshd_config.d/50-hardening.conf
$ sudo sshd -t && sudo systemctl restart sshd
$ sudo firewall-cmd --permanent --remove-service=cockpit && sudo firewall-cmd --reload
$ getenforce
Tested onAlmaLinux 10.2 (Lavender Lion), dnf 4.20.0, OpenSSH 9.9p1 Test dateJuly 17, 2026 Environmentcontainer lab for command validation, cross-checked with AlmaLinux and Rocky Linux 10 release notes Also appliesRocky Linux 10, RHEL 10 (same family, same commands)

Step 0: a server to practice on, and the CPU detail nobody tells you

Disclosure: the Vultr link below is a referral. You get 300 dollars of trial credit for 30 days, this site gets a commission if you stay. That is the whole arrangement.

If you are doing this on a work machine, skip ahead. If you want a disposable box to break, I spin these labs up on Vultr's 300 dollar trial credit: deploy the smallest instance, follow this guide, destroy it, repeat. The credit covers a month of that many times over, and practicing a lockout recovery on a server you can delete is worth more than reading about one.

Before you pick a distribution, know this: Rocky Linux 10 requires an x86-64-v3 CPU (Intel Haswell from 2013 onward, or equivalent AMD), while AlmaLinux 10 also ships a separate x86-64-v2 build for hardware back to roughly 2008. Any current cloud instance is v3, but older home servers and some budget VPS plans are not. Check before you download:

$ /lib64/ld-linux-x86-64.so.2 --help | grep supported
  x86-64-v3 (supported, searched)
  x86-64-v2 (supported, searched)

If v3 is missing from that list, AlmaLinux's v2 build is your distribution and the rest of this guide is identical. Both are rebuilds of RHEL 10 on kernel 6.12, and everything below works the same on either.

Step 1: update and confirm what you are on

$ sudo dnf -y upgrade
$ grep PRETTY /etc/os-release
PRETTY_NAME="AlmaLinux 10.2 (Lavender Lion)"
$ dnf --version | head -1
4.20.0

Yes, dnf 4: unlike Fedora, the RHEL 10 family stays on the dnf 4 line for its lifetime. Same commands you know, no dnf5 surprises.

While you are here, give the machine a name and a clock you can trust in logs. Time sync via chrony is already on by default in this family; naming is on you:

$ sudo hostnamectl set-hostname lab01.example.internal
$ sudo timedatectl set-timezone America/Sao_Paulo
$ timedatectl
               Local time: Fri 2026-07-17 22:10:03 -03
System clock synchronized: yes
              NTP service: active

Named hosts and synchronized clocks sound cosmetic until the first time you correlate an auth log across three servers at 2 a.m. Do it while it costs nothing.

Step 2: a sudo user, because root is not a daily driver

$ sudo useradd -m -G wheel deploy
$ sudo passwd deploy
$ id deploy
uid=1000(deploy) gid=1000(deploy) groups=1000(deploy),10(wheel)

The wheel group is sudo on the RHEL family, enabled out of the box by the %wheel ALL=(ALL) ALL line in sudoers. One honest gotcha from testing this on a minimal image: sudo itself may not be installed on stripped down cloud images and containers. If sudo comes back command not found, you are root anyway on first login, so dnf -y install sudo and carry on.

Step 3: SSH keys only, with a config you can roll back

From your own machine, put your key on the server before touching the SSH daemon:

$ ssh-copy-id [email protected]
$ ssh [email protected]   # confirm the key works BEFORE hardening

Now harden. RHEL 10 family ships OpenSSH 9.9, and the clean way is a drop-in file, not editing the main config:

$ printf 'PermitRootLogin no\nPasswordAuthentication no\n' | sudo tee /etc/ssh/sshd_config.d/50-hardening.conf
$ sudo sshd -t
$ sudo systemctl restart sshd

sshd -t printing nothing is the good outcome: the config parses. The iron rule: keep your current SSH session open while you restart the daemon and test a fresh login from a second terminal. If the fresh login fails, you still hold a live session to undo the change with sudo rm /etc/ssh/sshd_config.d/50-hardening.conf and a restart.

Step 4: firewalld stays on, and gets smaller

Do not disable the firewall, trim it. See what the default zone actually exposes:

$ sudo firewall-cmd --list-services
cockpit dhcpv6-client ssh

SSH stays, obviously. Cockpit is the web admin console on port 9090; if you are not using it, it is attack surface:

$ sudo firewall-cmd --permanent --remove-service=cockpit
$ sudo firewall-cmd --reload
$ sudo firewall-cmd --list-services
dhcpv6-client ssh

When you later add a web server, you add its service the same way: --add-service=http --add-service=https, permanent, reload. The habit to build is that every open port is a decision you made, not a default you inherited.

Step 5: SELinux stays exactly where it is

$ getenforce
Enforcing

Half the tutorials you will find end with "disable SELinux to avoid problems". That advice is how test boxes become breach writeups, and it is the line this site will never cross. SELinux denials are not mysteries, they are log entries with fixes: relabel the file, flip the boolean, add the port. When a denial bites you in a real deployment, ausearch -m AVC -ts recent tells you exactly what was blocked, and fixing that one thing takes five minutes. Leave it Enforcing today and your future self inherits a server where security was never traded for convenience.

Step 6: security updates without you

$ sudo dnf -y install dnf-automatic
$ sudo systemctl enable --now dnf-automatic.timer

The default configuration downloads and applies updates on a daily timer; set apply_updates = yes under [commands] in /etc/dnf/automatic.conf if your build ships it off. For a lab or a small server, automatic security patching beats a forgotten server every time. Reboots for kernel updates remain yours to schedule.

If this fails

  • Locked out after step 3: use your provider's web console (every VPS panel has one), log in locally as root, remove /etc/ssh/sshd_config.d/50-hardening.conf, restart sshd, and redo the step with the key tested first.
  • sudo: command not found on a minimal image: you are root on first login anyway; dnf -y install sudo and re-run step 2.
  • firewall-cmd answers with a DBUS error: firewalld is not running yet (common in containers and kickstart scripts). sudo systemctl enable --now firewalld, or use firewall-offline-cmd in build scripts.
  • Rocky Linux 10 installer or image refuses to boot on older hardware: that is the x86-64-v3 requirement from step 0. Switch to AlmaLinux 10's v2 build, everything else in this guide is unchanged.

Wrap up

Twenty minutes, six steps, and the server now fails safe: no root over SSH, no passwords to brute force, a firewall you can enumerate from memory, SELinux still doing its job, and patches applying themselves. This is the baseline every other guide on this site builds on. The next ones go deeper into the two tools people are most tempted to turn off, firewalld zones and SELinux troubleshooting, in the same spirit as everything this domain has stood for since 2003: the right way, tested, with the output to prove it.