SELinux的简单介绍
1.Ubuntu11.10支持SELinux :apt-get install selinux
2.安装软件:selinux 、 setools 、 policycoreutils
3.selinux的配置文件:/etc/selinux/config
4.SELinux的工作模式(以centos为标准)
SELinux是通过委任式访问控制(Mandatory Access Control ,MAC),他可以针对特定耳朵程序与特定的文件资源进行权限管理,他控制的主体是程序,而且表则是该程序能否读取文件资源。
主体(Subject)
SELinux主要管理的就是程序。
目标(Object)
主体程序访问的目标资源一般是文件系统。
策略(Policy)
由于程序与文件数量庞大,因此SELinux会依据某些服务来指定基本的访问安全策略。这些策略内会有详细的规则来指定不同的服务开放某些资源的访问与否。
目前有targeted 和 mls 两个主要策略,其中targeted是默认的策略,他针对网络服务限制较多,针对本机限制较少。
安全性环境(Security Context)
主体要符合指定的策略之外,主体和目标的安全性环境必须一致才能顺利访问目标文件
上图的重点在『主体』如何取得『目标』的资源访问权限! 由上图我们可以发现,(1)主体程序必须要通过 SELinux 政策内的规则放行后,就可以与目标资源进行安全性本文的比对, (2)若比对失败则无法存取目标,若比对成功则可以开始存取目标。问题是,最终能否存取目标还是与文件系统的 rwx 权限设定有关喔!如此一来,加入了 SELinux 之后,出现权限不符的情况时,你就得要一步一步的分析可能的问题了!
这个安全性本文你就将他想成 SELinux 内必备的 rwx 就是了,安全性本文是放置到档案的 inode 内。
安全性本文主要用冒号分为三个字段 (最后一个字段先略过不看),这三个字段的意义为:
Identify:role:type
身份识别:角色:类型
- 身份识别 (Identify): 相当于账号方面的身份识别!主要的身份识别则有底下三种常见的类型:
- root:表示 root 的账号身份,如同上面的表格显示的是 root 家目录下的数据啊!
- system_u:表示系统程序方面的识别,通常就是程序啰;
- user_u:代表的是一般使用者账号相关的身份。
- 角色 (Role): 透过角色字段,我们可以知道这个数据是属于程序、档案资源还是代表使用者。一般的角色有:
- object_r:代表的是档案或目录等档案资源,这应该是最常见的啰;
- system_r:代表的就是程序啦!不过,一般使用者也会被指定成为 system_r 喔!
- 类型 (Type): 在预设的 targeted 政策中, Identify 与 Role 字段基本上是不重要的!重要的在于这个类型 (type) 字段! 基本上,一个主体程序能不能读取到这个档案资源,与类型字段有关!而类型字段在档案与程序的定义不太相同,分别是:
- type:在档案资源 (Object) 上面称为类型 (Type);
- domain:在主体程序 (Subject) 则称为领域 (domain) 了!
domain 需要与 type 搭配,则该程序才能够顺利的读取档案资源啦!
程序与档案 SELinux type 字段的相关性
那么这三个字段如何利用呢?首先我们来瞧瞧主体程序在这三个字段的意义为何!透过身份识别与角色字段的定义, 我们可以约略知道某个程序所代表的意义喔!基本上,这些对应资料在 targeted 政策下的对应如下:
身份识别 | 角色 | 该对应在 targeted 的意义 |
root | system_r | 代表供 root 账号登入时所取得的权限 |
system_u | system_r | 由于为系统账号,因此是非交谈式的系统运作程序 |
user_u | system_r | 一般可登入用户的程序啰! |
但就如上所述,其实最重要的字段是类型字段,主体与目标之间是否具有可以读写的权限,与程序的 domain 及档案的 type 有关!这两者的关系我们可以使用达成 WWW 服务器功能的 httpd 这支程序与 /var/www/html 这个网页放置的目录来说明。 首先,看看这两个咚咚的安全性本文内容先:
[root@www ~]# apt-get install httpd [root@www ~]# ll -Zd /usr/sbin/httpd /var/www/html -rwxr-xr-x. root root system_u:object_r:httpd_exec_t:s0 /usr/sbin/httpd drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html # 两者的角色字段都是 object_r ,代表都是档案!而 httpd 属于 httpd_exec_t 类型, # /var/www/html 则属于 httpd_sys_content_t 这个类型! |
httpd 属于 httpd_exec_t 这个可以执行的类型,而 /var/www/html 则属于 httpd_sys_content_t 这个可以让 httpd 领域 (domain) 读取的类型。文字看起来不太容易了解吧!我们使用图示来说明这两者的关系!
图 7.4-2、主体程序取得的 domain 与目标档案资源的 type 相互关系
上图的意义我们可以这样看的:
- 首先,我们触发一个可执行的目标档案,那就是具有 httpd_exec_t 这个类型的 /usr/sbin/httpd
- 该档案的类型会让这个档案所造成的主体程序 (Subject) 具有 httpd 这个领域 (domain), 我们的政策针对这个领域已经制定了许多规则,其中包括这个领域可以读取的目标资源类型;
- 由于 httpd domain 被设定为可以读取 httpd_sys_content_t 这个类型的目标档案 (Object), 因此你的网页放置到 /var/www/html/ 目录下,就能够被 httpd 那支程序所读取了;
- 但最终能不能读到正确的资料,还得要看 rwx 是否符合 Linux 权限的规范!
上述的流程告诉我们几个重点,第一个是政策内需要制订详细的 domain/type 相关性;第二个是若档案的 type 设定错误, 那么即使权限设定为 rwx 全开的 777 ,该主体程序也无法读取目标档案资源的啦!不过如此一来, 也就可以避免用户将他的家目录设定为 777 时所造成的权限困扰。
SELinux type 的修改
既然 SELinux 的类型字段 (type) 这么重要,那如何修改与变更这个字段,当然就是最重要的一件事啰。 首先,我们来看看如果复制一个档案到不同的目录去,会发生什么状况吧!
# 范例:将 /etc/hosts 复制到 root 家目录,并观察相关的 SELinux 类型变化 [root@www ~]# cp /etc/hosts /root [root@www ~]# ls -dZ /etc/hosts /root/hosts /root -rw-r--r--. root root system_u:object_r:net_conf_t:s0 /etc/hosts dr-xr-x---. root root system_u:object_r:admin_home_t:s0 /root -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 /root/hosts # 范例:将 /root/hosts 移动到 /tmp 下,并观察相关的 SELinux 类型变化 [root@www ~]# mv /root/hosts /tmp [root@www ~]# ls -dZ /tmp /tmp/hosts drwxrwxrwt. root root system_u:object_r:tmp_t:s0 /tmp -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 /tmp/hosts |
看到没有?当你单纯的复制时,SELinux 的 type 字段是会继承目标目录的,所以 /root/hosts 的类型就会变成 admin_home_t 这个类型了。但是如果是移动呢?那么连同 SELinux 的类型也会被移动过去,因此 /tmp/hosts 会依旧保持 admin_home_t 而不会变成 /tmp 的 tmp_t 这个类型呦!要注意!要注意!那么,如何将 /tmp/hosts 变更成为最原始的 net_conf_t 这个类型呢?那就得要使用 chcon 啰!
- chcon
[root@www ~]# chcon [-R] [-t type] [-u user] [-r role] 档案 [root@www ~]# chcon [-R] --reference=范例文件 档案 选项与参数: -R :连同该目录下的次目录也同时修改; -t :后面接安全性本文的类型字段!例如 httpd_sys_content_t ; -u :后面接身份识别,例如 system_u; -r :后面街角色,例如 system_r; --reference=范例文件:拿某个档案当范例来修改后续接的档案的类型! # 范例:将刚刚的 /tmp/hosts 类型改为 etc_t 的类型 [root@www ~]# chcon -t net_conf_t /tmp/hosts [root@www ~]# ll -Z /tmp/hosts -rw-r--r--. root root unconfined_u:object_r:net_conf_t:s0 /tmp/hosts # 范例:以 /var/spool/mail/ 为依据,将 /tmp/hosts 修改成该类型 [root@www ~]# ll -dZ /var/spool/mail drwxrwxr-x. root mail system_u:object_r:mail_spool_t:s0 /var/spool/mail [root@www ~]# chcon --reference=/var/spool/mail /tmp/hosts [root@www ~]# ll -Z /tmp/hosts -rw-r--r--. root root system_u:object_r:mail_spool_t:s0 /tmp/hosts |
chcon 的修改方式中,我们必须要知道最终我们的 SELinux type 是啥类型后,才能够变更成功。 如果你想要作的是『复原成原有的 SELinux type』呢?那可以参考底下的指令来进行呦!
- restorecon
[root@www ~]# restorecon [-Rv] 档案或目录 选项与参数: -R :连同次目录一起修改; -v :将过程显示到屏幕上 # 范例:将刚刚 /tmp/hosts 移动至 /root 并以预设的安全性本文改正过来 [root@www ~]# mv /tmp/hosts /root [root@www ~]# ll -Z /root/hosts -rw-r--r--. root root system_u:object_r:mail_spool_t:s0 /root/hosts [root@www ~]# restorecon -Rv /root restorecon reset /root/hosts context system_u:object_r:mail_spool_t:s0-> system_u:object_r:admin_home_t:s0 # 上面这两行其实是同一行喔!表示将 hosts 由 mail_spool_t 改为 admin_home_t |
默认目录的安全性本文查询与修改
透过上面这几个练习,你就会知道啦,SELinux type 恐怕会在档案的复制/移动时产生一些变化,因此需要善用 chcon, restorecon 等指令来进行修订。那你应该还是会想到一件事,那就是, restorecon 怎么会知道每个目录记载的默认 SELinux type 类型呢?这是因为系统有记录嘛!记录在 /etc/selinux/targeted/contexts,但是该目录内有很多不同的数据, 要使用文本编辑器去查阅很麻烦,此时,我们可以透过 semanage 这个指令的功能来查询与修改喔!
[root@www ~]# semanage {login|user|port|interface|fcontext|translation} -l [root@www ~]# semanage fcontext -{a|d|m} [-frst] file_spec 选项与参数: fcontext :主要用在安全性本文方面的用途, -l 为查询的意思; -a :增加的意思,你可以增加一些目录的默认安全性本文类型设定; -m :修改的意思; -d :删除的意思。 # 范例:查询一下 /var/www/ 的预设安全性本文设定为何! [root@www ~]# yum install policycoreutils-python [root@www ~]# semanage fcontext -l | grep '/var/www' SELinux fcontext 类型 Context /var/www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0 /var/www(/.*)?/logs(/.*)? all files system_u:object_r:httpd_log_t:s0 ....(后面省略).... |
从上面的说明,我们知道其实 semanage 可以处理非常多的任务,不过,在这个小节我们主要想了解的是每个目录的默认安全性本文。 如上面范例所示,我们可以查询的到每个目录的安全性本文啦!而目录的设定可以使用正规表示法去指定一个范围。那么如果我们想要增加某些自定义的目录的安全性本文呢? 举例来说,我想要制订 /srv/vbird 成为 public_content_t 的类型时,应该如何指定呢?
# 范例:利用 semanage 设定 /srv/vbird 目录的默认安全性本文为 public_content_t [root@www ~]# mkdir /srv/vbird [root@www ~]# ll -Zd /srv/vbird drwxr-xr-x. root root unconfined_u:object_r:var_t:s0 /srv/vbird # 如上所示,预设的情况应该是 var_t 这个咚咚的! [root@www ~]# semanage fcontext -l | grep '/srv' /srv directory system_u:object_r:var_t:s0 <==看这里 /srv/.* all files system_u:object_r:var_t:s0 ....(底下省略).... # 上面则是预设的 /srv 底下的安全性本文数据,不过,并没有指定到 /srv/vbird 啦 [root@www ~]# semanage fcontext -a -t public_content_t "/srv/vbird(/.*)?" [root@www ~]# semanage fcontext -l | grep '/srv/vbird' /srv/vbird(/.*)? all files system_u:object_r:public_content_t:s0 [root@www ~]# cat /etc/selinux/targeted/contexts/files/file_contexts.local # This file is auto-generated by libsemanage # Please use the semanage command to make changes /srv/vbird(/.*)? system_u:object_r:public_content_t:s0 # 其实就是写入这个档案的啰! ^_^ [root@www ~]# restorecon -Rv /srv/vbird* <==尝试恢复默认值 [root@www ~]# ll -Zd /srv/vbird drwxr-xr-x. root root system_u:object_r:public_content_t:s0 /srv/vbird # 有默认值,以后用 restorecon 来修改比较简单! |
semanage 的功能很多,不过鸟哥主要用到的仅有 fcontext 这个项目的动作而已。如上所示, 你可以使用 semanage 来查询所有的目录默认值,也能够使用他来增加默认值的设定!如果您学会这些基础的工具, 那么 SELinux 对你来说,也不是什么太难的咚咚啰!
SELinux 政策内的规则布尔值修订
前面讲到,要通过 SELinux 的验证之后才能开始档案权限 rwx 的判断,而 SELinux 的判断主要是 (1)政策内的规则比对与 (2)程序与档案的 SELinux type 要符合才能够放行。前一个小节谈的是 SELinux 的 type ,这个小节就是要谈一下政策内的规则啰, 包括如何查询与修改相关的规则放行与否啰。
- 政策查阅
CentOS 6.x 预设使使用 targeted 政策,那么这个政策提供多少相关的规则呢?此时可以透过 seinfo 来查询喔!(Ubuntu :apt-get install setools)
[root@www ~]# yum install setools-console [root@www ~]# seinfo [-Atrub] 选项与参数: -A :列出 SELinux 的状态、规则布尔值、身份识别、角色、类别等所有信息 -t :列出 SELinux 的所有类别 (type) 种类 -r :列出 SELinux 的所有角色 (role) 种类 -u :列出 SELinux 的所有身份识别 (user) 种类 -b :列出所有规则的种类 (布尔值) # 范例一:列出 SELinux 在此政策下的统计状态 [root@www ~]# seinfo tatistics for policy file: /etc/selinux/targeted/policy/policy.24 Policy Version & Type: v.24 (binary, mls) <==列出政策所在档与版本 Classes: 77 Permissions: 229 Sensitivities: 1 Categories: 1024 Types: 3076 Attributes: 251 Users: 9 Roles: 13 Booleans: 173 Cond. Expr.: 208 Allow: 271307 Neverallow: 0 Auditallow: 44 Dontaudit: 163738 Type_trans: 10941 Type_change: 38 Type_member: 44 Role allow: 20 Role_trans: 241 Range_trans: 2590 ....(底下省略).... # 从上面我们可以看到这个政策是 targeted ,此政策的 SELinux type 有 3076 个; # 而针对网络服务的规则 (Booleans) 共制订了 173 条规则! # 范例二:列出与 httpd 有关的规则 (booleans) 有哪些? [root@www ~]# seinfo -b | grep httpd Conditional Booleans: 173 allow_httpd_mod_auth_pam httpd_setrlimit httpd_enable_ftp_server ....(底下省略).... # 你可以看到,有非常多的与 httpd 有关的规则订定呢! |
从上面我们可以看到与 httpd 有关的布尔值,同样的,如果你想要找到有 httpd 字样的安全性本文类别时, 就可以使用『 seinfo -t | grep httpd 』来查询了!如果查询到相关的类别或者是布尔值后,想要知道详细的规则时, 就得要使用 sesearch 这个指令了!
[root@www ~]# sesearch [--all] [-s 主体类别] [-t 目标类别] [-b 布尔值] 选项与参数: --all :列出该类别或布尔值的所有相关信息 -t :后面还要接类别,例如 -t httpd_t -b :后面还要接布尔值的规则,例如 -b httpd_enable_ftp_server # 范例一:找出目标档案资源类别为 httpd_sys_content_t 的有关信息 [root@www ~]# sesearch --all -t httpd_sys_content_t Found 683 semantic av rules: allow avahi_t file_type : filesystem getattr ; allow corosync_t file_type : filesystem getattr ; allow munin_system_plugin_t file_type : filesystem getattr ; ....(底下省略).... # 『 allow 主体程序安全性本文类别 目标档案安全性本文类别 』 # 如上,说明这个类别可以被那个主题程序的类别所读取,以及目标档案资源的格式。 |
你可以很轻易的查询到某个主体程序 (subject) 可以读取的目标档案资源 (Object)。 那如果是布尔值呢?里面又规范了什么?让我们来看看先:
# 范例三:我知道有个布尔值为 httpd_enable_homedirs ,请问该布尔值规范多少规则? [root@www ~]# sesearch -b httpd_enable_homedirs --all Found 43 semantic av rules: allow httpd_user_script_t user_home_dir_t : dir { getattr search open } ; allow httpd_sys_script_t user_home_dir_t : dir { ioctl read getattr } ; ....(后面省略).... |
从这个布尔值的设定我们可以看到里面规范了非常多的主体程序与目标档案资源的放行与否! 所以你知道了,实际规范这些规则的,就是布尔值的项目啦!那也就是我们之前所说的一堆规则是也! 你的主体程序能否对某些目标档案进行存取,与这个布尔值非常有关系喔!因为布尔值可以将规则设定为启动 (1) 或者是关闭 (0) 啦!
- 布尔值的查询与修改
上面我们透过 sesearch 知道了,其实 Subject 与 Object 能否有存取的权限,是与布尔值有关的, 那么系统有多少布尔值可以透过 seinfo -b 来查询,但,每个布尔值是启动的还是关闭的呢?这就来查询看看吧:
[root@www ~]# getsebool [-a] [布尔值条款] 选项与参数: -a :列出目前系统上面的所有布尔值条款设定为开启或关闭值 # 范例一:查询本系统内所有的布尔值设定状况 [root@www ~]# getsebool -a abrt_anon_write --> off allow_console_login --> on allow_cvs_read_shadow --> off ....(底下省略).... # 您瞧!这就告诉你目前的布尔值状态啰! |
那么如果查询到某个布尔值,并且以 sesearch 知道该布尔值的用途后,想要关闭或启动他,又该如何处置?
[root@www ~]# setsebool [-P] 布尔值=[0|1] 选项与参数: -P :直接将设定值写入配置文件,该设定数据未来会生效的! # 范例一:查询 httpd_enable_homedirs 是否为 on,若不为 on 请启动他! [root@www ~]# getsebool httpd_enable_homedirs httpd_enable_homedirs --> off <==结果是 off ,依题意给他启动! [root@www ~]# setsebool -P httpd_enable_homedirs=1 [root@www ~]# getsebool httpd_enable_homedirs httpd_enable_homedirs --> on |
这个 setsebool 最好记得一定要加上 -P 的选项!因为这样才能将此设定写入配置文件! 这是非常棒的工具组!你一定要知道如何使用 getsebool 与 setsebool 才行!