Bonky Zhu
If someone is able to show me that what I think or do is not right, I will happily change, for I seek the truth, by which no one was ever truly harmed. It is the person who continues in his self-deception and ignorance who is harmed.

Linux 之SELinux

什么是 SELinux

SELinux 的全称是 Security Enhanced Linux,SELinux 是由美国国家安全局 (NSA) 开发的,当初开发的目的是因为很多企业界发现, 通常系统出现问题的原因大部分都在于内部员工的资源误用所导致的,实际由外部发动的攻击反而没有这么严重。

所以说,SELinux 是在进行进程、文件等细部权限设定依据的一个核心模块! 由于启动网络服务的也是进程,因此刚好也能够控制网络服务能否存取系统资源的一道关卡。

自主式访问控制 DAC

自主式访问控制 (Discretionary Access Control, DAC),其实就是常规 Linux 的管理制度,通过设置用户,群组和其它人的 rwx 来控制权限。 DAC 有以下问题:

  • root 具有最高的权限:如果不小心某支 root 权限的进程被有心人士取得, 那么这支进程就可以在系统上进行任何资源的存取。这是十分危险的。
  • 使用者可以取得进程来变更文件资源的访问权限:如果你不小心将某个目录的权限设定为 777 ,由于对任何人的权限会变成 rwx ,因此该目录就会被任何人所任意存取。如果碰上不懂 Linux 的用户就 GG 了。

委任式访问控制 MAC

委任式访问控制 (Mandatory Access Control, MAC) 是为了解决了 DAC 所带来的困扰(防止不懂 Linux 的用户乱操作)。

MAC 主要是通过针对特定的进程与特定的文件资源来进行权限的控管,控制的主体不再是用户而是文件进程。举例来说,假如我们运行了 httpd, 默认情况下, httpd 仅能在 /var/www/ 这个目录底下存取文件,如果 httpd 这个进程想要到其他目录去存取数据时, 除了规则设定要开放外,目标目录也得要设定成 httpd 可读取的模式。

image-20200213190300999

工作原理

SELinux 是透过 MAC 的方式来控管进程,他控制的主体是进程, 而目标则是该进程能否读取的文件资源

  • 主体 (Subject):SELinux 主要管理的就是进程
  • 目标 (Object):主体进程能否存取的目标一般就是文件系统。
  • 政策 (Policy):由于进程与文件数量庞大,因此 SELinux 会依据某些服务来制订基本的存取安全性政策。这些政策内还会有详细的规则 (rule) 来指定不同的服务开放某些资源的存取与否。在目前的 CentOS 7.x 里面仅有提供三个主要的政策,分别是:-
    • targeted:针对网络服务限制较多,针对本机限制较少,是预设的政策;
    • minimum:由 target 修订而来,仅针对选择的进程来保护!
    • mls:完整的 SELinux 限制,限制方面较为严格。
    • 建议使用预设的 targeted 政策即可。
  • 安全上下文 (security context):主体能不能存取目标除了指定政策之外,主体与目标的安全性上下文必须一致才能够顺利存取。 其实和 rwx 差不多。

image-20200213191309348

安全上下文

使用 ls -Z 我们可以看到文件的安全上下文:

➜  ~ ls -Z
-rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
-rw-r--r--. root root system_u:object_r:admin_home_t:s0 initial-setup-ks.cfg
drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 ohmyzsh


利用 ps -Z 可以看到进程的安全上下文:

➜  / ps -Z
LABEL                             PID TTY          TIME CMD
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 14308 pts/2 00:00:00 zsh
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 16712 pts/2 00:00:00 ps


安全上下文主要有前三个字段控制:

Identify:role:type

  • 身份识别:unconfined_u:不受限的用户。因为 bash 环境是不受 SELinux 管制的,所以 bash 进程所产生的文件,其身份识别大多就是 unconfined_u 这个不受限用户。
    • system_u:系统用户,大部分就是系统自己产生的文件。
  • 角色:object_r:代表的是文件或目录等文件资源。
    • system_r:代表的就是进程啦!不过,一般使用者也会被指定成为 system_r。
  • 类型:一个主体进程能不能读取到这个文件资源,与类型字段有关。(进程的类型是 domain,一个 domain 可以对应多个文件的类型 type)

image-20200214110530067

一般来说,进程访问文件都是这样检查权限的,以上图为例:

  1. 首先,我们触发一个可执行的目标文件,那就是具有 crond_exec_t 这个类型的 /usr/sbin/crond 文件
  2. 该文件的类型会让这个文件所造成的主体进程 (Subject) 具有 crond 这个领域 (domain), 我们的政策针对这个领域已经制定了许多规则,其中包括这个领域可以读取的目标资源类型
  3. 由于 crond 的 domain 被设定为可以读取 system_cron_spool_t 这个类型的目标文件, 因此你的配置文件放到 /etc/cron.d/ 目录下,就能够被 crond 那支进程所读取了;
  4. 但最终能不能读到正确的资料,还得要看 rwx 是否符合 Linux 权限的规范!

SELinux 的三种模式

image-20200214111345121

  • enforcing:强制模式,代表 SELinux 运作中,且已经正确的开始限制 domain/type 了;
  • permissive:宽容模式:代表 SELinux 运作中,不过仅会有警告讯息并不会实际限制 domain/type 的存取。这种模式可以运来作为 SELinux 的 debug 之用;
  • disabled:关闭,SELinux 并没有实际运作。

我们可以通过 getenforce 得到目前的模式:

➜  ~ getenforce
Enforcing


或者通过 sestatus 查看更加详细的信息:

➜  ~ sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      31


修改的话可以修改配置文件 /etc/selinux/config,如果 pemissive 和 enforcing 模式的切换可以使用 setenforce (不能在 disable 下使用):

➜  ~ setenforce [0|1]
选项与参数:
0 :转成 permissive 宽容模式;
1 :转成 Enforcing 强制模式


getsebool,seinfo, sesearch

seinfo, sesearch 包括在 setools 中,需要自行安装:

➜  ~ yum install setools


getsebool

getsebool [-a] [规则的名称]


设置的话使用 setsebool [-P] 规则名称 [0|1]

seinfo

seinfo [-Atrub]
选项与参数:
-A :列出 SELinux 的状态、规则布尔值、身份识别、角色、类别等所有信息
-u :列出 SELinux 的所有身份识别 (user) 种类
-r :列出 SELinux 的所有角色 (role) 种类
-t :列出 SELinux 的所有类别 (type) 种类
-b :列出所有规则的种类 (布尔值)


sesearch

sesearch [-A] [-s 主体类别] [-t 目标类别] [-b 布尔值]
选项与参数:
-A :列出后面数据中,允许『读取或放行』的相关数据
-t :后面还要接类别,例如 -t httpd_t
-b :后面还要接 SELinux 的规则,例如 -b httpd_enable_ftp_server


找出 crond_t 这个进程能够读取的文件 SELinux type:

➜  ~ sesearch -A -s crond_t | grep spool
   allow crond_t var_spool_t : dir { ioctl read getattr lock search open } ;
   allow crond_t system_cron_spool_t : dir { ioctl read getattr lock search open } ;


allow crond_t var_spool_t : dir 的含义是 domain 为 crond_t 进程可以读取类型为 var_spool_t 的目录。

修改安全上下文

使用 chcon 手动修改文件的 SELinux type

chcon [-R] [-t type] [-u user] [-r role] 文件


下面是一个具体使用例子:

➜  ~ ll -Z /etc/hosts
-rw-r--r--. root root system_u:object_r:net_conf_t:s0   /etc/hosts
➜  ~ chcon -v -t net_conf_t /etc/cron.d/checktime
changing security context of ‘/etc/cron.d/checktime’
➜  ~ ll -Z /etc/cron.d/checktime
-rw-r--r--. root root unconfined_u:object_r:net_conf_t:s0   /etc/cron.d/checktime


使用 restorecon 让文件恢复正确的 SELinux type

手动设置实在太麻烦了,用 restorecon 可以方便快捷的设置:

restorecon [-Rv] 文
选项与参数:
-R :连同次目录一起修改;
-v :将过程显示到屏幕上


semanage 目录的默认安全上下文查询与修改

semanage fcontext -{a|d|m} [-frst] file_spec
选项与参数:
fcontext :主要用在安全性本文方面的用途, -l 为查询的意思;
-a :增加的意思,你可以增加一些目录的默认安全性本文类型设定;
-m :修改的意思;
-d :删除的意思。

Share

You may also like...

发表评论