vlambda博客
学习文章列表

Linux安全:SELinux 基本概念

SELinux (Security-Enhanced Linux) ,是由NSA发起对Linux系统的强制性安全审查机制,在Linux Kernel 2.6 版本后,被整合进入内核,是目前使用较为广泛的Linux系统安全方案。

在理解 SELinux前,首先有必要知道Linux Security Module(LSM) 。LSM 所要解决的核心问题其实就是

May <subject> do <action> to <object>

其中:

  • 主体(Subject):SELinux 主要想要管理的就是程序

  • 目标(Object):主体程序能否存取的“目标资源”一般就是文件系统,也包括套接字、端口等可被访问或使用的资源。

  • 动作(Action):就是主体对目标所做的动作,如读、写

其在系统中的大体逻辑如下图

  1. 进程通过系统调用(System Call) 访问某个资源,进入Kernel 后,先会做基本的检测,如果异常则直接返回;

  2. Linux Kernel DAC 审查,如果异常则直接返回;

  3. 调用Linux Kernel Modules 的相关hooks,对接到SELinux 的hooks,进而进行MAC 验证,如果异常则直接返回;

  4. 访问真正的系统资源;

  5. 返回用户态,将结果反馈。

在以上过程中,DAC 是Discretionary Access Control,即自主访问控制, 主要涉及文件和目录的权限和所有权。通过使用权限位对user/group/other进行简单的权限匹配,相对精细化的如sudo、capabilities等都属于这一层的检查。

与DAC相对应的是MAC(Mandatory Access Control)强制访问控制,会使权限管理粒度更细。没有超级用户的概念,并且从上述流程中可以发现,该限制单元是独立于传统的Linux安全机制运作的。SELinux就是其中最常见的一种。

SELinux 相关概念

在继续学习SELinux前,还需要先理解一下SELinux中涉及的基本概念。

主体(Subject)、 目标(Object)

同上文所提到的 Subject 和 Object

政策(Policy)

由于程序与文件数量庞大,因此SELinux 会依据某些服务来制订基本的存取安全性政策。这些政策内还会有详细的规则(rule) 来指定不同的服务开放某些资源的存取与否。在目前的CentOS 7.x 里面仅有提供三个主要的政策,分别是:

  • targeted:针对网络服务限制较多,针对本机限制较少,是默认的政策;

  • minimum:由target 修订而来,仅针对选择的程序来保护!

  • mls:完整的SELinux 限制,限制方面较为严格。建议使用默认的targeted 政策即可。

安全上下文(security context)

类似文件系统的 rwx的安全性文本,存在于主体程序中与目标文件资源中。程序在内存内,所以安全性本文也就在内存内;而文件的安全上下文则是放置到文件的 inode 内的,因此主体程序想要读取目标文件资源时,同样需要读取 inode , 这 inode 内就可以比对安全性本文以及 rwx 等权限值是否正确,而给予适当的读取权限依据。

以文件的安全上下文为例,其主要内容结构如下

# 使用 ls -Z 可以显示安全上下文的内容,必须已经启动了 SELinux 才行
-rw-r--r--. root root system_u:object_r:admin_home_t:s0 initial-setup-ks.cfg

以上system_u:object_r:admin_home_t:s0 就是安全性本文的内容,安全性本文主要用冒号分为五个字段,其中后两个不是必须的,这五个字段的意义为

Identify:role:type:sensitivity:category
身份识别:角色:类型:安全级别:分类

  • 身份识别 (Identify): 相当于账号方面的身份识别,字段最后面使用_u来结尾,可以使用命令seinfo -u列出系统中所有类型,常见的有下面几种类型

  • unconfined_u:不受限的用户,也就是说,该文件来自于不受限的程序所产生的!一般来说,我们使用可登陆账号来取得 bash 之后, 默认的 bash 环境是不受 SELinux 管制的~因为 bash 并不是什么特别的网络服务!因此,在这个不受 SELinux 所限制的 bash 程序所产生的文件, 其身份识别大多就是 unconfined_u 这个“不受限”用户

  • system_u:系统用户,大部分就是系统自己产生的文件

  • 角色 (Role): 表示这个数据是属于程序、文件资源还是代表使用者,字段最后面使用_r来结尾,可以使用命令seinfo -r列出系统中所有角色,一般的角色有

  • object_r:代表的是文件或目录等文件资源,这应该是最常见的

  • system_r:代表的就是程序,不过,一般使用者也会被指定成为 system_r

  • 类型 (Type): 规则中定义何种进程类型访问何种文件Target策略基于type实现,可以使用命令seinfo -t列出系统中所有类型。这部分是SELinux中最重要的部分,在下面会继续提到。

  • 安全级别(Sensitivity):限制访问的需要,由组织定义的分层安全级别,如unclassified,secret,top,secret,一个对象有且只要一个sensitivity,分0-15级,s0最低,Target策略默认使用s0

  • 分类(Category):对于特定组织划分不分层的分类,如FBI Secret,NSA secret,一个对象可以有多个catagroy,c0-c1-23共1024个分类,Target策略不适用category

SELinux 工作过程

Selinux 模块主要又可拆分为如下三个模块

  • 安全服务器:在系统初始化阶段加载好规则

  • 访问向量缓存:简称AVC,主要会为LSM Hook提供接口,如果命中缓存,会立刻返回结果;如果没有,则会访问安全服务器获取策略并缓存起来。

  • SELinux文件系统 :该虚拟文件系统其实就是存储访问策略的规则数据库,会在系统启动时,以文件系统类型为selinuxfs的虚拟文件系统,挂载到/sys/fs/selinux这个目录中。

其中的比对过程,下面具体介绍一下,首先,通过ps -Z可以查看程序的安全上下文文本

# ps -eZ
LABEL PID TTY TIME CMD
system_u:system_r:kernel_t:s0 1 ? 00:00:02 systemd
system_u:system_r:kernel_t:s0 2 ? 00:00:00 kthreadd
system_u:system_r:kernel_t:s0 4 ? 00:00:00 kworker/0:0H
system_u:system_r:kernel_t:s0 6 ? 00:00:00 ksoftirqd/0
....
unconfined_u:unconfined_r:unconfined_t:s0 10124 pts/2 00:00:00 bash

基本上程序主要就分为两大类,一种是系统有受限的 system_u:system_r,另一种则可能是用户自己的,比较不受限的程序 (通常是本机用户自己执行的程序),亦即是 unconfined_u:unconfined_r 这两种

基本上,这些对应数据在 targeted 政策下的对应如下

  • unconfined_u: unconfined_r 一般可登录使用者的程序啰!比较没有受限的程序之意!大多数都是用户已经顺利登陆系统 (不论是网络还是本机登陆来取得可用的 shell) 后, 所用来操作系统的程序!如 bash, X window 相关软件等。

  • system_u:system_r 由于system_r为系统账号,因此是非交谈式的系统运行程序,大多数的系统程序均是这种类型

如上所述,在默认的 target 政策下,其实最重要的字段是类型字段 (type),所以接上文提到的安全性上下文中的Type,该类型字段在文件与程序的定义中不太相同的,在文件资源 (Object) 上面称为类型 (Type);在主体程序 (Subject) 则称为领域 (domain) 了。domain 需要与 type 搭配,程序才能够顺利地读取文件资源。

httpd服务为例,执行如下命令,查看程序的domain为httpd_t和文件的type为httpd_sys_content_t 之间拥有的权限,如果检查匹配则允许相关的操作。

sesearch --allow --source httpd_t --target httpd_sys_content_t --class file
Found 6 semantic av rules:
allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock map open } ;
allow httpd_t httpd_content_type : file { ioctl read getattr lock map open } ;
allow httpd_t httpdcontent : file { ioctl read write create getattr setattr lock append unlink link rename open } ;
allow httpd_t httpdcontent : file { ioctl read getattr map execute execute_no_trans open } ;
allow domain file_type : file map ;
allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ;

接下来会具体学习Selinux的管理。

相关资料

  • SELinux 入门详解

  • 简介SELinux的在CentOS 7 – 第1部分:基本概念

  • 简介SELinux的在CentOS 7 – 第2部分:文件和进程

  • SELinux基本概念详解

  • 深入解析Linux系统中的SELinux访问控制功能