netblue30 / firejail

Linux namespaces and seccomp-bpf sandbox
https://firejail.wordpress.com
GNU General Public License v2.0
5.8k stars 567 forks source link

how to blacklist everything? #354

Closed gthreepw00d closed 8 years ago

gthreepw00d commented 8 years ago

Here is what I've tried so far: firejail --noprofile --noroot --blacklist=/ --debug-blacklists --debug-whitelists

Parent pid 28914, child pid 28915 Disable /etc/firejail Disable / Disable /sys/firmware Disable /sys/hypervisor Disable /sys/fs Disable /sys/module Disable /sys/power Disable /proc/kcore Disable /proc/kallsyms Disable /boot Disable /dev/port Disable /dev/kmsg Disable /proc/kmsg

Error: cannot mount a new user namespace unshare: Operation not permitted Error: cannot write to /proc/28915/uid_map: Operation not permitted Error: cannot establish communication with the parent, exiting...

No access to /proc? Ok. firejail --noprofile --noroot --blacklist=/ --whitelist=/proc --debug-blacklists --debug-whitelists

Parent pid 28928, child pid 28929 Disable /etc/firejail Error: invalid whitelist path /proc Error: cannot establish communication with the parent, exiting...

No success. Also it makes difference without --noroot: firejail --noprofile --blacklist=/ --debug-blacklists --debug-whitelists

Parent pid 29616, child pid 29617 Disable /etc/firejail Disable / Disable /sys/firmware Disable /sys/hypervisor Disable /sys/fs Disable /sys/module Disable /sys/power Disable /proc/kcore Disable /proc/kallsyms Disable /boot Disable /dev/port Disable /dev/kmsg Disable /proc/kmsg

Child process initialized

Jail is up, but / is fully accessible.

chiraag-nataraj commented 8 years ago

The reason --whitelist=/proc doesn't work is that, per the man page,

--whitelist=dirname_or_filename
       Whitelist directory or file. This feature is implemented only for user home, /dev,  /media,  /opt,  /var,
       and /tmp directories.

What exactly are you trying to blacklist? You can't completely block everything otherwise firefox itself wouldn't be able to start (the binary wouldn't be accessible in the new namespace). Until there are more "private-" options introduced, this is what I'm using:

# Blacklist/Whitelist

blacklist /usr/local/bin
blacklist /usr/local/sbin

whitelist ${HOME}/.mozilla
whitelist ${HOME}/Downloads/
whitelist ${HOME}/.pulse/
whitelist ${HOME}/.config/pulse/
whitelist ${HOME}/.config/gtk-3.0/
whitelist ${HOME}/.config/google-googletalkplugin/
whitelist ${HOME}/.gtkrc-2.0
whitelist ${HOME}/.gtkrc.mine
whitelist ${HOME}/.Xauthority
whitelist ${HOME}/PDF/

# Private directories

private-bin firefox.real,firefox,which,sh
private-etc hosts,passwd,mime.types,fonts/,mailcap,iceweasel/,xdg/,gtk-3.0/,resolv.conf,X11/,pulse/,adobe/,gcrypt/,alternatives/
private-tmp

# Miscellaneous options

shell none
seccomp
noroot
caps.drop all
protocol unix,inet,inet6

Note also that Firefox needs access to /etc/passwd because it also sets up its own sandbox. There are some system files that you basically can't prevent it from accessing without breaking it.

You can, of course, modify the blacklist and whitelist accordingly. I honestly think blocking almost all binaries (as I have done above) along with a tmpfs for home prevents a lot of attacks that would otherwise damage your personal data. Using private-etc and private-bin (and private-lib in git) will also prevent many, many attacks from actually being able to take place. Again, though, note that firefox needs access to certain files in /etc and certain binaries and libraries to function.

netblue30 commented 8 years ago

--blacklist=/

This will never work, you need a file system in order to run. Your programs are in the file system.

gthreepw00d commented 8 years ago

chiraag-nataraj And what about mounted flash disk with private data? What I'm trying to achieve is configuration where everything is blacklisted but some explicitly configured items. I don't like current approach, it's like firewall with everything allowed by default and specific rules to drop connections to opened ports. New service - new another rule required. Analogy with filesystem: new mount point with private data - another change to firejail profiles required.

the8472 commented 8 years ago

what you probably want is to chroot to some tmpfs and selectively bind-mount a few needed files/directories into it.

chiraag-nataraj commented 8 years ago

@gthreepw00d You could just blacklist all of the other system folders (such as /boot, /media, /mnt/, etc.). Again, you have to take care not to blacklist folders Firefox needs to function.

the8472 commented 8 years ago

@chiraag-nataraj, manually blacklisting top level folders is not really portable since different systems may have different top level folders.

e.g. zfs on linux puts zfs mounts on the top level by default, based on the pool name, which may be different for everyone. so if you have your private data on a zfs mount and trusted an application profile it might leave all that exposed to the jailed process.

whitelists are less brittle from a security perspective even though they're more fault-prone in that they may break the application on a different system.

chiraag-nataraj commented 8 years ago

@the8472 That's probably why the default profiles don't do anything like that. If you're using a profile someone else gave you, I would think you'd look at it first and change anything that needs to be changed. But yes, whitelists are usually better than blacklists in terms of security.

the8472 commented 8 years ago

I guess one of the problems is that --whitelist only works with a select few folders. It's not powerful enough to create a new / from scratch and then pivot_root into it generally would be preferable.

The bug title probably should be "whitelist is not flexible enough" instead of "blacklist everything"

netblue30 commented 8 years ago

I think you can look at --chroot command line option. You bring in your file system on a USB driver, mount it and run "firejail --chroot=mount-point".

msva commented 8 years ago

@netblue30, I think, OP wants something similar to that I talked about: something, that can be described like "block absolutely everything, then manually allow access to selected paths". And, ideally, without creating rootfs template for each jail, but whitelist all the neded paths on "real" rootfs ☺

Although, in my case it would also be nice to store changes made to some of "tmpfs" paths in the jail (say, you whitelisted ~/Downloads, and created ~/Documents inside jail, and you want it to be persistent between jail runs, but you do not want it to present as ~/Documents outside the jail)

netblue30 commented 8 years ago

In the next version I'll add support to move files between host system and sandbox. For example you run "firejail --private" (this places a tmpfs on top of your home directory), you download a file, and before you shut down the sandbox, copy the file out from the temporary filesystem, so you don't loose it.

allo- commented 7 years ago

@chiraag-nataraj: Why is it limited to these folders? I have a mountpoint at /foo and cannot use whitelist with it (i see why /foo may be hard to do, but whitelisting /foo/bar should work, shouldn't it?), while /media/foo works.

chiraag-nataraj commented 7 years ago

@allo- From the manpage:

Whitelist  directory  or  file.  A  temporary file system is mounted on the top directory, 
and the whitelisted files are mount-binded inside. Modifications to whitelisted files are 
persistent, everything else is discarded when the sandbox is closed. The top directory 
could be user home, /dev, /media, /mnt, /opt, /srv, /var, and /tmp.

As for why it's this way, you'd have to ask @netblue30.

allo- commented 7 years ago

Yes, the question is the why (and should be an answer to the manpage quote above) and possibly if an option could be added to allow other folders than these. I see, that they exist almost everywhere, but on the other hand why limit this list to a few standard folders?

msva commented 7 years ago

AFAIRC, @netblue30 said this is because it will grant attacker a way to do bad things and access to real FS. Or something like that.

Although, I guess, it can be fixed another way: allowing whitelisting everything, but introduce a short list of "restricted places" where whitelisting is not allowed for security reasons (well, I myself prefer to don't even have such list at all and be able to fully manage (black/white- list) absolutelly everything I may want...)

--

В письме от воскресенье, 4 июня 2017 г. 1:05:24 +07 пользователь allo- написал:

Yes, the question is the why (and should be an answer to the manpage quota above) and possibly if an option could be added to allow other folders than these. I see, that they exist almost everywhere, but on the other hand why limit this list to a few standard folders?

allo- commented 7 years ago

My problem is the other way round: /foo is per default exposed for the process. I can --blacklist it and then it is protected, but i cannot --whitelist the subfolder /foo/bar, so that foo is empty except for foo/bar.

For me that means, that i probably need to move a mountpoint into /media/foo and symlink it back to /foo. While this will be possible (and probably my short term solution), I currently do not understand the rationale why I need to use one of these folders.

And I had to find this bug before understanding the error message, which just tells that the folder cannot be whitelisted. Maybe there could be added a hint: "you cannot whitelist folders, which are no subfolders of [the list here]" to help the user understand why there is an error with some paths while others work fine.

ganeshjkale commented 7 years ago

i agree with @allo- i am also facing the same issue

ganeshjkale commented 7 years ago

@netblue30 how can we blacklist something like below ,

blacklist /home/* whitelist /home/user or whitelist ${HOME}

msklvsk commented 6 years ago

So is there a straightforward solution to achieve what @gthreepw00d desired? The analogy with a firewall is perfect. Restrict everything and allow only certain fs subtrees. Surprised it's not a default!

msklvsk commented 6 years ago

Not being able to block everything except certain makes firejail look childish with all that administrative discussions about blocking yet another location. It practically makes the tool useless for the server, where there are narrow specs of what does a process need. If I were a software publisher, I would even bundle whitelist profiles with my app for major distros.

having the same issue as @allo- and @gnshkl1

ganeshjkale commented 6 years ago

No progress on this issue after 1year also.

SkewedZeppelin commented 6 years ago

@msklvsk @gnshkl1 what exactly do you want blocked? Many profiles are already quite restricted.

You cannot simply "block everything".

Take whatever profile you want and you can add the following (if they don't already):

and on top of that many directories like /boot are blacklisted by default

that leaves /var which can have many files blacklisted using include /etc/firejail/whitelist-var-common.inc

you can use net to create a new network namespace that'll prevent the process from seeing connections of other processes

you can use ipc-namespace to further restrict interaction* with other processes.

you can prevent execution of code in memory by using memory-deny-write-execute

and there are many many more options to restrict programs, all documented in the manpages.

Not every profile can be super duper locked down, feel free to fine tune them to your needs. And to say that the current state of Firejail doesn't add any security is just wrong.

If you goal is to have everything completely separate, that is when you go and setup KVM and have each individual service in its own VM. And there are many other benefits to doing so (reproducibility, failover, etc.). And if you're really trying to lock down your processes that is when you need to sit down and write some rock solid selinux policies. If you don't want to bother with that you can try using TOMOYO or Grsecurity's RBAC systems which can automate creation of rules to an extent; the downside is that TOMOYO management tools aren't that great and Grsecurity isn't free.

allo- commented 6 years ago

I think firejail may not be the right technique for such a thing. With the argument that a user who can replace files in the virtual/ etc (see #1332) can get root, it seems not to have the sandbox needed for a full jail. Maybe it would need to include a LXC jail for getting "virtual root".

avaer commented 6 years ago

what exactly do you want blocked?

@SkewedZeppelin I think the answer is "everything firefail does not know about". This is an infinite and growing list. Ignoring the issue of new binaries, or binaries in unexpected locations, it seems firefox could update to move around private directories tomorrow and that would instantly break firejail's efforts to sandbox it.

I don't understand the technical argument here. Firejail seems to go to great lengths to explicitly ban a long list of things, but it lets an infinite amount of holes through. Shouldn't it be the exact opposite, where the efforts spent blacklisting sensitive things are instead spent on blacklisting all paths and additionally whitelisting the things that are needed for common apps? This is how most sandboxing things work.

In this thread I didn't see any reason why it can't be done that way.

To the above point, I find files like this frightening: https://github.com/netblue30/firejail/blob/7b15c335c31227917c34a3c535b5e27481cd0d91/etc/disable-passwdmgr.inc#L5

Because it looks like if any of these password managers change their user data path then suddenly the sandboxing does nothing, and the user will never know. So it seems there is an attempt at security, but it does not accomplish any reliable security. But it could, if blacklist everything was an option!

Vincent43 commented 6 years ago

Fiejail aims to be transparent from users perspective in traditional linux systems. Install it and firejail firefox works out of the box with equivalent experience to unsandboxed one. You don't have to install the whole new infrastructure which doesn't come from your distro package manager. MAC kernel solutions like apparmor or selinux usually work in a similar way.

There are other tools which can provide stricter system isolation based on full linux containers: systemd-nspawn, LXC/D, docker but their users have to redefine how they use their own systems where every app comes with their own infrastructure which isn't part of their host. Flatpak and snaps work similar. QubesOS is the most radical approach in this matter.

Firejail also comes with hundreds of app profiles which should work out of the box for most users. Maintainers try to harden them as far as possible without causing breakages which needs several compromises and is never-ending story as software constantly evolves.

More sophisticated users are supposed to tweak those profiles for their own use-case and can submit their changes for upstreaming. The alternative is to not provide any profiles at all and let users do whatever they want on their systems as some alternatives like nsjail or bubblewrap do.

Quote from bubblewrap readme:

trying to whitelist file paths is a bad idea given the myriad ways users have to manipulate paths, and the myriad ways in which system administrators may configure a system. The bubblewrap approach is to only retain a few specific Linux capabilities such as CAP_SYS_ADMIN, but to always access the filesystem as the invoking uid.

To sum up: firejail design is a choice. There is no ultimate solution which fits all. Everyone one can choose desired solution based on their needs.

avaer commented 6 years ago

Thanks, that helps.

I think others in this thread weren't asking for any change to firejail or its design, simply the ability to have a custom profile block everything, and then layer a whitelist on top. To me that actually does sounds like a solution that would fit all.

Vincent43 commented 6 years ago

That solution isn't practical when sandbox infrastructure is shared with host. Even if it can be done there are tools which better fit for this job. It's much easier to achieve it with containers system where the only shared thing is kernel or with tools like nsjail which leave all configuration steps to user.

Firejail tries to be user friendly and pre-configure some things which has its pros and cons.

tomjaguarpaw commented 3 years ago

I can confirm that nsjail works well for this use case. I use nsjail for fine-grained configurability and firejail for sandboxing desktop applications.

hakanai commented 2 years ago

Even an include we could include which blacklists everything would be good enough to make custom profiles practical to write, I think?

But I already went through all includes looking for something that might be close and couldn’t find anything that looked like it blocked everything.

Really the biggest shock was blacklist / not blacklisting anything at all. What is up with that?

rusty-snake commented 2 years ago

Even an include we could include which blacklists everything would be good enough to make custom profiles practical to write, I think?

How do you enumerate everything? I can write you an script that generates a include that blacklists a lot but even if it outputs an 5GB include (I hope you have enough RAM), there is still not everything blacklisted.

blacklist /

WTF

https://github.com/netblue30/firejail/issues/354#issuecomment-192697653

This is like an attempt to create a planet of size zero. How should it work?

Why not just use whitelisting? It's even more secure.

edit: here you go blacklist /*

hakanai commented 2 years ago

Now that is an ambush. Randomly for one directory we have to add * on the end even though I didn’t see any of the lines in other profiles doing this for all the directories they were blacklisting there. (!!)

How it would work: you get an error when you run it, then whitelist the path if you think it’s acceptable for that path to be accessed, rerun, rinse, repeat. The same way I’d do it for a firewall.

And yes, it would take forever to me to figure out how to write a profile which blocks everything to use as a baseline. That’s why it would be nice to just have an include we could put in which did that, and then we could whitelist only what we actually want the program to access.

rusty-snake commented 2 years ago

And yes, it would take forever to me to figure out how to write a profile which blocks everything to use as a baseline. That’s why it would be nice to just have an include we could put in which did that

It's trivial to get a include that blacklists everything.

python3 blacklist-everything.py > blacklist-everything.inc

p = "/*"
while len(p) <= 1080:    
    print("blacklist", p)
    p += "/*"