Deployment guide

CentOS Stream 9 Gui

Overview

This guide covers the deployment and configuration of CentOS Stream 9 with the GNOME desktop on Microsoft Azure using SecureAnyCloud's pre-configured virtual machine image from the Azure Marketplace.

CentOS Stream is a free, open source Linux distribution maintained by the CentOS Project and sponsored by Red Hat. Stream 9 is the continuously delivered branch that sits just ahead of Red Hat Enterprise Linux 9. It shows what the next RHEL 9 minor release will contain, while remaining compatible with the RHEL 9 platform.

This image is genuine CentOS Stream 9 with the distribution's own desktop added: the AppStream environment group @graphical-server-environment, which CentOS calls Server with GUI. You reach the desktop with any VNC viewer through TigerVNC, the VNC server that CentOS Stream ships in its own AppStream repository. Each user gets their own full GNOME session running on the virtual machine.

The image is built so that a freshly deployed machine exposes nothing but SSH. VNC ships switched off, no account has a password, and no VNC password exists anywhere in the image. When you turn VNC on, the server listens on localhost only, so you reach it through an SSH tunnel rather than over the internet.

What you get:

  • CentOS Stream 9 on the 5.14 kernel, with every available update applied at build time
  • The GNOME desktop from the CentOS Stream AppStream repository: GNOME Shell 40.10, the GDM 40 login screen and mutter 40.9
  • Desktop applications from the same group, including Files (Nautilus), Terminal, Firefox, Text Editor, Calculator, System Monitor, Disks, Logs and Software
  • TigerVNC 1.16 (tigervnc-server), configured for per-user desktops on localhost only, with every offered security type requiring the VNC password
  • sac-vnc, a small helper that shows the VNC state and starts or stops a user's desktop in one command
  • Guest sleep disabled, so the desktop never offers a Suspend that would leave an Azure virtual machine unreachable
  • dnf-automatic armed to apply updates automatically, so the machine keeps patching itself
  • SELinux in enforcing mode and the Azure provisioning path unchanged (cloud-init, the Azure Linux Agent, NetworkManager)
  • A 30 GiB operating system disk, sized for a desktop rather than a headless server
  • Generation 1 Hyper-V virtual machine support
  • 24/7 SecureAnyCloud support

The image carries around 1,180 packages and uses about 5.5 GiB of the 30 GiB operating system disk, which leaves the rest for your own software and data.

Platform: Microsoft Azure (Generation 1 Hyper-V, x64). Default user: azureuser.

Virtual machine generation. This image is a Generation 1 image, because the upstream CentOS Stream cloud image boots through the legacy BIOS path rather than UEFI. Generation 1 is supported across the common Azure VM families used for desktops, including the B, D and E v3 and v5 series. Choose a size that supports Generation 1, because a few of the newest families are Generation 2 only.

End of life: 31 May 2027

CentOS Stream 9 reaches end of life on 31 May 2027. The CentOS Project publishes that date on centos.org, and endoflife.date lists the same date for the end of both support and security updates for CentOS Stream 9. After that date, the CentOS Project stops publishing updates for Stream 9, and this image no longer receives security fixes from its repositories.

The upgrade path is CentOS Stream 10, supported until 31 May 2030. There is no in-place upgrade between CentOS Stream major versions. Deploy a new virtual machine from CentOS Stream 10 (SecureAnyCloud publishes CentOS Stream 10 with GNOME Desktop), move your data and configuration across, and then retire this machine. Plan any long-lived workload on this image with that date in mind.

Why VNC, and how it is locked down

The remote desktop options on CentOS Stream 9 are limited. GNOME Remote Desktop on this release only shares a session that someone is already logged into at the machine, so it cannot give you a remote login on a cloud server. xrdp is available only from EPEL, a third-party repository that this image does not use. TigerVNC is the first-party way to run headless GNOME desktops on CentOS Stream 9, and it is what Red Hat documents for RHEL 9.

VNC's own password protocol is old, and it uses only the first 8 characters of the password. That is why this image never exposes VNC to the network. The policy file /etc/tigervnc/vncserver-config-mandatory forces two settings for every user. TigerVNC loads the file after each user's own configuration, so a user's settings cannot undo it:

  • localhost makes the VNC server listen on 127.0.0.1 and ::1 only. You connect through an SSH tunnel, which is encrypted and authenticated with your SSH key.
  • securitytypes=tlsvnc,vncauth offers only security types that require the VNC password. None (no password) is never offered.

GDM runs with Wayland disabled (WaylandEnable=False in /etc/gdm/custom.conf), which RHEL 9 requires for TigerVNC desktops. Sessions are X11.

The two passwords, and which one goes where

Neither password exists until you create it, and both belong to you:

  • Your VNC password. You set it by running vncpasswd as your own user, without sudo. It is stored at ~/.config/tigervnc/passwd, readable only by you. Your VNC viewer asks for it when it connects. Only the first 8 characters count.
  • Your account password. You set it with sudo passwd <your-user>. The VNC session logs you straight into GNOME, but the desktop still asks for this password when the screen locks and when an application needs administrator rights. The image ships with no account password at all.

SSH stays key-only throughout. Setting either password does not enable password logins over SSH.

Security posture

This image ships with no known credential.

  • No account has a password. The root account is locked, and your administrator account is created at first boot with only the SSH key you supply.
  • SSH is key-only (PasswordAuthentication no).
  • No VNC password exists for any account. No VNC desktop is configured, and the unauthenticated inetd mode xvnc.socket is disabled. A new virtual machine listens on SSH port 22 only, and port 22 is the only port that the listing advertises.
  • When VNC is on, it listens on localhost only, and every offered security type requires the VNC password.
  • The helper refuses to start a desktop for a user who has no account password or no VNC password.
  • Guest sleep is disabled, so the desktop menu offers Restart, Power Off and Log Out, but never Suspend.
  • SSH host keys are removed before capture and regenerated on each machine at first boot. /etc/machine-id is regenerated per machine, so no two machines share a host identity. Firmware update tooling also generates its own client key per machine.
  • SELinux is left in enforcing mode, which is the CentOS Stream default, and GDM automatic login is not enabled.

Known issue: TigerVNC and CVE-2025-49177

CVE-2025-49177 is not fixed in the TigerVNC package on CentOS Stream 9, and Red Hat has said it will not fix it in TigerVNC on RHEL 9. Checked on 17 September 2026:

  • Red Hat (Security Data API for CVE-2025-49177) lists tigervnc on Red Hat Enterprise Linux 9 as "Will not fix", severity Important, CVSS 3.1 score 6.1 with vector AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:L, which is a local attack vector. Red Hat describes it as: "A flaw was found in the XFIXES extension. The XFixesSetClientDisconnectMode handler does not validate the request length, allowing a client to read unintended memory from previous requests." On mitigation Red Hat says: "Mitigation for this issue is either not available or the currently available options don't meet the Red Hat Product Security criteria".
  • CentOS Stream does not publish security advisories; its package sources are public instead. The CentOS Stream 9 TigerVNC source (the c9s branch of gitlab.com/redhat/centos-stream/rpms/tigervnc, version 1.16.2-4, the same build this image ships as tigervnc-server-1.16.2-4.el9) records fixes for CVE-2025-49175, CVE-2025-49176, CVE-2025-49178, CVE-2025-49179 and CVE-2025-49180 in its changelog, and no entry for CVE-2025-49177. The changelog of the installed package agrees. For comparison, the CentOS Stream 9 Xwayland source does record it: "CVE fix for: CVE-2025-49175 (RHEL-97288), CVE-2025-49176 (RHEL-97334), CVE-2025-49177 (RHEL-97357)" in xorg-x11-server-Xwayland 23.2.7-4, which is the newer X server generation.

SecureAnyCloud measured the following on this image. These are recorded as facts, not as a claim that you are unaffected.

  • Both the VNC server (Xvnc) and the login screen's Xorg server report the X.Org 1.20.11 code base.
  • When a client asks either of them for XFIXES protocol version 6.0, they negotiate version 5.0. The XFixesSetClientDisconnectMode request belongs to XFIXES version 6.
  • Xvnc runs as the desktop's own user and accepts X clients only through its local socket and that user's X authority cookie. It opens no X11 TCP port.

VNC is off until you enable it. If your security policy does not accept an unfixed vendor CVE, do not enable VNC on this image. If CentOS Stream publishes a fixed package, dnf-automatic applies it automatically.

Prerequisites

Before you deploy this image, ensure that you have:

  • An active Microsoft Azure subscription
  • Access to the Azure portal or the Azure CLI
  • An SSH key pair for Linux VM access
  • A VNC viewer: TigerVNC Viewer (Windows, macOS, Linux), RealVNC Viewer, Remmina on Linux, or the built-in Screen Sharing app on macOS

Recommended VM size: Standard_B2ms (2 vCPU, 8 GB RAM) or larger. On this image, the login screen plus one idle GNOME VNC session uses about 1.45 GiB of memory. That fits in the 4 GB of Standard_B2s for light use, but a browser and a few applications quickly need the extra room. There is no GPU requirement, because the desktop renders in software.

1

Deploy the virtual machine

Option A: Azure portal

  • Open the Azure Marketplace and search for "CentOS Stream 9 with GNOME Desktop SecureAnyCloud".
  • Select the image and choose Create.
  • On the Basics tab, select your Subscription, and create or select a Resource group.
  • Enter a Virtual machine name, and select your preferred Region.
  • For Size, select Standard_B2ms or larger. Choose a size that supports Generation 1.
  • Under Administrator account, select SSH public key and enter your key.
  • Under Inbound port rules, allow SSH (port 22) only. Do not open any VNC port, because the desktop is reached through an SSH tunnel.
  • Choose 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:centos-stream-9-gui:default:latest
az vm create \
  --resource-group myResourceGroup \
  --name my-centos-desktop \
  --image sac1647283583153:centos-stream-9-gui:default:latest \
  --size Standard_B2ms \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard
2

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-centos-desktop --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.

3

Confirm the release and the desktop

Check that the machine runs CentOS Stream 9 and boots to the graphical target. Also check that the GNOME login screen (GDM) is running with Wayland disabled, and see which desktop and VNC packages are installed:

cat /etc/centos-release uname -srm systemctl get-default systemctl is-active gdm.service grep '^WaylandEnable' /etc/gdm/custom.conf rpm -q --qf '%{NAME} %{VERSION}\n' gdm gnome-shell mutter xorg-x11-server-Xorg tigervnc-server

Expected output:

CentOS Stream release 9 Linux 5.14.0-745.el9.x86_64 x86_64 graphical.target active WaylandEnable=False gdm 40.1 gnome-shell 40.10 mutter 40.9 xorg-x11-server-Xorg 1.20.11 tigervnc-server 1.16.2

CentOS Stream is continuously delivered, so it has no minor version number. /etc/centos-release always reads CentOS Stream release 9, and the kernel and package versions move forward as you update.

The desktop and TigerVNC come from the distribution's own repositories, not from a third-party repository:

dnf group list --installed 2>/dev/null | grep -i 'Server with GUI' || true
dnf repolist echo "packages installed: $(rpm -qa | wc -l)" df -h /

dnf repolist shows exactly appstream, baseos and extras-common. No EPEL repository is configured.

The machine boots through the legacy BIOS path. The operating system disk keeps its first megabyte free for Azure, with the boot loader in a dedicated BIOS boot partition. The Azure Linux Agent names the operating system disk /dev/disk/azure/root, which is safer than a /dev/sdX letter. On a Generation 1 machine, the operating system disk and the temporary resource disk can swap letters between boots.

test -d /sys/firmware/efi && echo "firmware: UEFI (Gen2)" || echo "firmware: legacy BIOS (Generation 1)"
sudo parted -s /dev/disk/azure/root print | grep -E '^Partition Table|bios_grub'
firmware: legacy BIOS (Generation 1) Partition Table: gpt 1 1049kB 2097kB 1049kB BIOS boot partition bios_grub
4

Check that VNC is off

A new virtual machine has VNC switched off. The helper shows the full state in one command:

sudo sac-vnc status

Expected output on a new VM:

VNC policy: localhost only, security types tlsvnc,vncauth (/etc/tigervnc/vncserver-config-mandatory) xvnc.socket (unauthenticated mode): disabled / inactive VNC desktops configured: none listening on VNC ports 5900-5999: none users with a VNC password set: none (each user runs: vncpasswd)

The helper lives at /usr/local/sbin/sac-vnc. On CentOS Stream, sudo replaces your PATH with its own secure_path, which does not include /usr/local/sbin. The image therefore also ships /usr/sbin/sac-vnc as a symlink, so sudo sac-vnc works as written. Its subcommands are status, enable [<user>], disable [<user>] and details. The <user> argument defaults to your administrator account.

Confirm the policy and the network side as well:

grep -vE '^#|^$' /etc/tigervnc/vncserver-config-mandatory
sudo ss -tln | awk '$1=="LISTEN"{print $4}' | sort
localhost securitytypes=tlsvnc,vncauth 0.0.0.0:22 [::]:22

SSH on port 22 is the only service listening.

5

Set your two passwords

First, set your account password. Run the following command yourself on the VM, and enter the new password twice when prompted:

sudo passwd azureuser

Then set your VNC password. Run vncpasswd as yourself, without sudo. Enter the password twice, and answer n to the view-only question:

vncpasswd
Password: Verify: Would you like to enter a view-only password (y/n)? n A view-only password is not used

Only the first 8 characters of a VNC password are used, and vncpasswd stores it in ~/.config/tigervnc/passwd with mode 0600. Your SSH access is unaffected, because SSH remains key-only.

6

Start your VNC desktop

sudo sac-vnc enable

Expected output:

VNC desktop for azureuser enabled on display :1: listening on localhost port 5901 only from your own machine: ssh -N -L 5901:localhost:5901 azureuser@<vm-ip> then point a VNC viewer at localhost:5901 and enter azureuser's VNC password

The helper adds :1=azureuser to /etc/tigervnc/vncserver.users and runs systemctl enable --now vncserver@:1.service. It then waits until port 5901 is listening, and it refuses and stops the desktop again if the port is bound anywhere other than localhost. The desktop starts again after a reboot.

If a password is missing, the helper refuses and tells you which one:

refusing to start a VNC desktop for azureuser: the account has no password yet. The GNOME lock screen and administrator prompts inside the desktop ask for it. Set it first:
sudo passwd azureuser
refusing to start a VNC desktop for azureuser: no VNC password is set. As azureuser (without sudo) run: vncpasswd
7

Connect through an SSH tunnel

On your own workstation, open the tunnel and leave it running:

ssh -N -L 5901:localhost:5901 azureuser@<vm-ip>

Azure drops a TCP connection that has carried no traffic for about four minutes, and an idle SSH tunnel looks exactly like that. The ssh process keeps running, but the forward silently stops working. On this image, a tunnel opened without keepalives stopped forwarding after 270 seconds idle. The same tunnel with -o ServerAliveInterval=60 still authenticated after 280 seconds idle. If you leave the tunnel open between sessions, add the keepalive:

ssh -N -o ServerAliveInterval=60 -L 5901:localhost:5901 azureuser@<vm-ip>

Then point your VNC viewer at localhost:5901. TigerVNC and RealVNC accept localhost:5901, and some viewers want the display form localhost:1. On macOS, open Screen Sharing and connect to vnc://localhost:5901. Enter your VNC password, and your GNOME desktop opens.

TigerVNC Viewer marks the password dialog "This connection is not secure". It does so because the server has no certificate for the viewer to verify, since TigerVNC's TLSVnc security type uses anonymous TLS. Through the SSH tunnel, the connection is encrypted and SSH authenticates the server. That is why the image allows VNC only over the tunnel.

8

Use the desktop

GNOME opens in the Activities overview. Press Escape to reach the desktop, or press the Super key to return to the overview. The top-right system menu offers Restart, Power Off and Log Out. Suspend is absent by design, because a suspended Azure virtual machine stops answering while Azure still reports it as running:

The application grid holds the applications that come with the Server with GUI group:

A terminal inside the session behaves exactly as your SSH session does, and your administrator account keeps its sudo rights. The session type is X11, and the VNC server listens on the loopback addresses only:

To add software, use dnf as on any CentOS Stream machine, for example sudo dnf install -y libreoffice. Then open the application from the grid.

Closing your VNC viewer leaves the session running on the VM. Connect again to return to it.

9

Add desktops for more users

Each user gets their own display and port. Create the user with a password, have them run vncpasswd, and then enable their desktop. The helper assigns the next free display (:2 is port 5902):

sudo useradd -m alice
sudo passwd alice
sudo -u alice -H vncpasswd
sudo sac-vnc enable alice

After her SSH key is in place, Alice tunnels her own port, for example with ssh -N -L 5902:localhost:5902 alice@<vm-ip>.

10

Turn VNC off again

sudo sac-vnc disable
VNC desktop for azureuser disabled: display :1 removed, nothing listening on port 5901

This command stops the session, disables vncserver@:1.service and removes the mapping, so nothing listens after a reboot. sudo sac-vnc status shows the state at any time.

11

Verify the security posture

Confirm that SELinux is enforcing, that SSH is key-only, that no account has a password until you set one, and that guest sleep is disabled:

getenforce
sudo sshd -T | grep -E '^(passwordauthentication|kbdinteractiveauthentication) '
sudo passwd -S root | awk '{print $1, $2}'
sudo awk -F: '$2 !~ /^[!*]/ && $2 != "" {n++} END {print "accounts with a password: " n+0}' /etc/shadow busctl call org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager CanSuspend

This is the expected output on a new VM. After Step 5, the password count reads 1, which is your own account:

Enforcing passwordauthentication no kbdinteractiveauthentication no root LK accounts with a password: 0 s "na"

LK means that the root account is locked, and na means that logind will not suspend the machine. Drop-in files pin both the sleep policy and the SSH policy, so a later package update to the main configuration cannot quietly loosen them:

grep -vE '^#|^$' /etc/systemd/sleep.conf.d/20-sac-no-guest-sleep.conf
grep -vE '^#' /etc/ssh/sshd_config.d/60-sac-hardening.conf
[Sleep] AllowSuspend=no AllowHibernation=no AllowSuspendThenHibernate=no AllowHybridSleep=no PermitRootLogin prohibit-password PasswordAuthentication no KbdInteractiveAuthentication no ChallengeResponseAuthentication no
12

Review patching and updates

Every available update was applied when this image was built. dnf-automatic is armed, so the machine downloads and applies updates on its own schedule:

systemctl is-enabled dnf-automatic.timer grep -E '^(upgrade_type|download_updates|apply_updates) ' /etc/dnf/automatic.conf

Expected output:

enabled upgrade_type = default download_updates = yes apply_updates = yes

Why the image applies all updates and not only security updates. CentOS Stream publishes no security advisory metadata. Its repositories carry no updateinfo data, so a security-only selection has nothing to select.

SecureAnyCloud verified this during the image build. With one package update pending, dnf upgrade --security and dnf-automatic set to upgrade_type = security both reported "No security updates needed, but 1 update available" and installed nothing. With upgrade_type = default, the update was installed. On CentOS Stream, the only way to keep a machine patched unattended is to apply every update, and this image does so.

If you prefer to review updates yourself, set apply_updates = no in /etc/dnf/automatic.conf. To opt out entirely, run sudo systemctl disable --now dnf-automatic.timer.

Check whether anything is pending at any time. The advisory count is always zero on CentOS Stream, so the check-update exit code is the result that matters:

dnf -q check-update >/dev/null 2>&1; echo "check-update exit=$? (0 = nothing pending, 100 = updates available)" echo "advisories published for this release: $(dnf -q updateinfo list --all 2>/dev/null | wc -l)"
check-update exit=0 (0 = nothing pending, 100 = updates available) advisories published for this release: 0

Automatic updates never restart the machine for you. After a kernel update, check whether a restart is owed, and pick your own maintenance window:

dnf needs-restarting -r || true

You can always update on your own schedule with sudo dnf -y upgrade, and reboot if a new kernel was installed.

GNOME Software may show "Software Updates Ready to Install" on your first login even when dnf reports nothing pending. That notification comes from the firmware updater (fwupd), not from a package. It can offer firmware variable updates published through the Linux Vendor Firmware Service. It is not an operating system package and is not part of this image, and you decide whether to apply a firmware update to your virtual machine. fwupdmgr get-updates shows exactly what it offers.

13

Review networking, the firewall and the services that ship switched off

The Azure Network Security Group is the enforced firewall for this image. You do not need to open any port for the desktop, because it travels inside SSH.

The Server with GUI group brings several daemons that a cloud server does not need, and the base image had rpcbind listening. These services are left installed but disabled, never masked, so the image exposes only port 22 and you can turn any of them back on with a single command:

for u in cockpit.socket avahi-daemon.service cups.service bluetooth.service firewalld.service rpcbind.socket xvnc.socket; do echo "$u: $(systemctl is-enabled "$u" 2>/dev/null || true)" done
cockpit.socket: disabled avahi-daemon.service: disabled cups.service: disabled bluetooth.service: disabled firewalld.service: disabled rpcbind.socket: disabled xvnc.socket: disabled

To enable any of them, for example the Cockpit web console, run sudo systemctl enable --now cockpit.socket and open the port in your Network Security Group. Do not enable xvnc.socket, because it serves a login screen over VNC on port 5900 with no VNC password (-SecurityTypes=None).

firewalld is installed but switched off, so your NSG rules take effect exactly as written. If your policy requires a host firewall, enable it yourself and allow SSH through it:

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

The VNC desktop needs no firewalld rule, because the tunnel arrives over SSH. The network stack is NetworkManager, configured by cloud-init exactly as on CentOS Stream 9 Server.

Verify what you are running

Three commands answer three questions: which release this is, whether it is a desktop image, and whether VNC is currently on.

cat /etc/centos-release systemctl get-default
sudo sac-vnc status

Common use cases

  • A cloud workstation for enterprise Linux development with a full GNOME desktop, reached through an SSH tunnel
  • Previewing and testing, with a desktop, what the next RHEL 9 minor release will bring before it reaches RHEL
  • Running graphical administration and data tools close to your Azure resources
  • Training labs and demonstrations that need a desktop rather than a shell, with one desktop per user
  • A secure jump desktop that exposes nothing but SSH

Troubleshooting

"Connection refused" on localhost:5901

VNC is off on a fresh VM by design. Run sudo sac-vnc enable first. Check that the SSH tunnel is still running in its own terminal window, and that the port matches your display (:1 is 5901, :2 is 5902). sudo sac-vnc status shows what is listening.

The viewer hangs connecting to localhost:5901 after the tunnel sat idle

The VNC server is fine. Azure dropped the tunnel's TCP connection after about four idle minutes, while the ssh -N process on your workstation kept running. Stop that ssh process, open the tunnel again, and use -o ServerAliveInterval=60 so that it stays alive while idle (Step 7). Your desktop session on the VM is unaffected and is still there when you reconnect.

The viewer says "Authentication failure"

The viewer wants your VNC password, the one you set with vncpasswd, not your account password. Only its first 8 characters count. Set it again with vncpasswd and reconnect. The running desktop does not need restarting.

Connecting directly to the VM's public IP on port 5901 does not work

This is the intended security design, because the VNC server listens on localhost only. Use the SSH tunnel from Step 7. The localhost setting in /etc/tigervnc/vncserver-config-mandatory also overrides any interface or localhost setting in a user's own ~/.config/tigervnc/config.

The screen is locked and asks for a password

The lock screen wants your account password from sudo passwd <your-user>. If you never set one, the helper would not have started the desktop. If you removed it afterwards, set it again over SSH.

A desktop that you start again can also open straight at the lock screen. GNOME remembers, per display, that the previous desktop on that display was locked when it stopped (for example, after it locked while idle). It keeps that state for the next desktop on the same display while you are still logged in over SSH. Click or press a key, and enter your account password.

The desktop does not start for a user

journalctl -u vncserver@:1 shows the service, and the session log is in the user's ~/.local/state/tigervnc/. TigerVNC cannot start a VNC desktop for a user who is already logged into another graphical session on the same machine, so log out of that session first.

"This connection is not secure" in TigerVNC Viewer

This message is expected, as Step 7 explains. The server has no certificate, and the SSH tunnel provides the encryption and server authentication.

The VM size I picked will not deploy

This is a Generation 1 image. If Azure reports that the size does not support the image's generation, pick a size from a family that supports Generation 1, such as the B series (Standard_B2ms) or the D and E v5 series.

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.
  • Confirm that you are using the administrator username that you named at create time.
  • Verify that your SSH key matches the one you supplied at create time. Password login over SSH is disabled by design.

A service is blocked and the logs mention SELinux

SELinux is enforcing, which is the secure default and should stay that way. SELinux records denials in the audit log, so look there instead of in the journal:

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 considering any policy change. vncpasswd already creates ~/.config/tigervnc with the correct vnc_home_t label.

Important notes

CentOS Stream is free and open source, but it is not covered by a single license. The distribution is a collection of thousands of independently packaged components, each carrying its own terms, predominantly GPL and LGPL, with MIT, BSD, Apache 2.0, MPL and others. The GNOME desktop, GDM and TigerVNC are free software packaged in the CentOS Stream AppStream repository. You can read every package's terms on the machine with rpm -qi <package> and under /usr/share/licenses/. No subscription, entitlement or license key is required to run this image, and no Red Hat subscription is involved.

CentOS Stream 9 reaches end of life on 31 May 2027 (see the End of life section above). The upgrade path is CentOS Stream 10 on a new virtual machine.

CentOS is a trademark of Red Hat, Inc. and GNOME is a trademark of the GNOME Foundation. Both names are used here nominatively, only to identify the distribution and the desktop environment this image contains. SecureAnyCloud is not affiliated with, endorsed by or sponsored by Red Hat, the CentOS Project or the GNOME Foundation.

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 CentOS Stream 9 with GNOME Desktop 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