Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add encrypted 'home' support #37

Open
donob4n opened this issue Jun 8, 2022 · 32 comments
Open

Add encrypted 'home' support #37

donob4n opened this issue Jun 8, 2022 · 32 comments
Labels
enhancement New feature or request

Comments

@donob4n
Copy link

donob4n commented Jun 8, 2022

Description

Hi, I'm currently using 'gocryptfs' and I feel that it could be nicely integrated into bubblejail, specially for automatically umount it after closing the sandbox (maybe it could auto close due inactivty?).

I open this issue for share some comments about it. I would like to do some draft for gocrypts having in mind that I should be easily integrated with other alternatives.

Gocrypts (and most encrypt fs) uses a folder for save the data encrypted, so it could just be saved on '~/.local/share/bubblejail/instances/instance/secret' and then mounted on its respective 'home'.

@igo95862
Copy link
Owner

igo95862 commented Jun 8, 2022

Hello.

What do you think the UI/UX would be?

If a user tries to run the instance that has an encrypted home they should be prompted a password entry?

Or should the password be stored somewhere? Kind of not very useful if the password would be stored in the instance configuration directory.

There is actually a freedesktop-secrets API that can be used to securely store passwords. It can be implemented to store the directories keys. I made the binds for it with my D-Bus library that I plan to integrate but I have heard that Alpine Linux does not like D-Bus.

I had an idea of some generic mechanism of instance home preprocessors. For example, creating a BtrFs subvolme.

@igo95862
Copy link
Owner

igo95862 commented Jun 8, 2022

BTW there is Open a blank issue. option when creating a new issue but it is kind of small and hard to notice so I guess I will add a template Suggestion/Idea

@igo95862
Copy link
Owner

igo95862 commented Jun 8, 2022

Keepassxc implemented the secrets API in 2.5.0: https://keepassxc.org/blog/2019-10-26-2.5.0-released/

(so it is not GNOME/KDE specific)

@donob4n
Copy link
Author

donob4n commented Jun 8, 2022

Hello.

What do you think the UI/UX would be?

If a user tries to run the instance that has an encrypted home they should be prompted a password entry?

On creation the instance should be flagged as 'encrypted' and the password prompted for initalization. Then, on run it should check the 'encrypted' option and handle the mounting/unmounting before/after launching bwrap.

Or should the password be stored somewhere? Kind of not very useful if the password would be stored in the instance configuration directory.

There is actually a freedesktop-secrets API that can be used to securely store passwords. It can be implemented to store the directories keys. I made the binds for it with my D-Bus library that I plan to integrate but I have heard that Alpine Linux does not like D-Bus.

I think that there are two use cases for this. The first is having a last security layer in case the whole system gets compromised or stolen while it's unlocked. So having the encrypted sandbox stopped and unlock password saved outside seems mandatory.

The other use case is a secure way for share/backup some folder in public clouds like dropbox. In this scenario running it 24h or having a passworldess start seems ok.

I had an idea of some generic mechanism of instance home preprocessors. For example, creating a BtrFs subvolme.

I think that it would be nice, and probably very easy to achieve with it. But for some users maybe a more clearly UI just for encryption it's nice.

@igo95862 igo95862 added the enhancement New feature or request label Jun 8, 2022
@igo95862
Copy link
Owner

igo95862 commented Jun 8, 2022

On creation the instance should be flagged as 'encrypted' and the password prompted for initalization.

It is possible. There is even python module to enter passwords: https://docs.python.org/3/library/getpass.html#getpass.getpass

The other use case is a secure way for share/backup some folder in public clouds like dropbox. In this scenario running it 24h or having a passworldess start seems ok.

To be honest this sounds like something backup script or software should be taking care of. There are instruction on how to run gocryptfs in reverse mode: https://wiki.archlinux.org/title/Gocryptfs#Example_using_reverse_mode

But for some users maybe a more clearly UI just for encryption it's nice.

This is what secrets API should be taking care of. Unless you think there should be another Qt application that should come with bubblejail which should popup when asks for password. But that would be very difficult to implement and maintain.

@donob4n
Copy link
Author

donob4n commented Jun 8, 2022

The other use case is a secure way for share/backup some folder in public clouds like dropbox. In this scenario running it 24h or having a passworldess start seems ok.

To be honest this sounds like something backup script or software should be taking care of. There are instruction on how to run gocryptfs in reverse mode: https://wiki.archlinux.org/title/Gocryptfs#Example_using_reverse_mode

Yes, reverse mode has more sense in this scenario. Maybe it could be seen as a different bubblejail freature (remote backup?). I'm really only interested on extra protection for sensitive data, so asking for the password on each run seems better.

Maybe it's out of bubblejail scope but would be nice that it notifies if some process outside the sandbox tries to read/write something. It will probably need root permissions.

But for some users maybe a more clearly UI just for encryption it's nice.

This is what secrets API should be taking care of. Unless you think there should be another Qt application that should come with bubblejail which should popup when asks for password. But that would be very difficult to implement and maintain.

I would try to do a first draft without secrets/password storage.

@igo95862
Copy link
Owner

@donob4n I created 11a886c in the branch gocryptfs-test

It is a very rough draft. The command line arguments are not final.

Creating instance with gocryptfs home directory:

create --profile generic --no-desktop-entry --home-plugin gocryptfs_home -- test

The gocryptfs will ask for password to create a new encrypted dir.

Running it:

bubblejail run test chromium

You can only run it from terminal currently because it depends on gocryptfs asking for password. In release version it definitely will need D-Bus Secrets API.

@Nonie689
Copy link

Nonie689 commented Jun 22, 2022

If you use ext4 you can use a transparent encryption [folder-only-encrpytion] with a custom pass for every folder in the ext4 system.

I wouldn't recomment gocryptfs!!!

But I am not sure, if this work if you use the systemd-homed encrypted by ext4 plus the subfolder encryption by ext4! But you could add a ext4 filesystem and mount them in the:

~/.local/share/bubblejail/instances/

and add then for every instances an custom password!

@donob4n
Copy link
Author

donob4n commented Jun 26, 2022

@donob4n I created 11a886c in the branch gocryptfs-test

It is a very rough draft. The command line arguments are not final.
...
Running it:

bubblejail run test chromium

Wow I just tested it and looks great.

You can only run it from terminal currently because it depends on gocryptfs asking for password. In release version it definitely will need D-Bus Secrets API.

Well, probably is the best option for normal users (maybe the more pytonic way too?), but as an intent of minimalist user I like pinentry[1] concept wich has gtk and qt backends and even a dmenu. It also has at least one python package[2].

It looks that using -extpass CMD gocrypts should call pinentry easily. So it doesn't require even python handling of it.

[1] - https://www.gnupg.org/related_software/pinentry/index.html
[2] - https://pypi.org/project/pynentry/

@donob4n
Copy link
Author

donob4n commented Jun 26, 2022

If you use ext4 you can use a transparent encryption [folder-only-encrpytion] with a custom pass for every folder in the ext4 system.

Well, I'm currently using btrfs and also feel that this option would loose some portability.

I wouldn't recomment gocryptfs!!!

Probably this is not the best place for discussing this but if you have some sources supporting it I will take a look.

@igo95862
Copy link
Owner

It looks that using -extpass CMD gocrypts should call pinentry easily. So it doesn't require even python handling of it

Good find.

Should be pretty simple to implement.

@donob4n
Copy link
Author

donob4n commented Jun 26, 2022

Well, pinentry process options or commands from STDIN. So an basic execution for a 'foo' password looks like:

echo "GETPIN" | pinentry

OK pinentry-bemenu 0.9.0
D foo
OK

So maybe passing it to sed (I'm trying but I haven't got it yet), or maybe handling the stdout with python.

EDIT:
I get this working:
echo "GETPIN" | pinentry | sed -nr '/^D (.+)/s//\1/p'
But not sure how to pass to subprocess.call, maybe gocryptfs doesn't support a shell command and needs to wrapper it on a script.

@donob4n
Copy link
Author

donob4n commented Jun 26, 2022

It seems that others instances fail due missing home_plugins dir:

FileNotFoundError: [Errno 2] No such file or directory: '/home/donoban/.local/share/bubblejail/instances/..../home_plugins

@igo95862
Copy link
Owner

It seems that others instances fail due missing home_plugins dir:

FileNotFoundError: [Errno 2] No such file or directory: '/home/donoban/.local/share/bubblejail/instances/..../home_plugins

Do you have entire stack trace?

@donob4n
Copy link
Author

donob4n commented Jun 26, 2022

It seems that others instances fail due missing home_plugins dir:
FileNotFoundError: [Errno 2] No such file or directory: '/home/donoban/.local/share/bubblejail/instances/..../home_plugins

Do you have entire stack trace?


Traceback (most recent call last):
  File "/usr/bin/bubblejail", line 14, in <module>
    bubblejail_main()
  File "/usr/lib/python3.10/site-packages/bubblejail/bubblejail_cli.py", line 418, in bubblejail_main
    args.func(args)
  File "/usr/lib/python3.10/site-packages/bubblejail/bubblejail_cli.py", line 125, in run_bjail
    run_instace(
  File "/usr/lib/python3.10/site-packages/bubblejail/bubblejail_cli.py", line 109, in run_instace
    async_run(
  File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
    return future.result()
  File "/usr/lib/python3.10/site-packages/bubblejail/bubblejail_instance.py", line 265, in async_run_init
    async with init:
  File "/usr/lib/python3.10/site-packages/bubblejail/bubblejail_instance.py", line 544, in __aenter__
    for plugin_path in self.plugins_dir.iterdir():
  File "/usr/lib/python3.10/pathlib.py", line 1017, in iterdir
    for name in self._accessor.listdir(self):
FileNotFoundError: [Errno 2] No such file or directory: '/home/donoban/.local/share/bubblejail/instances/....../home_plugins'

@igo95862
Copy link
Owner

I forgot that old instances are not going to have home_plugins. Looks trivial to fix.

@igo95862
Copy link
Owner

@Nonie689
Copy link

Nonie689 commented Aug 5, 2022

If you use ext4 you can use a transparent encryption [folder-only-encrpytion] with a custom pass for every folder in the ext4 system.

Well, I'm currently using btrfs and also feel that this option would loose some portability.

I wouldn't recomment gocryptfs!!!

Probably this is not the best place for discussing this but if you have some sources supporting it I will take a look.

Here is an tutorial...

https://wiki.gentoo.org/wiki/Ext4_encryption

@jim3692
Copy link

jim3692 commented Jul 8, 2024

Hello all.

I just came to this issue as I would like to lock some apps on my system.

If I understood the patch correctly, it mounts the encrypted filesystem on the host and then binds it to bubblejail instance. This makes the files available to all the processes of the user, until the instance is closed.

I was wondering whether it's possible to mount the encrypted filesystem directly inside the bubblewrap's mount namespace, hiding it from the host system.

I will do some more research and I will post back.

@igo95862
Copy link
Owner

igo95862 commented Jul 8, 2024

Do you mean something like a FUSE filesystem? Probably possible but I have not experimented with it.

@rusty-snake
Copy link
Contributor

I was wondering whether it's possible to mount the encrypted filesystem directly inside the bubblewrap's mount namespace, hiding it from the host system.

You seem to have a misunderstanding about bubblewraps security model.

  • The host it privileged, the child is unprivileged
  • The security boundary is oneway
  • ==> Everything inside from bubblewrap is accessible/controllable from the host.
  • In fact bubblewrap weaks the isolation in the host->child direction.
    $ sleep 1m &
    $ gdb -p $(pidof sleep)
    ptrace: Operation not permitted.
    $ bwrap --dev-bind / / sleep 1m &
    $ gdb -p $(pidof sleep)
    successfully attached
  • The mountnamespace can be inspected from /proc/<pid>/root or just by joining it.

@jim3692
Copy link

jim3692 commented Jul 9, 2024

I hadn't realized that /proc/$pid/root is accessible by anyone.

I was only aware of nsenter requiring sudo and thought this idea is secure.

Back to the drawing board...

@igo95862
Copy link
Owner

igo95862 commented Jul 9, 2024

nsenter does not require sudo unless your kernel has unpriviledged user namespaces disables.

@jim3692
Copy link

jim3692 commented Jul 9, 2024

My kernel (linux-zen on Arch) has unprivileged namespaces enabled (CONFIG_USER_NS_UNPRIVILEGED=y), but I need sudo to enter the mount namespace of a bubblejailed app.

$ nsenter --mount=/proc/<pid from bubblejailed app>/ns/mnt bash
> nsenter: reassociate to namespace 'ns/mnt' failed: Operation not permitted

$ sudo nsenter --mount=/proc/<pid from bubblejailed app>/ns/mnt bash
> [root@arch /]#

@igo95862
Copy link
Owner

igo95862 commented Jul 9, 2024

If you use --user-parent option that I added to nsenter you can easily enter bubblejail namespaces:

nsenter --preserve-credentials --user-parent --mount --target <pid of sandboxed app>

When --dev option is used with bwrap it will create an intermediate user namespace only accessible with ioctl. The --user-parent option will fetch the parent user namespace from the mount namespace and enter it before entering the mount namespace.

The reason the root works is probably because it holds the CAP_SYS_ADMIN for all descendant namespaces.

@jim3692
Copy link

jim3692 commented Jul 9, 2024

Thank you for the explanation on nsenter.

As it turns out, namespaces may not be a good option for implementing encryption at runtime.

So, I came up with a completely different, hacky, solution.

I remembered how proot works. It overrides syscalls via LD_PRELOAD.

My idea is to override the filesystem related calls (stat, open, etc.) and handle the encryption and decryption at the application level, without actually mounting anything.

Since, this will override the syscalls, instead of mounting an encrypted filesystem, there will be no way for other programs to read the raw files.

This certainly complicates things a lot and seems very difficult to maintain and secure.

@rusty-snake
Copy link
Contributor

It overrides syscalls via LD_PRELOAD.

LD_PRELOAD overrides library functions not syscalls. Programs calling the raw syscalls will break.

Since, this will override the syscalls, instead of mounting an encrypted filesystem, there will be no way for other programs to read the raw files.

Read my comment above regarding security model again. The child is less privileged. You can easily ptrace or whatever it.

In order to protect a process from other processes you either have to move the process you want to protect upwards / sidewards or move all processes from whom you want to protect downwards. You can not move a process downwards to secure it. Moving downwards secures everything from it.
In practice this means you have to switch to a different UID.

@jim3692
Copy link

jim3692 commented Jul 9, 2024

Sorry @rusty-snake, at first I hadn't fully understood your security model comment. Now I get it.

Also, I made a mistake. proot is based on ptrace, not LD_PRELOAD. Source: https://github.com/proot-me/proot/blob/master/doc/proot/manual.rst#description

In practice this means you have to switch to a different UID.

So, the only solution is to daemonize bubblejail as root (or make it setuid) and have it execute the jails as different UID, on the X/Wayland session of the current user?

@rusty-snake
Copy link
Contributor

Your welcome.

to daemonize bubblejail as root (or make it setuid) and have it execute the jails as different UID

Simplified yes. uid switching can be implemented in several ways

So, the only solution is to

SELinux would also be an solution I think. But much more complicated and not supported everywhere.

X

Lets programs control other programs.

@igo95862
Copy link
Owner

igo95862 commented Jul 9, 2024

Not entirely sure from what you are trying to encrypt files from. Is it against other sandboxes or your user overall?

@jim3692
Copy link

jim3692 commented Jul 9, 2024

Not entirely sure from what you are trying to encrypt files from. Is it against other sandboxes or your user overall?

There are apps, holding private data, that allow their home data to be copied and used in another machine without any additional steps. I do not know if I am allowed to publicly disclose the names of those apps.

On top of that, some online games are known to have RCE vulnerabilities, allowing attackers to get access to that data.

I am trying to understand what is the best approach to protect apps, with sensitive data, from anything that may be running on a user level.

But it's probably easier to just sandbox the games, and not the sensitive apps. The other way around seemed easier to configure, as I know which apps hold sensitive data, but I cannot be sure about all of the vulnerable software on my PC.

@igo95862
Copy link
Owner

igo95862 commented Jul 9, 2024

Yes, you should sandbox the less trusted applications like games or web browsers. The descendant namespaces cannot join parent namespaces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants