Stop Disabling SELinux: A Real-World Guide
learntemail.sam.today
learntemail.sam.today
I think one reason security programs are sometime ineffective and end up being disabled is that they give problems to developers and sysadmin but no solutions.
I wish that rather than messages like "doesn't work - too bad", these programs would output a solution as well, such as "consider setting `httpd_can_network_connect` to `true` to allow it".
In some cases it might be tricky to propose a solution, in which case even a link to the doc would be useful like "check http://example.com/doc#456 for more information". That would go a long way towards making security software issues less of a pain for those who aren't expert in the topic.
I actually write SELinux policies for software I develop, first thing I do is put them in the most restrictive context imaginable with no permissions, set SELinux in permissive mode and run the application through it's paces, at the end run audit2allow and there's 90% of the work done for you outside of defining fcontext's.
"This service did the bad thing, supposedly", ok, so what am I supposed to do with that? Is the service at fault? or is the default SElinux config borked? or both?
If the answer is actually "no that's fine", then why am I being alerted about it?
I tried understanding the principles behind it and configuring the different exceptions for several classes, but often, this didn't work (e.g. I had used wrong class, or enabled exceptions that were still blocked). The users of the rails app kept calling, asking me why this or that feature wouldn't work. It was impossible for me to configure all exceptions - to me this was not surprising, given the complexity of the software that we had installed. I simply deemed the apps too complex and too "feature rich" to configure all SELinux exceptions manually.
I then understood that there is a different way: To set it to permissive, keep it running for a while and then generate an installable permissions profile, allowing all occured violations as some kind of permissable exceptions.
This made sense to me, however it required downloading some dubious python script, that would create some dubious binary file. I got this to work, but then again, this or that feature was blocked. I finally kept it running on permissive. This is my individual story. The article makes it look as if it was really simple to configure it (When I started with SE I tried similar moves but never got it to work).
So, is it just me, or might it be that SELinux just has a major usability issue?
audit2allow is a great tool for simplifying the development of SELinux policies, but it doesn't remove some hand-crafted modifications to policies, especially in regards to file contexts (fcontext).
Further, the divide between ops and developers in many cases leaves this as an unsolvable problem - it's not the dev's job to do sysadmin, and ops lacks the expertise (or time) to comprehensively analyze the code base
You're right that this makes the app poorly behaved, but if that can't be addressed then... permissive mode it is
I wear both hats, and then some more on top of that - if someone on my team is doing something that will make deployment and security difficult I make sure to nip it in the bud during testing.
To make matters worse SELinux-related errors can be pretty arcane if you don't know what's going on. I'm usually a FreeBSD guy but I had to setup a CentOS 7 box a little while ago. I thought I was going insane when I couldn't get nginx to connect to a unix domain socket. After a hour of hair pulling and non-conclusive googling I finally understood that it was SELinux related.
I will admit that after that I simply disabled SELinux and never looked back. The benefits didn't seem worth the hassle to me.
If I want additional security and sandboxing I'd sooner use something like FreeBSD/solaris jails. It's not exactly the same thing of course but I find the mental model a lot simpler ("a machine within a machine") than SELinux's complicated and (IMO) hard-to-debug rules.
1) Configure some software you need.
2) The software doesn't work.
3) Disable SELinux.
4) The software works.
5) F--- SELinux.
After a dozen occurrences of this pattern, your experience will have taught you to begin all deployments from step 5 ;)
On the server I usually use Ubuntu and run custom server software running in a container and never have problems.
I really don't see any reason to disable SELinux. Maybe back in RHEL5 days, but not since then. Just educate yourself on some tools. It really isn't that hard.
You may not see a reason to disable SELinux, but not all Linux systems are RHEL, and don't have it enabled to begin with. I personally would not enable it on a system that did not design for it as a default.
setsebool httpd_can_network_connect=1
audit2allow even tells you right away which booleans apply: tail /var/log/audit.log | audit2allowBut it kinds of demonstrate my problem with SELinux: when I had my unix socket issue I tried to debug my problem using my usual tools: strace, ls, ps, dmesg, etc... but I couldn't figure out what wasn't working right. All the permissions looked fine and yet I kept getting cryptic failures.
With something like a jail, once it's set up I can just use my un*x admin experience without having to learn a brand new OS-specific (if not distribution-specific) set of tools.
That's just not true. There is plenty of security technology that doesn't require you to figure out new tools. There is security technology that doesn't have tools at all and there is nothing to figure out. The program either works correctly or it's buggy and there is no knob to make a buggy program correct.
And then there is security technology that is more or less understandable with knowledge of existing Unix tools. pledge() on OpenBSD, for instance, doesn't introduce new fancy tools. A program doing something it promised not to do will get killed with abort trap (which can, admittedly, be a little cryptic if you don't know pledge does that). In addition, the name of the binary, the pid, and the offending syscall is printed in dmesg. Perhaps it would be better still if the dmesg line included the word "pledge" as a hint & guarantee that you'd get relevant results on Google.
My point is that any ACL framework will require configuration, be it SELinux, AppArmor, Tomoyo, or pledge.
If you want to use pledge to confine applications that don't use the pledge API, it will get complicated, too (admittedly not quite as complicated as SELinux, but still).
SELinux writes denials to the audit log and you get plenty of relevant results.
pledge is obviously much more sane than SELinux, but someone has to write a policy no matter what technology is used.
YUP, this right here. SELinux needs to be way more user friendly if you want to see wider adoption.
I wouldn't run an 'exposed' system that had SELinux support (and decent rules) without SELinux. Not discounting chroot, but given root a lot is possible in a jail.
Lxc is much closer to jails in that sense - but eg lxc/Lxd on Ubuntu is hardly (meant to be) a silver bullet.
However the Redhat certified admin and engineer classes cover it with enough practical examples to make any SA functional with the tool. And as a former consultant learning anything people consider difficult whether or not it really is can be profitable. :-)
It would take an explicit release goal to enable selinux for Debian, and part of that release goal would be requiring package maintainers to help with maintaining the policy files for their packages.
1. The package has only one maintainer.
2. The package requires heavy maintainer intervention.
3. Shit's on fire, yo.
All suggest that whatever it is that SELinux is meant to be a solution to, it's not a particularly good, or compelling, solution.
Stuff that needs custom wiring for every single package (and at last count Debian was in the 50-60k packages range, though a fair number of those are extra, source, and documentation packages) suggests ... issues.
Well, yes. Enforcing that surgeons wash their hands and wear protective clothing in the OR also isn't a compelling solution to surgeons, because it limits their response time. But the behaviour is forced upon them anyway (by either employment policy or insurance), because it is better for the patient. Selinux does the same thing: it requires security-aware behaviour from developers (by requiring the package to enumerate its expected behaviour beforehand) not out of convenience for the developer, but to improve the security for the user.
And that explains why Debian does not use it while Red Hat does: Red Hat can enforce selinux compliance by company policy, while Debian has to rely on every individual developer's judgement about the effort/benefit ratio. And just as with hygiene in medicine, the effort is internal while the benefit is external. That's why I said it would take a release goal (or general resolution) to effect that change in Debian.
Protective rules are not meant to be a compelling solution for those who have to abide by it. I don't see why we should expect selinux to be any different.
There's also this little thing that Debian has an order of magnitude more tools and programs included in its official repository, and two or three orders more packages. This alone pretty much explains why Debian cannot just put SELinux into use, while Red Hat somewhat can.
You hear it over and over again that blacklisting will always fail, and whitelisting is what needs to be done. Well, when you finally do go from default-allow to default-deny, you're going to have to fix every single package to keep things working.
Debian has accumulated a load of technical debt and has to pay all of it off before it can flip the switch on SELinux and see any benefit. It's understandable (if undesirable) that they feel that way. That doesn't invalidate the fact that they'll have to do the same for any whitelist.
What do you mean?
But the point is really - this is a distro issue and SELinux is a building block. If your distro is using SELinux and it's causing you no end of headaches consider that it may be your distro that's the problem...
Then expand to "negative" behavioral tests (from letting httpd write to /var/log/access.log to checking that it can't write to auth.log etc)?
Perhaps static analysis to see which library functions are linked in the package (require symbols in all binaries) and then having a set of default policies per-package based on those (including like you said, "this program never calls X, is not in category Y, therefore it doesn't need to be able to write to /path/to/Z" and so on)..
I dunno. Ideas
No major problems, just minor policy changes needed that the helper was already suggesting and that were easily fixed.
With the only exception that SELinux does not like my iPhone.
That was the error description I got: "When starting the network does not work. I have to do a lot of things to make it work." Later I got more infos: "It says there are 7 errors. If I let it fix it it has to restart and then works".
It turns out that these 7 errors are all SE-Linux-Errors. Something about /etc/resolv.conf not being readable. The error helper suggests to fix it for now and also some command to fix it permanently, those commands fail and do nothing. So of course I just deactivated that SE-bullshit.
Really, fucking vanilla Fedora on a mainstream Gnome3 desktop. What the hell are they thinking?
And btw, that is exactly what I don't want. I do report errors, I solve bugs. But I don't want to debug SE-errors, which just because of its paranoia makes perfectly normal usage impossible, so far that distros that enable SEL spit out errormessages immediately after installation.
I don't see its purpose anyway.
A security-solution that makes normal use impossible is not a solution. Security solutions never work if they make usability worse. SELinux goes farther, it also makes functionality worse till impossible. That is what I meant when I wrote that I don't see the point of it.
Something like that can be a good solution if you are manually hardening a specific process. As a general security solution it is completely unfit. I don't see the point of pushing it for that. Fedora should never have activated it.
I think the only problem I've encountered has been when Virtual Box (or was it VMWare?) tried to compile and install its custom kernel-modules, while using UEFI with secure-boot. They wouldn't load, because they weren't signed. Took me some debugging to figure out what was going on, but it was easily bypassed.
The solution was to disable secure-boot and just boot UEFI in "regular" mode. Felt a bit like fixing things by running as root/admin, but apart from that one story, I've had absolutely zero other issues with SELinux. Fedora has implemented it really well.
[0] https://docs.fedoraproject.org/en-US/Fedora/18/html/UEFI_Sec...
[1] http://gorka.eguileor.com/vbox-vmware-in-secureboot-linux/
You may be absolutely right here and I may have incorrectly conflated the issues.
That said it's UEFI secure boot, not Microsoft secure boot.
Microsoft helped create the spec, but anyone is free to implement it and use it without any Microsoft involvement.
Maybe you're conflating some things too ;)
It pretty much doubles the effort for most sysadmin tasks, even simple things like tweaking a server setting become multi-step processes.
In my case, it was part of the reason I switched the team from DevOps only and brought in a real sysadmin.
If you're running a headless server and can't figure out why your service suddenly can't start after a seemingly simple configuration updates (changing port, changing data directory path, etc), be sure to check AppArmor (Ubuntu) or SELinux (Red Hat distros) logs first.
I might just turn it to enforcing mode.
I'd really recommend it, it doesn't seem to impact the system usability in any way.
Knobs that can be tweaked can be tweaked wrong, and wrongly-tweaked knobs are security problems. Frankly I don't even like ACLs and capabilities for that exact reason: it's no longer immediately obvious what the actual permissions in a situation are ("let's see, the daemon is running in an unprivileged account, but it has CAP_SYS_ADMIN set, and this file is inheriting its ACLs from the parent dir..."). Making it more difficult to reason about security is generally a Bad Thing, and not worth whatever features that difficulty brings with it.
That said, SELinux determines what is allowed. Having it introduce an additional vulnerability/permission just due to configuration is really odd.
I tried searching for your example, but can only find security bugs, not configuration issues.
I should probably just read the manpages.
1) Develop a new policy from scratch. This is fairly hard, and the tools, such as they are[0], are not great. There's a couple of good resources out there, including [1] which has some good examples, and Dan Walsh's blog [2].
2) Use audit2allow to generate a policy semi-automatically. The resultant policy won't be very clean, and will almost certainly be more permissive than it needs to be, but if 1) is too much work (and I wouldn't blame you for this), then this is the next best thing.
3) Run your binary in the unconfined domain (do something like chcon -t unconfined_exec_t /usr/local/bin/foo), but leave the rest of the system enforcing. This will mean your binary itself is able to do anything, but the rest of the system is still protected.
Oh, and if you haven't read it before, you should definitely check out [3](pdf).
0: http://oss.tresys.com/archive/slide.php 1: https://github.com/TresysTechnology/refpolicy/blob/master/po... 2: http://danwalsh.livejournal.com/ 3: https://people.redhat.com/duffy/selinux/selinux-coloring-boo...
Really, it's as simple as this, I swear:
1. Write an empty policy for your application, defining a type for your binary (myapp_exec_t) with no permissions at all. Label your binary with this using chcon.
2. Set SELinux in permissive mode, run your application through it's paces.
3. Run audit2allow to get a decent policy to start with
4. Figure out where your application stores data on disk, if at all. Create another type (myapp_t) and label those directories with it (you shouldn't be writing outside of these directories by default, if you allow it to be changed in a config file the administrator can label new directories with semanage), then grant your application access to this type. Also make sure the installed path of your binary is labeled with your myapp_exec_t type.
5. Clean up the messy policy that audit2allow created if so desired, it's likely more permissive than necessary and not overly pretty. This will become easier as you work with SELinux policies more.
6. You're done
This will be time consuming the first couple times you do it, but you'll get quicker at it over time like anything else.
The default SELinux policy is "targeted" - this means that is has to be enabled for each service you want to confine.
Unless you explicitly switch it on, your service will run just fine.
apparmor is less complex but SELinux can be fine tuned at the cost of pulling out your hair with what security gain? The BIG ISSUE is the KERNEL SELinux and apparmor have the same policy with Linux Kernel aka both of them can be bypassed and a hacker can just focus on the Kernel.
Hours I've spent dicking with selinux - too many before disabling it.
OTOH I've been admining *nix from before Linux existed.
Comparison matrix;
>Since September 9, 2015, the availability of stable grsecurity patches has become limited to the commercial customers of grsecurity.
But ideally, you could be using Grsec without RBAC, but with SELinux.
for example - networkmanager-openvpn. Openvpn certfiles are usually shared by vpn providers and then when trying to load them, throws selinux errors.
Here's the bounty to fix it - https://www.bountysource.com/issues/41582244-doesn-t-copy-re...
Not that selinux is wrong.. my point is that these files should never have been used in the first place.
Linux keyring is a kernel level infrastructure. However, we still have ssh keyfiles being stored in ~/.ssh . Not sure if I'm right, but it seems to me that openssh wants to be cross platform friendly. So it doesnt play with linuxism very well.
It also doesn't limit access in any way. Anyone who can connect to the keyring socket gets access to everything. How is this better than storing it in files?
That is not something im personally qualified to answer. However, ypu should ask that question of selinux.
Assuming something like selinux makes sense, and gnome-keyring is protected by selinux.. my point is to use builtin infrastructure.
Fedora's default policy prevents openvpn from accessing your SSH keys.
It is NOT asking you to do some specific openvpn restricted setting. Its basically setting it to the same permission level as gnome-keyring. Except - not even password protected. And the biggest issue - obviously an end-user has to muck about this stuff.
OpenVPN runs confined, so the only thing it's allowed to access in your profile directory is the certificate files.
The OpenVPN SELinux policy says "OpenVPN may only access files marked home_cert_t".
With gnome-keyring, it would have access to all your secrets.
AFAIK - its the same story on OSX. I dont begrudge openssh - I'm not sure how it would work with multiple systems, but I dont know if it was ever a priority.
But in this day and age of a "reloaded" Lavabit... these are infrastructure decisions that must be solved !
Interestingly, for all the hate that Lennart gets, he refused to implement "systemd-keyring" and suggested people should use the kernel level keyring service that already exists [1]. You can test it out using "keyctl". Remember however, that IMHO kernel keys do not persist across powercycles.. There is some kind of funky interplay between ecryptfs, kernel keyring and gnome-keyring that I dont completely understand (and is the basis of encrypted home directory in Linux)
[1] https://lists.freedesktop.org/archives/systemd-devel/2014-Ju...
It hasn't been GNOME-specific for around 5 years.
Quoting https://wiki.gnome.org/Projects/Libsecret:
"libsecret is a library for storing and retrieving passwords and other secrets. It communicates with the "Secret Service" using DBus. gnome-keyring and ksecretservice are both implementations of a Secret Service.
libsecret replaces libgnome-keyring."
IMO it definitely reduces privilege escalation attacks there. I wonder if Apple uses similar MAC system on iOS?
Also, it is usually transparent for user app developers but can cause a bit of headache for platform/system devs.
I just literally spent a day on an issue where android system service checks selinux permission but does not audit the denial (= no error in logs) under certain conditions. That was not a problem with selinux per se, but disabling selinux would "solve" the problem.
The attacks for servers tend to be over the network and there are many different ways to mitigate those.
Example: your web application allows remote code execution. Even the default rules prevents most access (spawning a shell etc.) and generate lots of alerts.
Thus, when you run some program locally, sometimes it runs as your user/group and sometimes a new user/group is created for it.
From this simple abstraction springs the issue that any (potentially misbehaving) application running locally needs to be treated as if it were a user on its own: with all the quirks a random "user" could bring like deleting files, accessing private information, and so on.
Hence the need for these finer grained access control mechanisms. Any program that you download from the Internet (every program most of us run) might as well be a remote user on your system, in a sense.
Thanks, but I'd rather start from something that works, and build adding security from there, not viceversa.
Stick that in your pipe and smoke it.
I agree SELinux adds something to the table, but the article shows two examples (httpd_sys_content_t and httpd_can_network_connect). Let's assume there is a third httpd_can_foo_bar that is required down the line. And then a http_can_bar_quux a few hours after that. All in all this can be a bit risky. Perhaps if there was an easier way to administer SELinux?
2. Using something like setroubleshoot will make sure any SELinux denials appear in the syslog so should be simple to diagnose, and sealert will tell you likely solutions. Personally I think that's how distros should be shipping SELinux, not sure what the downsides are.
Note, I'm mainly talking about servers here. Personal computers always seem to have messily-packaged applications running, so I can see why people get annoyed with SELinux there (although I've never had a problem with Fedora, yet...)
By not coming out openly and explicitly criticizing the US security services for their anti constitutional and blatant authoritarianism Redhat has demonstrated which side it is on. It has no qualms enabling and supporting this behavior and is not a principled member of the free software movement. Something for which it has yet to be held to account.
Given the movement against Trump is exactly against this kind of authoritarianism the lack of scrutiny of tech companies like Redhat, Palantir and others is hypocritical. By not speaking out you are supporting these actions.
The fact that it is an absolute pain to configure and representative of a user hostile software model makes it that much more easy to avoid even for those with more practical considerations.
Anyway, though I get the sentiment, SELinux is a great example of leveraging OSS regardless of whether you agree with the creators or not politically. That's a win for OSS in general because it means we don't have to like (or maybe even trust) each other to benefit mutually across the net.
The best arguments against SELinux are purely technical because there are alternative ideas about how such a system could be implemented (see: App Armor for example).