我们在Linux系统下面部署一些软件的时候,总是习惯性的将SELinux关闭。很多人用了几年Linux操作系统了,知道SELinux是安全相关的,却说不出更多细节来。您知道SELinux具体是做什么的吗?
Linux操作系统是一个多用户操作系统,这样就存在资源共享与隔离的问题。也就是说用户A的资源不愿意让用户B访问,用户C的资源与用户D的资源可以共享;同时,又存在超级用户访问所有用户资源的可能性。因此在Linux操作系统下就需要一套权限管理的功能。
Linux原生的权限管理机制是基于用户角色的管理机制,也就是UGO+RWX/ACL权限控制。其中UGO是User、Group和Other的简称;RWX则是Read、Write和eXecute的简称;ACL是Access Control List的简称。Linux原生的访问控制称为自主访问控制。
自主访问控制(Discretionary Access Control, DAC)是指对象(比如程序、文件、进程)的拥有者可以任意修改或者授予此对象相应的权限。这里的拥有者就是指具体的用户,也就是角色(例如root)。这种控制方式的问题在于黑客入侵后可以以该用户的角色执行任何允许的操作。
另外一种访问控制策略是基于标签的访问控制。比如我们给程序和其访问的资源打上标签,这样程序就可以访问有标签的资源,对于没有标签的资源则不能访问。这种模式并非基于用户,而是基于许可。这种策略被称作强制访问控制(Mandatory Access Control ,简称MAC)。其中SELinux就是强制访问控制。
一、RWX访问控制概述
RWX访问控制恐怕是我们见得最多的访问控制了。当我们通过ls命令获取文件的详细信息时,其前面的rwx字符串就是对文件权限的标示,而后面跟的root root则是其所属用户和组的信息。如图1就是RWX的一个实例。
RWX的组成及含义如图2所示。整个权限描述分为4段,第一段用于描述该文件的类型,可以是常规文件(-)、目录(d)、块设备(b)、链接(l)和字符设备(c)等等。
后面三段是文件具体的权限描述信息了,分别是文件主权限、组用户权限和其它用户的权限。通过上述三段的组合就可以实现比较复杂的权限控制。比如允许某个用户的文件可以被其它用户读,但是不可以改写和执行等等。
上述权限控制信息中包含rwx-四种字符,具体含义如下:
- r表示对于该用户可读,对于文件来说是允许读取内容,对于目录来说是允许读取其中的文件;
- w表示对于该用户可写,对于文件来说是允许修改其内容,对于目录来说可以写信息到目录中,即可以创建、删除文件、移动文件等操作。
- x表示对于该用户可执行,对于文件来说就是可以执行该文件,对于目录来说则是可以进入目录;可以搜索(能用该目录名称作为路径名去访问它所包含的文件和子目录)
从用户角度来说文件的权限是通过rwx字符串表示的,其实在底层实现就是一些标示位。如果该位置1则表示有该权限,否则没有该权限。这些信息保持在文件的inode信息中。
上图中的宏定义就是Linux内核中对文件权限属性的宏定义,例如S_IRUSR表示主权限可读的标示。这里需要理解的是每个标示占用一个位,本文暂时不过多介绍,这里先有个概念就可以了。
我们经常使用的chmod和chown等命令就是用来修改文件的访问权限信息的。其中chmod用于修改文件权限熟悉,而chown则用于修改文件所属的用户和组。
例如我们想让文件b具有执行权限,那么可以执行如下命令:
- sudo chmod +x b
执行后结果如图4所示,可以对比图中上下两部分,看到文件b的权限熟悉发生了变化。其中增加了可执行属性。
由于底层是二进制的方式存储的,chmod也是支持通过数字的方式修改其权限属性的。比如执行如下命令:
- sudo chmod 777 b
由于777其实就是使所有的RWX为1,也即可以被任何用户和组访问。执行效果如下。
关于RWX的权限访问控制就先介绍到这里,后续我们在详细介绍,并且介绍在内核中是如何实现的。
二、SELinux访问控制概述
SELinux是另外一种访问控制机制,它并非通过角色,而是通过标签的方式实现对主体与被访问对象的控制。这句话可能不太容易理解,比如对于Apache进程想访问某个目录下的文件,那么需要对Apache进程和该目录都打上标签,并且标注其可访问性。这样Apache进程才可以访问该目录。
文章《Linux下SELinux卡通图解,豁然开悟》通过卡通的方式介绍了该机制的原理,非常形象生动。如果对上文的解释还是稀里糊涂,那么推荐看看这篇文章。
SELinux通常并非默认打开的,如果使用该特性需要我们手动打开。当然,SELinux已经为我们做了很多事情了,通常情况下打开后就可以使用,并不需要我们做更多的事情。如果想实时打开SELinux,直接执行如下命令即可。
- setenforce 1
但如果想永久生效,则需要修改SELinux的配置文件。修改起来也非常简单,只需要修改图中红色方框一行的内容即可。
上图中,将disabled修改为enforcing就可以使SELinux永久生效(需重启系统)。另外一个参数是permissive,该参数的含义是只记录日志,不进行实际的控制。
最下面一行参数表示该SELinux使用的规则库。SELinux默认定义了很多规则库,所以通常情况下,我们只需要开启就可以了。但是有时候也并非如此,此时就需要根据情况定义自己的规则(策略,policy)。
SELinux的原理也是比较简单的,其核心是规则库(Policy Database)。当有进程访问资源(例如文件,或者套接字)时,内核中的接口中会通过规则库中的数据进行匹配,如果满足要求,则放行;否则阻止访问,并记录审计日志。