SELinux 是 Security Enhanced Linux 的缩写,字面意思是安全增强型linux
设计目的:避免资源的误用
-摘自鸟哥的linux
SELinux 是由美国国家安全局 (NSA) 开发的,当初开发这玩意儿的目的是因为很多企业界发现, 通常系统出现问题的原因大部分都在於『内部员工的资源误用』所导致的,实际由外部发动的攻击反而没有这么严重。
举例来说,如果有个不是很懂系统的系统管理员为了自己配置的方便,将网页所在目录 /var/www/html/ 的权限配置为 drwxrwxrwx 时,你觉得会有什么事情发生?
现在我们知道所有的系统资源都是透过程序来进行存取的,那么 /var/www/html/ 如果配置为 777 , 代表所有程序均可对该目录存取,万一你真的有启动 WWW 服务器软件,那么该软件所触发的程序将可以写入该目录, 而该程序却是对整个 Internet 提供服务的!只要有心人接触到这支程序,而且该程序刚好又有提供使用者进行写入的功能, 那么外部的人很可能就会对你的系统写入些莫名其妙的东西!那可真是不得了!一个小小的 777 问题可是大大的!
为了控管这方面的权限与程序的问题,所以美国国家安全局就著手处理操作系统这方面的控管。 由於 Linux 是自由软件,程序码都是公开的,因此她们便使用 Linux 来作为研究的目标, 最后更将研究的结果整合到 Linux 核心里面去,那就是 SELinux 啦!所以说, SELinux 是整合到核心的一个模块喔!
更多的 SELinux 相关说明可以参考:http://www.nsa.gov/research/selinux/
这也就是说:其实 SELinux 是在进行程序、文件等细部权限配置依据的一个核心模块! 由於启动网络服务的也是程序,因此刚好也能够控制网络服务能否存取系统资源的一道关卡! 所以,在讲到 SELinux 对系统的存取控制之前,我们得先来回顾一下之前谈到的系统文件权限与使用者之间的关系。 因为先谈完这个你才会知道为何需要 SELinux 的啦!
传统的文件权限与帐号关系:自主式存取控制, DAC
-摘自鸟哥的linux
linux系统的帐号主要分为系统管理员 (root) 与一般用户,而这两种身份能否使用系统上面的文件资源则与 rwx 的权限配置有关。 不过你要注意的是,各种权限配置对 root 是无效的。因此,当某个程序想要对文件进行存取时, 系统就会根据该程序的拥有者/群组,并比对文件的权限,若通过权限检查,就可以存取该文件了
这种存取文件系统的方式被称为『自主式存取控制 (Discretionary Access Control, DAC)』,基本上,就是依据程序的拥有者与文件资源的 rwx 权限来决定有无存取的能力。
不过这种 DAC 的存取控制有几个困扰,那就是:
root 具有最高的权限:如果不小心某支程序被有心人士取得, 且该程序属於 root 的权限,那么这支程序就可以在系统上进行任何资源的存取!真是要命!
使用者可以取得程序来变更文件资源的存取权限:如果你不小心将某个目录的权限配置为 777 ,由於对任何人的权限会变成 rwx ,因此该目录就会被任何人所任意存取!
这些问题是非常严重的!尤其是当你的系统是被某些漫不经心的系统管理员所掌控时!她们甚至觉得目录权限调为 777 也没有什么了不起的危险哩…
以政策守则订定特定程序读取特定文件:委任式存取控制, MAC
-摘自鸟哥的linux
现在我们知道 DAC 的困扰就是当使用者取得程序后,他可以藉由这支程序与自己默认的权限来处理他自己的文件资源。 万一这个使用者对 Linux 系统不熟,那就很可能会有资源误用的问题产生。为了避免 DAC 容易发生的问题,因此 SELinux 导入了委任式存取控制 (Mandatory Access Control, MAC) 的方法!
委任式存取控制 (MAC) 有趣啦!他可以针对特定的程序与特定的文件资源来进行权限的控管! 也就是说,即使你是 root ,那么在使用不同的程序时,你所能取得的权限并不一定是 root , 而得要看当时该程序的配置而定。如此一来,我们针对控制的『主体』变成了『程序』而不是使用者喔! 此外,这个主体程序也不能任意使用系统文件资源,因为每个文件资源也有针对该主体程序配置可取用的权限! 如此一来,控制项目就细的多了!但整个系统程序那么多、文件那么多,一项一项控制可就没完没了! 所以 SELinux 也提供一些默认的政策 (Policy) ,并在该政策内提供多个守则 (rule) ,让你可以选择是否激活该控制守则!
在委任式存取控制的配置下,我们的程序能够活动的空间就变小了!举例来说, WWW 服务器软件的达成程序为 httpd 这支程序, 而默认情况下, httpd 仅能在 /var/www/ 这个目录底下存取文件,如果 httpd 这个程序想要到其他目录去存取数据时, 除了守则配置要开放外,目标目录也得要配置成 httpd 可读取的模式 (type) 才行喔!限制非常多! 所以,即使不小心 httpd 被 cracker 取得了控制权,他也无权浏览 /etc/shadow 等重要的配置档喔!
从 Android 4.3 起,SELinux 开始为传统的自主访问控制 (DAC) 环境提供强制访问控制 (MAC) 保护功能。例如,软件通常情况下必须以 Root 用户帐号的身份运行,才能向原始块设备写入数据。在基于 DAC 的传统 Linux 环境中,如果 Root 用户遭到入侵,攻击者便可以利用该用户身份向每个原始块设备写入数据。不过,可以使用 SELinux 为这些设备添加标签,以便被分配了 Root 权限的进程可以只向相关政策中指定的设备写入数据。这样一来,该进程便无法重写特定原始块设备之外的数据和系统设置。
-摘自鸟哥的linux
再次的重复说明一下,SELinux 是透过 MAC 的方式来控管程序,他控制的主体是程序, 而目标则是该程序能否读取的『文件资源』!所以先来说明一下这些咚咚的相关性啦!
主体 (Subject):
SELinux 主要想要管理的就是程序,因此你可以将『主体』跟本章谈到的 process 划上等号;
目标 (Object):
主体程序能否存取的『目标资源』一般就是文件系统。因此这个目标项目可以等文件系统划上等号;
政策 (Policy):
由於程序与文件数量庞大,因此 SELinux 会依据某些服务来制订基本的存取安全性政策。这些政策内还会有详细的守则 (rule) 来指定不同的服务开放某些资源的存取与否。在目前的 CentOS 5.x 里面仅有提供两个主要的政策,分别是:
targeted:针对网络服务限制较多,针对本机限制较少,是默认的政策;
strict:完整的 SELinux 限制,限制方面较为严格。
建议使用默认的 targeted 政策即可。
安全性本文 (security context):
我们刚刚谈到了主体、目标与政策面,但是主体能不能存取目标除了政策指定之外,主体与目标的安全性本文必须一致才能够顺利存取。 这个安全性本文 (security context) 有点类似文件系统的 rwx 啦!安全性本文的内容与配置是非常重要的! 如果配置错误,你的某些服务(主体程序)就无法存取文件系统(目标资源),当然就会一直出现『权限不符』的错误信息了!
上图的重点在『主体』如何取得『目标』的资源存取权限! 由上图我们可以发现,主体程序必须要通过 SELinux 政策内的守则放行后,就可以与目标资源进行安全性本文的比对, 若比对失败则无法存取目标,若比对成功则可以开始存取目标。问题是,最终能否存取目标还是与文件系统的 rwx 权限配置有关喔!如此一来,加入了 SELinux 之后,出现权限不符的情况时,你就得要一步一步的分析可能的问题了!
安全性本文 (Security Context)
安全性本文存在於主体程序中与目标文件资源中。程序在内存内,所以安全性本文可以存入是没问题。 那文件的安全性本文是记录在哪里呢?事实上, 安全性本文是放置到文件的 inode 内的 ,因此主体程序想要读取目标文件资源时,同样需要读取 inode , 这 inode 内就可以比对安全性本文以及 rwx 等权限值是否正确,而给予适当的读取权限依据。
那么安全性本文到底是什么样的存在呢?我们先来看看 /root 底下的文件的安全性本文好了。 观察安全性本文可使用『 ls -Z 』去观察如下:(注意:你必须已经启动了 SELinux 才行!)
如上所示,安全性本文主要用冒号分为三个栏位,这三个栏位的意义为:
这三个栏位的意义仔细的说明一下吧:
身份识别 (Identify):
相当於帐号方面的身份识别!主要的身份识别则有底下三种常见的类型:
root:表示 root 的帐号身份,如同上面的表格显示的是 root 家目录下的数据啊!
system_u:表示系统程序方面的识别,通常就是程序罗;
user_u:代表的是一般使用者帐号相关的身份。
你会发现身份识别中,除了 root 之外,其他的识别后面都会加上『 _u 』的字样呢! 这个身份识别重点再让我们了解该数据为何种身份所有哩~ 而系统上面大部分的数据都会是 system_u 或 root 啦!至於如果是在 /home 底下的数据,那么大部分应该就会是 user_u 罗!
透过角色栏位,我们可以知道这个数据是属於程序、文件资源还是代表使用者。一般的角色有:
object_r:代表的是文件或目录等文件资源,这应该是最常见的罗;
system_r:代表的就是程序啦!不过,一般使用者也会被指定成为 system_r 喔!
你也会发现角色的栏位最后面使用『 _r 』来结尾!因为是 role 的意思嘛!
在默认的 targeted 政策中, Identify 与 Role 栏位基本上是不重要的!重要的在於这个类型 (type) 栏位! 基本上,一个主体程序能不能读取到这个文件资源,与类型栏位有关!而类型栏位在文件与程序的定义不太相同,分别是:
type:在文件资源 (Object) 上面称为类型 (Type);
domain:在主体程序 (Subject) 则称为领域 (domain) 了!
domain 需要与 type 搭配,则该程序才能够顺利的读取文件资源啦!
程序与文件 SELinux type 栏位的相关性
那么这三个栏位如何利用呢?首先我们来瞧瞧主体程序在这三个栏位的意义为何!透过身份识别与角色栏位的定义, 我们可以约略知道某个程序所代表的意义喔!基本上,这些对应数据在 targeted 政策下的对应如下:
但就如上所述,其实最重要的栏位是类型栏位,主体与目标之间是否具有可以读写的权限,与程序的 domain 及文件的 type 有关!这两者的关系我们可以使用达成 WWW 服务器功能的 httpd 这支程序与 /var/www/html 这个网页放置的目录来说明。 首先,看看这两个咚咚的安全性本文内容先:
httpd 属於 httpd_exec_t 这个可以运行的类型,而 /var/www/html 则属於 httpd_sys_content_t 这个可以让 httpd 领域 (domain) 读取的类型。文字看起来不太容易了解吧!我们使用图示来说明这两者的关系!
上图的意义我们可以这样看的:
1. 首先,我们触发一个可运行的目标文件,那就是具有 httpd_exec_t 这个类型的 /usr/sbin/httpd 文件;
2. 该文件的类型会让这个文件所造成的主体程序 (Subject) 具有 httpd 这个领域(domain),
我们的政策针对这个领域已经制定了许多守则,其中包括这个领域可以读取的目标资源类型;
3. 由於 httpd domain 被配置为可以读取 httpd_sys_content_t 这个类型的目标文件 (Object),
因此你的网页放置到 /var/www/html/ 目录下,就能够被 httpd 那支程序所读取了;
4. 但最终能不能读到正确的数据,还得要看 rwx 是否符合 Linux 权限的规范!
上述的流程告诉我们几个重点,第一个是政策内需要制订详细的 domain/type 相关性;第二个是若文件的 type 配置错误, 那么即使权限配置为 rwx 全开的 777 ,该主体程序也无法读取目标文件资源的啦!不过如此一来, 也就可以避免使用者将他的家目录配置为 777 时所造成的权限困扰。
目前SELinux支持三种模式:
那你怎么知道目前的 SELinux 模式呢?就透过 getenforce 吧!
另外,我们又如何知道 SELinux 的政策 (Policy) 为何呢?这时可以使用 sestatus 来观察:
如果你已经在 Enforcing 的模式,但是可能由於一些配置的问题导致 SELinux 让某些服务无法正常的运行, 此时你可以将 Enforcing 的模式改为宽容 (permissive) 的模式,让 SELinux 只会警告无法顺利连线的信息, 而不是直接抵挡主体程序的读取权限。让 SELinux 模式在 enforcing 与 permissive 之间切换的方法为:
不过请注意, setenforce 无法在 Disabled 的模式底下进行模式的切换喔!
有时候安全性文本是错误,我们想临时修改一下,那么怎么修改呢?可以通过两个命令。
首先我们使用 chcon 来处理:
chcon 是透过直接指定的方式来处理安全性本文的类型数据。那我们知道其实系统默认的目录都有特殊的 SELinux 安全性本文, 举例来说, /var/www/html 原本就是 httpd 可以读取的目录嘛!既然如此,那有没有可以使用默认的安全性本文来还原的方式? 有的,那就是 restorecon 这玩意儿:
这个过程完全没有动到 rwx 权限, 因为该权限本来就是对的!而错的部分是在於 SELinux 的安全性本文当中那个类型 (type) 配置错误! 而配置错误的原因很可能是因为该文件由其他位置复制或移动过来所导致的!因此, 你得要善用 restorecon 以及 chcon 来处理这方面的问题喔!
由於 SELinux 是整合到核心的一个核心功能,因此你几乎不需要启动什么额外的服务来开启 SELinux 的。 启动完成后, SELinux 就启动了。不过,你刚刚也发现到当我们复制或移动某些数据到特定的目录时, 可能由於没有注意到修改 SELinux 的安全性本文内容,结果导致网络服务无法顺利运行的问题! 有没有什么方法可以记录当发生 SELinux 错误时,将那些有用的资讯记录下来,并且提供解决的方案呢? 此时就得要底下的几个服务的辅助罗!
auditd –> 详细数据写入 /var/log/audit/audit.log
audit 是稽核的意思,这个 auditd 会将 SELinux 发生的错误资讯写入 /var/log/audit/audit.log 中! 与上个服务相同的,你最好在启动时就配置这服务为启动的模式,因此可以照样造句:
与 setroubleshoot 不同的是, auditd 会将许多的 SELinux 资讯都记录下来,不只是错误信息而已, 因此登录档 /var/log/audit/audit.log 非常的庞大!要直接到这文件里面去搜寻数据是挺累人的~ 还好,SELinux 有提供一个 audit2why 的命令来让我们查询错误信息的回报呢!那么这个命令如何使用呢? 可以这样用的:
audit2why 的用法与输出结果如上,比较有趣的是那个 AVC ,AVC 是 access vector cache 的缩写, 目的是记录所有与 SELinux 有关的存取统计数据。输出的资讯当中,会有谈到产生错误的问题为何,如上表特殊字体部分, 你会发现错误信息主要告知 type 不符,所以导致错误的发生啊!不过,就鸟哥来看,我个人觉得 setroubleshoot 比较好用呢! 这两个好东西都可以帮助你解决 SELinux 的错误,因此,请务必至少要学会其中一项错误分析的方法喔!
现在你应该知道,一个主体程序能否读取到目标文件资源的重点在於 SELinux 的政策以及政策内的各项守则, 然后再透过该守则的定义去处理各目标文件的安全性本文,尤其是『类型』的部分。现在我们也知道可以透过 sestatus 与 getenforce 去取得目前的 SELinux 状态。 但是,能不能知道更详细的政策说明与守则项目呢?底下我们就来了解了解!
你可以很轻易的查询到某个主体程序 (subject) 可以读取的目标文件资源 (Object) , 从我们上面的练习,我们也可以很轻松的就知道,为何 httpd_t 可以读取 httpd_sys_content_t 罗! 那如果是布林值呢?里面又规范了什么?让我们来看看先:
从这个布林值的配置我们可以看到里面规范了非常多的主体程序与目标文件资源的放行与否! 所以你知道了,实际规范这些守则的,就是布林值的项目啦!那也就是我们之前所说的一堆守则是也! 你的主体程序能否对某些目标文件进行存取,与这个布林值非常有关系喔!因为布林值可以将守则配置为启动 (1) 或者是关闭 (0) 啦!
由 seinfo 与 sesearch 的输出资讯,我们也会得到实际的政策数据都是放置到 /etc/selinux/targeted/policy/ 底下, 事实上,所有与 targetd 相关的资讯都是放置到 /etc/selinux/targeted 里面的呢!包括安全性本文相关的资讯。
布林值的查询与修改
上面我们透过 sesearch 知道了,其实 Subject 与 Object 能否有存取的权限,是与布林值有关的, 那么系统有多少布林值可以透过 seinfo -b 来查询,但,每个布林值是启动的还是关闭的呢?这就来查询看看吧:
那么如果查询到某个布林值,并且以 sesearch 知道该布林值的用途后,想要关闭或启动他,又该如何处置?
这个 setsebool 最好记得一定要加上 -P 的选项!因为这样才能将此配置写入配置档! 这是非常棒的工具组!你一定要知道如何使用 getsebool 与 setsebool 才行!
布林值的查询与修改
还记得我们在使用 restorecon 时谈到每个目录或文件都会有默认的安全性本文吗? 会制订目录的安全性本文,是因为系统的一些服务所放置文件的目录已经是确定的,当然有默认的安全性本文管理上较方便。 那你如何查询这些目录的默认安全性本文呢?就得要使用 semanage 罗!
从上面的说明,我们知道其实 semanage 可以处理非常多的任务,不过,在这个小节我们主要想了解的是每个目录的默认安全性本文。 如上面范例一所示,我们可以查询的到每个目录的安全性本文啦!而目录的配置可以使用正规表示法去指定一个范围。那么如果我们想要添加某些自订的目录的安全性本文呢? 举例来说,我想要制订 /srv/samba 成为 public_content_t 的类型时,应该如何指定呢?
semanage 的功能很多,不过鸟哥主要用到的仅有 fcontext 这个项目的动作而已。如上所示, 你可以使用 semanage 来查询所有的目录默认值,也能够使用他来添加默认值的配置!如果您学会这些基础的工具, 那么 SELinux 对你来说,也不是什么太难的咚咚罗!