What is Session?
From the Session Lightpaper: “Session is a decentralised messenger that supports completely private, secure, and anonymous communications. Session provides one-on-one (direct message, or ‘DM’), group chats, and voice calls.”
What is session-desktop and how does the Session protocol differ from Signal protocol?
Oxen’s session-desktop is a fork of Signal’s signal-desktop, an E2EE messaging app available for Linux. The key contributions of Session are decentralization of E2EE and the addition of onion routing (lokinet) to protect metadata. The Session protocol does not implement PFS or deniability, but it does provide similar protections by way of anonymity. For example, use of a public key (SessionID) as an identifier in place of a personal phone number. session-desktop does not require a link to any other devices, whereas signal-desktop requires periodic linking to the Signal app on one’s mobile device to function.
For all of the details read:
How to install session-desktop
in Qubes
The following adapts the official (Debian) Linux install instructions from Oxen. To maintain good security practice, please also read the Qubes guide on Verifying Signatures.
1. (optional) Create a new templateVM, <template>
.
In the following we will assume <template>
is a clone of debian-12-minimal.
[user@dom0 ~]$ sudo qubesctl --skip-dom0 --targets=debian-12-minimal --show-output state.sls update.qubes-vm
[user@dom0 ~]$ qvm-clone debian-12-minimal <template>
Open a root terminal in the (new) template.
[user@dom0 ~]$ qvm-run -u root <template> xterm
Run the following commands as root, which will install the curl
program needed to download the Oxen signing key, a notification daemon for use with session-desktop, and the Qubes networking package. Add the Oxen GPG signing key and the Session repository. Finally, fetch all repositories (including the Session repo) and install Session:
Note: If using cacher, replace “https://
” with “http://HTTPS///
” in each command below.
root@<template>:~# apt install curl xfce4-notifyd qubes-core-agent-networking glib-networking
root@<template>:~# curl -so /etc/apt/trusted.gpg.d/oxen.gpg --proxy 127.0.0.1:8082 https://deb.oxen.io/pub.gpg
root@<template>:~# echo "deb https://deb.oxen.io bookworm main" | tee /etc/apt/sources.list.d/oxen.list
root@<template>:~# apt update && apt install session-desktop
Optional: Installing color emojis will improve the messaging experience, as will installation of a file manager in the minimal template (substitute nautilus
for thunar
based on personal preference).
root@<template>:~# apt install fonts-noto-color-emoji thunar qubes-core-agent-thunar qubes-pdf-converter qubes-img-converter
Exit the root terminal and shutdown the templateVM.
[user@dom0 ~]$ qvm-shutdown <template>
2. Create a disposableVM template, <dvm-template>
,
based on the <template>
with session-desktop installed. Choose a color from the Qubes scheme for the label, which is red in this example. The final command will create an app menu for the disposableVM.
[user@dom0 ~]$ qvm-create --template <template> --label red <dvm-template>
[user@dom0 ~]$ qvm-prefs <dvm-template> template_for_dispvms True
[user@dom0 ~]$ qvm-features <dvm-template> appmenus-dispvm 1
By default this setup will use sys-firewall as the netVM, but a sys-vpn as netVM will also work. To display the file manager and Session app menu entries for the disposableVM choose the following from the Qubes app menu: “Template (disp): <dvm-template>
” → “<dvm-template>
: Qube Settings” → “Applications” and select the appropriate apps.
3. Create a SessionID in a disposableVM and make it persistent
The following instructions demonstrate how to persist the SessionID while using disposableVMs. This setup will work well if you prefer ephemeral messaging. If you want messages to persist, then create an appVM based on <template>
in place of the following setup.
Open a disposable terminal and execute session-desktop
from the terminal, which will maintain access to the config files after closing the app.
[user@dom0 ~]$ qvm-run --dispvm=<dvm-template> --service qubes.StartApp+debian-xterm
[user@disp<#> ~]$ session-desktop
- In the Session window select “Create Session ID”, then “Continue” and enter a personalized display name.
- Select “Get Started”.
- Show the recovery code to finish the setup process and store it in your vault (there are no passwords to remember).
- While leaving the terminal open, close the Session chat window to free up the terminal.
- Copy the following two, automatically generated, files to the disposableVM template,
<dvm-template>
.
[user@disp<#> ~]$ qvm-copy .config/Session/config.json
[user@disp<#> ~]$ qvm-copy .config/Session/sql/db.sqlite
- In
<dvm-template>
create a new directory,/rw/config/Session
, and move the above two files to this location, where they will persist. - Add the following lines to the
rc.local
script. This will ensure that each disposable Session instance spawned by<dvm-template>
is configured with the above SessionID from the get go.
[user@dom0 ~]$ qvm-run -u root <dvm-template> xterm
[root@<dvm-template> ~]$ mkdir /rw/config/Session
[root@<dvm-template> ~]$ mv /home/user/QubesIncoming/disp<#>/* /rw/config/Session/
[root@<dvm-template> ~]$ echo -e "mkdir -p /home/user/.config/Session/sql/\ncp /rw/config/Session/config.json /home/user/.config/Session/\ncp /rw/config/Session/db.sqlite /home/user/.config/Session/sql/\nsudo chown -R user /home/user/.config/Session" >> /rw/config/rc.local
A quick check
[root@<dvm-template> ~]$ cat /rw/config/rc.local
should include the following lines:
mkdir -p /home/user/.config/Session/sql/ cp /rw/config/Session/config.json /home/user/.config/Session/ cp /rw/config/Session/db.sqlite /home/user/.config/Session/sql/ sudo chown -R user /home/user/.config/Session
4. Enjoy
With setup complete, we can now close our disposable template and run Session as a disposable app with an anonymous, but persistent, SessionID.
[user@dom0 ~]$ qvm-shutdown <dvm-template>
[user@dom0 ~]$ qvm-run --dispvm=<dvm-template> --service qubes.StartApp+session-desktop
Note: session-desktop
will pull in approximately two weeks worth of existing messages after opening a new dispVM. You can read more of the details of how this works in the Session whitepaper.
Work-in-progress?
- Eliminate the recovery phrase popup with each respawn of the dispVMs
- Persistence of contacts
*Thanks to the authors of the Qubes community guide for Signal, which provided a ready template for this guide.