Skip to content

image

AlmaLinux 9

RHEL 9 compatibility without the subscription. firewalld, SELinux enforcing, a ten-year lifecycle. For teams whose tooling, vendors or auditors speak Red Hat.

Who should run it

AlmaLinux 9 tracks Red Hat Enterprise Linux 9. Pick it if your configuration management targets RHEL, if a vendor supports only RHEL-family systems, or if your compliance team has a CIS or DISA STIG baseline for RHEL 9 they'd rather not rewrite. The release landed in May 2022. Active support runs to 2027 and security fixes to 2032. Ten years is the longest Linux runway in our catalogue.

If none of that applies, an apt-based image will probably feel lighter. AlmaLinux pays off when the RHEL ecosystem is already part of how you work.

First boot

dnf -y upgrade --refresh
dnf -y install epel-release vim-enhanced tmux policycoreutils-python-utils
hostnamectl set-hostname db-01.lon
timedatectl set-timezone Europe/London
useradd -m -G wheel ops && passwd -l ops
mkdir -p /home/ops/.ssh && cp ~/.ssh/authorized_keys /home/ops/.ssh/
chown -R ops:ops /home/ops/.ssh && chmod 700 /home/ops/.ssh
restorecon -Rv /home/ops/.ssh

That last line matters. Files copied into .ssh can carry the wrong SELinux label, and sshd will then silently refuse the key. restorecon resets the context. When key logins fail on a RHEL-family box, check labels before anything else.

cat >/etc/ssh/sshd_config.d/50-local.conf <<'EOF'
PasswordAuthentication no
PermitRootLogin no
EOF
sshd -t && systemctl reload sshd

firewalld

firewalld is running from first boot with the public zone allowing SSH and little else. Add services by name and make the changes permanent:

firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-port=8443/tcp
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=203.0.113.10/32 service name=postgresql accept'
firewall-cmd --reload
firewall-cmd --list-all

Rich rules handle "allow PostgreSQL only from my app server" cleanly. Mirror the coarse rules in the portal firewall as an outer layer.

SELinux in practice

SELinux ships enforcing. Most stock packages from the base repos come with correct policy. Trouble starts when you move data to non-default paths or bind services to non-standard ports:

# nginx proxying to a local app
setsebool -P httpd_can_network_connect on
# PostgreSQL data on a custom path
semanage fcontext -a -t postgresql_db_t '/srv/pgdata(/.*)?'
restorecon -Rv /srv/pgdata
# sshd on port 2222
semanage port -a -t ssh_port_t -p tcp 2222
# what was denied, recently
ausearch -m AVC -ts recent

Five commands cover ninety per cent of SELinux friction. Learn them once and stop reaching for setenforce 0.

Automatic updates

dnf -y install dnf-automatic
sed -i 's/^upgrade_type.*/upgrade_type = security/; s/^apply_updates.*/apply_updates = yes/' \
  /etc/dnf/automatic.conf
systemctl enable --now dnf-automatic.timer
dnf needs-restarting -r

dnf needs-restarting -r exits non-zero when a reboot is due. Wire that into your monitoring.

Gotchas

  • AppStream module streams. Newer Node, PHP or PostgreSQL versions come as module streams or versioned packages. Check dnf module list before you add a third-party repo.
  • EPEL is separate. Many tools you take for granted on Debian, such as htop or certbot, live in EPEL.
  • Minor releases move the base. 9.4, 9.5 and later arrive as normal updates. You don't reinstall for a point release, but read the release notes for deprecations.
  • Port 25. Postfix is often installed, but outbound mail is blocked by default on our network. Request an unblock in the portal if you need it.

Hardening baselines

If you work to a formal baseline, the scap-security-guide package ships OpenSCAP profiles for the RHEL 9 family, including CIS levels. Scan first, then remediate selectively:

dnf -y install openscap-scanner scap-security-guide
oscap xccdf eval --profile cis_server_l1 \
  --report /root/cis-report.html \
  /usr/share/xml/scap/ssg/content/ssg-almalinux9-ds.xml

Read the HTML report before applying automated fixes. Some CIS rules, such as separate partitions for /var/log, assume a layout that a single-disk VPS doesn't have. Document those as accepted exceptions rather than fighting them.

Sizing

A minimal AlmaLinux 9 install wants a little more memory than Debian. Boost is a comfortable floor for anything beyond a single tiny service. PostgreSQL or MariaDB with real data belongs on Turbo or Nitro. Background reading is in databases.

Questions

Is AlmaLinux binary compatible with RHEL?

AlmaLinux describes itself as ABI compatible with RHEL. In practice, software certified for RHEL 9 installs and runs on AlmaLinux 9, and the same EPEL and vendor repositories apply.

Should I disable SELinux to get my app working?

No. Find the denial with ausearch or journalctl, then fix the file context or set the right boolean. Disabling SELinux removes a layer that genuinely limits damage after a compromise.

How long is AlmaLinux 9 supported?

Active support with regular updates runs to 2027, and security fixes continue until 2032, mirroring the RHEL 9 lifecycle.