Setup Xpra

1. About

Xpra is like a "screen for X". It is similar to X11 forwarding, but much more efficient and with lots of features.

In a cloud server Xpra is needed to access remotely the graphical displays (VGA consoles) of the virtual machines (for example from a laptop). Xpra makes it easy and efficient.

2. Install

We need to install Xpra both on the server and on the client (on the laptop):

apt install --yes xpra

On the server we also need to install the package virt-viewer (which provides remote-viewer) and some other required packages:

apt install --yes \
    virt-viewer tilix dbus-x11 python3-pil

3. Basic usage

We can start Xpra on the server, like this:

xpra start :7
DISPLAY=:7 tmux
Instead of 7 we can use any other port for the display.

From the client, we can attach to the Xpra server like this:

xpra attach ssh:root@11.12.13.14:7

Now, from the tmux on the server we can start any GUI application (for example firefox or chromium), and it will be displayed on the local machine:

apt install --yes chromium
chromium --no-sandbox

4. SSH options

  • If we use a non-standard SSH port or ssh-key for accessing the server, we can use the option --ssh, like this:

    xpra attach ssh:user@11.12.13.14:7 \
         --ssh="ssh -p 222 -i ssh-key"

    In this case, Xpra will use a command like this for accessing the server:

    ssh -p 222 -i ssh-key user@11.12.13.14
  • Let’s assume we have an entry like this in the config file ~/.ssh/config:

    Host server1
      HostName 11.12.13.14
      Port 222
      User root
      IdentityFile ~/.ssh/server1.key

    This allows us to access the server with a command like: ssh server1. All the details (server IP, SSH port, usename and identity file) are specified in the config file, and SSH can pick them up from there.

    In this case, we can attach to Xpra with a command like this:

    xpra attach ssh:server1:7 --ssh="ssh"

    The SSH command that will be used by Xpra is: ssh server1

In all these cases, ‘:7’ is the Xpra display number.

5. Non-root user

Usually it is better/safer to use a non-root user. So, let’s see how to setup Xpra for a non-root user.

First of all, let’s create a new user:

adduser user1

5.1. Setup SSH access

  1. On the server, generate an SSH key pair:

    su - user1
    
    ssh-keygen -t ecdsa -q -N '' -f xprakey
    ls -l xprakey*
  2. Add the public key to ~/.ssh/authorized_keys:

    mkdir -p ~/.ssh
    chmod 700 ~/.ssh
    touch ~/.ssh/authorized_keys
    chmod 600 ~/.ssh/authorized_keys
    cat xprakey.pub >> ~/.ssh/authorized_keys
  3. Transfer the private key to the client (laptop), to the file ~/.ssh/xprakey.

  4. On the client, create an SSH config entry, like this:

    mkdir -p ~/.ssh
    chmod 700 ~/.ssh/
    chmod 600 ~/.ssh/xprakey
    
    touch ~/.ssh/config
    chmod 600 ~/.ssh/config
    
    cat <<EOF >> ~/.ssh/config
    Host server1
        HostName 11.12.13.14
        Port 222
        User user1
        IdentityFile ~/.ssh/xprakey
        IdentitiesOnly yes
    EOF

    Try to login:

    ssh server1

    Alternatively, create a script like this, which is more portable:

    login-server1-user1.sh
    cat <<'EOF' > login-server1-user1.sh
    #!/bin/bash
    
    server=11.12.13.14
    port=222
    
    keyfile=$(mktemp)
    sed -n -e '/^-----BEGIN/,/^-----END/p' $0 > $keyfile
    
    ssh -i $keyfile -p $port user1@$server
    
    rm -f $keyfile
    exit 0
    EOF
    
    cat ~/.ssh/xprakey >> login-server1-user1.sh
    
    chmod 700 login-server1-user1.sh
    ./login-server1-user1.sh

5.2. Setup Xpra

  1. On the server, add the env variable XDG_RUNTIME_DIR:

    su - user1
    
    echo 'export XDG_RUNTIME_DIR=$HOME/.xpra' >> ~/.bashrc
    echo 'export XDG_RUNTIME_DIR=$HOME/.xpra' >> ~/.profile
  2. On the server, create a script for starting Xpra:

    su - user1
    
    cat << 'EOF' > xpra-start.sh
    #!/bin/bash -x
    killall xpra
    xpra start :100 \
        --start-new-commands=yes #\
        #--sharing=yes --readonly=no
    EOF
    
    chmod +x xpra-start.sh
    
    ./xpra-start.sh
    ps ax | grep xpra
    The display number is :100.
  3. On the client, create a script for attching to the display :100 of the server:

    cat <<'EOF' > xpra-attach-100.sh
    #!/bin/bash -x
    xpra attach ssh:server1:100 --ssh="ssh" \
        --sharing=yes --readonly=no
    EOF
    
    chmod +x xpra-attach-100.sh
    ./xpra-attach-100.sh

    Alternatively, create a script like this, which is more portable:

    xpra-attach-100.sh
    cat <<'EOF' > xpra-attach-100.sh
    #!/bin/bash -x
    
    user=user1
    server=11.12.13.14
    port=222
    display=100
    
    keyfile=$(mktemp)
    sed -n -e '/^-----BEGIN/,/^-----END/p' $0 > $keyfile
    
    xpra attach ssh:$user@$server:$display \
        --ssh="ssh -i $keyfile -p $port" \
        --sharing=yes --readonly=no
    
    rm -f $keyfile
    exit 0
    EOF
    
    cat ~/.ssh/xprakey >> xpra-attach-100.sh
    
    chmod 700 xpra-attach-100.sh
    ./xpra-attach-100.sh
    We should get a tilix terminal by default, but if not, we can start it from the Xpra icon (click it and keep it pressed, then go to "Server", then to "Run a command" and release the mouse button, type "tilix" and press Enter). From this terminal we can type Incus commands, and when we try to access the display of a virtual machine it will be shown on the laptop.