From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ricardo Wurmus Subject: Re: [PATCH] Add SELinux policy for guix-daemon. Date: Fri, 26 Jan 2018 15:47:07 +0100 Message-ID: <878tckvfro.fsf@mdc-berlin.de> References: Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:46307) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ef5tI-0003zM-JD for guix-devel@gnu.org; Fri, 26 Jan 2018 10:26:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ef5tF-0005g8-Ck for guix-devel@gnu.org; Fri, 26 Jan 2018 10:26:08 -0500 Received: from sinope02.bbbm.mdc-berlin.de ([141.80.25.24]:56140) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ef5tE-0005fm-Ul for guix-devel@gnu.org; Fri, 26 Jan 2018 10:26:05 -0500 In-Reply-To: List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: "Guix-devel" To: Catonano Cc: guix-devel Hi, Catonano writes: > I' m not sure I understand: is this meant to allow Guix to run in forei= gn > distros like Fedora ? > > Or is this meant to have SELinux running inside the GuixSD environment = ? On GuixSD we don=E2=80=99t have a base policy yet, so it would not work o= n GuixSD. The base policy specifies a bunch of things that this guix-daemon policy relies on, such as the type =E2=80=9Cinit_t=E2=80=9D a= nd 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=E2=80=99t yet = had the time to switch to =E2=80=9Cenforcing=E2=80=9D mode, which would block any= operation that is not explicitly permitted by the policy, so I suggest starting with =E2=80=9Cpermissive=E2=80=9D mode and using it for a while. After some t= ime 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 SELin= ux > 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-Stapl= ed.pdf But I *really* don=E2=80=99t recommend it for learning SELinux. Half of = the book doesn=E2=80=99t even apply to common SELinux installations, and the = bit that *does* apply really isn=E2=80=99t thorough enough. All I took away = from it was that a dog shouldn=E2=80=99t eat cat food (and that=E2=80=99s enforce= d by an angry penguin). The lack of *good* documentation for SELinux is very frustrating. Here=E2=80=99s a high level overview: the goal is to ensure that processe= s 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=E2=80= =99t 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 =E2=80=93 or it c= ould 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 =E2=80=9Cguix_daemon_t=E2=80=9D is permitted= to perform a =E2=80=9Csearch=E2=80=9D action on a =E2=80=9Cdir(ectory)=E2=80=9D, if th= at directory has the label/type =E2=80=9Cuser_home_t=E2=80=9D. These types are defined by policy develop= ers; 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 (=E2=80=9Cany=E2=80=9D) matching= the given regular expression with the type =E2=80=9Cguix_store_content_t=E2=80=9D (= ignore the =E2=80=9Cunconfined_u=E2=80=9D and =E2=80=9Cobject_r=E2=80=9D, and also t= he =E2=80=9Clow=E2=80=9D). By running =E2=80=9Crestorecon=E2=80=9D recursively on the file system, all files wi= ll 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=E2=80=99s specifie= d 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 =E2=80=9Cinit_t=E2=80=9D may trans= ition to domain =E2=80=9Cguix_daemon_t=E2=80=9D if the file that spawns the process has t= he label =E2=80=9Cguix_daemon_exec_t=E2=80=9D. Again, =E2=80=9Cinit_t=E2=80=9D 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 =E2=80=9Cinit_t=E2=80=9D, so when the d= aemon is started via SystemD it=E2=80=99s in =E2=80=9Cinit_t=E2=80=9D and then tra= nsitions to =E2=80=9Cguix_daemon_t=E2=80=9D because the executable file =E2=80=9Cguix= -daemon=E2=80=9D is labeled =E2=80=9Cguix_daemon_exec_t=E2=80=9D. Getting back to the rule above: it says that a process in the =E2=80=9Cguix_daemon_t=E2=80=9D domain may perform a =E2=80=9Csearch=E2=80= =9D on a =E2=80=9Cdir=E2=80=9D if that directory has the label =E2=80=9Cuser_home_t=E2=80=9D. If that=E2=80=99s= the only rule, then that=E2=80=99s the only permitted action for such a process. At some point I=E2=80=99d like to build a base policy for GuixSD, which d= efines 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=E2=80=99t share the s= ame 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