Deployment guide

openSUSE Leap 16 ARM64

Overview

openSUSE Leap is a community distribution produced by the openSUSE Project, sharing its core codebase with SUSE Linux Enterprise 16. This SecureAnyCloud image is the native 64-bit Arm (AArch64/arm64) build of openSUSE Leap 16.0, running the 6.12 kernel, as a preconfigured virtual machine image in the Azure Marketplace.

It runs on Azure's Arm virtual machine sizes, which are powered by the Azure Cobalt 100 processor (the Dpsv6 and Dplsv6 families). Many workloads deliver the same performance on these sizes at a lower cost than on x86.

What you get:

  • openSUSE Leap 16.0, native 64-bit Arm (arm64 / AArch64) with the standard 4k page size kernel
  • Every available patch applied at build time, and again immediately before capture
  • Automatic security patching installed, armed and enabled, so the machine keeps patching itself
  • Azure Linux Agent (waagent) and cloud-init for Azure integration, with a first-boot fix that cuts five minutes off every launch
  • Chrony for NTP time synchronization against the Azure host clock
  • SELinux in enforcing mode, the Leap 16 default
  • The repo-oss update path enabled and GPG-checked, so your patch 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 openSUSE Leap 16.0, on Arm

This listing tracks openSUSE Leap 16.0. Leap 16.0 reached general availability on 1 October 2025 and is supported until 31 October 2027. That is a shorter support window than the Leap 15.x series offered, so plan your upgrade to the next Leap release before that date.

The image is built from the current Leap 16.0 maintenance stream and brought up to date at build time. Your own zypper patch then rolls the machine forward within Leap 16.0 in the normal way.

The Arm build is a separate product from the x86 openSUSE Leap 16 image. It carries aarch64 packages and an aarch64 kernel, and it runs only on Arm virtual machine sizes. It uses a flat partition layout, a plain EFI system partition plus a root partition with no LVM, and the standard 4k page size kernel.

The image is built from the official openSUSE Azure disk image published by the openSUSE Project, not from a third-party Marketplace image. This matters for licensing. The image carries no Marketplace purchase plan of its own, and you need to accept no vendor terms beyond SecureAnyCloud's own to launch it.

What this image changes from the stock openSUSE Leap 16 Arm image

Every change below was measured on the stock vendor image before it was made, and every change is reversible in one command. Nothing is removed.

  • The five-minute first-boot stall is fixed. On the stock image, cloud-init's Azure data source asks dhcpcd for a temporary DHCP lease. dhcpcd gets the lease in about two seconds, but cloud-init runs it with --persistent, so it never exits. cloud-init then waits for its full 300-second timeout, logs Failed to obtain DHCP lease and an Azure data source failure, and only then reads the lease it already had. Boot succeeds, but every machine wastes five minutes and cloud-init status reports degraded forever afterwards. This image installs the ISC dhclient, which exits once it has the lease, and tells cloud-init to prefer it. Measured on the build machine, boot time fell from 5 minutes 19 seconds to 10.2 seconds, and cloud-init reports done instead of degraded.
  • Automatic security patching is installed and armed. The stock image has no automatic update mechanism at all. openSUSE has no dnf-automatic and no unattended-upgrades, so this image ships a systemd timer, sac-zypper-patch.timer, that runs zypper patch daily.
  • SSH is hardened by a drop-in file that sorts ahead of every other SSH configuration file, so a later package update cannot quietly loosen it.
  • rpcbind is confirmed switched off, so nothing listens on port 111. Re-enable it with sudo systemctl enable --now rpcbind.socket if you need NFSv3.

The first-boot change is recorded on the machine itself at /var/lib/sac/data/cloud-init-dhcp-client, together with the command that reverts it.

Two changes that SecureAnyCloud's Rocky Linux Arm images need are deliberately not made here, because the problems do not exist on this base. openSUSE Leap 16 ships no Cockpit web console, so nothing listens on port 9090. It also ships no rng-tools, so nothing fails at boot for want of a hardware random number generator. The port check in Step 5 proves the result either way.

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 and keyboard-interactive authentication are disabled in the SSH daemon, so every login is by key.
  • PermitRootLogin is set to prohibit-password, so root can never log in with a password. No root key ships in the image, so root has no SSH login at all until you add one deliberately. Use sudo from azureuser instead.
  • 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 build account is deleted before capture, and the image is checked to confirm that no account with a user ID of 1000 or above survives.
  • The only key that works is the public key you supply when you create the virtual machine. Azure injects it at first boot into the administrator account you name.
  • SELinux is left in enforcing mode, the openSUSE Leap 16 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 will not accept this image.

1

Deploy the virtual machine

Option A: Azure Portal

  • Open the Azure Marketplace and search for "openSUSE Leap 16 Arm64 SecureAnyCloud".
  • Select the image and click Create.
  • Choose your subscription, resource group and region.
  • Pick an Arm64 size such as Standard_D2ps_v6.
  • Set the administrator username and paste your SSH public key.
  • Allow inbound port 22 (SSH) and create the machine.

Option B: Azure CLI

Run the commands below 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:opensuse-leap-16-arm64:default:latest
az vm create \
  --resource-group myResourceGroup \
  --name my-opensuse-leap-16-arm64-vm \
  --image sac1647283583153:opensuse-leap-16-arm64:default:latest \
  --size Standard_D2ps_v6 \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

The --size must be an Arm64 size (Standard_D2ps_v6 above). Azure rejects an x86 size for an Arm image at create time.

2

Connect via SSH

ssh azureuser@<your-vm-public-ip>

Azure accepts only the key you supplied at create time. There is no password login.

3

Confirm the release and the architecture

Confirm that you have genuine openSUSE Leap 16.0, built for Arm:

cat /etc/os-release
NAME="openSUSE Leap" VERSION="16.0" ID="opensuse-leap" ID_LIKE="suse opensuse" VERSION_ID="16.0" PRETTY_NAME="openSUSE Leap 16.0" ANSI_COLOR="0;32" CPE_NAME="cpe:/o:opensuse:leap:16.0" BUG_REPORT_URL="https://bugs.opensuse.org" HOME_URL="https://www.opensuse.org/" DOCUMENTATION_URL="https://en.opensuse.org/Portal:Leap" LOGO="distributor-logo-Leap"

Confirm the architecture and the processor. aarch64 is the Arm 64-bit architecture, and Neoverse-N2 is the core that Azure Cobalt 100 uses:

uname -m && lscpu | grep -E 'Architecture|Model name|BIOS Model'
aarch64 Architecture: aarch64 Model name: Neoverse-N2 BIOS Model name: Cobalt 100 None CPU @ 3.4GHz

Check the kernel and its page size. This image uses the standard 4k page size kernel:

uname -r && getconf PAGESIZE
6.12.0-160000.37-default 4096

The kernel is a packaged, managed kernel, so it receives patches through the normal update path. Confirm the kernel package:

rpm -q kernel-default
kernel-default-6.12.0-160000.37.1.aarch64

The disk layout

The image uses a flat GPT layout: an EFI system partition and a root partition, with no LVM. The root filesystem is btrfs, openSUSE's standard choice, with separate subvolumes for the directories that benefit from them:

lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT && findmnt -no SOURCE,FSTYPE /
NAME SIZE FSTYPE MOUNTPOINT sda 30G ├─sda1 512M vfat /boot/efi └─sda2 29.5G btrfs /var sr0 1024M /dev/sda2[/@/.snapshots/1/snapshot] btrfs

It is normal for openSUSE to report the root filesystem as a subvolume path, and it is not a fault. To see the subvolumes, run:

sudo btrfs subvolume list /
ID 256 gen 11 top level 5 path @ ID 257 gen 16 top level 256 path @/.snapshots ID 258 gen 63 top level 257 path @/.snapshots/1/snapshot ID 259 gen 46 top level 256 path @/home ID 260 gen 16 top level 256 path @/opt ID 261 gen 55 top level 256 path @/root ID 262 gen 16 top level 256 path @/srv ID 263 gen 66 top level 256 path @/var ID 264 gen 16 top level 256 path @/boot/writable ID 265 gen 55 top level 256 path @/usr/local ID 266 gen 16 top level 256 path @/boot/grub2/arm64-efi ID 267 gen 16 top level 256 path @/boot/grub2/i386-pc

The operating system disk is 30 GB and carries no swap:

df -hT / /boot/efi && swapon --show
Filesystem Type Size Used Avail Use% Mounted on /dev/sda2 btrfs 30G 1.8G 28G 7% / /dev/sda1 vfat 512M 4.3M 508M 1% /boot/efi

swapon --show prints nothing, which means no swap is configured. Azure image certification requires this. You can add swap yourself if a workload needs it.

4

Check the patch level and automatic updates

openSUSE uses zypper, not dnf or apt. The image was patched at build time, so a freshly launched machine reports only patches released since then. When there are none, the output reads:

sudo zypper patch-check
Loading repository data... Reading installed packages... 0 patches needed (0 security patches)

zypper patch-check exits 0 when nothing is pending, 100 when ordinary patches are available and 101 when security patches are available. This makes it convenient in scripts.

Your update path is the repo-oss repository, with GPG checking enabled:

sudo zypper lr -E
# | Alias | Name | Enabled | GPG Check | Refresh --+------------------------+----------------------+---------+-----------+-------- 3 | openSUSE:repo-openh264 | repo-openh264 (16.0) | Yes | (r ) Yes | Yes 4 | openSUSE:repo-oss | repo-oss (16.0) | Yes | (r ) Yes | Yes

If you are used to Leap 15, note that Leap 16 does not have a separate repo-update. Maintenance patches are delivered through repo-oss itself, so the two repositories above are the whole update path.

Apply patches yourself at any time with:

sudo zypper refresh && sudo zypper patch

Automatic updates

openSUSE has no dnf-automatic and no unattended-upgrades, so this image ships a SecureAnyCloud systemd timer. The timer runs zypper patch daily with a randomized delay of up to an hour:

systemctl is-enabled sac-zypper-patch.timer && systemctl list-timers sac-zypper-patch.timer --no-pager
enabled NEXT LEFT LAST PASSED UNIT ACTIVATES Tue 2026-09-15 00:06:31 UTC 1h 31min - - sac-zypper-patch.timer sac-zypper-patch.service 1 timers listed.

To see what the timer will run, or to run it immediately:

systemctl cat sac-zypper-patch.service
sudo systemctl start sac-zypper-patch.service

If your change control requires it, turn automatic patching off:

sudo systemctl disable --now sac-zypper-patch.timer

Some patches need a reboot to take effect. Check whether one is needed:

sudo zypper needs-rebooting
5

Verify the security posture

Confirm the effective SSH configuration. This command reads the parsed, effective settings rather than the file, so it accounts for every drop-in:

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

without-password is the older spelling of prohibit-password and means the same thing: root may not log in with a password.

Confirm the root account has no usable password:

sudo passwd -S root
root L 2009-12-22 -1 -1 -1 -1

The L means locked.

Confirm SELinux is enforcing:

getenforce
Enforcing

Confirm that SSH is the only service listening off the machine. This is worth checking on any image you run, not just this one:

ss -tln && ss -uln
State 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 [::]:*

Port 22 is the only port reachable from outside the machine. The two UDP sockets on port 323 are chrony's control interface. They are bound to the loopback address only, so they are not reachable from the network.

6

Verify Azure integration

Confirm the Azure Linux Agent is present and running:

waagent --version
WALinuxAgent-2.14.0.1 running on opensuse 16.0 Python: 3.13.14 Goal state agent: 2.14.0.1

Confirm that cloud-init completed cleanly. This is where the first-boot fix shows up. On the stock image, this command reports degraded:

cloud-init status --long
status: done extended_status: done boot_status_code: enabled-by-generator detail: DataSourceAzure [seed=/var/lib/waagent] errors: [] recoverable_errors: {}

Check how long the machine took to boot:

systemd-analyze
Startup finished in 949ms (kernel) + 4.016s (initrd) + 5.244s (userspace) = 10.211s

For comparison, the stock vendor image reaches the same point after 5 minutes and 19 seconds, because of the DHCP stall described earlier.

Confirm time synchronization against the Azure host clock. PHC0 is the hypervisor clock, and stratum 1 means the machine is synchronized directly to it:

chronyc tracking
Reference ID : 50484330 (PHC0) Stratum : 1 System time : 0.000002129 seconds slow of NTP time

Confirm nothing failed during boot:

systemctl list-units --state=failed

An empty list is the expected result.

The Azure serial console works through the Arm PL011 UART. This is ttyAMA0, not the ttyS0 you would see on an x86 machine:

cat /proc/cmdline | tr ' ' '\n' | grep console=
console=tty1 console=ttyAMA0
7

Networking and the firewall

No host firewall is installed or enabled on this image. Your Azure Network Security Group is the firewall, which is the usual arrangement for an Azure Linux image. Manage inbound rules there, and you have one place to look.

If you also want a host firewall, install one:

sudo zypper install firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=ssh sudo firewall-cmd --reload

Add the firewall after you have confirmed SSH access. Always keep port 22 open in the rule set, or you will lock yourself out.

8

Install software

Install packages with zypper:

sudo zypper refresh
sudo zypper install nginx

Search for a package:

zypper search nginx

Find which package owns a file:

zypper search --provides /usr/bin/python3

If you are coming from a Red Hat family distribution, the rough translations are dnf install to zypper install, dnf search to zypper search, dnf update to zypper update, and dnf upgrade --security to zypper patch.

Common use cases

  • A general-purpose Linux server on Arm, where the lower cost of Azure Cobalt 100 is attractive
  • Build and test agents for software that ships aarch64 binaries or container images
  • Web and application servers, where the workload is already available for Arm
  • A development environment that matches a SUSE Linux Enterprise 16 production target, since Leap 16 shares its core codebase

Troubleshooting

Cannot connect via SSH

Check that the Network Security Group allows inbound TCP 22 from your address, that the machine is running, and that you are using the private key that matches the public key you supplied at create time. Password authentication is disabled by design, so a password prompt means the key was not offered.

The VM will not create, or will not boot

The most common cause is an x86 virtual machine size. This is an Arm64 image and runs only on Arm sizes such as Standard_D2ps_v6. Confirm the architecture with uname -m, which must print aarch64.

Azure agent not running

sudo systemctl status waagent
sudo systemctl restart waagent

Package manager issues

Refresh the repository metadata first:

sudo zypper refresh

If a repository fails to refresh, confirm that the machine has outbound internet access. If zypper reports a lock held by another process, the automatic patch timer may be running. Wait for it to finish, or stop it with sudo systemctl stop sac-zypper-patch.service.

Locked plymouth packages

sudo zypper locks

openSUSE Leap 16 ships a vendor lock covering the plymouth boot splash packages. The lock is part of the stock distribution and is cosmetic. It does not hold back security patches, and zypper patch-check reporting clean is the proof. Leave it in place.

A service is blocked and the logs mention SELinux

sudo ausearch -m AVC -ts recent

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

The boot log mentions a dhclient timeout

One message appears at error level on every boot:

journalctl -p err -b --no-pager
dhclient[...]: Timeout too large reducing to: 2147483646 (TIME_MAX - 1)

Azure's DHCP server hands out an unlimited lease time, and ISC dhclient logs a notice when it clamps that value to the largest number it can store. The message is cosmetic and does not affect the lease. It is a direct consequence of the first-boot fix described earlier: one harmless log line in exchange for five minutes off every boot. It is safe to ignore.

Important notes

openSUSE Leap is free and open source. A single license does not cover it: the distribution is a collection of independently licensed packages. On this image, 550 installed packages carry 86 distinct license strings, most commonly GPL-2.0-or-later, MIT, LGPL-2.1-or-later, GPL-3.0-or-later, BSD-3-Clause and Apache-2.0. You can read any package's terms with rpm -qi <package>.

No subscription, entitlement or license key is required, and no per-seat cost applies. No SUSE entitlement is involved.

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

openSUSE Leap 16.0 reached general availability on 1 October 2025 and is supported until 31 October 2027. Check the openSUSE Leap roadmap for the dates that apply to your deployment, and plan your upgrade to the next Leap release before support ends.

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 openSUSE Leap 16 Arm64 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