Operating Systems Azure

Ubuntu 26.04 LTS with XFCE Desktop on Azure User Guide

| Product: Ubuntu 26.04 LTS with XFCE Desktop on Azure

Overview

This guide covers the deployment and configuration of Ubuntu 26.04 LTS with the XFCE desktop on Microsoft Azure using cloudimg's pre configured virtual machine image from the Azure Marketplace.

Ubuntu is a widely used Linux distribution produced by Canonical. Version 26.04 is a long term support (LTS) release, published on 23 April 2026, with standard security maintenance to 29 May 2031. This image is Ubuntu Server 26.04 LTS with the XFCE 4.20 desktop added and xrdp 0.10 set up as the remote desktop server: you connect with any RDP client, sign in with your own account name and password, and get a full XFCE session running on the virtual machine.

XFCE is deliberately light. The whole desktop idles in roughly 600 MB of memory on this build, which is why the image is happy on a 2 vCPU, 4 GB Standard_B2s where a GNOME desktop would not be.

The image is built so that 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 decide to turn it on.

What's included:

  • Ubuntu 26.04 LTS on the Azure kernel, with the XFCE 4.20 desktop (Thunar file manager, XFCE Terminal, Mousepad text editor, Task Manager, Application Finder, Settings Manager) and the LightDM display manager
  • xrdp 0.10 with xorgxrdp, configured for remote desktop sessions over TLS. The session manager talks to the server over a local UNIX socket, so it adds no network port of its own
  • A per-VM TLS certificate and a per-VM xrdp RSA key, generated at first boot and readable by root only
  • cloudimg-remote-desktop, a small helper to show the remote desktop state, switch it on and off, and print your VM's connection details
  • Every available security update applied at build time, with unattended-upgrades armed so the machine keeps patching itself
  • The Azure provisioning path unchanged: cloud-init, the Azure Linux Agent and systemd-networkd, exactly as on Ubuntu Server
  • Gen2 Hyper V virtual machine support
  • 24/7 cloudimg support

What's deliberately NOT included: a web browser (install one with sudo apt install firefox-esr or sudo snap install firefox), an office suite (sudo apt install libreoffice), NetworkManager (networking is managed by systemd-networkd, the Azure default), printing, Bluetooth, the Avahi service discovery daemon, and any screen locker. None of these add anything on a cloud server by default, and several would open network listeners. The Applications menu's "Web Browser" and "Mail Reader" entries are XFCE's generic handlers: they will not do anything until you install a browser or a mail client. The desktop background is plain by design - no wallpaper package is installed.

Platform: Microsoft Azure (Gen2 Hyper V, x64) Default user: azureuser

A note on package support

The XFCE desktop, xrdp, xorgxrdp and LightDM all come from the Ubuntu universe archive. Universe is maintained by the Ubuntu community rather than by Canonical, and Canonical's guaranteed security-update commitment for universe packages is only available under an Ubuntu Pro subscription, which is not included with this image and which cloudimg does not hold on your behalf.

In practice that means: this image is fully patched from the public Ubuntu archive at the moment it is built, and unattended-upgrades keeps installing whatever the archive publishes. But the desktop stack does not carry the same support commitment as the packages in Ubuntu's main archive. If your security policy requires a guaranteed fix timeline for every installed package, either attach your own Ubuntu Pro subscription to the VM (sudo pro attach <token>) or choose a desktop image built entirely from main. This is stated plainly here because it is a real difference, not a footnote.

Security posture

This image ships with no known credential:

  • No account has a password. The root account is locked, and azureuser 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.
  • At first boot the machine generates its own TLS certificate and key for xrdp, and its own xrdp RSA key. Nothing is shared between two machines, and nothing is baked into the image.
  • Remote desktop cannot be switched on until an administrator account has a password, so an RDP login box is never exposed with nothing to protect it.
  • xrdp-sesman is configured to refuse root logins, and every session module except the local Xorg one has been removed from xrdp.ini, so the RDP login box cannot be used to make your VM open outbound connections elsewhere.
  • The machine identity and the SSH host keys are regenerated uniquely on every instance, and AppArmor is enforcing.

There is only one password, and it is yours. Unlike RDP servers that carry a credential of their own, xrdp authenticates you through PAM against your ordinary Linux account. The password the RDP login box asks for is the one you set with sudo passwd, and until you set it nobody can sign in at all.

Prerequisites

Before deploying this image, ensure you have:

  1. An active Microsoft Azure subscription
  2. Access to the Azure Portal or Azure CLI
  3. An SSH key pair for Linux VM access
  4. 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_B2s (2 vCPU, 4 GB RAM) or larger. XFCE idles at roughly 600 MB, so 4 GB is genuinely comfortable; for heavier desktop work pick Standard_D2s_v5 or larger. There is no GPU requirement: the desktop renders in software.

Step 1: Deploy the Virtual Machine

Option A: Azure Portal

  1. Navigate to the Azure Marketplace and search for "Ubuntu 26.04 LTS with XFCE Desktop cloudimg"
  2. Select the image and click Create
  3. Configure the basics:
  4. Subscription: Select your Azure subscription
  5. Resource Group: Create new or select existing
  6. Virtual Machine Name: Enter a name for your VM
  7. Region: Select your preferred Azure region
  8. Size: Standard_B2s or larger
  9. Under Administrator Account, select SSH public key and enter your key
  10. Under Inbound Port Rules, allow SSH (port 22) only. You do not need to open port 3389: the recommended way to reach the desktop is through an SSH tunnel (Step 6)
  11. Click Review + Create, then Create

Option B: Azure CLI

cloudimg images carry a Marketplace purchase plan, so accept its terms once per subscription, then create the VM:

az vm image terms accept --urn cloudimg1647283583153:ubuntu-26-04-xfce:default:latest

az vm create \
  --resource-group myResourceGroup \
  --name my-ubuntu-xfce \
  --image cloudimg1647283583153:ubuntu-26-04-xfce:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Step 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-ubuntu-xfce --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.

Step 3: Confirm the release and the desktop

Check the release, that the machine booted to the graphical target, that the LightDM display manager is running, and which desktop packages are installed:

grep -E '^(PRETTY_NAME|VERSION_ID)=' /etc/os-release
systemctl get-default
systemctl is-active lightdm
dpkg-query -W -f='${Package} ${Version}\n' xfce4 xfce4-session lightdm xrdp xorgxrdp

Expected output:

PRETTY_NAME="Ubuntu 26.04.1 LTS"
VERSION_ID="26.04"
graphical.target
active
lightdm 1.32.0-6ubuntu4
xfce4 4.20.1
xfce4-session 4.20.4-1
xorgxrdp 1:0.10.2-1build1
xrdp 0.10.1-4.1

The terminal shows os-release reporting Ubuntu 26.04.1 LTS, the default target graphical.target, LightDM active, the installed versions of xfce4, xfce4-session, lightdm, xrdp and xorgxrdp, and zero pending upgrades

Step 4: Check that remote desktop is off

A new virtual machine has remote desktop switched off. The helper shows the whole picture:

sudo cloudimg-remote-desktop status
sudo ss -tln | awk '$1=="LISTEN"{print $4}' | sort

Expected output (the certificate fingerprint is unique to your VM):

remote desktop service: disabled / inactive
session manager: disabled / inactive
listening on 3389: no
per-VM TLS certificate: generated (/etc/xrdp/cert.pem)
TLS certificate SHA-256: 7C:F6:51:CB:E9:24:50:6F:D5:CB:D5:B6:5D:B9:89:FB:77:E4:F4:8E:9F:B5:A8:83:C9:99:3D:20:FB:6A:47:96
accounts able to log in at the XFCE remote desktop: none (set one with: sudo passwd <user>)
0.0.0.0:22
127.0.0.53%lo:53
127.0.0.54:53
[::]:22

The terminal shows cloudimg-remote-desktop status reporting the xrdp service and session manager disabled and inactive, nothing listening on 3389, a per-VM TLS certificate generated, and the TCP listeners limited to SSH on port 22 and the loopback resolver

The only listener reachable from outside the machine is SSH on port 22. The two port 53 entries are the local DNS resolver, bound to loopback addresses only.

Step 5: Set your password and turn remote desktop on

The XFCE login box asks for your account password, and a new VM has none. Choose your own. Run this yourself on the VM, and enter the new password twice when prompted:

sudo passwd azureuser

Your SSH access is unaffected: SSH remains key only. Now switch remote desktop on:

sudo cloudimg-remote-desktop enable

Expected output:

remote desktop enabled: listening on port 3389
TLS certificate SHA-256: 7C:F6:51:CB:E9:24:50:6F:D5:CB:D5:B6:5D:B9:89:FB:77:E4:F4:8E:9F:B5:A8:83:C9:99:3D:20:FB:6A:47:96
sign in with your own account name and the password you set with sudo passwd
safest route: ssh -L 3389:localhost:3389 <user>@<vm-ip>, then point your RDP client at localhost:3389

If no administrator account has a password yet, the helper refuses and tells you which command to run first. The setting survives reboots. Under the hood it runs systemctl enable --now xrdp.service, which starts the session manager with it.

Print this VM's connection details:

sudo cloudimg-remote-desktop credentials

The output lists RDP_USERNAME (your admin account name), RDP_PORT and the TLS certificate fingerprints. Note what it says about the password: there isn't a separate one. RDP_PASSWORD_SOURCE records that the password is your own account password.

Step 6: Connect with your RDP client

The recommended route keeps port 3389 closed to the internet and carries RDP inside your SSH connection. On your workstation, open a 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, computer localhost:3389
  • macOS: Windows App, add a PC with the name localhost:3389
  • Linux: Remmina (RDP), server localhost:3389, or FreeRDP 3: xfreerdp3 /v:localhost:3389 /u:azureuser /gfx /bpp:32

On first connection the client shows the server's certificate: it is self signed and unique to your VM, so compare its fingerprint with RDP_TLS_SHA256 (or RDP_TLS_SHA1, which is what Windows displays as the thumbprint) before you accept it.

The xrdp login box appears. The Session list has one entry, Xorg, which is the one you want:

The xrdp login box shown in an RDP session, with the session type set to Xorg and fields for username and password

Enter your account name and the password you set in Step 5. The XFCE desktop appears:

The XFCE desktop in a remote session, with the Applications menu and clock in the top panel, the File System and Home icons on the desktop, and the application dock along the bottom

Disconnecting your RDP client leaves the session running on the VM; connect again with the same account and you return to it. xrdp asks for your password again every time you connect, so a disconnected session is not left unprotected.

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, from your workstation (replace the placeholders):

az network nsg rule create --resource-group myResourceGroup --nsg-name my-ubuntu-xfceNSG \
  --name allow-rdp-from-me --priority 1010 --access Allow --protocol Tcp \
  --direction Inbound --destination-port-ranges 3389 --source-address-prefixes <your-public-ip>/32

Step 7: Use the desktop

Open the Applications menu at the top left to see what is installed:

The XFCE Applications menu open in the remote session, listing the installed accessories, system tools and settings

A terminal is in the dock at the bottom, and in Applications under Terminal Emulator. azureuser keeps its Azure administrator rights, so sudo works in the desktop exactly as it does over SSH:

XFCE Terminal inside the remote desktop session showing Ubuntu 26.04.1 LTS, the graphical target, and cloudimg-remote-desktop status reporting the service enabled and listening on port 3389

To add software, use apt in the terminal as on any Ubuntu machine, for example sudo apt install libreoffice. For a web browser, sudo apt install firefox-esr or sudo snap install firefox.

Settings live in Applications, then Settings, then Settings Manager: appearance, display resolution, keyboard layout and the panel are all configured there. The display resolution of a remote session is set by your RDP client, not by the VM.

Step 8: Verify the security posture

Confirm that SSH is key only, root is locked, and no account has a password until you set one:

sudo sshd -T | grep -E '^(permitrootlogin|passwordauthentication) '
sudo passwd -S root
sudo awk -F: '$2 !~ /^[!*]/ && $2 != "" {n++} END {print "accounts with a password: " n+0}' /etc/shadow

Expected output on a new VM (after Step 5 the last line reads 1, your own account):

permitrootlogin prohibit-password
passwordauthentication no
root L 2009-12-22 -1 -1 -1 -1
accounts with a password: 0

The terminal shows the effective sshd policy with permitrootlogin prohibit-password and passwordauthentication no, the root account locked, zero accounts with a password, and eth0 routable and configured under systemd-networkd

prohibit-password means root may not authenticate with a password. L means the root account is locked. (Older OpenSSH releases print the same setting as without-password.)

Step 9: Networking

The Azure network interface is configured by cloud-init and systemd-networkd, exactly as on Ubuntu Server. Unlike a GNOME desktop image, the XFCE package set does not try to hand your interface to NetworkManager, so no override file is needed and none is shipped:

networkctl list --no-legend | awk '$2=="eth0"'

Expected output:

  2 eth0 ether    routable configured

Because NetworkManager is not installed, there is no network panel in the XFCE settings; that is expected. If you want one, install NetworkManager yourself and test the change from the Azure serial console before you reboot.

The Azure Network Security Group is the enforced firewall. ufw is installed but inactive, the Ubuntu default. If you enable it, allow SSH first (sudo ufw allow OpenSSH), and allow 3389 only if you connect directly rather than through the tunnel.

Step 10: Turn remote desktop off, or change your password

To switch remote desktop off again (the setting survives reboots), run this yourself:

sudo cloudimg-remote-desktop disable

To change the password the RDP login box asks for, change your account password — they are the same thing:

sudo passwd azureuser

To replace this VM's TLS certificate with one of your own, write it to /etc/xrdp/cert.pem and /etc/xrdp/key.pem (the key readable by group xrdp) and restart the service with sudo systemctl restart xrdp.

Step 11: Check the patch level

The image is fully updated at build time. Confirm no upgrades are pending (grep -c exits non-zero on a zero count, hence the || true):

echo "pending upgrades: $(apt-get -s -o APT::Get::Always-Include-Phased-Updates=true dist-upgrade | grep -c '^Inst ' || true)"

Expected output:

pending upgrades: 0

unattended-upgrades installs security updates automatically. You can still update on your own schedule with sudo apt-get update && sudo apt-get -y dist-upgrade, and reboot if a new kernel was installed. Remember the universe caveat above: updates arrive when the Ubuntu community publishes them.

Common Use Cases

  • A lightweight cloud workstation for Linux development, reachable from any RDP client
  • Running graphical administration and data tools close to your Azure resources without paying for a large VM
  • 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 but the screen is black, or the session closes immediately

Check what the session manager recorded:

sudo journalctl -u xrdp-sesman --no-pager -n 30

On xrdp 0.10 a healthy sign-in logs Access permitted for user: <your account>, then X server :10 is working and Session in progress on display :10. If instead you see pam_authenticate failed: Authentication failure followed by AUTHFAIL: user=<your account>, the password is wrong or the account has none yet, so set it with sudo passwd <user> over SSH and try again.

I connected a second time and was immediately disconnected

You get one XFCE desktop session per account. If you disconnect and reconnect later, xrdp returns you to the session you left — that is the normal path and it works: the session manager logs ++ reconnected session: username <you>, display :10.0. But if you open a second connection while the first is still attached, xrdp starts a second session for the same account, xfce4-session refuses to run twice for one user and exits, and the new connection is dropped (the client reports ERRINFO_LOGOFF_BY_USER). This is how XFCE behaves anywhere, not something specific to this image.

If you need two desktops at once, sign in as two different accounts — create the second one with sudo adduser <name> and give it a password. To abandon a session you can no longer reach, end it from SSH with sudo pkill -u <your-account> xfce4-session, then connect again.

The RDP login box will not accept my password

The account has no password yet, or you typed a different account's name. Set it again with sudo passwd azureuser over SSH, then retry. The username is your Linux account name, not an email address.

I get "connection refused" on localhost:3389

The tunnel is not up, or remote desktop is still off. Check sudo cloudimg-remote-desktop status on the VM, and confirm your ssh -N -L 3389:localhost:3389 command is still running on your workstation.

The desktop resolution is wrong

Resize is controlled by your RDP client. In Remote Desktop Connection set the display size before connecting; with FreeRDP pass /size:1920x1080 or /f for full screen.

Cannot connect via SSH

  1. Verify the VM is in Running state in the Azure Portal
  2. Check that port 22 is allowed in the Network Security Group
  3. Ensure you are using the correct username: azureuser
  4. Verify your SSH key matches the one you supplied at create time. Password login over SSH is disabled by design.

Azure agent not running

sudo systemctl status walinuxagent --no-pager

If it is not running, start it yourself with sudo systemctl enable --now walinuxagent.

Important Notes

Ubuntu is free and open source. It is not covered by a single licence: it is a distribution assembled from thousands of independently packaged components, each carrying its own terms, including the GPL, LGPL, MIT, BSD, Apache 2.0 and MPL. XFCE is free software under the GPL and LGPL; xrdp and xorgxrdp are under the Apache Licence 2.0. Every package's terms are readable with dpkg -s <package> and under /usr/share/doc/<package>/copyright. No subscription or licence key is required to run this image.

The desktop stack in this image comes from the Ubuntu universe archive, which is community maintained. Canonical's guaranteed security-update commitment for universe is available only under an Ubuntu Pro subscription, which is neither included with nor required by this image. See "A note on package support" above.

Ubuntu 26.04 LTS receives standard security maintenance until 29 May 2031. Plan a move to a newer LTS image before that date for workloads that need to outlive it.

Ubuntu is a trademark of Canonical Ltd. Xfce is a project of the Xfce development team. The names are used here nominatively, only to identify the software this image contains. cloudimg is not affiliated with, endorsed by or sponsored by Canonical Ltd. or the Xfce project.

Support

For assistance with this image, contact cloudimg support: