As I mentioned yesterday, I'd like to harden what I perceive as the major security weakness of my set-up: the web browser.
This tool supports a protected X11 environment, allows to mount separated
/tmp, and allows to select a SELinux Security Context to
apply to the sandboxed program. It even comes with a set of pre-compiled
sandbox types matching some common needs.
A one-liner for Firefox follows, see sandbox(8) for explanations:
$ sandbox -X -M -H /tmp/sehome/ -T /tmp/setemp/ -t sandbox_web_t firefox
A couple of gotchas:
1. The need for more policies
Sandbox is a generic tool. It comes with policies, but I'm guessing it's not easy to predict what software the user is going to confine with it.
Sure enough, starting Firefox in this way ends up in a ton of AVC denials.
It is not even necessary to visit some evil site for this to happen: Firefox
will reasonably try reading system configurations (e.g.
startup. It is actually quite reasonable.
Those AVC denials will however end up flooding the system. Besides the useless noise, this can make the system unusable, as it ends up into notifications in the graphical environment (at least, on Fedora).
Lurking around I figured that the solution is surprisingly simple:
Track those audit messages which involve the process (in this case Firefox)
root# ausearch -c firefox
Note: this command appears to be simply a nice to use filter on
/var/log/audit/audit.log. But maybe has some fancy extra feature, I should lurk more.
Turn those messages into a policy definition with the
root# ausearch -c firefox -ts recent --raw | audit2allow -D -m firefox_sandbox > firefox_sandbox.ts
Note: This tool will write "allow" policies by default, but the
-Dflag specifies we want to keep denying those actions. The goal is in fact just to avoid the unnecessary auditing. I keep denying all those permissions, however reasonable, that are not strictly necessary for Firefox to operate.
Compile the obtained policy into a binary modular policy package, as by the example in the
root# checkmodule -M -m -o firefox_sandbox.mod firefox_sandbox.te root# semodule_package -o firefox_sandbox.pp -m firefox_sandbox.mod root# semodule -i firefox_sandbox.pp
Or simply rely on
audit2allowto do the compilation directly:
root# ausearch ... | audit2allow -D -M firefox_sandbox
.teis in textual format: it can be modified with a
ed(1)-itor (or a
vi(1)-itor, or an
emacs(1)-itorfor what it matters).
Load the resulting policy in the kernel:
root# semodule -i firefox_sandbox.pp
When this is done, the one-liner will no longer result in the auditing system being spammed, at least not for the same reasons.
I believe the obtained policy might use some iterative refinement, up to the sweet spot in which only anomalous activity is detected (with a few or no false positives). It could be necessary to relax the policy and allow for some strictly required operation. I would not be surprised to learn that the obtained policy can be improved manually!
2. No copy paste from/to the sandboxed browser
Deal with it. The browser is in a confined environment, and can't easily communicate with the rest of the operating system.
Or maybe not? Maybe there's a way. Probably the policy can be refined to allow for copy-paste buffers. I need to lurk more.
EDIT it is really trivial and supported out of the box. Look
here. In short, the
mounted user home will have a file named
seremote containing the display
pass(1) will easily work:
$ more /tmp/sehome/seremote
$ /tmp/sehome/seremote pass show -c stuff/bank
I'll have to figure out how to make the policy resilient to reboots. For
iptables rules and
sysctl settings must be restored upon
reboot. But perhaps SELinux works differently.
EDIT: policy is maintained after reboot.
3. I need to lurk more
Generally true. This seems the tip of the iceberg, really :)