[GH-ISSUE #1824] Is there way to start few applications in single x11 sandbox? #1240

Closed
opened 2026-05-05 07:42:58 -06:00 by gitea-mirror · 4 comments
Owner

Originally created by @punksta on GitHub (Mar 22, 2018).
Original GitHub issue: https://github.com/netblue30/firejail/issues/1824

I'd like to run time-tracking app with ide and browser in single x11 sandbox. Is it possible?

Originally created by @punksta on GitHub (Mar 22, 2018). Original GitHub issue: https://github.com/netblue30/firejail/issues/1824 I'd like to run time-tracking app with ide and browser in single x11 sandbox. Is it possible?
gitea-mirror 2026-05-05 07:42:58 -06:00
Author
Owner

@Fincer commented on GitHub (Mar 24, 2018):

I have used systemd-nspawn to run Pale Moon web browser in a container with graphical interface (X11) + Pulseaudio enabled. Pulseaudio is needed for any web media content that have audio in it (such as Youtube videos).

I have read it is possible to run graphical applications with docker, too.

Please take also a look on x11docker project which claims to focus on X11 security issues and should provide a somewhat easy set-up for X11 + docker container environment.

For loose reference:
Running Firefox in a systemd-nspawn container

You can very likely use firejail inside systemd-nspawn container so that the end-user environment is kind of having two containers stacked. I have planned to use firejail in my systemd-nspawn containers after issue private-lib doesn't work with Palemoon & Firefox is fixed.

Security & X11

Problem of sharing X11 environment with the host is the shared memory which, in some cases, can be a security issue. This is likely an issue with Pulseaudio, too.

Setting up systemd-nspawn container + X11 application (my personal setup)

I have done this on Arch Linux, so some parts are specific for that distribution. The following stuff assumes you have your main system's current user in sudo group and you have working internet connection available in the system.

  1. Create a new container folder (in your home folder, for example):
mkdir -p ~/my-container

You can choose whatever path you want to. ~/my-container is just an example here.

  1. Set up container environment by running the following in your main system (this is Arch Linux specific approach):
sudo pacman -S arch-install-scripts
sudo pacstrap -i -c ~/my-container curl pacman coreutils systemd nano
  1. Login to the Arch Linux container environment:
sudo systemd-nspawn -b -D ~/my-container
  1. In container environment, login as root when login credentials are asked.

  2. In this step, we request public keys of Arch Linux package maintainers and run database updates.
    In container environment, run:

pacman-key --init && pacman-key --populate archlinux
pacman -Syy && pacman -Fy
  1. In container environment, create a new user 'default' & set home directory óf this user to /home/default:
useradd -d /home/default -u 1000 default
mkdir -p /home/default && chown 1000:1000 /home/default
  1. In container environment, install your program (as root):
pacman -S program_name
  1. In container environment, add password to user 'default' and change to user 'default' shell. In default user's shell, create a new file called 'launch.sh' in his/her home directory and set it as executable:
passwd default
su default
touch /home/default/launch.sh
chmod +x /home/default/launch.sh

The last two commands (touch & chmod) must be run as 'default' user.

  1. In container environment, edit the created 'launch.sh' file as user 'default' (nano /home/default/launch.sh). Add the following contents in it:
#!/bin/sh

su default -c "QT_X11_NO_MITSHM=1 PULSE_SERVER=unix:/run/user/host/pulse/native DISPLAY=:0 my_command"

where 'my_command' is the name of your program's executable file in container environment. If you don't use Pulseaudio in container environment, remove PULSE_SERVER=unix:/run/user/host/pulse/native part.

Note: any environment variables you describe in the command above depends on your set-up. If you use ALSA, for example, write a correct string for that.

  1. Exit the container environment by pressing CTRL + % key combination (or CTRL + ] with en_US keyboard) rapidly three times sequentially.

  2. Execute your program in container by running the following command in your main system:

sudo xhost local:root && sudo systemd-nspawn \
--bind-ro=$HOME/.Xauthority:/home/default/.Xauthority \
--bind-ro=/tmp/.X11-unix \
--bind-ro=/run/user/1000/pulse:/run/user/host/pulse \
--bind-ro=/dev/snd \
-D ~/my-container \
/home/default/launch.sh

The above command does as follows:

  • Share main system X11 environment

  • Initialize systemd-nspawn container

  • bind your main system's current user .Xauthority file to the container's default user home directory (read-only).

  • bind your main system's X11 sockets to the container environment (read-only)

  • bind your main system's Pulseaudio to the container environment (read-only)

  • specify container path (-D ~/my-container)

  • in container environment, execute home/default/launch.sh (in which we have set up that our command is executed as user 'default')

Additional Pale Moon parameters

NOTE: bind parameters you might want to use vary, depending on the requirements for the program. For example, I have additional parameters for my 'Pale Moon' web browser environment:

--bind-ro=/usr/share/icons/:/usr/share/icons/ \
--bind-ro=/usr/share/themes/:/usr/share/themes/ \
--bind-ro=/usr/share/fonts/:/usr/share/fonts/ \
--bind-ro=$HOME/.gtkrc-2.0:/home/browser/.gtkrc-2.0 \
--bind=$HOME/Downloads:/home/browser/Downloads \

Note that I have binded my main system's $HOME/Downloads folder as writable.

Some of these bindings are irrelevant if I have set up a working GTK2 environment or installed fonts/icons into the container. As I haven't installed fonts/icons in the container, I bind the ones I have in my main system. And, for example, without GTK2/icon bindings the program (Pale Moon) works but looks awful.

Which systemd-nspawn bindings to use?

How do you know which bindings you want to use? Check your program requirements.

Does your containerized program use Qt5, GTK2 or GTK3? Does it require ALSA or Pulseaudio? Does it require some fonts installed? Does it require some icons installed? Just find out (can be tricky) and by your findings, set up your --bind-ro parameters correctly to the command in step 11.

Firefox/Palemoon + systemd-nspawn X11 workaround

For Firefox and Pale Moon, there seems to be a bug of some sort which prevents these web browsers to start (ABORT: X_ShmPutImage).

If you encounter this issue, you may try the following as a workaround: set up a short while loop for the launch command (in /home/default/launch.sh) which executes it twice unless the program has already been started successfully. So, in my case with Pale Moon, I replace the contents of /home/default/launch.sh with the following:

#!/bin/sh

i=1
while [[ i -ge 0 ]]; do
    su browser -c "QT_X11_NO_MITSHM=1 PULSE_SERVER=unix:/run/user/host/pulse/native DISPLAY=:0 palemoon" 2>/dev/null
    if [[ $(ps -C palemoon | wc -l) -gt 2 ]]; then
        break
    fi
    let i--
done

NOTE: Executable name varies depending on your program of choice. In my case, it is palemoon, as seen in the above command.

NOTE: I don't guarantee this workaround works for you but I can say "It works for me".

In the above command, I need procps-ng package to be installed in my Arch Linux container. To do that, I simply execute the following in the main system:

sudo pacstrap -i -c ~/my-container procps-ng

Now I should be able to launch the program correctly with the command introduced in step 11, with additional Pale Moon parameters (see 'Additional Pale Moon parameters' section above).

Setting up a shortcut for the container

  1. To set up a shortcut for your container in your main system, simply create a new .desktop file (such as my-container.desktop) with the following 'Exec=' parameter (NOTE: this applies to KDE environment, use your preferred terminal emulator here):
Exec=konsole -e /home/user/launch-my-container.sh
  1. Create a new file launch-my-container.sh in the home folder of your system's current user with the contents described in step 11. Make this file as executable:
chmod +x /home/user/launch-my-container.sh

Other contents of your desktop file vary depending on your program of choice.

Controlling systemd-nspawn container resources

Please check this, this and this link for some details.


I hope this helps you a little bit in your issue. Remember to fit my instructions depending on your running system environment (do you run Ubuntu/Debian/Fedora...etc.) and program requirements.

-Fincer

<!-- gh-comment-id:375875970 --> @Fincer commented on GitHub (Mar 24, 2018): I have used [systemd-nspawn](https://wiki.archlinux.org/index.php/Systemd-nspawn) to run [Pale Moon web browser](https://en.wikipedia.org/wiki/Pale_Moon_%28web_browser%29) in a container with graphical interface (X11) + Pulseaudio enabled. Pulseaudio is needed for any web media content that have audio in it (such as Youtube videos). I have read it is possible to run graphical applications with [docker](https://stackoverflow.com/questions/25281992/alternatives-to-ssh-x11-forwarding-for-docker-containers/25334301#25334301), too. Please take also a look on [x11docker](https://github.com/mviereck/x11docker) project which claims to focus on X11 security issues and should provide a somewhat easy set-up for X11 + docker container environment. For loose reference: [Running Firefox in a systemd-nspawn container](http://dabase.com/e/12009/) You can very likely use firejail inside systemd-nspawn container so that the end-user environment is kind of having two containers stacked. I have planned to use firejail in my systemd-nspawn containers after issue [private-lib doesn't work with Palemoon & Firefox](https://github.com/netblue30/firejail/issues/1818) is fixed. Security & X11 ----------- Problem of sharing X11 environment with the host is the shared memory which, in some cases, can be a security issue. This is likely an issue with Pulseaudio, too. Setting up systemd-nspawn container + X11 application (my personal setup) ----------- I have done this on Arch Linux, so some parts are specific for that distribution. The following stuff assumes you have your main system's current user in sudo group and you have working internet connection available in the system. 1. Create a new container folder (in your home folder, for example): ``` mkdir -p ~/my-container ``` You can choose whatever path you want to. _~/my-container_ is just an example here. 2. Set up container environment by running the following in your main system (this is Arch Linux specific approach): ``` sudo pacman -S arch-install-scripts sudo pacstrap -i -c ~/my-container curl pacman coreutils systemd nano ``` 3. Login to the Arch Linux container environment: ``` sudo systemd-nspawn -b -D ~/my-container ``` 4. In container environment, login as root when login credentials are asked. 5. In this step, we request public keys of Arch Linux package maintainers and run database updates. In container environment, run: ``` pacman-key --init && pacman-key --populate archlinux pacman -Syy && pacman -Fy ``` 6. In container environment, create a new user 'default' & set home directory óf this user to /home/default: ``` useradd -d /home/default -u 1000 default mkdir -p /home/default && chown 1000:1000 /home/default ``` 7. In container environment, install your program (as root): ``` pacman -S program_name ``` 8. In container environment, add password to user 'default' and change to user 'default' shell. In default user's shell, create a new file called 'launch.sh' in his/her home directory and set it as executable: ``` passwd default su default touch /home/default/launch.sh chmod +x /home/default/launch.sh ``` The last two commands (touch & chmod) must be run as 'default' user. 9. In container environment, edit the created 'launch.sh' file as user 'default' (_nano /home/default/launch.sh_). Add the following contents in it: ``` #!/bin/sh su default -c "QT_X11_NO_MITSHM=1 PULSE_SERVER=unix:/run/user/host/pulse/native DISPLAY=:0 my_command" ``` where 'my_command' is the name of your program's executable file in container environment. If you don't use Pulseaudio in container environment, remove _PULSE_SERVER=unix:/run/user/host/pulse/native_ part. Note: any environment variables you describe in the command above depends on your set-up. If you use ALSA, for example, write a correct string for that. 10. Exit the container environment by pressing _CTRL + %_ key combination (or _CTRL + ]_ with en_US keyboard) rapidly three times sequentially. 11. Execute your program in container by running the following command in your main system: ``` sudo xhost local:root && sudo systemd-nspawn \ --bind-ro=$HOME/.Xauthority:/home/default/.Xauthority \ --bind-ro=/tmp/.X11-unix \ --bind-ro=/run/user/1000/pulse:/run/user/host/pulse \ --bind-ro=/dev/snd \ -D ~/my-container \ /home/default/launch.sh ``` The above command does as follows: - Share main system X11 environment - Initialize systemd-nspawn container - bind your main system's current user .Xauthority file to the container's default user home directory (read-only). - bind your main system's X11 sockets to the container environment (read-only) - bind your main system's Pulseaudio to the container environment (read-only) - specify container path (-D ~/my-container) - in container environment, execute _home/default/launch.sh_ (in which we have set up that our command is executed as user 'default') Additional Pale Moon parameters ----------- NOTE: bind parameters you might want to use vary, depending on the requirements for the program. For example, I have additional parameters for my 'Pale Moon' web browser environment: ``` --bind-ro=/usr/share/icons/:/usr/share/icons/ \ --bind-ro=/usr/share/themes/:/usr/share/themes/ \ --bind-ro=/usr/share/fonts/:/usr/share/fonts/ \ --bind-ro=$HOME/.gtkrc-2.0:/home/browser/.gtkrc-2.0 \ --bind=$HOME/Downloads:/home/browser/Downloads \ ``` Note that I have binded my main system's _$HOME/Downloads_ folder as writable. Some of these bindings are irrelevant if I have set up a working GTK2 environment or installed fonts/icons into the container. As I haven't installed fonts/icons in the container, I bind the ones I have in my main system. And, for example, without GTK2/icon bindings the program (Pale Moon) works but looks awful. Which systemd-nspawn bindings to use? ----------- How do you know which bindings you want to use? Check your program requirements. Does your containerized program use Qt5, GTK2 or GTK3? Does it require ALSA or Pulseaudio? Does it require some fonts installed? Does it require some icons installed? Just find out (can be tricky) and by your findings, set up your _--bind-ro_ parameters correctly to the command in step 11. Firefox/Palemoon + systemd-nspawn X11 workaround ----------- For Firefox and Pale Moon, there seems to be a bug of some sort which prevents these web browsers to start ([ABORT: X_ShmPutImage](https://bugzilla.mozilla.org/show_bug.cgi?format=default&id=1129790)). If you encounter this issue, you may try the following as a workaround: set up a short while loop for the launch command (in _/home/default/launch.sh_) which executes it twice unless the program has already been started successfully. So, in my case with Pale Moon, I replace the contents of _/home/default/launch.sh_ with the following: ``` #!/bin/sh i=1 while [[ i -ge 0 ]]; do su browser -c "QT_X11_NO_MITSHM=1 PULSE_SERVER=unix:/run/user/host/pulse/native DISPLAY=:0 palemoon" 2>/dev/null if [[ $(ps -C palemoon | wc -l) -gt 2 ]]; then break fi let i-- done ``` NOTE: Executable name varies depending on your program of choice. In my case, it is _palemoon_, as seen in the above command. NOTE: I don't guarantee this workaround works for you but I can say "It works for me". In the above command, I need _procps-ng_ package to be installed in my Arch Linux container. To do that, I simply execute the following in the main system: ``` sudo pacstrap -i -c ~/my-container procps-ng ``` Now I should be able to launch the program correctly with the command introduced in step 11, with additional Pale Moon parameters (see 'Additional Pale Moon parameters' section above). Setting up a shortcut for the container ----------- 12. To set up a shortcut for your container in your main system, simply create a new _.desktop_ file (such as my-container.desktop) with the following 'Exec=' parameter (NOTE: this applies to KDE environment, use your preferred terminal emulator here): ``` Exec=konsole -e /home/user/launch-my-container.sh ``` 13. Create a new file _launch-my-container.sh_ in the home folder of your system's current user with the contents described in step 11. Make this file as executable: ``` chmod +x /home/user/launch-my-container.sh ``` Other contents of your desktop file vary depending on your program of choice. Controlling systemd-nspawn container resources ----------- Please check [this](https://copyninja.info/blog/taming_systemd_nsapwn.html), [this](https://blog.selectel.com/systemd-containers-introduction-systemd-nspawn/) and [this link](https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html) for some details. ----------- I hope this helps you a little bit in your issue. Remember to fit my instructions depending on your running system environment (do you run Ubuntu/Debian/Fedora...etc.) and program requirements. -Fincer
Author
Owner

@punksta commented on GitHub (Mar 24, 2018):

@Fincer Thank you for such detailed answer! it's was unexpected. I'll try to follow this in free time.
For quick solution I've just set up qemu-kvm image for work environment with not trusted applications (upwork, zoom, slack, teamviewer). I can combine firejail and vm os now :). Maybe having second os on another encrypted partition is best option for that case.

<!-- gh-comment-id:375886632 --> @punksta commented on GitHub (Mar 24, 2018): @Fincer Thank you for such detailed answer! it's was unexpected. I'll try to follow this in free time. For quick solution I've just set up qemu-kvm image for work environment with not trusted applications (upwork, zoom, slack, teamviewer). I can combine firejail and vm os now :). Maybe having second os on another encrypted partition is best option for that case.
Author
Owner

@Fincer commented on GitHub (Mar 24, 2018):

You are welcome. 👍 Actually, I just had similar problem earlier in this week so the timing for your question was a fun coincidence for me.

Take your time, feel free to comment the solution as well!


Not many answers given for this issue in the internet satisfied me. Personally, either I couldn't find a proper answer which could perfectly satisfy my needs.

Therefore, as...

  1. ...I investigated the issue + found satisfying answer by myself and...

  2. ...because I see there are people who fight with the exact same issues...

...I decided to write my personal documented answer here. It's not foolproof, may have security or other issues depending on system environment but, at least, it's a good starting point and can be fine tuned afterwards.


Personally, I haven't checked the docker solution I described above, but I think it's totally worth closer look.

My starting point for the little "Create a container for Pale Moon web browser" project was my basic requirement to get rid of bulky x86_64 virtual machine environments (Oracle VirtualBox) I have set up on my main system, and to reduce RAM usage as a result.

I have also set up an encrypted Vault container (KDE) for my Pale Moon browser profile. The solution I currently use is not a good one and should be improved. I have ideas for this but just haven't tried them yet.

<!-- gh-comment-id:375888249 --> @Fincer commented on GitHub (Mar 24, 2018): You are welcome. :+1: Actually, I just had similar problem earlier in this week so the timing for your question was a fun coincidence for me. Take your time, feel free to comment the solution as well! ---------------- Not many answers given for this issue in the internet satisfied me. Personally, either I couldn't find a proper answer which could perfectly satisfy my needs. Therefore, as... 1) ...I investigated the issue + found satisfying answer by myself and... 2) ...because I see there are people who fight with the exact same issues... ...I decided to write my personal documented answer here. It's not foolproof, may have security or other issues depending on system environment but, at least, it's a good starting point and can be fine tuned afterwards. ---------------- Personally, I haven't checked the docker solution I described above, but I think it's totally worth closer look. My starting point for the little "Create a container for Pale Moon web browser" project was my basic requirement to get rid of bulky x86_64 virtual machine environments (Oracle VirtualBox) I have set up on my main system, and to reduce RAM usage as a result. I have also set up an encrypted Vault container (KDE) for my Pale Moon browser profile. The solution I currently use is not a good one and should be improved. I have ideas for this but just haven't tried them yet.
Author
Owner

@netblue30 commented on GitHub (Mar 24, 2018):

It is quite easy, you start the first application and find out on what display is running:

$ firejail --x11=xephyr transmission-qt
Reading profile /etc/firejail/Xephyr.profile
Reading profile /etc/firejail/whitelist-common.inc
Parent pid 28509, child pid 28510
Child process initialized in 34.46 ms

*** Attaching to Xephyr display 230 ***

Reading profile /home/netblue/.config/firejail/transmission-qt.profile
Reading profile /etc/firejail/transmission-qt.profile
Reading profile /etc/firejail/disable-common.inc
[...]

Then, you start all the other sandboxes using DISPLAY environment variable:

$ DISPLAY=":230" firejail xterm
[...]

If you want to verify, run "firemon --x11":

$ firemon --x11
28509:netblue::/usr/bin/firejail /usr/bin/Xephyr -ac -br -noreset -screen 800x
28526:netblue:torrent:firejail transmission-qt 
  DISPLAY :230
28693:netblue::firejail xterm 
  DISPLAY :230

So, you'll have a sandbox for each app, and another one for xephyr/xpra

<!-- gh-comment-id:375918512 --> @netblue30 commented on GitHub (Mar 24, 2018): It is quite easy, you start the first application and find out on what display is running: ````` $ firejail --x11=xephyr transmission-qt Reading profile /etc/firejail/Xephyr.profile Reading profile /etc/firejail/whitelist-common.inc Parent pid 28509, child pid 28510 Child process initialized in 34.46 ms *** Attaching to Xephyr display 230 *** Reading profile /home/netblue/.config/firejail/transmission-qt.profile Reading profile /etc/firejail/transmission-qt.profile Reading profile /etc/firejail/disable-common.inc [...] ````` Then, you start all the other sandboxes using DISPLAY environment variable: ````` $ DISPLAY=":230" firejail xterm [...] ````` If you want to verify, run "firemon --x11": ````` $ firemon --x11 28509:netblue::/usr/bin/firejail /usr/bin/Xephyr -ac -br -noreset -screen 800x 28526:netblue:torrent:firejail transmission-qt DISPLAY :230 28693:netblue::firejail xterm DISPLAY :230 ````` So, you'll have a sandbox for each app, and another one for xephyr/xpra
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/firejail#1240
No description provided.