Hi, Catonano <caton...@gmail.com> writes:
> I' m not sure I understand: is this meant to allow Guix to run in foreign > distros like Fedora ? > > Or is this meant to have SELinux running inside the GuixSD environment ? On GuixSD we don’t have a base policy yet, so it would not work on GuixSD. The base policy specifies a bunch of things that this guix-daemon policy relies on, such as the type “init_t” and the assumption that processes spawned by the init system are executed in this domain. > I might be interested in runnig Guix on my Fedora installation. It should be useful for that purpose. I have a Fedora workstation at work and I developed and tested the policy on it. I haven’t yet had the time to switch to “enforcing” mode, which would block any operation that is not explicitly permitted by the policy, so I suggest starting with “permissive” mode and using it for a while. After some time you can then analyse the audit logs to see if the daemon misbehaved according to the policy. > Also, Ricardo, I remember you posted a link to an introduction to SELinux > for human beings, some months ago. Yeah, it was the SELinux Coloring Book by Red Hat: https://people.redhat.com/duffy/selinux/selinux-coloring-book_A4-Stapled.pdf But I *really* don’t recommend it for learning SELinux. Half of the book doesn’t even apply to common SELinux installations, and the bit that *does* apply really isn’t thorough enough. All I took away from it was that a dog shouldn’t eat cat food (and that’s enforced by an angry penguin). The lack of *good* documentation for SELinux is very frustrating. Here’s a high level overview: the goal is to ensure that processes only have a set of permissions to do exactly what they were designed to do, and nothing more. A common example is an HTTP server. It should be allowed to publish *some* files and not others. A misbehaving HTTP server process should be prevented from publishing files that I didn’t label as publishable (like my private home directory or /etc/passwd). Traditionally, the only way to achieve this was to let the server process run under a separate user identity and change the ownership of files that are allowed to be published. To that end the server process would be started as root and then drop privileges by becoming that separate user. This assumes that software is bug free, though. What if the server process has a bug that allows an attacker to run code as root, though? In that case it could publish *any* file – or it could delete or overwrite files. So the idea behind SELinux is that the kernel should watch all access attempts to all resources and only allow specific operations. This way a rogue server process is automatically prevented from, say, publishing the system passwords. A system admin informs the kernel about what operations are permitted through rules in a so-called policy. These rules look something like this (in the SELinux Common Intermediate Language): (allow guix_daemon_t user_home_t (dir (search))) This says: a process of type “guix_daemon_t” is permitted to perform a “search” action on a “dir(ectory)”, if that directory has the label/type “user_home_t”. These types are defined by policy developers; they are completely arbitrary. There are two things in this example that have types: processes and files. Files get their types by labeling. Looking at the policy for guix-daemon you see things like this: (filecon "/gnu/store(/.+)?" any (unconfined_u object_r guix_store_content_t (low low))) This is an instruction to label anything (“any”) matching the given regular expression with the type “guix_store_content_t” (ignore the “unconfined_u” and “object_r”, and also the “low”). By running “restorecon” recursively on the file system, all files will get labels according to instructions like that. How about processes? How do they get their types? (In other words: how does a process enter a certain domain?) They start out in a certain domain and then may transition to other domains. That’s specified by transition rules like this one: (typetransition init_t guix_daemon_exec_t process guix_daemon_t) This says that a process in the domain “init_t” may transition to domain “guix_daemon_t” if the file that spawns the process has the label “guix_daemon_exec_t”. Again, “init_t” is an arbitrary name for a type, which in the case of Fedora is specified in some other policy that I simply take for granted. On Fedora, all processes that are spawned by the init system are in the domain “init_t”, so when the daemon is started via SystemD it’s in “init_t” and then transitions to “guix_daemon_t” because the executable file “guix-daemon” is labeled “guix_daemon_exec_t”. Getting back to the rule above: it says that a process in the “guix_daemon_t” domain may perform a “search” on a “dir” if that directory has the label “user_home_t”. If that’s the only rule, then that’s the only permitted action for such a process. At some point I’d like to build a base policy for GuixSD, which defines a couple of basic types, label rules, and type transitions. The hardest part in designing a policy is finding good names for types and figuring out how types should be allowed to transition. In the case of Guix this is all made more difficult because applications don’t share the same root-controlled global namespace (such as /usr, or /bin). But the core idea is the same: make explicit what *type* of files there are and what type of processes should be granted access to files of these types. -- Ricardo