Deployment guide

AlmaLinux 9.8

Overview

AlmaLinux is a community-owned enterprise Linux distribution, produced by the AlmaLinux OS Foundation to be binary compatible with Red Hat Enterprise Linux. Version 9.8, codename Olive Jaguar, is a point release in the RHEL 9 family and runs the 5.14 kernel.

This guide covers deploying and configuring AlmaLinux 9.8 on Microsoft Azure, using SecureAnyCloud's preconfigured virtual machine image from the Azure Marketplace.

What you get:

  • AlmaLinux 9.8, binary compatible with RHEL 9
  • Every available update in the 9.8 stream applied at build time
  • Automatic updates armed and enabled, so the machine keeps patching itself
  • Azure Linux Agent (waagent) and cloud-init for Azure integration
  • Chronyd for NTP time synchronisation
  • SELinux in enforcing mode
  • BaseOS, AppStream and Extras repositories enabled, so your update path is intact
  • No swap on the operating system disk
  • Gen2 Hyper-V virtual machine support
  • 24/7 SecureAnyCloud support

Platform: Microsoft Azure (Gen2 Hyper-V). Default user: azureuser.

Which AlmaLinux 9 image should I choose?

SecureAnyCloud publishes AlmaLinux 9 in two shapes, and they are deliberately different products. Pick the one that matches how your organisation procures an operating system.

AlmaLinux 9.8 (this image) AlmaLinux 9

Named for The 9.8 point release The 9 major release

Built from 9.8 specifically, asserted at build time Whichever AlmaLinux 9 point release is current when it is rebuilt

Suits Change control and validated configuration matrices that name an exact minor version Teams who simply want current AlmaLinux 9

Choose this image when your build sheet, compliance baseline or vendor support matrix names 9.8 and you need the image you procured to say so. The build refuses to run against any other point release, so a machine launched from this listing reports release 9.8 and nothing else.

Two points are worth stating plainly:

  • At the time of publication, 9.8 is also the newest AlmaLinux 9 point release. RHEL-family security backports roll into the latest minor stream, so today this image carries materially the same current software as the rolling AlmaLinux 9 image. The distinction becomes visible when AlmaLinux ships 9.9. The AlmaLinux 9 image moves on, and this one continues to identify as the 9.8 build.
  • This is a pin on what you procured, not a freeze on what you run. The image keeps the standard BaseOS, AppStream and Extras repositories, so your own dnf update rolls the machine forward within AlmaLinux 9 in the normal way. If you need to hold a fleet at 9.8, see Step 6, and read the warning there first.

Security posture

This image ships with no known credential. There is no default password and no baked-in SSH key:

  • The root account password is locked, so no one can log in as root with a password.
  • No account on the image has a usable password at all.
  • PasswordAuthentication is disabled in the SSH daemon, so every login is by key.
  • PermitRootLogin is set to without-password, so root cannot be reached with a password. No root key ships in the image, so in practice root has no remote login until you create one deliberately.
  • SSH host keys are removed before capture and regenerated on each machine at first boot, so no two machines you launch share a host identity.
  • /etc/machine-id is cleared before capture and regenerated per machine.
  • The only key that works is the public key you supply when you create the virtual machine. Azure injects it into azureuser at first boot.
  • SELinux is left in enforcing mode, the AlmaLinux default.

Prerequisites

Before you deploy this image, make sure you have:

  • An active Microsoft Azure subscription
  • Access to the Azure Portal or Azure CLI
  • An SSH key pair for Linux VM access
  • Familiarity with Azure VM management

Recommended VM size: Standard_B2s (2 vCPU, 4 GB RAM) or larger.

1

Deploy the Virtual Machine

Option A: Azure Portal

  • Open the Azure Marketplace and search for "AlmaLinux 9.8 SecureAnyCloud".
  • Select the image and choose Create.
  • Configure the basics:
    • Subscription: select your Azure subscription.
    • Resource Group: create a new one or select an existing one.
    • Virtual Machine Name: enter a name for your VM.
    • Region: select your preferred Azure region.
    • Size: Standard_B2s is recommended.
  • Under Administrator Account, select SSH public key and enter your key.
  • Under Inbound Port Rules, allow SSH (port 22).
  • Choose Review + Create, then choose Create.

Option B: Azure CLI

Run these commands on your own workstation. Substitute your resource group, VM name and preferred region:

az vm image terms accept --urn sac1647283583153:almalinux-9-8:default:latest
az vm create \
  --resource-group myResourceGroup \
  --name my-almalinux-9-8-vm \
  --image sac1647283583153:almalinux-9-8:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard
2

Connect via SSH

Run these commands on your own workstation, not on the VM. Find the public IP, then connect:

az vm show --resource-group myResourceGroup --name my-almalinux-9-8-vm --show-details --query publicIps -o tsv ssh azureuser@<vm-ip>

There is no password to enter. If SSH asks for one, the key your client is offering is not the key you supplied at create time.

3

Confirm the release

First, check that the machine runs the point release you procured:

cat /etc/almalinux-release
AlmaLinux release 9.8 (Olive Jaguar)

The os-release fields carry the same information in a machine-readable form, which is what configuration management tools read:

grep -E '^(NAME|VERSION|ID|VERSION_ID|PLATFORM_ID)=' /etc/os-release
NAME="AlmaLinux" VERSION="9.8 (Olive Jaguar)" ID="almalinux" VERSION_ID="9.8" PLATFORM_ID="platform:el9"

VERSION_ID is 9.8, not 9. Inventory and compliance tools key on this field, and it is the reason this listing exists as a separate product.

The distribution itself asserts the RHEL compatibility lineage:

cat /etc/redhat-release
AlmaLinux release 9.8 (Olive Jaguar)

Then check the kernel:

uname -srm
Linux 5.14.0-687.36.1.el9_8.x86_64 x86_64
4

Check the patch level and automatic updates

Every update available in the 9.8 stream was applied when this image was built. The dnf check-update command exits 100 when updates are pending and 0 when none are:

dnf -q check-update >/dev/null 2>&1; echo "exit=$?"
exit=0

Check that no reboot is pending either:

dnf needs-restarting -r
No core libraries or services have been updated since boot-up. Reboot should not be necessary.

Your update path is intact. List the enabled repositories. There are three:

dnf repolist --enabled
repo id repo name appstream AlmaLinux 9 - AppStream baseos AlmaLinux 9 - BaseOS extras AlmaLinux 9 - Extras

CRB (CodeReady Builder) ships configured but disabled, which is the AlmaLinux default. Enable CRB only if you build software that needs its development headers:

sudo dnf config-manager --set-enabled crb

Automatic updates

Unlike a stock AlmaLinux cloud image, this machine keeps patching itself. The dnf-automatic package is installed and its timer is enabled, so the machine applies updates on its own schedule:

systemctl is-enabled dnf-automatic.timer
enabled
systemctl cat dnf-automatic.timer | grep -E 'OnCalendar|RandomizedDelaySec'
OnCalendar=*-*-* 6:00 RandomizedDelaySec=60m

The policy applies all available updates, not only those tagged as security errata. It never reboots automatically, so a kernel update waits for a window you choose instead of restarting a production machine without warning:

grep -E '^(apply_updates|upgrade_type|download_updates|reboot)' /etc/dnf/automatic.conf
upgrade_type = default download_updates = yes apply_updates = yes reboot = never

upgrade_type is deliberately default rather than security. On an image whose errata metadata is not always populated, a security-only policy can silently resolve to applying nothing. The default setting is the one that actually keeps the machine current.

Because reboot = never, check periodically whether a restart is owed after a kernel update, using the needs-restarting -r command above. To opt out entirely, run sudo systemctl disable --now dnf-automatic.timer.

5

Verify the security posture

Confirm that SELinux is enforcing:

getenforce
Enforcing

Confirm that the root account is locked. LK in the second field means locked:

passwd -S root
root LK 2009-12-22 -1 -1 -1 -1 (Alternate authentication scheme in use.)

Confirm that no account on the machine has a usable password. This command prints nothing on a clean image:

sudo awk -F: '($2 !~ /^[!*]/) && ($2 != "") {print $1}' /etc/shadow

Read the SSH daemon's effective policy instead of the config file, because the running daemon is what a client actually meets:

sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication|pubkeyauthentication) '
permitrootlogin without-password pubkeyauthentication yes passwordauthentication no

The image has no swap on the operating system disk. Azure manages swap on the ephemeral resource disk if you want it, and a swap file baked into a Marketplace image is not permitted. This command prints nothing:

swapon --show

Confirm what is listening. On a freshly launched machine, sshd on port 22 is your remote access. The base OS also runs rpcbind on port 111 and chronyd bound to the loopback address for time synchronisation:

ss -tulnH | awk '{print $1, $5}' | sort -u
tcp 0.0.0.0:111 tcp 0.0.0.0:22 tcp [::]:111 tcp [::]:22 udp 0.0.0.0:111 udp 127.0.0.1:323 udp [::1]:323 udp [::]:111

The Azure Network Security Group (NSG) controls inbound traffic. Only the ports you explicitly open in the NSG are reachable from outside the VM, regardless of what is bound locally.

If you do not use RPC-based services and want to close port 111 on the host as well, run sudo systemctl disable --now rpcbind.socket rpcbind.service.

6

Holding a machine at 9.8

By default this machine behaves like any other AlmaLinux 9 system. sudo dnf update moves it forward within the AlmaLinux 9 series, including across future point releases. This is the right behaviour for most workloads, and it is how you receive security fixes.

If your change control requires a fleet to stay on the 9.8 package set, use AlmaLinux's mechanism, the releasever variable:

echo "9.8" | sudo tee /etc/dnf/vars/releasever

Read this before you pin. AlmaLinux serves a pinned minor release from its vault, and a vault is only populated once that release has been superseded. At the time of writing, 9.8 is the current release, so pinning today would point dnf at a vault location that may not exist yet.

More importantly, once a vault is frozen it stops receiving new security backports. Pinning trades security currency for version stability. Pin only if a compliance obligation requires it, revisit the decision on a schedule, and never pin a machine that is exposed to the internet without compensating controls.

For most people the right choice is to leave the repositories alone and let the automatic updates run. Use this listing for what it is: a guarantee about the release you procured.

7

Verify Azure integration

The Azure Linux Agent handles provisioning, extensions and the portal's serial console. Check the agent and the related packages:

systemctl is-active waagent rpm -q WALinuxAgent cloud-init chrony
active WALinuxAgent-2.14.0.1-4.el9.noarch cloud-init-24.4-8.el9_8.1.alma.1.noarch chrony-4.8-1.el9.x86_64

Cloud-init should report done, which means provisioning finished cleanly:

cloud-init status
status: done

The kernel puts a console on ttyS0. This makes boot diagnostics and the portal's serial console work when you cannot reach the machine over SSH:

grep -o 'console=ttyS0[^ ]*' /proc/cmdline

Time synchronisation runs through chronyd against the Azure host clock. Check the time sources:

chronyc -n sources | head -4
MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== #* PHC0 2 3 377 8 -5662ns[-8956ns] +/- 3607ns

Azure attaches an ephemeral resource disk, which waagent formats and mounts at /mnt. The disk is fast and local, but it is erased whenever the machine is deallocated or moved. Use it for scratch data and caches, never for data you need to keep:

df -h / /mnt
Filesystem Size Used Avail Use% Mounted on /dev/sda4 29G 1.4G 28G 5% / /dev/sdb1 7.8G 28K 7.4G 1% /mnt
8

Networking and the firewall

The Azure Network Security Group controls inbound and outbound traffic. It is the first place, and usually the only place, where you need to open a port.

This image is a minimal build, so firewalld is not installed:

rpm -q firewalld || echo "(firewalld absent - the Azure NSG is your only firewall)"
package firewalld is not installed (firewalld absent - the Azure NSG is your only firewall)

This is deliberate. With no host firewall in the way, your NSG rules take effect exactly as written, with no second layer to keep in sync. Confirm what is listening before you open anything:

ss -tlnp

If your policy also requires a host firewall, install and enable it yourself:

sudo dnf install -y firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-port=443/tcp sudo firewall-cmd --reload

Once firewalld is running, a port must be open in both the Azure NSG and firewalld before traffic reaches your service.

9

Install software

AppStream carries the application packages. Search it, then install what you need:

dnf search nginx

Install a package and enable it in the usual way. For example, run sudo dnf install -y nginx, then sudo systemctl enable --now nginx.

To add another administrator, create the account with sudo adduser <name>. Add it to the wheel group with sudo usermod -aG wheel <name>. Then copy your public key into /home/<name>/.ssh/authorized_keys, with mode 600 on the file and mode 700 on the .ssh directory, both owned by that user.

The image ships with no human accounts at all, so azureuser is the only login until you add one. List the group members:

getent group wheel

Common use cases

  • An enterprise Linux base for application servers where the exact minor release is part of a validated configuration
  • A RHEL-compatible platform for workloads certified against RHEL 9, without a subscription
  • A standard operating system baseline for fleets managed by Ansible, Puppet or Salt
  • A build and test host for software that must be verified against a named RHEL 9 point release

Troubleshooting

Cannot connect via SSH

Check that the Network Security Group allows inbound TCP 22 from your address. Confirm that the machine is running. Make sure your client offers the private key that matches the public key you supplied at create time. Password authentication is disabled, so a password prompt means key negotiation already failed.

Check the power state of the VM:

az vm show --resource-group myResourceGroup --name my-almalinux-9-8-vm --show-details --query powerState -o tsv

Azure agent not running

Check the agent status and its recent log:

systemctl status waagent --no-pager sudo journalctl -u waagent -n 50 --no-pager

If waagent is stopped, the extensions and portal features that depend on it stop working. Restart it with sudo systemctl restart waagent.

Package manager issues

Clear the metadata cache and rebuild it:

sudo dnf clean all
sudo dnf makecache

If a repository is unreachable, confirm that the machine has outbound HTTPS and that DNS resolves. AlmaLinux's mirror system is reached over both.

A service is blocked and the logs mention SELinux

SELinux is enforcing, which is the secure default and should stay that way. Look at the denial instead of disabling SELinux:

sudo ausearch -m AVC -ts recent 2>/dev/null || echo "no recent AVC denials"

Most denials on a fresh machine come from software installed into a non-standard path. Relabel with sudo restorecon -Rv /path before you consider any policy change.

Important notes

AlmaLinux is free and open source software. A single licence does not cover it. The distribution is a collection of free and open source licences across its package set, predominantly GPL, with LGPL, BSD, MIT, Apache and others. No subscription, entitlement or licence key is required, and no per-seat cost applies.

AlmaLinux is a trademark of the AlmaLinux OS Foundation. SecureAnyCloud is not affiliated with or endorsed by the AlmaLinux OS Foundation, and uses the name only to identify the distribution this image contains.

AlmaLinux 9 follows the RHEL 9 lifecycle, with support running into 2032. Check the AlmaLinux release notes for the dates that apply to your deployment.

Support

For assistance with this image, contact SecureAnyCloud support:

  • Website: secureanycloud.com
  • Product catalogue: secureanycloud.com/products
  • User guides: secureanycloud.com/guides
  • SLA: 24-hour response guaranteed

Deploy on Azure

Launch AlmaLinux 9.8 on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure