Search
Join the Technical Preview Program
See how NVMe-oF removes iSCSI
bottlenecks in your HCI
The Best Hyperconverged
Infrastructure
(HCI) for Enterprise
ROBO, SMB & Edge
The Best Virtual SAN
for Enterprise ROBO, SMB & Edge

How to Harden AlmaLinux 9 and 10 for Production

  • November 13, 2026
  • 16 min read
IT Engineer and Technical Author. Karim is a specialist in Linux and open-source ecosystems. A prolific technical blogger, he provides expert guidance on system administration, shell scripting, and server optimization. Karim delivers high-authority content for various industry websites, focusing on enterprise Linux deployments and IT infrastructure management.
IT Engineer and Technical Author. Karim is a specialist in Linux and open-source ecosystems. A prolific technical blogger, he provides expert guidance on system administration, shell scripting, and server optimization. Karim delivers high-authority content for various industry websites, focusing on enterprise Linux deployments and IT infrastructure management.

A default AlmaLinux installation starts with SELinux, firewalld, and secure package repositories, but production systems still need a documented security baseline. This guide covers four high-value controls for AlmaLinux 9 and 10: SSH access, firewall exposure, SELinux enforcement, and automated security updates.

The commands are intended for system administrators and DevOps engineers. Test every change in staging, keep an active recovery path, and adapt the baseline to the application, network design, compliance requirements, and storage or cloud platform.

Production Security Baseline

Security hardening reduces avoidable exposure and limits the effect of a compromised account or service. It is a repeatable operating process rather than a one-time command list. Record approved settings, review exceptions, monitor changes, and retest the baseline after major application or operating system updates.

AlmaLinux Production Hardening Checklist

Start by updating supported packages and confirming that recovery access works. Restrict SSH to named administrators using keys, expose only required network services, keep SELinux in enforcing mode, and schedule security updates through a controlled rollout. This article covers that core baseline; production hosts still need centralized logging, backups, account lifecycle controls, vulnerability management, and workload-specific configuration.

Part 1 Secure SSH Access

OpenSSH is a common entry point on managed Linux servers. Review the effective configuration before editing files, require key-based access for administrators, disable direct root login, and validate every change before reloading the service.

Review the Effective SSH Configuration

Do not rely on commented lines in sshd_config. OpenSSH combines the main file with drop-in files, so use sshd -T to view the effective settings.

sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication|pubkeyauthentication)'

Confirm that a named administrator can connect with a key before disabling password authentication. Keep a second authenticated session open until the new configuration is verified.

sudoedit /etc/ssh/sshd_config.d/40-hardening.conf
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no

Configure Key Based Authentication

Generate an Ed25519 key on the administrator workstation and copy the public key to the server. Protect the private key with a passphrase and store recovery credentials according to your access policy.

ssh-keygen -t ed25519
ssh-copy-id admin@server.example.com

Change the SSH Port Only When Required

A non-default port can reduce automated log noise, but it does not replace key authentication, access restrictions, or monitoring. If policy requires another port, update the SSH configuration, SELinux port label, and firewall rule as one planned change.

sudo dnf install -y policycoreutils-python-utils
sudo semanage port -a -t ssh_port_t -p tcp 2222

Open the new port and test it in a second session before removing access to port 22. Roll back the change if validation fails.

Restrict SSH to Named Accounts

Use AllowUsers or an approved group policy to limit SSH access. Review the list whenever administrators join, leave, or change roles.

AllowUsers admin deploy

Validate and Reload SSH

Validate the configuration before applying it. A syntax error can prevent new SSH sessions.

sudo sshd -t

Reload sshd after validation, then inspect the effective values and test a new connection.

sudo systemctl reload sshd
sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication|allowusers|port)'

Keep the existing administrative session open until a second session succeeds with the intended account, key, port, and source network.

Part 2 Restrict Network Access with Firewalld

AlmaLinux uses firewalld to group interfaces and sources into zones. Apply rules to the zone that actually owns the server interface, and expose only the services required by the workload.

Confirm Firewalld Is Active

Check the service state before relying on firewall rules.

sudo systemctl status firewalld

Review Active Zones and Rules

Identify the active interfaces, their assigned zones, and the services and ports allowed in each zone.

sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=public --list-all

Use the Correct Zone for Each Interface

There is no universal production zone. Select a zone that matches the interface’s trust boundary, and specify that zone in change commands. Changing the global default zone does not replace a review of existing interface assignments and can disrupt remote access.

sudo firewall-cmd --get-default-zone
sudo firewall-cmd --get-zone-of-interface=eth0

Allow Only Required Services

Add named services or ports only to the zone that serves the workload. The example below assumes the public zone is correct for the host; replace it when another zone owns the interface.

sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload

If SSH uses another port, add it to the active zone and verify a new connection before removing the ssh service from that zone.

sudo firewall-cmd --permanent --zone=public --add-port=2222/tcp
sudo firewall-cmd --reload

Restrict Sensitive Ports by Source

Use a rich rule for administration or database access that should originate from a fixed host or trusted subnet. Replace the example addresses and port with approved values.

sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.10/32" port port="8443" protocol="tcp" accept'
sudo firewall-cmd --reload

Verify the Final Firewall Configuration

List all active zones and confirm the rules attached to the interface that carries production traffic.

sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=public --list-all

Every allowed service, port, source, and forwarding rule should have an owner and a documented reason.

Part 3 Keep SELinux Enforcing

SELinux confines processes even after an application account or service is compromised. Keep it enabled and investigate policy denials instead of disabling enforcement to make an application start.

Check the Current SELinux State

Use sestatus and getenforce to confirm whether SELinux is enabled and enforcing.

sestatus
getenforce

A standard AlmaLinux installation uses enforcing mode. Treat permissive or disabled mode as an exception that needs investigation and an approved remediation plan.

Return SELinux to Enforcing Mode

If SELinux is enabled but permissive, set enforcing mode temporarily, update the persistent configuration, and test the workload.

sudo setenforce 1
sudoedit /etc/selinux/config

If SELinux is disabled, do not switch directly to enforcing on a production host. Set SELINUX=permissive, schedule fixfiles -F onboot, reboot for a complete relabel, resolve denials, and change to enforcing only after validation. Plan the relabel and reboot during a maintenance window.

Diagnose SELinux Denials

Review recent AVC denials and identify the process, target, requested access, and file context. Correct labels, ports, file locations, or documented SELinux booleans before considering a custom policy.

sudo ausearch -m AVC -ts recent
sudo journalctl -t setroubleshoot --since today

Install the troubleshooting tools when a clearer explanation is required.

sudo dnf install -y setroubleshoot-server policycoreutils-python-utils
sudo sealert -a /var/log/audit/audit.log

Use Custom Policy Only as a Last Resort

Generate a local policy module only after confirming that the denied action is expected and no supported label, port type, or boolean solves the problem. Review the generated .te source before loading the module.

sudo ausearch -c '<process-name>' --raw | audit2allow -R -M local_service
less local_service.te

A custom allow rule can grant more access than intended. Keep the source under change control and remove the module when the application no longer needs it.

Part 4 Automate Security Updates

Security updates should follow a defined schedule with monitoring, staged deployment, and reboot handling. DNF Automatic can install security advisories, but it does not decide whether services or the kernel need a restart.

Install DNF Automatic

Install the package from the standard AlmaLinux repositories.

sudo dnf install -y dnf-automatic

Configure Security Only Updates

Edit the DNF Automatic configuration file.

sudoedit /etc/dnf/automatic.conf

Set upgrade_type to security. The install timer used below applies downloaded updates even if apply_updates has another value in the file.

[commands]
upgrade_type = security

Security-only mode limits the automatic transaction to packages associated with security advisories. Review the journal and monitor failed transactions.

Enable the Install Timer

Enable the timer that downloads and installs updates.

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

Confirm that the timer is enabled and check its next scheduled run.

sudo systemctl status dnf-automatic-install.timer
systemctl list-timers dnf-automatic-install.timer

Stage Updates and Plan Reboots

Use deployment rings or a staging environment before broad rollout. Monitor the first systems, check application health, and schedule required service or kernel restarts. Avoid patching every production node at the same time when redundancy depends on staggered availability.

Final Checks

Before go-live, verify key-based administrative access, the effective SSH policy, active firewalld zones, SELinux enforcing mode, and the DNF Automatic install timer. Record the approved state and retain a tested recovery method for access, package, and boot failures.

This checklist is a baseline, not a complete security program. Add centralized logs, time synchronization, backups with restore tests, least-privilege sudo rules, account lifecycle management, vulnerability scanning, workload-specific controls, and regular configuration review.

FAQ

How often should AlmaLinux security updates be installed?
Apply critical security fixes according to the organization’s exposure and change policy. Internet-facing systems usually need a faster schedule than isolated systems. Use staged deployment, health checks, and planned restarts.

How can I list AlmaLinux security advisories?
Run sudo dnf updateinfo list security to list available security advisories. Use sudo dnf upgrade –security for a reviewed manual security update transaction.

Should I disable SELinux when an application is blocked?
No. Review AVC denials, correct labels and ports, and check documented booleans. Create a narrow local policy only after verifying that the access is required.

Is changing the SSH port a security control?
It mainly reduces automated scanning noise. Key authentication, restricted users, source filtering, logging, and timely updates provide stronger protection.

What should I verify before putting AlmaLinux into production?
Verify supported package versions, SSH recovery access, firewall exposure, SELinux enforcement, automatic update monitoring, backups, logs, time synchronization, account ownership, and application-specific controls.

Found Karim’s article helpful? Looking for a reliable, high-performance, and cost-effective shared storage solution for your production cluster?
Dmytro Malynka
Dmytro Malynka StarWind Virtual SAN Product Manager
We’ve got you covered! StarWind Virtual SAN (VSAN) is specifically designed to provide highly-available shared storage for Hyper-V, vSphere, and KVM clusters. With StarWind VSAN, simplicity is key: utilize the local disks of your hypervisor hosts and create shared HA storage for your VMs. Interested in learning more? Book a short StarWind VSAN demo now and see it in action!