[GH-ISSUE #3840] Temporary private home directory based on template where changes are discarded? #2417

Open
opened 2026-05-05 09:05:38 -06:00 by gitea-mirror · 7 comments
Owner

Originally created by @faern on GitHub (Dec 19, 2020).
Original GitHub issue: https://github.com/netblue30/firejail/issues/3840

Maybe this is already supported with some combination of settings I have not yet figured out.

Use case: I want to create "disposable" firefox instances that are as isolated from the rest of the system as possible and from other instances of jails of the same type. And on exit I want everything done in that jail to be discarded/deleted. Sounds like --private, I know. But I don't want my jail to start off on a completely clean slate. I want to base it off a known good setup (.mozilla etc.) I have with add-ons and all. The use case is kind of how DisposableVMs work in Qubes-OS: https://www.qubes-os.org/doc/disposablevm/.

--private=jails/firefox-disposable will not work since everything the jail does is persisted in this separate home directory. I need a combination of --private and --private=<path>.

I currently solve this by having a script that creates a temporary directory, copies my "home template" over, runs the jail from there and deletes it on exit. But it would be waaay cleaner if firejail did this internally. It already has awesome support for overlayfs and other types of re-mounting. So everything to support it is there already as I understand it.

Current workaround: The script I'm currently solving my use case with:

#!/usr/bin/env bash
set -eu

tmp_home=$(mktemp -dt firefox-disposable-XXXXXXX)
echo "Starting disposable firefox with HOME=$tmp_home"

cp -r $HOME/firejails/firefox-disposable/. "$tmp_home"/

function delete_tmp_home() {
    rm -rf "$tmp_home"
}
trap 'delete_tmp_home' EXIT

firejail \
    --profile=firefox-disposable \
    --private="$tmp_home" \
    --netns=vpn \
    --name=$(basename $tmp_home) \
    firefox --no-remote

I would much rather do something like:

firejail --private-template=$HOME/firejails/firefox-disposable firefox --no-remote

Where --private-template=directory would mean:

Same as --private but the temporary filesystem mounted at /home/user will be based off of the content in <directory>.

Originally created by @faern on GitHub (Dec 19, 2020). Original GitHub issue: https://github.com/netblue30/firejail/issues/3840 Maybe this is already supported with some combination of settings I have not yet figured out. **Use case:** I want to create "disposable" firefox instances that are as isolated from the rest of the system as possible and from other instances of jails of the same type. And on exit I want everything done in that jail to be discarded/deleted. Sounds like `--private`, I know. But I don't want my jail to start off on a completely clean slate. I want to base it off a known good setup (`.mozilla` etc.) I have with add-ons and all. The use case is kind of how DisposableVMs work in Qubes-OS: https://www.qubes-os.org/doc/disposablevm/. `--private=jails/firefox-disposable` will not work since everything the jail does is persisted in this separate home directory. I need a combination of `--private` and `--private=<path>`. I currently solve this by having a script that creates a temporary directory, copies my "home template" over, runs the jail from there and deletes it on exit. But it would be waaay cleaner if firejail did this internally. It already has awesome support for overlayfs and other types of re-mounting. So everything to support it is there already as I understand it. **Current workaround:** The script I'm currently solving my use case with: ```bash #!/usr/bin/env bash set -eu tmp_home=$(mktemp -dt firefox-disposable-XXXXXXX) echo "Starting disposable firefox with HOME=$tmp_home" cp -r $HOME/firejails/firefox-disposable/. "$tmp_home"/ function delete_tmp_home() { rm -rf "$tmp_home" } trap 'delete_tmp_home' EXIT firejail \ --profile=firefox-disposable \ --private="$tmp_home" \ --netns=vpn \ --name=$(basename $tmp_home) \ firefox --no-remote ``` I would much rather do something like: ```bash firejail --private-template=$HOME/firejails/firefox-disposable firefox --no-remote ``` Where `--private-template=directory` would mean: > Same as `--private` but the temporary filesystem mounted at /home/user will be based off of the content in `<directory>`.
gitea-mirror added the
enhancement
label 2026-05-05 09:05:38 -06:00
Author
Owner

@faern commented on GitHub (Dec 19, 2020):

For a little while I thought I had found the solution in --private=directory --overlay-tmpfs. But these flags don't seem compatible with each other. As soon as I add --overlay-tmpfs the --private=directory is ignored and I can see my full normal home directory from inside the jail.

<!-- gh-comment-id:748539136 --> @faern commented on GitHub (Dec 19, 2020): For a little while I thought I had found the solution in `--private=directory --overlay-tmpfs`. But these flags don't seem compatible with each other. As soon as I add `--overlay-tmpfs` the `--private=directory` is ignored and I can see my full normal home directory from inside the jail.
Author
Owner

@ghost commented on GitHub (Dec 19, 2020):

Have you played with the private-home option yet? Quoting verbatim from the man:

--private-home=file,directory
    Build a new user home in a temporary filesystem, and copy the files and directories
    in the list in the new home. The files and directories in the list must be expressed as
    relative to the current user's home directory. All modifications are discarded when
    the sandbox is closed.

    Example:
    $ firejail --private-home=.mozilla firefox

On a side-note regarding your script, recent firejail versions support referring to a profile with the app-name only. So a line like

--profile=$HOME/.config/firejail/firefox-disposable.profile \

can be simplified to

--profile=firefox-disposable \

<!-- gh-comment-id:748540764 --> @ghost commented on GitHub (Dec 19, 2020): Have you played with the `private-home` option yet? Quoting verbatim from the man: ``` --private-home=file,directory Build a new user home in a temporary filesystem, and copy the files and directories in the list in the new home. The files and directories in the list must be expressed as relative to the current user's home directory. All modifications are discarded when the sandbox is closed. Example: $ firejail --private-home=.mozilla firefox ``` On a side-note regarding your script, recent firejail versions support referring to a profile with the app-name only. So a line like --profile=$HOME/.config/firejail/firefox-disposable.profile \ can be simplified to --profile=firefox-disposable \
Author
Owner

@reinerh commented on GitHub (Dec 19, 2020):

Maybe --tmpfs=dirname? In firejail-git this is allowed for non-root users inside their home directories.

<!-- gh-comment-id:748540857 --> @reinerh commented on GitHub (Dec 19, 2020): Maybe `--tmpfs=dirname`? In firejail-git this is allowed for non-root users inside their home directories.
Author
Owner

@faern commented on GitHub (Dec 20, 2020):

--private-home=firejails/firefox-disposable errors with Error: only top files and directories in user home are allowed. I can do --private-home=firejails and end up with a new temporary home with only firejails/. Maybe I can move stuff around and just have ~/.mozilla.disposable, --private-home that dir and give firefox some flags to use it instead? But it feels like a suboptimal and more error-prone way than just giving the jail a full home dir with correctly named content to isolate itself in.

It feels like the help text for --private-home can be improved. Because it does not copy arbitrary files to the new home. If it was expressed as "Creates a new temporary home based on a subset of the current user's home" or something along those lines it would better showcase the intended usage? When I read "expressed as relative to the current user's home" I hesitate and kind of assume that ../another_user would work, since that's technically a relative path from my home ;)

For --tmpfs=dirname I don't really understand at all what it does. When I use --tmpfs=a_dir_with_files I end up in an empty jail. Not sure how to proceed. Great that the root requirement is fixed. But I still don't get how it works yet :)

@glitsj16 Thanks for the hint on --profile. I think I was using it as --profile=firefox-disposable.profile before and that's why it did not work for me and I switched to the full path.

<!-- gh-comment-id:748566588 --> @faern commented on GitHub (Dec 20, 2020): `--private-home=firejails/firefox-disposable` errors with `Error: only top files and directories in user home are allowed`. I can do `--private-home=firejails` and end up with a new temporary home with only `firejails/`. Maybe I can move stuff around and just have `~/.mozilla.disposable`, `--private-home` that dir and give firefox some flags to use it instead? But it feels like a suboptimal and more error-prone way than just giving the jail a full home dir with correctly named content to isolate itself in. It feels like the help text for `--private-home` can be improved. Because it does not copy arbitrary files to the new home. If it was expressed as "Creates a new temporary home based on a subset of the current user's home" or something along those lines it would better showcase the intended usage? When I read "expressed as relative to the current user's home" I hesitate and kind of assume that `../another_user` would work, since that's technically a relative path from my home ;) For `--tmpfs=dirname` I don't really understand at all what it does. When I use `--tmpfs=a_dir_with_files` I end up in an empty jail. Not sure how to proceed. Great that the root requirement is fixed. But I still don't get how it works yet :) @glitsj16 Thanks for the hint on `--profile`. I think I was using it as `--profile=firefox-disposable.profile` before and that's why it did not work for me and I switched to the full path.
Author
Owner

@faern commented on GitHub (Dec 20, 2020):

Ok. --tmpfs needs an absolute path. But it does not print any type of error if I give it a ralative path.

Anyway. I can't seem to combine --tmpfs=directory with --private=directory in a way that does what I want anyway.

sudo firejail --noprofile --tmpfs=/home/faern/firejails/test --private=/home/faern/firejails/test

I end up in a jail locked into the test dir. So far so good. But all changes to that dir are still persisted. For any other value I try to pass to --tmpfs I end up in other strange states.

<!-- gh-comment-id:748567617 --> @faern commented on GitHub (Dec 20, 2020): Ok. `--tmpfs` needs an **absolute path**. But it does not print any type of error if I give it a ralative path. Anyway. I can't seem to combine `--tmpfs=directory` with `--private=directory` in a way that does what I want anyway. ``` sudo firejail --noprofile --tmpfs=/home/faern/firejails/test --private=/home/faern/firejails/test ``` I end up in a jail locked into the test dir. So far so good. But all changes to that dir are still persisted. For any other value I try to pass to `--tmpfs` I end up in other strange states.
Author
Owner

@rusty-snake commented on GitHub (Dec 20, 2020):

Does --chroot=foo --overlay-tmpfs work?

<!-- gh-comment-id:748581569 --> @rusty-snake commented on GitHub (Dec 20, 2020): Does `--chroot=foo --overlay-tmpfs` work?
Author
Owner

@faern commented on GitHub (Dec 20, 2020):

Does --chroot=foo --overlay-tmpfs work?

Nope. I get Error: --overlay and --chroot options are mutually exclusive (with firejail 0.9.62 this time, because I changed to an older computer now. Not sure if this has changed. All earlier posts from me was using version 0.9.64).

<!-- gh-comment-id:748588511 --> @faern commented on GitHub (Dec 20, 2020): > Does `--chroot=foo --overlay-tmpfs` work? Nope. I get `Error: --overlay and --chroot options are mutually exclusive` (with firejail 0.9.62 this time, because I changed to an older computer now. Not sure if this has changed. All earlier posts from me was using version 0.9.64).
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#2417
No description provided.