Hacker Timesnew | past | comments | ask | show | jobs | submitlogin

AppArmor is great. It can do much of what SELinux does, but it uses plain configuration files as opposed to incredibly obscure and clunky filesystem-level hacks.


AppArmour assumes everything is allowed unless it is explicitly denied by policy, SELinux assumes everything is banned unless it is allowed by policy. This makes SELinux fundamentally more secure because unlike apparmour you cant forget to deny some access that leaves you wide open, instead you forget to allow things and your app breaks. It also makes SELinux more complicated to implement because you have to allow everything you need or your app breaks whereas apparmour lets you deny the things you're worried about and ignore everything else.

SELinux also supports interesting things like applying security levels and contexts to data, so you can have data that is only accessible to appropriatly cleared users in one department but not to people with similar clearances in other departments. Very few people use this stuff though.

Selinux uses extended attributes to store its labels which is a pretty standard way of associating metadata with objects, and is supported by most standard unix commands (via the -Z flag) so I'm not sure what you mean by "filesystem hacks". Fundamentally they are both implemented as security modules in the kernel and do pretty much the same thing, which is best depends on whether the added security of SELinux is worth it to you.


> AppArmour assumes everything is allowed unless it is explicitly denied by policy

No, AppArmor uses a whitelist approach as well for its profiles. "Deny" rules are used in exceptional cases.

> SELinux also supports interesting things like applying security levels and contexts to data, so you can have data that is only accessible to appropriatly cleared users in one department but not to people with similar clearances in other departments.

AppArmor has subprofiles and variables that can be used for this approach.


It still has the same gotchas as a user though.

I was daemonizing a uvicorn (Python) process using systemd and could not get the Python script to write its log file anywhere. Not the current directory owned by the user, not elsewhere, and no errors showing up in the system logs.

After a few hours banging my head against the wall I discovered systemd's ReadWritePaths. Once I set that, it would log to any directory I specified.

It's the only service I've created where this has been necessary, and others write logs, so I have no idea why this one caused errors. If I did something wrong, let me know how this should be handled.


Most systemd services log to stdout and let systemd put it in the journal, or they log to syslog and let systemd put it in the journal. Most don’t write their own log files any more. I really recommend going that route because it is nice to be able to search the journal, especially if you provide extra metadata for each log message.

It sounds like you were using the DynamicUser=, ProtectSystem=, or ProtectHome= settings which can greatly limit where a service is allowed to read from and write to and thus require you to open specific directories back up. Instead of using ReadWritePaths=, you might prefer to set LogsDirectory=.


> It sounds like you were using the DynamicUser=, ProtectSystem=, or ProtectHome= settings which can greatly limit where a service is allowed to read from and write to

Thank you! I have DynamicUser set - I can't think why I added it here, perhaps no reason at all - and that is the difference to previous systemd services I've written. I did not know it had such an effect on behavior.


It is a nice security measure; it means that no other service can accidentally read or write to the same files. An older form of the security measure was to create new system users like “ftp” and “mail” so that the ftp daemon couldn’t be tricked into overwriting someone’s mail queue and so on. The downside is that this takes a certain amount of effort on the part of the system administrators and distros to arrange; the bookkeeping becomes a significant source of manual effort.

The DynamicUser= setting tells systemd to invent a new user on the spot, with an id that is not in use by any other service. You can add as many such services as you like¹ without having to do any extra work to keep /etc/passwd updated.

¹ as many as you like as long is it isn’t more than several thousand, unless you recompile systemd with larger limits.


How does this work when you want to log different things? Like if I had a web server, I wouldn't want the server log and access log to go to the same place. Sure, I guess I could send one to stdout and the other to stderr, but what if I have three things?

Maybe systemd/journald supports this use case by forcing you to adopt some sort of structured log format that you emit to stdout, but I don't think I want to have to conform to whatever journald wants me to do, unless it's standardized and well-supported among various logging tools.


Journald indeed supports structured logging.

Try `journalctl -o json` to see all the fields that get logged. Applications can add more.

So it very much means that a webserver logging to journald can already provide it all with fields for the vhost, status, URL, referer, and whatnot, and you can just search the log by that and don't need to do your own parsing.


Fair, but still annoying. The simple solution, that always works, is to write separate streams to separate files. At least journald supports JSON, and not some proprietary format, though I imagine the particular fields it supports might not be supported by other logging systems.

I'm just tired of all this added complexity, when I don't really see much of the benefit.


The point is that you can include arbitrary metadata of your choosing, in addition to the standard fields that journald keeps track of for you. For example, if you include the id of the logged–in user with every message, then when they complain about a bug you can query the journal to find exactly what they did without any noise from all your other users. And you don’t even have to pay a SaaS company for the privilege.

> I'm just tired of all this added complexity, when I don't really see much of the benefit.

There is a lot less for each application to implement on its own, such as log levels, timestamp format, log rotation or even just the paths where logs should go. Instead those details can be configured by the system administrator using a uniform interface across all applications.


Yet another rabbit hole has emerge. And it is called “systemd”.

What a great time to be a Linux system administrator.


Compared to selinux, though, the systemd documentation is excellent, and the tools for observing the state of the system are very good.


Excellent? Whew. You must be privy to some private systemd dictionary somewhere.

Meanwhile, I am holding my own just fine, latest systemd-wise.

https://GitHub.com/egberts/easy-admin/blob/main/500-dns/512-...

It is all about reading the friggin’ source code … of systemd.


This is a selinux gotcha, not an apparmor one, right?


No, this is happening with apparmor on an Ubuntu 20.04 server.


I feel stupid --- ReadWritePaths= is a systemd feature, not an apparmor one, so how exactly is it an apparmor problem?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: