Deployment guide

Rocky Linux 8 Server

Overview

This guide covers the deployment and configuration of Rocky Linux 8 (Rocky Linux release 8.10, Green Obsidian) on Microsoft Azure, using SecureAnyCloud's Rocky Linux 8 virtual machine image from the Azure Marketplace.

Rocky Linux is a community enterprise Linux distribution from the Rocky Enterprise Software Foundation, built to be binary compatible with Red Hat Enterprise Linux 8. Version 8.10 is the final minor release of the 8 series. Updates keep you on 8.10 while security fixes continue to arrive.

Every command and every output in this guide was run on virtual machines deployed from the public Marketplace image (image version 4.0.1), as the azureuser account that a customer gets.

Support lifecycle

Rocky Linux 8 is in maintenance support until 31 May 2029 (Rocky Linux downloads, planned end of life). Until then, the Rocky Linux project publishes security and bug fixes for the 8.10 stream. For workloads that need to outlive that date, plan a move to a Rocky Linux 9 or 10 image.

This image was patched when it was built. Updates published after that build are not applied automatically, either at boot or on a timer, so a fresh virtual machine has updates waiting. Step 4 shows how to check for and apply them.

What you get

  • Rocky Linux 8.10 (Green Obsidian), binary compatible with RHEL 8
  • Azure Linux Agent (waagent, WALinuxAgent 2.7.0.6) active and enabled, plus cloud-init 23.4, for Azure provisioning
  • chronyd for time synchronisation, using the Azure host clock
  • SELinux in enforcing mode
  • The BaseOS, AppStream and Extras repositories enabled, so your update path is intact
  • Python 3.6.8 (python3, the platform Python that dnf uses)
  • Two plans: one for Gen1 virtual machines (BIOS boot) and one for Gen2 virtual machines (UEFI boot)
  • 24/7 SecureAnyCloud support

Platform: Microsoft Azure (Gen1 or Gen2 Hyper-V, by plan). Default user: azureuser (or the administrator name you choose at create time).

The Azure CLI is not installed on the image. Step 6 shows how to add it if you want it on the virtual machine.

Security posture

This image ships with no default password, and SSH accepts keys only:

  • Key-only SSH. PasswordAuthentication and KbdInteractiveAuthentication are no in the SSH daemon, so every login is by key.
  • Your own key. The key that logs you in is the public key you supply when you create the virtual machine. Azure installs it for your administrator user at first boot.
  • Per-machine identity. The SSH host keys and /etc/machine-id are generated on each virtual machine at first boot, so no two machines you launch share them.
  • Locked root. The root password is locked. SSH logins as root only print Please login as the user "azureuser" rather than the user "root". and close the connection.
  • SELinux enforcing. SELinux is in enforcing mode, the Rocky Linux default.
  • Network Security Group. No host firewall is installed, and the Azure Network Security Group controls inbound traffic (Step 7).

Prerequisites

Before you deploy this image, you need:

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

Choose a virtual machine size that suits your workload, and the plan that matches it: the first plan for Gen1 sizes and the Gen2 plan for Gen2 sizes.

1

Deploy the virtual machine

Option A: Azure Portal

  • Open the Azure Marketplace and search for "Rocky Linux 8 SecureAnyCloud".
  • Open the Rocky Linux 8 listing and choose Get it now, then 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 your preferred Azure region.
  • Size: select a size for your workload.
  • Under Administrator Account, select SSH public key and enter your key.
  • Under Inbound Port Rules, allow SSH (port 22), ideally from your own network only.
  • Choose Review + Create, then Create.

Option B: Azure CLI

The image carries a Marketplace purchase plan, so accept its terms once per subscription, then create the virtual machine. Replace <your-vm-size> with the size you chose:

az vm image terms accept --urn sac1647283583153:608f7ee7-2a42-4f52-893d-be662ec11828:608f7ee7-2a42-4f52-893d-be662ec11828:latest
az vm create \
  --resource-group myResourceGroup \
  --name my-rocky-8-vm \
  --image sac1647283583153:608f7ee7-2a42-4f52-893d-be662ec11828:608f7ee7-2a42-4f52-893d-be662ec11828:latest \
  --size <your-vm-size> \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

The offer and the first plan are both named by the same identifier (608f7ee7-2a42-4f52-893d-be662ec11828), which is why it appears twice in the URN. For a Gen2 size, use the Gen2 plan instead in both commands:

sac1647283583153:608f7ee7-2a42-4f52-893d-be662ec11828:608f7ee7-2a42-4f52-893d-be662ec11828-gen2:latest
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-rocky-8-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 that you supplied at create time.

The login message Activate the web console with: systemctl enable --now cockpit.socket comes from the cockpit-ws package on the image. The web console is not set up: the main cockpit package is not installed and the socket is disabled. Step 8 shows how to turn it on if you want it.

3

Confirm the release

Check that the machine is the Rocky Linux 8.10 release you expect:

cat /etc/rocky-release grep -E '^(NAME|VERSION|ID|PLATFORM_ID)=' /etc/os-release uname -rm

The expected output on a fresh virtual machine from image 4.0.1 is:

Rocky Linux release 8.10 (Green Obsidian) NAME="Rocky Linux" VERSION="8.10 (Green Obsidian)" ID="rocky" PLATFORM_ID="platform:el8" 4.18.0-553.172.1.el8_10.x86_64 x86_64

The el8_10 tag in the kernel version shows that the machine is on the 8.10 maintenance stream. After you apply updates (Step 4) and reboot, the kernel version moves on while the release stays 8.10.

4

Check for and apply updates

dnf check-update returns exit code 100 when updates are pending and 0 when none are. Run:

sudo dnf check-update > /dev/null 2>&1 echo "check-update exit code: $?" dnf repolist --enabled

The expected output on a fresh virtual machine is:

check-update exit code: 100 repo id repo name appstream Rocky Linux 8 - AppStream baseos Rocky Linux 8 - BaseOS extras Rocky Linux 8 - Extras

The image was patched when it was built, so the exit code 100 reflects only the updates published since then (on 2 November 2026, a fresh virtual machine had 37 waiting). sudo dnf history list shows the build-time upgrade as its newest entry.

Apply the updates, and reboot if a new kernel was installed:

sudo dnf upgrade -y sudo systemctl reboot

The image does not update itself. dnf-makecache.timer is enabled, but it only refreshes the repository metadata, and dnf-automatic is not installed. To have updates applied on a schedule, install and enable it:

sudo dnf install -y dnf-automatic
sudo sed -i 's/^apply_updates = no/apply_updates = yes/' /etc/dnf/automatic.conf
sudo systemctl enable --now dnf-automatic.timer
5

Verify the security posture

Confirm that SELinux is enforcing, root is locked and SSH is key-only:

getenforce grep -E '^[[:space:]]*SELINUX=' /etc/selinux/config
sudo passwd -S root | cut -d' ' -f1-2 sudo sshd -T | grep -E '^(pubkeyauthentication|passwordauthentication|kbdinteractiveauthentication) '

The expected output is:

Enforcing SELINUX=enforcing root LK pubkeyauthentication yes passwordauthentication no kbdinteractiveauthentication no

root LK means the root password is locked.

sudo sshd -T | grep '^permitrootlogin' prints permitrootlogin yes, from the PermitRootLogin yes line in /etc/ssh/sshd_config (the Rocky Linux 8 default). Root still cannot log in, because its password is locked and the only entry in /root/.ssh/authorized_keys is cloud-init's, which prints the "Please login as the user" message and closes the connection.

To turn root login off in the SSH daemon as well, change that line:

sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.orig
sudo sed -i 's/^PermitRootLogin yes$/PermitRootLogin no/' /etc/ssh/sshd_config
sudo sshd -t && sudo systemctl restart sshd
sudo sshd -T | grep '^permitrootlogin'

The last command then prints permitrootlogin no. Keep your current session open until you have checked that a new ssh azureuser@<vm-ip> connection still works.

6

Verify Azure integration

Confirm the Azure Linux Agent, cloud-init and time synchronisation are healthy:

systemctl is-active waagent
systemctl is-enabled waagent cloud-init --version sudo cloud-init status
systemctl is-active chronyd timedatectl | grep 'Time zone'

The expected output is:

active enabled /usr/bin/cloud-init 23.4-7.el8_10.11.0.2 status: done active Time zone: UTC (UTC, +0000)

waagent is what lets Azure provision your SSH key, run extensions and report VM health, so it should always be active and enabled. chronyc sources shows PHC0, the Azure host clock, as the selected time source.

python3 --version reports Python 3.6.8. That is the platform Python that dnf itself uses. For application work, install a newer interpreter from AppStream alongside it, for example sudo dnf install -y python3.11.

The Azure CLI is not installed. To add it, use Microsoft's repository for RHEL 8-compatible systems:

sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
sudo dnf install -y https://packages.microsoft.com/config/rhel/8/packages-microsoft-prod.rpm
sudo dnf install -y azure-cli az version

Sign in with az login before using it against your subscription.

7

Networking and the firewall

The Azure Network Security Group is the control plane for inbound and outbound traffic. It is the first, and usually the only, place where you need to open a port. The image needs a single inbound port, SSH on 22.

firewalld is not installed (rpm -q firewalld prints package firewalld is not installed), so your NSG rules take effect exactly as written. Confirm what is listening before you open anything:

ss -tlnu

On a fresh virtual machine, you see sshd on port 22 and rpcbind on port 111 (TCP and UDP), on all addresses. You also see chronyd on 127.0.0.1:323 and [::1]:323, which only the machine itself can reach.

Keep port 111 closed in your NSG. If you do not use NFS, switch rpcbind off:

sudo systemctl disable --now rpcbind.service rpcbind.socket

If your policy requires a host firewall as well, install and enable it, keeping SSH open:

sudo dnf install -y firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --list-services

--list-services then prints cockpit dhcpv6-client ssh, because firewalld's default zone already allows SSH. Once firewalld is running, a port must be open in both the NSG and firewalld before traffic reaches your service.

8

Install software

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

dnf search nginx

The 8 series ships several versions of some languages, databases and servers as module streams, so you can pick a version rather than take the default:

dnf module list nginx

The list shows the streams from 1.14 [d] (the default) up to 1.24. Install a package and enable it in the usual way, for example sudo dnf install -y nginx followed by sudo systemctl enable --now nginx.

To use the web console that the login message mentions, install it and enable the socket. Reach port 9090 over an SSH tunnel rather than opening it in the NSG:

sudo dnf install -y cockpit
sudo systemctl enable --now cockpit.socket

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 with mode 600, and give the .ssh directory mode 700, owned by that user.

azureuser is the only login account until you add one. Check the wheel group:

getent group wheel

Filesystem layout

The image uses these mount points:

  • /: root filesystem (XFS, /dev/sda5)
  • /boot: kernel files (XFS, /dev/sda2)
  • /boot/efi: EFI system partition (/dev/sda1)
  • /mnt: Azure temporary resource disk (ext4). Its contents are lost when the VM is deallocated.

The OS disk is GPT-partitioned with both an EFI system partition and a BIOS boot partition. This is how one image layout serves both the Gen1 and Gen2 plans.

Server components

The image contains these components:

  • Rocky Linux: 8.10 (Green Obsidian), maintenance support until 31 May 2029
  • Azure Linux Agent: WALinuxAgent 2.7.0.6 (waagent), active and enabled
  • cloud-init: 23.4 (check it with sudo cloud-init status)
  • Python 3: 3.6.8 (python3, the platform Python)
  • chrony: from BaseOS (chronyd, active)
  • firewalld: not installed (Step 7 shows how to add it)
  • Azure CLI: not installed (Step 6 shows how to add it)

Common use cases

  • RHEL 8-compatible application hosting
  • Software certified on the Enterprise Linux 8 platform
  • Long-lived enterprise server workloads, within the 8 series support window
  • A migration target for CentOS 8 estates

Troubleshooting

Cannot connect via SSH

  • Verify that the VM is in the Running state in the Azure Portal.
  • Check that port 22 is allowed in the Network Security Group.
  • Make sure that you are using the correct username: azureuser, or the administrator name you chose.
  • Verify that your SSH key matches the one you supplied at create time. Password login is disabled, so a wrong key cannot fall back to a password prompt.

To see which key your client is actually offering, run ssh -v azureuser@<vm-ip> from your workstation and look for the Offering public key lines.

The VM does not start with my chosen size

Gen2-only sizes need the Gen2 plan, and the first plan needs a size that supports Gen1. Recreate the VM with the plan that matches your size (Step 1).

Azure agent not running

Check the agent's status:

systemctl status waagent --no-pager

If it is not running, start and enable it with sudo systemctl enable --now waagent.

Package manager issues

Refresh the metadata cache, then check that the Rocky Linux mirrors resolve:

sudo dnf clean all
sudo dnf makecache getent hosts download.rockylinux.org

A service is blocked and the logs mention SELinux

SELinux is enforcing on this image. Rather than disabling it, look at what was denied. On a fresh machine there are no recent denials, so the command below reports none:

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

Security recommendations

  • Apply the updates waiting on a new virtual machine (Step 4), and consider dnf-automatic for scheduled updates.
  • Allow SSH in the Network Security Group from your own address ranges only, and keep port 111 closed or switch rpcbind off (Step 7).
  • Set PermitRootLogin no if your policy requires it (Step 5).
  • Remove the installer's kickstart file if you do not need it. The image keeps it at /root/original-ks.cfg (readable by root only). It records the build's installer settings, including a hashed installer password that no account on your virtual machine uses. Remove it with sudo rm /root/original-ks.cfg.

Important notes

Rocky Linux is free and open source, distributed under the BSD 3-Clause licence with GPL-licensed components. No subscription or licence key is required.

Rocky Linux 8 is in maintenance support until 31 May 2029. For workloads that need to outlive that date, plan a move to a Rocky Linux 9 or 10 image.

Rocky Linux is a trademark of the Rocky Enterprise Software Foundation. The name is used here nominatively, only to identify the distribution that this image contains. SecureAnyCloud is not affiliated with, endorsed by or sponsored by the Rocky Enterprise Software Foundation.

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 Rocky Linux 8 on Azure with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure