AlmaLinux 10 Gui
Overview
AlmaLinux is a community-owned enterprise Linux distribution, produced by the AlmaLinux OS Foundation to be binary compatible with Red Hat Enterprise Linux. This SecureAnyCloud image is genuine, stable AlmaLinux 10 with the distribution's own desktop added: the AppStream environment group @graphical-server-environment, which AlmaLinux calls Server with GUI. You reach it from any RDP client through GNOME Remote Desktop in system mode. You see the GNOME login screen and sign in to a full desktop session on the virtual machine.
A freshly deployed machine exposes nothing but SSH. Remote desktop ships switched off, no account has a password, and nothing listens on the RDP port until you turn it on. A desktop login always needs a password, so the image never ships one. You set your own over SSH, then enable remote desktop with a single command.
What you get:
- AlmaLinux 10 (10.2, "Lavender Lion") on the 6.12 kernel, binary compatible with RHEL 10, with every available update applied at build time
- The GNOME desktop from the AlmaLinux AppStream repository: GNOME Shell 49.4, the GDM 47 login screen, mutter 49.4 and gnome-settings-daemon 47.2
- Desktop applications from the same group: Files (Nautilus), the Ptyxis terminal, Firefox, Text Editor, Calculator and Software
- GNOME Remote Desktop 49.3 in system mode, which provides RDP remote login through the GNOME login screen
- A per-VM RDP credential and a per-VM self-signed TLS certificate, generated at first boot and readable by root only
sac-remote-desktop, a small helper that shows the remote desktop state, switches it on and off, and prints your VM's RDP credentialdnf-automaticarmed for security updates, so the machine keeps patching itself- SELinux in enforcing mode, BaseOS, AppStream, CRB and Extras enabled, and the Azure provisioning path unchanged (cloud-init, the Azure Linux Agent, NetworkManager)
- Gen2 Hyper-V virtual machine support on Microsoft Azure (x64), with default user
azureuser - About 1,189 packages, using about 4.6 GiB of the 30 GiB operating system disk and leaving the rest for your own software and data
- 24/7 SecureAnyCloud support
The desktop is a Wayland session. RHEL 10 removed the Xorg server, so AlmaLinux 10 has no Xorg server to install. Xwayland is present and runs X applications inside the Wayland session as normal.
The two secrets, and which one goes where
Read this section carefully. On a machine with remote desktop turned on, there are two separate secrets, and both are unique to your virtual machine:
- The per-VM RDP credential. The VM generates it at first boot into
/root/sac-remote-desktop-credentials.txt(mode0600, root only). The username is your VM's own administrator account (the--admin-usernameyou chose). The password is 24 random alphanumeric characters. Your RDP client asks for this credential before the login screen is drawn, because GNOME Remote Desktop uses Network Level Authentication. It is not an operating system account and it cannot be used for SSH. Read it withsudo /usr/local/sbin/sac-remote-desktop credentials. - Your account password. You set this yourself with
sudo passwd <your-admin-user>. The GNOME login screen asks for it once Network Level Authentication has passed. The image ships with no account password, so you must choose one.
The VM also generates a self-signed RSA-3072 TLS certificate for the RDP server at first boot, with the VM's hostname as its common name. Its SHA-256 fingerprint is written to the same credentials file, so you can compare it with the fingerprint your RDP client shows.
None of this is baked into the image, and no two machines you launch share any of it.
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). Setting an account password for the desktop does not enable password logins over SSH. - The remote desktop server is installed but disabled. A new virtual machine listens on SSH port 22 only, and 22 is the only port the listing advertises.
- At first boot, the machine generates its own RDP credential and its own TLS certificate. Nothing is shared between two machines.
- Remote desktop cannot be switched on until an administrator account has a password, so the login screen is never exposed with nothing behind it.
- SSH host keys are removed before capture and regenerated on each machine at first boot.
/etc/machine-idis also regenerated per machine, so no two machines share a host identity. - SELinux stays in enforcing mode, the AlmaLinux default, and GDM automatic login is not enabled.
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
- An RDP client: Windows App or Remote Desktop Connection on Windows, Windows App on macOS, or Remmina or FreeRDP on Linux
Recommended VM size: Standard_B2ms (2 vCPU, 8 GB RAM) or larger. GNOME's login screen plus a remote session does not fit in the 4 GB of Standard_B2s. For smooth everyday use, pick Standard_D4s_v5 or larger. There is no GPU requirement, because the desktop renders in software.
Deploy the virtual machine
Option A: Azure Portal
- Open the Azure Marketplace and search for "AlmaLinux 10 with GNOME Desktop SecureAnyCloud".
- Select the image and click Create.
- Configure the basics:
- Subscription: select your Azure subscription.
- Resource Group: create a new group or select an existing one.
- Virtual Machine Name: enter a name for your VM.
- Region: select your preferred Azure region.
- Size:
Standard_B2msor larger. - Under Administrator Account, select SSH public key and enter your key.
- Under Inbound Port Rules, allow SSH (port 22) only. You do not need to open port 3389, because the recommended way to reach the desktop is through an SSH tunnel (Step 6).
- Click Review + Create, then Create.
Option B: Azure CLI
Run these commands 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:almalinux-10-gui:default:latest
az vm create \
--resource-group myResourceGroup \
--name my-almalinux-desktop \
--image sac1647283583153:almalinux-10-gui:default:latest \
--size Standard_B2ms \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku StandardConnect 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-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 you supplied at create time.
Confirm the release and the desktop
Check that the machine is AlmaLinux 10, that it boots to the graphical target, that the GNOME login screen (GDM) is running, and which desktop packages are installed:
cat /etc/almalinux-release uname -srm systemctl get-default systemctl is-active gdm.service rpm -q --qf '%{NAME} %{VERSION}\n' gdm gnome-shell gnome-settings-daemon mutter gnome-remote-desktopExpected output:
AlmaLinux release 10.2 (Lavender Lion) Linux 6.12.0-211.53.1.el10_2.x86_64 x86_64 graphical.target active gdm 47.0 gnome-shell 49.4 gnome-settings-daemon 47.2 mutter 49.4 gnome-remote-desktop 49.3The desktop comes from the distribution's own environment group, not from a third-party repository:
dnf group list --installed | grep -i 'Server with GUI' || true echo "packages installed: $(rpm -qa | wc -l)" df -h /There is no Xorg server on AlmaLinux 10, because RHEL 10 removed it. The session is Wayland, and Xwayland runs X applications inside it:
rpm -q xorg-x11-server-Xorg || echo "(no Xorg server: AlmaLinux 10 GNOME is Wayland only)" rpm -q --qf '%{NAME} %{VERSION}\n' xorg-x11-server-XwaylandCheck that remote desktop is off
A new virtual machine has remote desktop switched off. The helper shows the full status in one command:
sudo /usr/local/sbin/sac-remote-desktop statusThe helper lives at /usr/local/sbin/sac-remote-desktop and its subcommands are status, enable, disable and credentials. On AlmaLinux, sudo replaces your PATH with its own secure_path (/sbin:/bin:/usr/sbin:/usr/bin), which does not include /usr/local/sbin. For that reason, the image also ships /usr/sbin/sac-remote-desktop as a symlink to it. Both the short form sudo sac-remote-desktop status and the full path above work.
Expected output on a new VM (the fingerprint is unique to your machine):
remote desktop service: disabled / inactive RDP backend: disabled listening on 3389: no per-VM RDP credential: generated (/root/sac-remote-desktop-credentials.txt) TLS certificate SHA-256: <the SHA-256 fingerprint of this VM's own certificate> accounts able to log in at the GNOME login screen: none (set one with: sudo passwd <user>)Confirm the state from the network side as well:
sudo ss -tln | awk '$1=="LISTEN"{print $4}' | sort0.0.0.0:22 [::]:22SSH on port 22 is the only service reachable from outside the machine. Any other entry you see is bound to a loopback address (127.0.0.1 or ::1) and is not reachable from the network.
Set your account password and turn remote desktop on
The GNOME login screen asks for your account password, and a new VM has none. Choose your own. Run this command on the VM and enter the new password twice when prompted:
sudo passwd azureuserYour SSH access is unaffected. SSH remains key-only, and this does not enable SSH password logins. Now switch remote desktop on:
sudo /usr/local/sbin/sac-remote-desktop enableExpected output:
remote desktop enabled: listening on port 3389 TLS certificate SHA-256: <the SHA-256 fingerprint of this VM's own certificate> RDP credential: sudo sac-remote-desktop credentials safest route: ssh -L 3389:localhost:3389 <user>@<vm-ip>, then point your RDP client at localhost:3389If no administrator account has a password yet, the helper refuses rather than opening a login screen with nothing behind it, and tells you exactly which command to run first:
refusing to enable remote desktop: no administrator account has a password yet, so the GNOME login screen would have nothing to accept. Set your own first:
sudo passwd azureuserThe setting survives reboots. The helper runs grdctl --system rdp enable, then systemctl enable --now gnome-remote-desktop.service. It waits until port 3389 is listening before it reports success.
Now print this VM's RDP credential. You need it in the next step:
sudo /usr/local/sbin/sac-remote-desktop credentialsRDP_USERNAME=azureuser RDP_PASSWORD=<24 random characters, generated at this VM's first boot> RDP_PORT=3389 RDP_TLS_SHA256=<SHA-256 fingerprint of this VM's certificate> RDP_TLS_SHA1=<SHA-1 fingerprint of the same certificate, shown as the thumbprint by Windows>RDP_USERNAME is your own administrator account name. RDP_PASSWORD is for your RDP client only. It is not an operating system password and it does not work for SSH.
Connect with your RDP client
Port 3389 is not open by default, and the SSH tunnel is the recommended route. The tunnel keeps RDP inside your existing SSH connection, so nothing new is exposed to the internet. On your own workstation, open the tunnel and leave it running:
ssh -N -L 3389:localhost:3389 azureuser@<vm-ip>Then point your RDP client at localhost:3389:
- Windows: Remote Desktop Connection (
mstsc) or Windows App, computerlocalhost:3389 - macOS: Windows App, add a PC with the name
localhost:3389 - Linux: Remmina (RDP), server
localhost:3389, or FreeRDP 3 (xfreerdp3on Debian and Ubuntu,xfreerdpon AlmaLinux and Fedora):xfreerdp3 /v:localhost:3389 /u:azureuser /gfx /bpp:32
When the client asks for credentials, enter RDP_USERNAME and RDP_PASSWORD from Step 5. The client asks before any screen is drawn.
On the first connection, the client shows the server's certificate. It is self-signed and unique to your VM. Compare its fingerprint with RDP_TLS_SHA256 (or RDP_TLS_SHA1, which Windows displays as the thumbprint) before you accept it.
The GNOME login screen then appears. Select your account and enter the password you set in Step 5. The full desktop session opens.
If you prefer a direct connection instead of the tunnel, allow port 3389 in the VM's network security group from your own public address only, never from the whole internet. For example, run this from your workstation, replacing the values in angle brackets:
az network nsg rule create --resource-group myResourceGroup --nsg-name my-almalinux-desktopNSG \
--name allow-rdp-from-me --priority 1010 --access Allow --protocol Tcp \
--direction Inbound --destination-port-ranges 3389 --source-address-prefixes <your-public-ip>/32Use the desktop
Open Activities, or press the Super key, to reach the application grid. The image includes the applications that come with the Server with GUI group: Files (Nautilus), the Ptyxis terminal, Firefox, Text Editor, Calculator and Software.
A terminal inside the session behaves exactly like your SSH session, and your administrator account keeps its sudo rights. To confirm that you are on a Wayland session, run this in Ptyxis inside the desktop:
echo "$XDG_SESSION_TYPE"To add software, use dnf as on any AlmaLinux machine, for example sudo dnf install -y libreoffice. Then open the application from the grid.
Disconnecting your RDP client leaves the session running on the VM. Connect again to return to it.
Turn remote desktop off again
When you have finished, switch remote desktop back off. This closes port 3389 and keeps it closed across reboots:
sudo /usr/local/sbin/sac-remote-desktop disableremote desktop disabled: nothing listening on port 3389sudo /usr/local/sbin/sac-remote-desktop status shows the state at any time, whether the service is on or off.
Verify the security posture
Confirm that SELinux is enforcing, that SSH is key-only, and that no account has a password until you set one:
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/shadowExpected output on a new VM (after Step 5 the last line reads 1, your own account):
Enforcing passwordauthentication no kbdinteractiveauthentication no root L accounts with a password: 0L in the second field means that the root account is locked. A drop-in file pins the SSH policy, so a later package update to the main configuration cannot quietly loosen it:
grep -vE '^#' /etc/ssh/sshd_config.d/60-sac-hardening.confPermitRootLogin prohibit-password PasswordAuthentication no KbdInteractiveAuthentication no ChallengeResponseAuthentication noPatching and updates
Every available update was applied when this image was built. dnf-automatic is armed, so the machine applies security updates on its own schedule:
systemctl is-enabled dnf-automatic.timer 2>/dev/null || systemctl is-enabled dnf-automatic-install.timer grep -E '^(upgrade_type|download_updates|apply_updates) ' /etc/dnf/automatic.confExpected output:
enabled upgrade_type = security download_updates = yes apply_updates = yesUpdates are applied, not merely downloaded. Check at any time whether anything is pending:
dnf -q check-update >/dev/null 2>&1; echo "exit=$? (0 = nothing pending, 100 = updates available)"Automatic updates never restart the machine. After a kernel update, check whether a restart is due and pick your own window:
dnf needs-restarting -r || trueYou can always update on your own schedule with sudo dnf -y upgrade. Reboot if a new kernel was installed. To opt out of automatic updates entirely, run sudo systemctl disable --now dnf-automatic.timer.
Review networking, the firewall and services that ship switched off
The Azure Network Security Group (NSG) is the enforced firewall for this image. It is the first, and usually the only, place where you need to open a port.
The Server with GUI group brings several daemons that a cloud server does not need. The image leaves them installed but disabled, never masked, so it 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; do echo "$u: $(systemctl is-enabled "$u" 2>/dev/null || echo not-installed)" donecockpit.socket: disabled avahi-daemon.service: disabled cups.service: disabled bluetooth.service: disabled firewalld.service: disabledTo enable one of them, for example the Cockpit web console, run sudo systemctl enable --now cockpit.socket and open the port in your NSG.
firewalld is installed but switched off, consistent with the rest of the SecureAnyCloud AlmaLinux family. With no host firewall in the way, your NSG rules take effect exactly as written and there is no second layer to keep in sync. If your policy requires a host firewall, enable it yourself and allow your own traffic through it:
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=ssh sudo firewall-cmd --reloadOnce firewalld is running, a port must be open in both the Azure NSG and firewalld before traffic reaches your service. This includes port 3389 if you connect to the desktop directly rather than through the SSH tunnel.
The network stack is NetworkManager, the native enterprise Linux stack, configured by cloud-init exactly as on AlmaLinux Server. The desktop adds no second network stack.
Verify what you are running
Three commands answer the three questions that matter: which release this is, that it is a desktop image, and whether remote desktop is currently on.
cat /etc/almalinux-release systemctl get-default
sudo /usr/local/sbin/sac-remote-desktop statusCommon use cases
- A cloud workstation for enterprise Linux development with a full GNOME desktop, reachable from any RDP client
- Graphical administration and data tools close to your Azure resources
- A RHEL 10 compatible desktop for testing applications certified against RHEL, without a subscription
- Training labs and demonstrations that need a desktop rather than a shell
- A secure jump desktop, reachable only through an SSH tunnel
Troubleshooting
The RDP client connects, then the screen stays black or it disconnects
GNOME Remote Desktop requires the RDP graphics pipeline. Current clients support it, including Windows App, Remote Desktop Connection (mstsc), Windows App on macOS and Remmina. With FreeRDP, you must pass /gfx /bpp:32. Without those flags, the server closes the connection after authentication. Read the server-side log with:
sudo journalctl -u gnome-remote-desktop --no-pager -n 20"Connection refused" on localhost:3389
Remote desktop is disabled on a fresh VM by design. Run sudo /usr/local/sbin/sac-remote-desktop enable first, and check that the SSH tunnel is still up in its own terminal window. sudo /usr/local/sbin/sac-remote-desktop status shows whether anything is listening on 3389.
The login screen appears but rejects my password
That screen expects your account password, the one you set with sudo passwd <your-user>, not the RDP credential. Your client already used the RDP credential before the screen was drawn. If you have not set an account password yet, set it over SSH and try again.
My RDP client says the credentials are wrong before any screen appears
This is the opposite case. The client expects the RDP credential from sudo /usr/local/sbin/sac-remote-desktop credentials, not your account password.
A certificate warning on the first connection
This warning is expected. The TLS certificate is self-signed and unique to your virtual machine. The VM generated it at first boot with its hostname as the common name. Compare the SHA-256 fingerprint your client shows with RDP_TLS_SHA256 from sudo /usr/local/sbin/sac-remote-desktop credentials (Windows shows the SHA-1 value as the thumbprint), then accept the certificate.
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 NSG.
- Use the administrator username 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, so a password prompt means key negotiation already failed.
A service is blocked and the logs mention SELinux
SELinux is enforcing, which is the secure default and should stay that way. Inspect 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, but it is not covered by a single licence. The distribution is a collection of thousands of independently packaged components, each with its own terms, predominantly GPL and LGPL, with MIT, BSD, Apache 2.0, MPL and others. The GNOME desktop, GDM and GNOME Remote Desktop are free software packaged in the AlmaLinux 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 licence key is required to run this image, and no Red Hat subscription is involved.
AlmaLinux 10 is not an end-of-life product. It reached general availability on 27 May 2025. 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.
AlmaLinux is a mark of the AlmaLinux OS Foundation 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 the AlmaLinux OS Foundation or the GNOME Foundation.
Support
For help 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 AlmaLinux 10 with GNOME Desktop on Azure with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com