Harden & secure browsers in containers, with GUI

I made a few Podman/ Docker images for different browsers and OS-es, so I can safely run different browsers in a secure sandbox.

Why

  • for safer internet surfing
  • for testing different configurations in different operating systems and browsers
  • for inspecting and isolating the network traffic of a specific browser
  • for organizing different projects that you run, by keeping different isolated profiles, with different credentials, bookmarks, navigation history
  • browsers are not as secure as they can be out of the box, so keeping them in isolated containers with limited access is a great way of minimising the potential attack surface
  • this won’t keep you safe from improper browser configuration
  • this won’t keep you safe from malicious browser addons

How

I made a repository of different configurations that I tried. To run them, you need either Podman, or Docker, and you just choose one of the images.
The repository is: https://github.com/croqaz/browsers

Once the browser is installed as root, it is launched by a regular non-root user, and the running container doesn’t have any special, or elevated permissions.
The browser will show up as a regular GUI window and you can use it just like normal.

For example, to launch the Firefox on Fedora configuration with Podman, you have to run:

# xhost is an app from xorg-xhost
# this is needed so you can launch the browser in a GUI
xhost +local:$HOST

podman pull docker.io/fedora
podman build -t ff-fedora -f Dockerfile-ff-fedora

# you have to mount the .Xauthority and .X11-unix files in the container to connect to the GUI server
# you have to mount a local folder in the container to keep the Firefox profile persistent between different browsing sessions
podman run -it --rm -e DISPLAY -v $XAUTHORITY:/home/.Xauthority:ro -v /tmp/.X11-unix/:/tmp/.X11-unix:ro -v $HOME/VOLUMES/ff-fedora:/home/.mozilla:U ff-fedora

In this example, the Firefox profile will be stored in $HOME/VOLUMES/ff-fedora, so you can backup it if you want and re-use it on other computers as well.

To launch the Chromium on Arch configuration, you have to run:

# needed to launch the browser in a GUI
xhost +local:$HOST

podman pull docker.io/archlinux
podman build -t chrom-arch -f Dockerfile-chrom-arch

podman run -it --rm -e DISPLAY -v $XAUTHORITY:/home/.Xauthority:ro -v /tmp/.X11-unix/:/tmp/.X11-unix:ro -v $HOME/VOLUMES/chrom-arch:/home/.config/chromium:U chrom-arch

In this example, the Chromium profile will be stored in $HOME/VOLUMES/chrom-arch; of course, you can change it.

To launch the Brave browser on Arch, you have to run:

# needed to launch the browser in a GUI
xhost +local:$HOST

podman pull docker.io/archlinux
podman build -t brave-arch -f Dockerfile-brave-arch

podman run -it --rm -e DISPLAY -v $XAUTHORITY:/home/.Xauthority:ro -v /tmp/.X11-unix/:/tmp/.X11-unix:ro -v $HOME/VOLUMES/brave-arch:/home/.config/BraveSoftware/Brave-Browser-Beta:U brave-arch

In this example, the Brave profile will be stored in $HOME/VOLUMES/brave-arch.
I added some flags when launching Chromium & Brave, which I think are useful and make the browser more secure, but feel free to tweak them:
https://github.com/croqaz/browsers/blob/00c9f5d38d8a68e669b5b294fa53b2209e4d421f/Dockerfile-brave-arch#L37-L48

I usually also mount a shared folder in the container, so I can move files between the isolated running browser, and the host machine.
For example, I mount the $HOME/Documents/shared-ff/ folder and I add some documents, or images that I want to use in a specific browser.

Issues

I didn’t find a good way to make a common shared folder for all the running containers, because regular users can’t write in root-owned folders, and the folders are mounted as root by default, unless you add the :U flag at the end of the volume, which changes the permissions of the host folder, but once you launch another container the permissions are changed again, which breaks the access for the previous users. Anyway, it’s not a big problem.

There are other small-ish issues like: emojis don’t really show in some cases, because the container doesn’t have enough fonts installed.
Some websites may not have audio, or video, depending on the codecs installed by default in the container.
The browser may not have the full capabilities of a regular browser, eg: may not detect USB devices (webcams, microphones, YubiKeys, etc), or printers.
All of these can be fixed with more tweaks either when building the image, or when launching it.

Ideas

I want to add a few more features in the containers, before I think they’re ready:


I hope you like it and you find it useful!

@notes #browser