Rocky 8 ARM64
Overview
Rocky Linux is a community enterprise operating system from the Rocky Enterprise Software Foundation, built to be binary-compatible with Red Hat Enterprise Linux. This image is the native 64-bit Arm (AArch64/arm64) build of Rocky Linux 8, running the 4.18 kernel and following the RHEL 8 lifecycle. It is a pre-configured virtual machine for Microsoft Azure.
The image runs on Azure's Arm virtual machine sizes, which are powered by the Azure Cobalt 100 processor (the Dpsv6 and Dplsv6 families). On these sizes, many workloads deliver the same performance at a lower cost than on x86.
What you get:
- Rocky Linux 8.10, native 64-bit Arm (arm64 / AArch64), binary-compatible with RHEL 8
- A 64k page size kernel, as RHEL 8 ships on aarch64 (see the page size section below, because it affects tuning)
- 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 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
Rocky Linux 8.10 is the final Rocky Linux 8 release, and it is still supported
Rocky Linux 8 ends at 8.10. There will be no 8.11. Unlike the Rocky Linux 9 and 10 listings, which track a moving minor release, this image is pinned to the release that the 8 series terminates on.
That does not make it a frozen, archived image. Rocky Linux 8 is in security maintenance until 31 May 2029, and 8.10 is the live stream that receives those errata. The image therefore stays on the rolling Rocky Linux 8 repositories (BaseOS, AppStream and Extras, with no vault.rocky.org pin). Your own dnf update keeps pulling security fixes for the life of the release. You get a supported platform, not an archived one.
This Arm build is a separate product from the x86 Rocky Linux 8 images. It carries aarch64 packages and an aarch64 kernel, and it runs only on Arm virtual machine sizes. It uses the flat partition layout, not the LVM variant.
The page size is 64k: know this before you tune
RHEL 8 builds its aarch64 kernel with a 64 KiB page size. RHEL 9 moved the aarch64 kernel to 4 KiB. If you are moving a workload here from a Rocky Linux 9 or 10 Arm machine, this is the platform difference most likely to surprise you.
Check the page size:
getconf PAGESIZE65536The most visible consequence is huge pages. On a 4k kernel the default huge page is 2 MiB. On this kernel it is 512 MiB:
grep -E '^Hugepagesize' /proc/meminfo; ls /sys/kernel/mm/hugepages/Hugepagesize: 524288 kB hugepages-16777216kB hugepages-2048kB hugepages-524288kBPractical implications:
- Databases that reserve huge pages (PostgreSQL
huge_pages, MySQLlarge-pages, Oracle) allocate in 512 MiB units here. Round your shared buffer or SGA sizing to that granularity instead of copying a 2 MiB-based figure from an x86 or EL9 host. - JVM workloads that use
-XX:+UseLargePagesinherit the same 512 MiB granularity.-XX:LargePageSizeInBytesvalues carried over from a 4k host will not apply cleanly. - Memory accounting looks coarser. Small allocations round up to 64 KiB, so a process with many small mappings reports a larger resident set than the same process on a 4k kernel. This is expected and is not a leak.
- Anything that assumes
PAGE_SIZE == 4096at compile time needs rebuilding. Everything in the Rocky Linux repositories is already built correctly for this kernel.
What this image changes from the stock Rocky Linux 8 Arm image
Everything below was measured on the stock vendor image before it was changed, and every change is reversible in one command. Nothing is removed: the packages stay installed so you can turn any of it back on.
rpcbindis switched off. This is the significant change. The stock image enables bothrpcbind.socketandrpcbind.service, which between them bind four sockets on port 111 (IPv4 and IPv6, TCP and UDP) on every interface. That is an unadvertised network listener on every machine you launch. An operating system base image should expose one service, and that service is SSH, so both units ship disabled. NFSv4 does not needrpcbind. If you need NFSv3 or another RPC service, re-enable it withsudo systemctl enable --now rpcbind.socket.bluetooth.serviceis switched off. Bluetooth is not part of the stock image. Thebluezpackage arrives as a dependency of the full security patch, and its unit is enabled by RPM preset. An Azure virtual machine has no Bluetooth radio, so the unit is pointless and ships disabled. Re-enable it withsudo systemctl enable --now bluetooth.service.- Automatic updates are installed and armed. The stock image has no
dnf-automaticat all: no package, no configuration and no timer. This image installs it and arms it withupgrade_type = defaultandapply_updates = yes, so the machine keeps patching itself. - SSH is hardened in the main configuration file. The stock image permits root login and X11 forwarding. Rocky Linux 8 ships OpenSSH 8.0p1, which predates the
Include /etc/ssh/sshd_config.d/*.confdirective. There is no such directory and no such include, so the hardening is applied to/etc/ssh/sshd_configitself. This is the only filesshdactually reads on this release, and a drop-in file would be silently ignored here. - A pointless network interface rename is suppressed. The stock image logs
Error changing net interface name 'eth1' to 'eth0': File existsat error level on every boot after the first, because Azure's Accelerated Networking virtual function shares the primary interface's MAC address. An empty/etc/udev/rules.d/60-net.rulesoverride stops the attempt. Nothing about your networking changes: the kernel already names the interfaceseth0andeth1becausenet.ifnames=0is on the command line.
Two things you might expect from the sibling Rocky Linux 10 Arm64 listing are not changed here. They were measured on this base and did not need changing:
- Cockpit is already off.
cockpit-wsis installed, butcockpit.socketis disabled and nothing is listening on 9090. On the Rocky Linux 10 Arm image the socket is enabled. On this one it is not. To use the web console, enable it withsudo systemctl enable --now cockpit.socketand open 9090 in your network security group. rngdis left running. On the Rocky Linux 10 Arm image, the entropy daemon has no usable source and leaves the machinedegraded. On Rocky Linux 8, the vendor's/etc/sysconfig/rngdleaves the jitter entropy source available, sorngdstarts cleanly and the machine reportsrunningwith no failed units. It is left exactly as the distribution ships it.
The two changes that close a listener are recorded on the machine itself, at /var/lib/sac/data/rpcbind-disabled and /var/lib/sac/data/bluetooth-disabled, together with the command that restores each one.
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.
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. Usesudofrom the administrator account you named at create time.- 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 is left in enforcing mode, the Rocky Linux default.
- SSH on port 22 is the only off-box listener. chrony's port 323 is bound to the loopback address only.
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 will not accept this image.
Deploy the Virtual Machine
Option A: Azure Portal
- Open the Azure Marketplace and search for "Rocky Linux 8 Arm64 SecureAnyCloud"
- Select the image and click Create
- On the basics tab, configure the following:
- 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 this on your own workstation. Substitute your resource group, VM name and preferred region. Accept the Marketplace terms once per subscription, then create the machine:
az vm image terms accept --urn sac1647283583153:rocky-8-arm64:default:latest
az vm create \
--resource-group myResourceGroup \
--name my-rocky-8-arm64-vm \
--image sac1647283583153:rocky-8-arm64:default:latest \
--size Standard_D2ps_v6 \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku StandardThe --size must be an Arm64 family (Standard_D2ps_v6 above). Azure rejects an x86 size for an Arm image at create time.
Connect via SSH
Run these on your own workstation, not on the VM. Find the public IP, then connect:
az vm show --resource-group myResourceGroup --name my-rocky-8-arm64-vm --show-details --query publicIps -o tsv ssh azureuser@<vm-ip>There is no password to enter. If SSH asks you for one, the key you supplied at create time is not the key your client is offering.
Confirm the release and the architecture
Check that the machine is Rocky Linux 8:
cat /etc/rocky-releaseRocky Linux release 8.10 (Green Obsidian)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="Rocky Linux" VERSION="8.10 (Green Obsidian)" ID="rocky" VERSION_ID="8.10" PLATFORM_ID="platform:el8"The RHEL compatibility lineage is asserted by the distribution itself:
cat /etc/redhat-releaseRocky Linux release 8.10 (Green Obsidian)Confirm the kernel and the architecture. Both must report aarch64:
uname -srmLinux 4.18.0-553.162.1.el8_10.aarch64 aarch64Then check the processor. BIOS Model name is where Azure reports the host CPU, which on an Arm size is the Azure Cobalt 100:
lscpu | grep -E '^(Architecture|Vendor ID|Model name|BIOS Model name|CPU\(s\)):'Architecture: aarch64 CPU(s): 2 Vendor ID: ARM BIOS Model name: Cobalt 100Check the patch level and automatic updates
The image is fully patched at capture. dnf check-update exits 0 when nothing is pending and 100 when updates are waiting, so 0 is the answer you want:
sudo dnf -q check-update >/dev/null 2>&1; echo "exit=$?"exit=0Nothing is waiting on a reboot either:
sudo needs-restarting -rNo core libraries or services have been updated since boot-up. Reboot should not be necessary.Your update path is intact. The three repositories a Rocky Linux 8 machine needs are enabled, and none of them is pinned to the vault archive:
sudo dnf repolist --enabledrepo id repo name appstream Rocky Linux 8 - AppStream baseos Rocky Linux 8 - BaseOS extras Rocky Linux 8 - ExtrasThe PowerTools repository (RHEL 8's developer package set, renamed crb in RHEL 9 and later) is present but disabled, as it is on a stock Rocky Linux 8 machine. Enable it with sudo dnf config-manager --set-enabled powertools if a build needs it.
Automatic updates
The stock Rocky Linux 8 Arm image has no dnf-automatic at all. This image installs it and arms it, so the machine keeps patching itself without you scheduling anything:
systemctl is-enabled dnf-automatic.timerenabledsystemctl cat dnf-automatic.timer | grep -E 'OnCalendar|RandomizedDelaySec'OnCalendar=*-*-* 6:00 RandomizedDelaySec=60mThe policy applies updates rather than only downloading them:
grep -E '^(apply_updates|upgrade_type|download_updates)' /etc/dnf/automatic.confupgrade_type = default download_updates = yes apply_updates = yesupgrade_type is deliberately default and not security. Rocky Linux does not publish the updateinfo security metadata that a security policy filters on, so a security setting would silently apply nothing, ever. default applies the errata that are actually published.
Exactly one kernel ships in the image, so there is no superseded kernel for a vulnerability scanner to report:
rpm -q kernelkernel-4.18.0-553.162.1.el8_10.aarch64Verify the security posture
SELinux is enforcing, and persists that way across reboots:
getenforce; grep -E '^SELINUX=' /etc/selinux/configEnforcing SELINUX=enforcingThe root account is locked. LK is the locked state:
sudo passwd -S rootroot LK 2009-12-22 -1 -1 -1 -1 (Alternate authentication scheme in use.)No account on the machine carries a usable password hash at all, so there is nothing to guess. This command prints nothing on a correct image:
sudo awk -F: '($2 !~ /^[!*]/) && ($2 != "") {print $1}' /etc/shadowThe effective SSH policy is what sshd actually computes, which is the only thing worth checking. Root login is refused outright, and password and keyboard-interactive authentication are both off:
sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication|pubkeyauthentication|kbdinteractiveauthentication|x11forwarding|gssapiauthentication|maxauthtries) 'maxauthtries 4 permitrootlogin no pubkeyauthentication yes gssapiauthentication no passwordauthentication no kbdinteractiveauthentication no x11forwarding noThe image has no swap, as Azure expects. Swap belongs on the ephemeral resource disk, managed by waagent, never on the captured operating system disk. This command prints nothing:
swapon --showSSH is the only thing listening off-box. TCP 22 is the whole set:
ss -tlnState Recv-Q Send-Q Local Address:Port Peer Address:PortProcess LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:*And the only UDP sockets are chrony's, bound to the loopback address, so they are not reachable from the network:
ss -ulnState Recv-Q Send-Q Local Address:Port Peer Address:PortProcess UNCONN 0 0 127.0.0.1:323 0.0.0.0:* UNCONN 0 0 [::1]:323 [::]:*The three units that would otherwise have opened a port, or run a radio stack that does not exist on a virtual machine, are all disabled. They are disabled, not masked, so any of them is one command from working:
for u in rpcbind.socket bluetooth.service cockpit.socket; do printf '%s: %s\n' "$u" "$(systemctl is-enabled $u 2>&1 | head -1)"; donerpcbind.socket: disabled bluetooth.service: disabled cockpit.socket: disabledVerify Azure integration
The Azure Linux Agent is running and starts at boot:
systemctl is-active waagent;
systemctl is-enabled waagentactive enabledThe guest integration packages are all the aarch64 or noarch builds, as they should be on an Arm machine:
rpm -q WALinuxAgent cloud-init chronyWALinuxAgent-2.7.0.6-8.el8_8.rocky.0.1.noarch cloud-init-23.4-7.el8_10.11.0.2.noarch chrony-4.5-2.el8_10.aarch64cloud-init finished cleanly on this boot:
cloud-init statusstatus: doneThe serial console is on ttyAMA0, the Arm PL011 UART, which is what Azure's Boot diagnostics and Serial console read from. On x86 this would be ttyS0:
grep -o 'console=ttyAMA0[^ ]*' /proc/cmdlineconsole=ttyAMA0Nothing failed on this boot:
systemctl is-system-running;
systemctl list-units --state=failed --no-legend --plainrunningNetworking comes up promptly. Azure's Accelerated Networking virtual function is left unmanaged by NetworkManager, so NetworkManager-wait-online does not wait on it:
systemd-analyze blame | grep NetworkManager-wait-online916ms NetworkManager-wait-online.serviceThe clock is synchronized against the Azure host's precision clock rather than a public NTP pool, which is the correct source on a virtual machine:
systemctl is-active chronyd; chronyc -n sources | head -3active MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== #* PHC0 2 3 377 4 +29us[ +37us] +/- 8564nsThe disk layout is flat: partitions sit directly on the disk with no LVM, so growing the root filesystem is a single growpart plus xfs_growfs, with nothing else to resize:
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTNAME SIZE TYPE FSTYPE MOUNTPOINT sda 11G disk ├─sda1 99M part vfat /boot/efi ├─sda2 1000M part xfs /boot ├─sda3 4M part ├─sda4 1M part └─sda5 9.9G part xfs /sda3 and sda4 are small unformatted PReP and BIOS boot partitions that the vendor image carries for boot compatibility; they hold no filesystem and need no attention.
The operating system disk is 11 GiB. If you need more room, resize the disk in Azure and grow the root partition and filesystem:
sudo growpart /dev/sda 5
sudo xfs_growfs /Networking and the firewall
The Azure Network Security Group is the control plane for inbound and outbound traffic, and it is the first and usually the only place you need to open a port.
firewalld is not installed on this image:
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)That matches the Rocky Linux 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 requires a host firewall as well, 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.
Your machine has two network interfaces, and that is normal. eth1 is the Accelerated Networking virtual function; it shares eth0's MAC address and is deliberately left unmanaged, so you configure eth0 and ignore eth1:
nmcli -t -f DEVICE,STATE,TYPE deviceeth0:connected:ethernet eth1:unmanaged:ethernet lo:unmanaged:loopbackInstall 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 1:1.14.1-9.module+el8.4.0+542+81547229 appstreamRocky Linux 8 uses modules (AppStream module streams) for several major packages, which is a RHEL 8 concept that RHEL 9 and 10 dropped. If you want a newer stream than the default, list what is available and enable one before installing:
sudo dnf module list nginx
sudo dnf module enable -y nginx:1.22
sudo dnf install -y nginxThen enable the service in the usual way with sudo systemctl enable --now nginx, and open the port in your Network Security Group.
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 and the .ssh directory mode 700, owned by that user. The image ships with no human accounts at all, so the administrator you named at create time is the only login until you add one:
getent group wheelwheel:x:10:Common Use Cases
- RHEL 8-compatible application hosting on cost-efficient Azure Cobalt 100 Arm virtual machines
- Lifting an existing RHEL 8 or CentOS 8 workload onto Arm without changing the major release
- A RHEL-compatible platform for workloads certified against RHEL 8, without a subscription
- Arm build and CI runners that produce
el8packages, 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. 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. Root cannot log in over SSH at all, so connect as the administrator you named at create time.
az vm show --resource-group myResourceGroup --name my-rocky-8-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. Rocky Linux's mirror system is reached over both.
A package needs a newer version than the one in AppStream
Rocky Linux 8 uses AppStream module streams. The default stream is often not the newest one packaged. Check which streams exist before you add a third-party repository:
sudo dnf module list <package>Enabling a different stream with sudo dnf module enable -y <package>:<stream> is usually the right answer, and keeps you on distribution packages that receive Rocky Linux errata.
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 rather than 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.
The boot log mentions a dhclient timeout being reduced
One message appears at error level on every boot:
journalctl -p err -b --no-pager | grep -c 'Timeout too large'1It reads dhclient: Timeout too large reducing to: 2147483646 (TIME_MAX - 1). Azure's DHCP server offers an effectively infinite lease time, and the stock Rocky Linux 8 dhclient clamps it to the largest value it can represent, logging as it does so. Your lease is fine and your networking is unaffected. It is emitted by a stock distribution component, nothing in this image introduces it, and it is safe to ignore.
A memory figure looks larger than expected
This kernel uses 64 KiB pages, so every allocation rounds up to 64 KiB rather than 4 KiB. A process with many small mappings therefore reports a larger resident set here than the identical process on a Rocky Linux 9 or 10 Arm machine. This is an accounting difference, not a leak. See the page size section above for the tuning settings it affects.
Important Notes
Rocky Linux is free and open source. 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.
Rocky Linux is a trademark of the Rocky Enterprise Software Foundation. SecureAnyCloud is not affiliated with or endorsed by the Rocky Enterprise Software Foundation, and uses the name only to identify the distribution this image contains.
Rocky Linux 8 follows the RHEL 8 lifecycle. 8.10 is the final release of the 8 series, and Rocky Linux 8 is in security maintenance until 31 May 2029. Check the Rocky Linux release notes for the dates that apply to your deployment, and plan a move to Rocky Linux 9 or 10 before that date.
Support
For help 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 Rocky Linux 8 Arm64 on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com