Connecting to isolated system environments using Waypipe

A Right Mental Attitude
A Right Mental Attitude 1200x1000
aluminium-tin-foil-hat_exw.jpg

Continuing with the previous boring opuses about environment isolation, it’s time to remember Wayland.
Of course, this is not a call to action, but just simple examples and reflections.
I personally adhere to a philosophy where the user is the center of the system, and he has the right to configure everything as he sees fit, and not as it is imposed by general trends, or as it is implemented in a specific distribution, at the same time understanding and accepting all the risks and consequences of these actions.
As the saying goes, “If you know what you are doing.”


And before we begin, it’s worth writing again that:

  • Yes, I understand that this is all very superficial.
  • Yes, any connections to the local graphical shell are not allowed for anything dangerous, and you must use VNC or virt-viewer/spice.
  • Unprivileged LXC should be replaced with Xen / KVM
  • And yes, I know that it is possible to breakout from KVM isolation too.
  • I know about Flatpak.
  • And finally, yes, I have known about Qubes OS and its architecture, let’s say, since its inception, which was 2010.


And, simplifying and adapting QubesOS ideas to my everyday needs, I prefer to use either other local users or lightweight unprivileged LXC environments.

And yes, I don’t run anything potentially dangerous in them, but rather something that many of you use directly under your system account, for example:

  • Firefox for everyday use and casual browsing.
  • Several projects using packages from PyPI, RubyGems.
  • Separately, what I compile from sources from GitHub.
  • Third-party programs, such as element-desktop, Telegram, Zoom.

What does this give?

  • Mitigating the consequences of typical and common attacks.
  • The ability to customize an individual environment for each set of specific programs, with smooth interaction.
  • No contamination of either the system or user environment.
    You simply don’t need to keep all these directories with endless configs in ~/.config, or packages in ~/.local.
  • More native support for specific software if it requires Ubuntu, CentOS, or Fedora.

Configuring .desktop files for easy launch from the KDE environment

Previously, for a long time, I used X network transparency, but Wayland is good enough and it is possible to switch to it without losing the concept, and, moreover, improving overall security.

nano /usr/share/applications/firefox.untrusted.desktop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[Desktop Entry]
Exec=/usr/bin/waypipe --title-prefix '[web-untrusted] ' ssh web-untrusted@10.1.1.249 /usr/local/bin/ff.sh
Name=Untrusted Web
Name[it]=Web-Siti non attendibili
Name[uk]=Недовірена мережа
Name[ru]=Недоверенные сайты
GenericName=Untrusted Web
GenericName[it]=Web-Siti non attendibili
GenericName[uk]=Недовірена мережа
GenericName[ru]=Недоверенные сайты
Comment=Firefox Browser for untrusted sites
Comment[it]=Browser Firefox per siti non attendibili
Comment[uk]=Браузер для недовірених веб-сайтів
Comment[ru]=Браузер для недоверенных сайтов
Icon=/opt/firefox/ff_icons/red/default64.png
MimeType=
StartupNotify=true
Terminal=false
TerminalOptions=
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=none
X-KDE-SubstituteUID=false
X-KDE-Username=

nano /usr/share/applications/firefox.trusted.desktop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[Desktop Entry]
Exec=/usr/bin/waypipe --title-prefix '[trusted-firefox] ' ssh trusted-firefox@10.1.1.245 /usr/local/bin/ff.sh
Name=Trusted Web
Name[it]=Siti affidabili
Name[uk]=Довірені сайти
Name[ru]=Доверенные сайты
GenericName=Trusted Web
GenericName[it]=Web-Siti affidabili
GenericName[uk]=Довірені сайти
GenericName[ru]=Доверенные сайты
Comment=Firefox Browser for Trusted sites
Comment[it]=Browser Firefox per siti affidabili
Comment[uk]=Браузер для довірених веб-сайтів
Comment[ru]=Браузер для доверенных сайтов
Icon=/opt/firefox/ff_icons/green/default64.png
MimeType=
StartupNotify=true
Terminal=false
TerminalOptions=
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=none
X-KDE-SubstituteUID=false
X-KDE-Username=

nano /usr/share/applications/chromium.trusted.desktop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[Desktop Entry]
Exec=/usr/bin/waypipe --title-prefix '[trusted-chromium] ' ssh trusted-chromium@10.1.1.245 /usr/local/bin/waypipe-run-chromium.sh
Name=Chromium - Trusted sites
Name[it]=Chromium - Siti affidabili
Name[uk]=Chromium - Довірені сайти
Name[ru]=Chromium - Доверенные сайты
GenericName=Chromium - Trusted sites
GenericName[it]=Chromium - Siti affidabili
GenericName[uk]=Chromium - Довірені сайти
GenericName[ru]=Chromium - Доверенные сайты
Comment=Chromium Browser for Trusted sites
Comment[it]=Browser Chromium per siti affidabili
Comment[uk]=Браузер Chromium для довірених веб-сайтів
Comment[ru]=Браузер Chromium для доверенных сайтов
Icon=/opt/chromium_green.png
MimeType=
StartupNotify=true
Terminal=false
TerminalOptions=
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=none
X-KDE-SubstituteUID=false
X-KDE-Username=

A bit of routine

Here I deliberately do not want to describe everything in detail, I will only provide commands and tips.
As you may have noticed, the example uses two LXC virtual machines and three users in them.
Virtual machines do not communicate with each other, nor do users.
I prefer to use not just one user, say, for trusted tasks, but one user per application.
Unless, of course, this leads to excessive complication of file flow between different entities.
Next, you must do some preparatory work.
Deploy the required number of LXC/KVM and configure them:

  • Install required software
  • Passthrough the necessary hardware, such as a GPU, to accelerate hw rendering in Firefox.
    Yes, additional hardware and its drivers are another attack surface ¯\_(⊙︿⊙)_/¯
  • Configure iptables/nft, sshd_config, enable routing and networking

Generating ed25519 keys for SSH

1
2
3
ssh-keygen -t ed25519 -f /home/awesome/.ssh/web-untrusted.ed25519 -C "web-untrusted@untrusted-lxc"
ssh-keygen -t ed25519 -f /home/awesome/.ssh/trusted-firefox.ed25519 -C "trusted-firefox@trusted-lxc"
ssh-keygen -t ed25519 -f /home/awesome/.ssh/trusted-chromium.ed25519 -C "trusted-chromium@trusted-lxc"

Let’s set up an SSH configuration for your user

nano /home/awesome/.ssh/config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Host 10.1.1.249
  User web-untrusted
  Port 22
  PreferredAuthentications publickey
  IdentityFile /home/awesome/.ssh/web-untrusted.ed25519
Host 10.1.1.245
  User trusted-firefox
  Port 22
  PreferredAuthentications publickey
  IdentityFile /home/awesome/.ssh/trusted-firefox.ed25519
Host 10.1.1.245
  User trusted-chromium
  Port 22
  PreferredAuthentications publickey
  IdentityFile /home/awesome/.ssh/trusted-chromium.ed25519

Make sure that the following lines are present in the virtual machine’s
/etc/ssh/sshd_config:

1
2
3
PasswordAuthentication  no
AllowTcpForwarding      yes                         # (default)
AllowUsers              web-untrusted@10.1.1.1      # 10.1.1.1 - assumed to be your host

Start scripts, /usr/local/bin/ff.sh, are quite primitive.

1
2
3
#!/bin/bash
/usr/lib/firefox-esr/firefox-esr --ProfileManager > /dev/null
exit 0

Script for running Chromium via waypipe is a bit more complicated.
/usr/local/bin/waypipe-run-chromium.sh

1
2
3
#!/bin/bash
/usr/bin/chromium  --enable-features=UseOzonePlatform --ozone-platform=wayland > /dev/null
exit 0


We also need to remember about the sound

It is configured for users in virtual machines in the
/home/trusted-chromium/.pulse/client.conf file.

1
default-server = 10.1.1.1

On the host accordingly
/home/awesome/.config/pipewire/pipewire-pulse.conf.d/50-network.conf

1
2
3
context.exec = [
    { path = "pactl" args = "load-module module-native-protocol-tcp listen='0.0.0.0' auth-ip-acl='127.0.0.1;10.1.1.245;10.1.1.249'" }
]

Next comes the firewall, authorization and all that stuff that I’m too lazy to describe.


Let’s set each application’s own icon

In addition to setting up Wayland itself, I had to spend quite a lot of time searching for ways to customize specific icons for specific windows.
Here is one of the solutions.

This is an example for /usr/share/applications/firefox.untrusted.desktop

Setting custom icons for waypipe / applications in KDE 1523x810 waypipe-set-icon.png
Setting custom icons for waypipe / applications in KDE

Let’s add some visuals and amenities

Each application, depending on its class, can be customized using either System Application Styles or, as in the case of the fox, Themes (of course only By Firefox).

I use a hidden sidebar with frequently used web apps.

Hidden sidebar with Web Apps 1920x1080 desktop_side_panel.png
Hidden sidebar with Web Apps

All windows have correctly assigned icons.

Correctly assigned icons for Waypipe 1920x1080 desktop_apps_waypipe.png
Correctly assigned icons for Waypipe

Logically and visually, everything is simple:

  • Red - everyday web surfing, 95% of websites.
  • Blue - development. Only my own and trusted sites / APIs.
  • Green - banking, personal information.

If a website doesn’t work correctly in fox, and this does happen, there’s a corresponding Chromium or Google Chrome browser.

Let’s configure compatibility for X11 applications

Legacy X11 App Support 1523x810 x11_legacy_apps.png
Legacy X11 App Support

Not just web surfing

The examples above show how to use browsers from different isolated virtual machines with a connection to Wayland via waypipe.
Similarly, you can launch various editors/IDEs, specialized applications, and configure unique interaction environments for specific versions of operating systems and software.
You can maintain this separately from the Host and your user, as well as from other projects.
And get quite convenient and safe access to use.


Trend direction

Just a few days ago, Fedora Hummingbird was released.

The central goal of Project:

  • to get as close to zero CVE reports as possible in every container image it ships, and to stay there continuously.


While it’s important to quickly deliver updates for packages like Python, Go, Node.js, Rust, Ruby, OpenJDK, PostgreSQL, nginx, it still doesn’t solve the problem of poor organization and separation of development environments from sensitive user data.
In this sense, QubesOS remains a reference model of paranoid system. In my opinion.


Original post on SecOps.it Blog Connecting to isolated system environments using Waypipe