鸟哥的Linux私房菜读书笔记--SELinux初探

版权声明:本文属博主原创,转载请联系QQ528055624 https://blog.csdn.net/qq_41825534/article/details/83242279

1、什么是SELinux

security Enhanced Linux,SELinux,字面意思是安全强化的linux

<1>当初设计的目标:避免资源的误用

SELinux是由美国安全局(NSA)开发的,目的在与因为很多企业界发现,通常系统出现问题的原因大部分在于内部员工的资源误用所导致的,实际由外部发动的攻击反而没有那么严重。SELinux是在进程、文件等细部权限设定依据的一个核心模块,由于启动网络服务的也是进程,因此能够控制网络服务能否存取系统资源的一道关卡。

<2>传统文件权限与账号关系:自主式访问控制DAC

当某个进程想要对文件进行存取时,系统会根据进程的拥有者/群组,并比对文件的权限,若通过权限检查就可以存取该文件了,这种存取文件系统的方式被称为自主式访问控制(discretionary Access Control,DAC),依据进程的拥有者与文件资源的rwx权限来决定有无存取能力,DAC的访问困扰:

· root 具有最高的权限:如果不小心某支进程被有心人士取得, 且该进程属于 root 的权限,那么这支进程就可以在系统上进行任何资源的存取!真是要命!
· 使用者可以取得进程来变更文件资源的访问权限:如果你不小心将某个目录的权限设定为 777 ,由于对任何人的权限会变成 rwx ,因此该目录就会被任何人所任意存取!

<3>以政策规则订定特定进程读取特定文件:委任式访问控制,MAC

DAC的困扰就是当使用者取得进程后,可以藉由这支进程与自己预设的权限来处理他自己的文件资源,如果该用户对Linux系统不熟悉,可能会导致资源误用的问题,为了避免DAC容易发生的问题,SELinux导入委任式访问控制MAC

MAC,可以针对特定的进程与特定的文件资源来进行权限的管控,即使你是root,在是用哪个不同的进程的时,你所取得的权限不一定是root,而是根据该进程的设定而设定的,由此,针对控制的主体就变成了进程而不是使用者

左图是没有 SELinux 的 DAC 存取结果,apache 这只 root 所主导的进程,可以在这三个目录内作任何文件的新建与修改。右边则是加上 SELinux 的 MAC 管理的结果,SELinux 仅会针对 Apache 这个『 process 』放行部份的目录, 其他的非正规目录就不会放行给 Apache 使用!因此不管你是谁,就是不能穿透 MAC 的框框!

2、 SELinux 的运作模式
SELinux 是透过 MAC 的方式来控管进程,他控制的主体是进程, 而目标则是该进程能否读取的『文件资源』!所以先来说明一下这些咚咚的相关性啦!
· 主体 (Subject):SELinux 主要想要管理的就是进程,因此你可以将『主体』跟本章谈到的 process 划上等号;
· 目标 (Object):主体进程能否存取的『目标资源』一般就是文件系统。因此这个目标项目可以等文件系统划上等号;
· 政策 (Policy):由于进程与文件数量庞大,因此 SELinux 会依据某些服务来制订基本的存取安全性政策。这些政策内还会有详细的规则 (rule) 来指定不同的服务开放某些资源的存取与否。在目前的 CentOS 7.x 里面仅有提供三个主要的政策,分别是:
o targeted:针对网络服务限制较多,针对本机限制较少,是预设的政策;
o minimum:由 target 修订而来,仅针对选择的进程来保护!
o mls:完整的 SELinux 限制,限制方面较为严格。
建议使用预设的 targeted 政策即可。
· 安全性本文 (security context):我们刚刚谈到了主体、目标与政策面,但是主体能不能存取目标除了政策指定之外,主体与目标的安全性本文必须一致才能够顺利存取。这个安全性本文 (security context) 有点类似文件系统的 rwx 啦!安全性本文的内容与设定是非常重要的! 如果设定错误,你的某些服务(主体进程)就无法存取文件系统(目标资源),当然就会一直出现『权限不符』的错误讯息了!

上图的重点在『主体』如何取得『目标』的资源访问权限! 由上图我们可以发现,(1)主体进程必须要通过 SELinux 政策内的规则放行后,就可以与目标资源进行安全性本文的比对, (2)若比对失败则无法存取目标,若比对成功则可以开始存取目标。问题是,最终能否存取目标还是与文件系统的 rwx 权限设定有关

<1>安全性文本(security context)

centos 7.x的target政策制定了非常多的规则,因此,只需要知道如何开启/关闭某项规则放行即可。安全性文本是放置在inode中国的,主体想要读取目标文件资源时,需要读取inode,在inode内就可以比对安全性文本以及rwx权限是否正确,从而给予适当的读取权限依据

· 身份识别 (Identify):相当于账号方面的身份识别!主要的身份识别常见有底下几种常见的类型:
o unconfined_u:不受限的用户,也就是说,该文件来自于不受限的进程所产生的!一般来说,我们使用可登入账号来取得 bash 之后, 预设的 bash 环境是不受 SELinux 管制的~因为 bash 并不是什么特别的网络服务!因此,在这个不受 SELinux 所限制的 bash 进程所产生的文件,其身份识别大多就是 unconfined_u 这个『不受限』用户啰!
o system_u:系统用户,大部分就是系统自己产生的文件啰!
基本上,如果是系统或软件本身所提供的文件,大多就是 system_u 这个身份名称,而如果是我们用户透过 bash 自己建立的文件,大多则是不受限的 unconfined_u 身份~如果是网络服务所产生的文件,或者是系统服务运作过程产生的文件,则大部分的识别就会是 system_u 啰!因为鸟哥这边教大家使用文字界面来产生许多的数据,因此你看上面的三个文件中,系统安装主动产生的 anaconda-ks.cfs 及 initial-setup-ks.cfg 就会是 system_u,而我们自己从网络上面抓下来的 regular_express.txt 就会是 unconfined_u 这个识别啊!
· 角色 (Role):透过角色字段,我们可以知道这个资料是属于进程、文件资源还是代表使用者。一般的角色有:
o object_r:代表的是文件或目录等文件资源,这应该是最常见的啰;
o system_r:代表的就是进程啦!不过,一般使用者也会被指定成为 system_r 喔!
你也会发现角色的字段最后面使用『 _r 』来结尾!因为是 role 的意思嘛!
· 类型 (Type) (最重要!):在预设的 targeted 政策中, Identify 与 Role 字段基本上是不重要的!重要的在于这个类型(type) 字段! 基本上,一个主体进程能不能读取到这个文件资源,与类型字段有关!而类型字段在文件与进程的定义不太相同,分别是:
o type:在文件资源 (Object) 上面称为类型 (Type);
o domain:在主体进程 (Subject) 则称为领域 (domain) 了!domain 需要与 type 搭配,则该进程才能够顺利的读取文件资源啦!

<2>进程与文件SELinux type字段的相关性

命令:$  ps -eZ     #观察系统进程的SELinux的相关信息

显示的内容在target政策的对应如下

身份识别  角色 该对应在 targeted 的意义
unconfined_u  unconfined_r 一般可登入使用者的进程啰!比较没有受限的进程之意!大多数都是用户已经顺利登入系统 (不论是网络还是本机登入来取得可用的 shell) 后, 所用来操作系统的进程!如 bash, X window 相关软件等。
system_u  system_r 由于为系统账号,因此是非交谈式的系统运作进程,大多数的系统进程均是这种类型!

 但就如上所述,在预设的 target 政策下,其实最重要的字段是类型字段 (type), 主体与目标之间是否具有可以读写的权限,与进程的 domain 及文件的 type 有关!这两者的关系我们可以使用 crond 以及他的配置文件来说明! 亦即是 /usr/sbin/crond, /etc/crontab, /etc/cron.d 等文件来说明。 

当我们执行 /usr/sbin/crond 之后,这个程序变成的进程的 domain 类型会是 crond_t 这一个~而这个
crond_t 能够读取的配置文件则为 system_cron_spool_t 这种的类型。因此不论 /etc/crontab, /etc/cron.d 
以及 /var/spool/cron 都会是相关的 SELinux 类型 (/var/spool/cron 为 user_cron_spool_t)。 文字看起
来不太容易了解,我们使用图示来说明这几个东西的关系!

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

3、SELinux三种模式的启动、关闭与观察

并非所有的Linux系统都支持SELinux,首先你需要先观察一下你的Linux系统是否支持,对于centos7.x都支持SELinux。

目前SELinux依据启动与否共有三种模式

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

如果是 Disabled 的模式,那么 SELinux 将不会运作,当然受限的进程也不会经过 SELinux , 也是直接去判断 rwx 而已。那如果是宽容 (permissive) 模式呢?这种模式也是不会将主体进程抵挡 (所以箭头是可以直接穿透的喔!),不过万一没有通过政策规则,或者是安全本文的比对时, 那么该读写动作将会被纪录起来 (log),可作为未来检查问题的判断依据。至于最终那个 Enforcing 模式,就是实际将受限主体进入规则比对、安全本文比对的流程,若失败,就直接抵挡主体进程的读写行为,并且将他记录下来。 如果通通没问题,这才进入到 rwx 权限的判断。

查询目前的SELinux模式:命令:$  getenforce

查询SELinux的政策:

[root@study ~]# sestatus [-vb]
选项与参数:
-v :检查列于 /etc/sestatus.conf 内的文件与进程的安全性本文内容;
-b :将目前政策的规则布尔值列出,亦即某些规则 (rule) 是否要启动 (0/1) 之意;
范例一:列出目前的 SELinux 使用哪个政策 (Policy)?
[root@study ~]# sestatus
SELinux status: enabled                 <==是否启动 SELinux
SELinuxfs mount: /sys/fs/selinux        <==SELinux 的相关文件数据挂载点
SELinux root directory: /etc/selinux    <==SELinux 的根目录所在
Loaded policy name: targeted            <==目前的政策为何?
Current mode: enforcing                 <==目前的模式
Mode from config file: enforcing        <==目前配置文件内规范的 SELinux 模式
Policy MLS status: enabled              <==是否含有 MLS 的模式机制
Policy deny_unknown status: allowed     <==是否预设抵挡未知的主体进程
Max kernel policy version: 28 
如上所示,目前是启动的,而且是 Enforcing 模式,而由配置文件查询得知亦为 Enforcing 模式。 此
外,目前的预设政策为 targeted 这一个。SELinux 的配置文件是/etc/selinux/config 
[root@study ~]# vim /etc/selinux/config
SELINUX=enforcing                       <==调整 enforcing|disabled|permissive
SELINUXTYPE=targeted                    <==目前仅有 targeted, mls, minimum 三种政策

<1>SELinux的启动与关闭

如果改变政策则需要重新启动,如果已经在Enforcing的模式下,但是可能由于一些设定的导致SELinux让某些服务无法正常运作,此时你可以将Enforcing的模式改为宽容模式,让SELinux只会警告无法顺利联机的讯息,而不是直接抵挡主体进程的读取权限,让SELinux模式在Enforcing与permissive之间切换的方法为:

命令:$  setenforce  [0|1]    #其中0代表转化成peimissive宽容模式;1代表转成Enforcing强制模式

4、SELinux政策内的规则管理

<1>SELinux各个规则的布尔值查询getsebool

[root@study ~]# getsebool [-a] [规则的名称]
选项与参数:
-a :列出目前系统上面的所有 SELinux 规则的布尔值为开启或关闭值

或者使用命令:$  sestatus -b

<2>SELinux各个规则规范的主题进程能够读取的文件SELinux type查询seinfo,sesearch

第一步:安装seinfo工具

第二步:

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

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

<3>修改SELinux规则的布尔值setsebool

[root@study ~]# setsebool [-P] 『规则名称』 [0|1]
选项与参数:
-P :直接将设定值写入配置文件,该设定数据未来会生效的!
范例一:查询 httpd_enable_homedirs 这个规则的状态,并且修改这个规则成为不同的布尔值
[root@study ~]# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off <==结果是 off ,依题意给他启动看看!
[root@study ~]# setsebool -P httpd_enable_homedirs 1 # 会跑很久很久!请耐心等待!
[root@study ~]# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> on

5、SELinux安全文本的修改

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

[root@study ~]# chcon [-R] [-t type] [-u user] [-r role] 文件
[root@study ~]# chcon [-R] --reference=范例文件 文件
选项与参数:
-R :连同该目录下的次目录也同时修改;
-t :后面接安全性本文的类型字段!例如 httpd_sys_content_t ;
-u :后面接身份识别,例如 system_u; (不重要)
-r :后面街角色,例如 system_r; (不重要)
-v :若有变化成功,请将变动的结果列出来
--reference=范例文件:拿某个文件当范例来修改后续接的文件的类型!
范例一:查询一下 /etc/hosts 的 SELinux type,并将该类型套用到 /etc/cron.d/checktime 上
[root@study ~]# ll -Z /etc/hosts
-rw-r--r--. root root system_u:object_r:net_conf_t:s0 /etc/hosts
[root@study ~]# chcon -v -t net_conf_t /etc/cron.d/checktime
changing security context of ‘/etc/cron.d/checktime’
[root@study ~]# ll -Z /etc/cron.d/checktime
-rw-r--r--. root root unconfined_u:object_r:net_conf_t:s0 /etc/cron.d/checktime
范例二:直接以 /etc/shadow SELinux type 套用到 /etc/cron.d/checktime 上!
[root@study ~]# chcon -v --reference=/etc/shadow /etc/cron.d/checktime
[root@study ~]# ll -Z /etc/shadow /etc/cron.d/checktime
-rw-r--r--. root root system_u:object_r:shadow_t:s0 /etc/cron.d/checktime
----------. root root system_u:object_r:shadow_t:s0 /etc/shadow


上面的练习『都没有正确的解答!』因为正确的 SELinux type 应该就是要以 /etc/cron.d/ 底下的文件
为标准来处理,让 SELinux 自己解决默认目录下的 SELinux type 用 restorecon
<2>使用 restorecon 让文件恢复正确的 SELinux type

[root@study ~]# restorecon [-Rv] 文件或目录
选项与参数:
-R :连同次目录一起修改;
-v :将过程显示到屏幕上
范例三:将 /etc/cron.d/ 底下的文件通通恢复成预设的 SELinux type!
[root@study ~]# restorecon -Rv /etc/cron.d
restorecon reset /etc/cron.d/checktime context system_u:object_r:shadow_t:s0->
system_u:object_r:system_cron_spool_t:s0
# 上面这两行其实是同一行喔!表示将 checktime 由 shadow_t 改为 system_cron_spool_t
范例四:重新启动 crond 看看有没有正确启动 checktime 啰!?
[root@study ~]# systemctl restart crond
[root@study ~]# tail /var/log/cron
# 再去瞧瞧这个 /var/log/cron 的内容,应该就没有错误讯息了

<3>semanage 默认目录的安全性本文查询与修改
为什么 restorecon 可以『恢复』原本的 SELinux type 呢?那肯定就是有个地方在纪录每个文件/目录的 SELinux 默认类型啰? 没错!是这样~那要如何 (1)查询预设的 SELinux type 以及 (2)如何增加/修改/删除预设的 SELinux type 呢?很简单~透过 semanage 即可!他是这样使用的:
 

[root@study ~]# semanage {login|user|port|interface|fcontext|translation} -l
[root@study ~]# semanage fcontext -{a|d|m} [-frst] file_spec
选项与参数:
fcontext :主要用在安全性本文方面的用途, -l 为查询的意思;
-a :增加的意思,你可以增加一些目录的默认安全性本文类型设定;
-m :修改的意思;
-d :删除的意思。
范例一:查询一下 /etc /etc/cron.d 的预设 SELinux type 为何?
[root@study ~]# semanage fcontext -l | grep -E '^/etc |^/etc/cron'
SELinux fcontext type Context
/etc all files system_u:object_r:etc_t:s0
/etc/cron\.d(/.*)? all files system_u:object_r:system_cron_spool_t:s0

6、一个网络服务案例及登录文件协助

详情见书P749-758

猜你喜欢

转载自blog.csdn.net/qq_41825534/article/details/83242279
今日推荐