Amazon.co.uk Widgets

Log in

X
Working headless RDP with GNOME Remote Desktop on Ubuntu 25.10

Setting up GNOME Remote Desktop for headless multi-user RDP access on Ubuntu 25.10 (Questing Quokka) is tricky. This guide shows a working approach if the out of the box clean install doesn't work using only the software included with Ubuntu Desktop and uses openssl to generate TLS certificates. It explains common errors you may see and how to resolve them.

TL:DR – I never really got this working on Ubuntu 25.04 So I spent a few hours trying to get to the bottom of it and finally it works!

Overview

  • Configure Remote Login (multi user, headless) and optionally Desktop Sharing (your current user) RDP certificates for GNOME Remote Desktop.
  • Avoid additional FreeRDP or winpr3-utils packages — OpenSSL is sufficient to generate the right kind of certificates.
  • We ensure the RDP service works Remote Login (multi user, headless) first authenticating via a system wide user name and password, which gives access to the graphical login screen, where end users can login using their usual user specific credentials.
  • You can also log in to Desktop Sharing for your current user.

First things first on a clean install Ubuntu 25.10 computer

  • Go to Settings > System > Click on Remote Login and enable it.
  • You have enabled multi user, headless Remote Login.
  • Set a device username and password (not your account username) to get you to the login. 

 

Ubuntu 25.10 Settings for Remote Login

 

  • Open a terminal, and type sudo systemctl enable --now gnome-remote-desktop.service 
  • Reboot your computer sudo reboot
  • Once your computer has rebooted run sudo grdctl --system status --show-credentials and you need to be able to see Unit status active and Status enabled. You can ignore the TPM messagee as it is just telling you about a fallback to a file.

 

sudo grdctl --system status --show-credentials
Init TPM credentials failed because No TPM device found, using GKeyFile as fallback.
Overall:
	Unit status: active
RDP:
	Status: enabled
	Port: 3389
	TLS certificate: /var/lib/gnome-remote-desktop/.local/share/gnome-remote-desktop/certificates/rdp-tls.crt
	TLS fingerprint: a4:3a:c2:ca:2b:80:15:25:36:54:84:35:68:ef:de:d2:45:31:69:a6:50:5c:e4:c7:b3:f2:a9:10:b7:60:10:07
	TLS key: /var/lib/gnome-remote-desktop/.local/share/gnome-remote-desktop/certificates/rdp-tls.key
	Username: device
	Password: weakpassword

 

  • Now try your remote desktop client of choice now with the system username ans password and if it 'just works' it takes you to the Ubuntu login screen where you can use your usual account.
  • Ignore the rest of this article. You've got a working system.

If the simple setup steps didn't work for your Ubuntu 25.10 computer then continue.

The Script

#!/usr/bin/env bash
set -euo pipefail

# --- Config ---
RDP_USER="${USER}"
RDP_PASS="changethistoyourpassword"
SYSTEM_CERT_DIR="/var/lib/gnome-remote-desktop"
USER_CERT_DIR="$HOME/.local/share/gnome-remote-desktop/certificates"
CERT_FILE="rdp-tls.crt"
KEY_FILE="rdp-tls.key"

echo "[+] Preparing certificate directories..."
sudo mkdir -p "$SYSTEM_CERT_DIR"
sudo chown gnome-remote-desktop:gnome-remote-desktop "$SYSTEM_CERT_DIR"/rdp-tls.key
sudo chown gnome-remote-desktop:gnome-remote-desktop "$SYSTEM_CERT_DIR"/rdp-tls.crt
mkdir -p "$USER_CERT_DIR"

# --- Generate PEM TLS certificates ---

echo "[+] Generating system PEM certificate..."
sudo openssl req -newkey rsa:2048 -nodes \
    -keyout "$SYSTEM_CERT_DIR/$KEY_FILE" \
    -x509 -days 365 \
    -out "$SYSTEM_CERT_DIR/$CERT_FILE" \
    -subj "/CN=$(hostname)"
sudo chown gnome-remote-desktop:gnome-remote-desktop "$SYSTEM_CERT_DIR/$KEY_FILE" "$SYSTEM_CERT_DIR/$CERT_FILE"
sudo chmod 600 "$SYSTEM_CERT_DIR/$KEY_FILE"
sudo chmod 644 "$SYSTEM_CERT_DIR/$CERT_FILE"

echo "[+] Generating user PEM certificate..."
openssl req -newkey rsa:2048 -nodes \
    -keyout "$USER_CERT_DIR/$KEY_FILE" \
    -x509 -days 365 \
    -out "$USER_CERT_DIR/$CERT_FILE" \
    -subj "/CN=$(hostname)"
chmod 600 "$USER_CERT_DIR/$KEY_FILE"
chmod 644 "$USER_CERT_DIR/$CERT_FILE"

# --- Enable GNOME Remote Desktop service ---
sudo systemctl enable --now gnome-remote-desktop.service

# --- Configure system RDP TLS ---
echo "[+] Configuring system RDP TLS..."
sudo grdctl --system rdp set-tls-key "$SYSTEM_CERT_DIR/$KEY_FILE"
sudo grdctl --system rdp set-tls-cert "$SYSTEM_CERT_DIR/$CERT_FILE"
sudo grdctl --system rdp enable

# --- Configure user RDP TLS and password ---
export XDG_RUNTIME_DIR="/run/user/$(id -u)"
echo "[+] Configuring user RDP TLS and password..."
grdctl rdp set-tls-key "$USER_CERT_DIR/$KEY_FILE"
grdctl rdp set-tls-cert "$USER_CERT_DIR/$CERT_FILE"
grdctl rdp set-credentials "$RDP_USER" "$RDP_PASS"
grdctl rdp enable

# --- Open firewall ---
if command -v ufw >/dev/null 2>&1; then
    echo "[+] Allowing TCP 3389 through firewall..."
    sudo ufw allow 3389/tcp
    sudo ufw reload || true
fi

# --- Ensure lingering so user session stays alive for RDP ---
sudo loginctl enable-linger "$USER"

echo
echo "[✓] GNOME Remote Desktop RDP is ready!"
echo "Connect with an RDP client to: rdp://$(hostname -I | awk '{print $1}')"
echo "Username: $RDP_USER"
echo "Password: $RDP_PASS"

Step-by-Step Explanation

  1. Directories: We create /var/lib/gnome-remote-desktop if it doesn't exist for system-wide certificates and ~/.local/share/gnome-remote-desktop/certificates/ if it doesnt exist for the user. Correct ownership ensures the GNOME Remote Desktop service can read the files.
  2. Generating certificates: Using OpenSSL, we generate PEM-format keys and self-signed certificates. GNOME Remote Desktop only accepts PEM keys, not OpenSSH keys. Both system and user certificates are created.
  3. Permissions: System certificates must be owned by gnome-remote-desktop and readable. User certificates must be readable by the logged-in user.
  4. Enabling the service: gnome-remote-desktop.service is enabled system-wide so RDP is available headless.
  5. Configuring system RDP: Using grdctl --system rdp, we assign the system PEM key and certificate and enable RDP. TPM error messages may appear (Init TPM credentials failed), but these are harmless fallback messages.
  6. Configuring user RDP: User certificates and a password are assigned using grdctl
  7. Firewall: TCP 3389 is opened using ufw, if available, allowing external RDP clients to connect.
  8. Lingering: loginctl enable-linger ensures that user sessions stay alive even if the user is not actively logged in.

Common Issues

  • TPM errors: Messages like Init TPM credentials failed are normal on headless systems without a TPM. GNOME uses a fallback keyfile.
  • Certificate errors: If you see BIO_new failed, it usually means the private key is in OpenSSH format. Ensure PEM keys are used.
  • Port errors: If you need headless multi user remote login and individial desktop sharing you will run into port confusion as RDP likes to use port 3389 and likely the user service will move to 3390.
  • Locked collection errors: If you are logged in to GNOME as the user concerned, there is no “locked collection” issue using grdctl

Testing the RDP Server

Once the script completes, you can test the RDP connection using any standard RDP client. Here’s a simple command using xfreerdp (available in Ubuntu repositories):

xfreerdp /v:$(hostname -I | awk '{print $1}') /u:your-username /p:changethistoyourpassword /cert-ignore

Or, if you prefer a graphical client, you can use Royal TSX, Windows App or GNOME Connections or Remmina 

  • Host: $(hostname -I | awk '{print $1}')
  • Username: your logged-in user
  • Password: changethistoyourpassword
  • Certificate: ignore or accept the self-signed certificate

Successful login will give you a headless GNOME session for that user. Repeat for multiple users by creating their certificates and credentials similarly.

Checking the status

You need to be able to see Unit status active and Status enabled. You can ignore the TPM messagee as it is just telling you about a fallback to a file. 

 

sudo grdctl --system status
Init TPM credentials failed because Failed to initialize transmission interface context: tcti:IO failure, using GKeyFile as fallback.
Overall:
	Unit status: active
RDP:
	Status: enabled
	Port: 3389
	TLS certificate: /var/lib/gnome-remote-desktop/rdp-tls.crt
	TLS fingerprint: 1a:4a:co:ff:ee:14:c4:0a:2d:d0:b6:d0:db:1d:63:53:43:0b:32:df:fa:ca:55:12:c9:1a:c8:c4:co:dd:ee:7c
	TLS key: /var/lib/gnome-remote-desktop/rdp-tls.key
	Username: (hidden)
	Password: (hidden)

$ grdctl  status
Overall:
	Unit status: active
RDP:
	Status: enabled
	Port: 3390
	TLS certificate: /home/angusf/.local/share/gnome-remote-desktop/certificates/rdp-tls.crt
	TLS fingerprint: co:ff:ee:11:22:c8:r2:d2:f7:db:48:cb:40:b7:f1:54:af:97:a6:93:52:c9:57:4c:5b:9d:92:37:e4:98:27:f9
	TLS key: /home/angusf/.local/share/gnome-remote-desktop/certificates/rdp-tls.key
	View-only: no
	Negotiate port: yes
	Username: (hidden)
	Password: (hidden)

 

Conclusion

Using this method, you can configure headless multi-user RDP access on Ubuntu 25.10 with GNOME Remote Desktop using only the software installed by default with Ubuntu Desktop. No extra utilities are required. No X Window System (X11, or X) or VNC protocols are used. This is purely Wayland and RDP. PEM certificates and correct permissions ensure secure and functional RDP connections. 

Ubuntu 25.10 RDP connection to Gnome Remote Desktop from a Mac
Ubuntu 25.10 RDP connection to Gnome Remote Desktop from a Mac

Other rabbit holes and inspirations

The Readme for GNOME Remote Desktop and a script for Fedora headless-remote-desktop-setup-process inspired this article.

See Upgrading to Ubuntu 25.10 from 25.04 for how to upgrade to Ubuntu 25.10 (Questing Quokka).