AlmaLinux 10 ARM64
Overview
AlmaLinux is a community-owned enterprise Linux distribution, produced by the AlmaLinux OS Foundation to be binary compatible with Red Hat Enterprise Linux (RHEL).
This SecureAnyCloud image is the native Arm build of AlmaLinux 10 for 64-bit Arm (AArch64/arm64) on Microsoft Azure. It runs the 6.12 kernel and follows the RHEL 10 lifecycle. It runs on Azure's Arm virtual machine sizes, which are powered by the Azure Cobalt 100 processor (the Dpsv6 and Dplsv6 families), where many workloads deliver the same performance at a lower cost than on x86.
What you get:
- AlmaLinux 10, native 64-bit Arm (arm64 / AArch64) with the standard 4k page size kernel, binary compatible with RHEL 10
- Every available update applied at build time, and again immediately before capture
- Automatic updates installed, armed and enabled, so the machine keeps patching itself
- Azure Linux Agent (waagent) and cloud-init for Azure integration
- chronyd for NTP time synchronization against the Azure host clock
- SELinux in enforcing mode
- BaseOS, AppStream, CRB and Extras repositories enabled, so your update path is intact
- SSH as the only network listener, with no swap on the operating system disk
- Gen2 Hyper-V virtual machine support
- 24/7 SecureAnyCloud support
Platform: Microsoft Azure (Gen2 Hyper-V, Arm64, Azure Cobalt 100) | Default user: azureuser
This is the AlmaLinux 10 major release, on Arm
This listing tracks the AlmaLinux 10 major release, not a frozen minor release. RHEL-family security fixes roll into the latest minor stream. The image is therefore built from whichever AlmaLinux 10 point release is current at build time and brought fully up to date.
Your own dnf update rolls the machine forward within AlmaLinux 10 in the normal way, so you keep receiving security fixes. AlmaLinux 10 has active support until May 2030 and security support until May 2035.
This Arm build is a separate product from the x86 AlmaLinux 10 images. It carries aarch64 packages and an aarch64 kernel, and it runs only on Arm virtual machine sizes. It is the standard 4k page size build, not the separate 64k page size variant.
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.
PasswordAuthenticationand keyboard-interactive authentication are disabled in the SSH daemon, so every login is by key.PermitRootLoginis set tono, so root cannot log in over SSH at all. Usesudofromazureuserinstead.- 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-idis 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 the administrator account you name at first boot.
- SELinux stays 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_D2ps_v6 (2 vCPU, 8 GB RAM, Azure Cobalt 100) or larger.
This is an Arm64 image, so you must launch it on an Arm virtual machine size, such as the Dpsv6 or Dplsv6 families. An x86 size such as Standard_B2s does not accept this image.
Deploy the Virtual Machine
Option A: Azure Portal
- Open the Azure Marketplace and search for "AlmaLinux 10 Arm64 SecureAnyCloud".
- Select the image and click Create.
- On the Basics tab, fill in these fields:
- 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 a region that offers Arm sizes
- Size:
Standard_D2ps_v6is recommended (an Arm64 size)
- Under Administrator account, select SSH public key and enter your key.
- Under Inbound port rules, allow SSH (port 22).
- Click Review + create, then Create.
Option B: Azure CLI
Run these commands on your own workstation, substituting your resource group, VM name and preferred region. Accept the Marketplace terms once per subscription, then create the VM:
az vm image terms accept --urn sac1647283583153:almalinux-10-arm64:default:latest
az vm create \
--resource-group myResourceGroup \
--name my-almalinux-10-arm64-vm \
--image sac1647283583153:almalinux-10-arm64:default:latest \
--size Standard_D2ps_v6 \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku StandardThe --size must be an Arm64 size (Standard_D2ps_v6 above). Azure rejects an x86 size for an Arm image at create time.
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-10-arm64-vm --show-details --query publicIps -o tsv ssh azureuser@<vm-ip>There is no password to enter. If SSH asks for one, your client is not offering the key you supplied at create time.
Confirm the release and the architecture
Check that the machine is AlmaLinux 10:
cat /etc/almalinux-releaseAlmaLinux release 10.2 (Lavender Lion)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-releaseNAME="AlmaLinux" VERSION="10.2 (Lavender Lion)" ID="almalinux" VERSION_ID="10.2" PLATFORM_ID="platform:el10"The distribution itself declares its RHEL compatibility lineage:
cat /etc/redhat-releaseAlmaLinux release 10.2 (Lavender Lion)Check the kernel and the page size. aarch64 confirms this is the native 64-bit Arm build, and 4096 confirms the standard 4k page size kernel:
uname -srm getconf PAGESIZELinux 6.12.0-211.53.1.el10_2.aarch64 aarch64 4096Check the processor. On Azure's Arm sizes it is the Azure Cobalt 100, built on Arm Neoverse N2 cores:
lscpu | grep -E '^(Architecture|Vendor ID|Model name|BIOS Model name):'Architecture: aarch64 Vendor ID: ARM Model name: Neoverse-N2 BIOS Model name: Cobalt 100 None CPU @ 3.4GHzThe version reported is the AlmaLinux 10 point release the image was patched to. This listing tracks the 10 major release, so dnf update rolls the machine forward across future point releases.
Check the patch level and automatic updates
Every available update was applied when this image was built. dnf check-update exits 100 when updates are pending and 0 when none are. Check it:
dnf -q check-update >/dev/null 2>&1; echo "exit=$?"exit=0No update is waiting on a reboot either:
dnf needs-restarting -rNo core libraries or services have been updated since boot-up. Reboot should not be necessary.Exactly one kernel is installed, and it is the one the machine is running. Superseded kernels are removed before capture:
rpm -q kernel-corekernel-core-6.12.0-211.53.1.el10_2.aarch64Your update path is intact. BaseOS, AppStream, CRB (CodeReady Builder) and Extras are all enabled, which is the AlmaLinux 10 cloud image default. List the repositories:
dnf repolist --enabledrepo id repo name appstream AlmaLinux 10 - AppStream baseos AlmaLinux 10 - BaseOS crb AlmaLinux 10 - CRB extras AlmaLinux 10 - ExtrasAutomatic updates
The stock AlmaLinux 10 Arm64 cloud image does not include dnf-automatic. This image installs it and enables its timer, so the machine applies updates on its own schedule. Verify the timer:
systemctl is-enabled dnf-automatic.timerenabledsystemctl cat dnf-automatic.timer | grep -E 'OnCalendar|RandomizedDelaySec'OnCalendar=*-*-* 6:00 RandomizedDelaySec=60mThe 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.confupgrade_type = default download_updates = yes apply_updates = yes reboot = neverupgrade_type is deliberately default rather than security. A security-only policy depends on errata metadata being present for every update. Where it is missing, that policy silently applies nothing, so default is the setting 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 of automatic updates entirely, run sudo systemctl disable --now dnf-automatic.timer.
Verify the security posture
Confirm SELinux is enforcing:
getenforceEnforcingConfirm the root account is locked. The L in the second field means locked:
passwd -S rootroot L 2009-12-22 -1 -1 -1 -1Confirm no account on the machine has a usable password. This prints nothing on a clean image:
sudo awk -F: '($2 !~ /^[!*]/) && ($2 != "") {print $1}' /etc/shadowRead the SSH daemon's effective policy rather than the configuration file, because the running daemon is what a client meets:
sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication|pubkeyauthentication|kbdinteractiveauthentication) 'permitrootlogin no pubkeyauthentication yes passwordauthentication no kbdinteractiveauthentication noA drop-in file pins that policy. It sorts ahead of every other SSH configuration file, so a later package update to the main configuration cannot quietly loosen it:
grep -vE '^#' /etc/ssh/sshd_config.d/00-sac-hardening.confPermitRootLogin no PasswordAuthentication no KbdInteractiveAuthentication no PermitEmptyPasswords noThere is no swap on the operating system disk, because a swap file baked into a Marketplace image is not permitted. This command prints nothing:
swapon --showConfirm what is listening. SSH on port 22 is the only service reachable from the network. The only other socket is chronyd, bound to the loopback address for time synchronization:
ss -tln
ss -ulnState Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:* State Recv-Q Send-Q Local Address:Port Peer Address:Port UNCONN 0 0 127.0.0.1:323 0.0.0.0:* UNCONN 0 0 [::1]:323 [::]:*The base operating system ships nfs-utils for NFS version 4 client mounts, which need no extra listener. The rpcbind service that NFS version 3 relies on is installed but disabled, so port 111 stays closed. Verify:
systemctl is-enabled rpcbind.socket rpcbind.service || truedisabled disabledIf you need NFS version 3, enable it with sudo systemctl enable --now rpcbind.socket and open only the ports you need in your network security group.
Verify Azure integration
The Azure Linux Agent handles extensions and the portal's recovery features, and cloud-init provisions the machine. Check both:
systemctl is-active waagent rpm -q WALinuxAgent cloud-init chronyactive WALinuxAgent-2.14.0.1-3.el10.noarch cloud-init-24.4-7.el10_2.1.noarch chrony-4.8-2.el10.aarch64Cloud-init should report done, which means provisioning finished cleanly:
cloud-init statusstatus: doneThe kernel puts a console on ttyAMA0, the Arm PL011 serial port. This makes boot diagnostics and the portal's serial console work when you cannot reach the machine over SSH. On x86 images the console is ttyS0; on Arm it is ttyAMA0:
grep -o 'console=ttyAMA0' /proc/cmdlineconsole=ttyAMA0Time synchronization runs through chronyd against the Azure host clock. Your offsets will differ:
chronyc -n sources | head -4MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== #* PHC0 2 3 377 9 -4633ns[-5103ns] +/- 10usThe operating system disk uses a flat layout with XFS for the root and boot filesystems:
df -h / findmnt -no SOURCE,FSTYPE,TARGET /bootFilesystem Size Used Avail Use% Mounted on /dev/sda3 29G 1.5G 28G 6% / /dev/sda2 xfs /bootStandard_D2ps_v6 has no local temporary disk, so there is no scratch disk at /mnt on that size. Arm sizes with a d in the name, such as Standard_D2pds_v6, add a local temporary disk. Treat anything on a temporary disk as disposable, because it is erased whenever the machine is deallocated or moved.
Networking and the firewall
The Azure network security group (NSG) controls inbound and outbound traffic. It is the first, and usually the only, place you need to open a port.
firewalld is not installed on this image. Confirm:
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 matches the AlmaLinux cloud image default. With no host firewall in the way, your NSG rules take effect exactly as written, with no second layer to keep in sync. 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 --reloadOnce firewalld is running, a port must be open in both the Azure NSG and firewalld before traffic reaches your service.
Install software
AppStream carries the application packages. Everything in the repositories is built for Arm, so dnf resolves aarch64 packages automatically, with nothing extra to configure:
dnf -q list --available nginx 2>/dev/null | tail -2Available Packages nginx.aarch64 2:1.26.3-6.el10_2.6 appstreamInstall a package and enable it in the usual way. For example, run sudo dnf install -y nginx, then sudo systemctl enable --now nginx, then open the port in your network security group.
To add another administrator, create the account with sudo adduser <name> and add it to the wheel group with sudo usermod -aG wheel <name>. Then copy your public key into /home/<name>/.ssh/authorized_keys. The file needs mode 600, the .ssh directory needs mode 700, and both must be owned by that user.
The image ships with no human accounts, so the administrator you named at create time is the only login until you add one. List the members of the wheel group:
getent group wheelCommon Use Cases
- RHEL 10-compatible application hosting on cost-efficient Azure Cobalt 100 Arm virtual machines
- Container platforms and cloud-native workloads on Arm
- A RHEL-compatible platform for workloads certified against RHEL 10, without a subscription
- Arm build and CI runners, and fleets managed by Ansible, Puppet or Salt
Troubleshooting
Cannot connect via SSH
Check that the network security group allows inbound TCP 22 from your address and 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. Root login over SSH is disabled too, so connect as the administrator you named at create time.
az vm show --resource-group myResourceGroup --name my-almalinux-10-arm64-vm --show-details --query powerState -o tsvThe VM will not create or will not boot
This is an Arm64 image. It runs only on Arm virtual machine sizes (the Dpsv6 and Dplsv6 Azure Cobalt 100 families and other p sizes).
If Azure rejects the size at create time, confirm that you selected an Arm size and not an x86 one such as Standard_B2s or Standard_D2s_v5. If the machine never becomes reachable, open Boot diagnostics and the Serial console in the portal. Both read from ttyAMA0.
Azure agent not running
Check whether the agent is running, and read its recent log:
systemctl is-active waagent
sudo journalctl -u waagent -n 20 --no-pagerIf it reports anything other than active, start it:
sudo systemctl enable --now waagentPackage manager issues
Clear the metadata cache and rebuild it:
sudo dnf clean all
sudo dnf makecacheIf 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 </dev/null 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. It is not covered by a single license: the distribution is a collection of free and open-source licenses across its package set, predominantly GPL and LGPL, with MIT, BSD, Apache and others. No subscription, entitlement or license 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 10 follows the RHEL 10 lifecycle: active support runs until 31 May 2030 and security support until 31 May 2035. 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 catalog: secureanycloud.com/products
- User guides: secureanycloud.com/guides
- SLA: 24 hour response guaranteed
Deploy on Azure
Launch AlmaLinux 10 Arm64 on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com