分类: LINUX
2015-07-20 16:28:33
产考:http://vbird.dic.ksu.edu.tw/linux_server/0210network-secure_4.php
SELinux是Security Enhanced Linux的缩写,字面的意思是安全强化的Linux。SELinux是整合到内核的一个模块。其实SELinux是在进行程序、文件等权限设置依据的一个内核模块,由于启动网络服务的也是程序,因此刚好也是控制网络服务能否访问系统资源的一道关卡!
自主访问控制DAC:系统的账号主要分为系统管理元root与一般用户,而这两种身份能否使用系统上面的文件资源与rwx的权限设置有关(各种权限设置对于root是无效的),因此,当某个进程要对文件进行访问时,系统就会根据该进程的所有者/用户组,并比较文件的权限,若通过检查,就可以访问该文件了。这种访问文件系统的方式称为"自主访问控制(discretionary access control,DAC)"。DAC的几个困扰,例如一般默认安装完系统,那么系统中大部分的文件权限为-rw-r--r--.(644),目录的权限为drwxr-xr-x.(755),也就是对于其他用户或组(other)而言,都有对这些文件的读权限,对目录的读和执行权限,那么例如apache这个用户,也就是网络中的其他用户使用IE或者其他浏览器访问系统的http服务时,那么他实际上使用的就是这个apache这个用户,而这个用户大多是不需要上述默认权限中的other(其他用户或组)权限的。也就是SELinux根据上下文(context)可以设置针对一个进程,定义最小的服务集。因此SELinux导入了强制访问控制(Mandatory Access Control,MAC)的方法。
强制访问控制MAC他可以针对特定的进程与特定的文件资源来进行权限控制,如此一来,我们针对控制的"主体"变成了"进程"而不是用户。在强制访问控制的设置下,我们的进程能够活动的空间就变小了! 由DAC访问架构转变为MAC(默认情况下你能做的事情)访问架构,你能做的事情其实就是一个结果集。
Process(uid gid ) file (ugo rwx)三种角色,三种权限,文件之所以能被程序(Program/Process)访问是因为我们的进程有UID和GID,UID和GID与文件的user与group相匹配,如果匹配不上那么就是"o"other权限啦!
SELinux是通过MAC的方式来控管进程,它控制的主体是进程,而目标则是该进程能否读取的"文件资源"
主体(Subject):即进程
目标(Object):即文件资源,一般就是文件系统。
策略(Policy):目前主要的策略有:1、targeted:针对网络服务限制较多,针对本机限制较少,是默认的策略;2、strict:完整的SELinux限制,限制方面较为严格。建议使用默认targeted策略。
安全上下文(Security context):主体(进程)能不能访问目标(文件系统)除了策略指定之外,主体与目标的安全上下文必须一致才能顺利访问。
AVC:access vector cache,目的是记录所有与SELinux有关的访问统计数据。
主体程序必须要通过SELinux策略内的规则放行后,就可以与目标资源进行安全上下文的比较,若比较失败则无法访问目标,若比较成功则可以开始访问目标。而且最终能否访问目标还是与文件系统给的rwx权限设置有关。如此一来,加入了SELinux之后,出现权限部分的情况是,你就要一步一步地分析,可能的问题了。
一般Linux系统已经帮我们制订了非常多的规则了,只要知道如何开启/关闭某项规则的放行与否即可。安全上下文可能需要自行配置。安全上下文存在于主体进程中与目标文件资源中。安全上下文是放置到文件的inode内的,因此主进程想要读取目标文件资源时,同样需要读取inode。这inode内就可以比较安全上下文及rwx等权限值是否正确,而给予适当的读取权限依据。
查看安全上下文使用ls –Z查看
[root@localhost ~]# ls -Z -rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 etc.tar.gz -rw-r--r--. root root system_u:object_r:admin_home_t:s0 install.log -rw-r--r--. root root system_u:object_r:admin_home_t:s0 install.log.syslog -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 ping.log |
如上所示,安全上下文主要用冒号分为三个字段:
Identify:role:type
身份识别:角色:类型
身份识别(Identify):相当于账号方面的身份标识,主要的身份标识则有:
root:表示root的账号身份
system_u:表示系统程序方面的标识,通常就是进程(系统上面大部分的数据都会是system_u,用户自己创建的或以某个用户安装的程序文件一般都是unconfined_u)
user_u:代表一般用户账号相关的身份
unconfined_u:无限制的,上面的两个unconfined文件是用root用户手工创建处理的(有时后安装的非系统程序文件也是如此),这个unconfined_u就是默认的身份识别值啊!
角色(Rule):通过角色字段,我们可以知道这个数据属于程序、文件资源、还是代表用户。一般角色有:
object_r:代表是文件或目录等文件资源,这应该是最常见的。
system_r:代表是进程,不过,一般用户也会被指定为system_r
类型(Type,最重要):一般targeted策略中,Identify与Role字段基本上是不重要的。重要的在于这个类型type字段!基本上,一个主进程能不能读取到这个文件资源与类型字段有关。常用的类型字段有:
type:在文件资源(Object)上面称为类型(Type);
domain:在主体程序Subject中则称为域(domain)了,domain需要与type搭配,则程序才能够顺利读取文件资源。
[root@localhost html]# 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/ [root@localhost html]# httpd属于httpd_exec_t类型,/var/www/html/则属于httpd_sys_content_t类型,这个类型字段可以分为两部分吧,如例子的httpd,为domain,exec_t和content是type。 |
上述流程几个重点:第一个是策略内需要制订详细的domain/type相关性;第二个是若文件的type设置错误,那么及时权限设置为777,该主体进程也无法读取目标文件资源。
SELinux支持的三种模式
enforcing:强制模式,代表SELinux正在运行,且已经正确开始限制domain/type了。
permissive:宽容模式,代表SELinux正在运行中,不过仅会有警告信息并不会实际限制(这个定义现在好像不够精确)domain/type的访问。这种模式可以用来作为SELinux的调试之用。
disable:关闭,就是关闭了
通过getenforce命令可以查看目前SELinux的状态
[root@localhost ~]# getenforce Enforcing [root@localhost ~]# |
通过sestatus命令可以查看目前SELinux使用的策略(policy)
sestatus [-vb] -v:检查列于/etc/sestatus.conf内的文件与程序的安全上下文内容 -b:将目前策略的规则布尔值列出,即某些规则(rule)是否要启动(0/1)。布尔值就是已经写好的规则,0表示关闭,1表示启动 列出目前的SELinux使用的策略policy [root@localhost init.d]# sestatus SELinux status: enabled #是否启动 SELinuxfs mount: /selinux #selinux的相关文件数据挂载点 Current mode: enforcing #目前的模式 Mode from config file: enforcing #配置文件指定的模式 Policy version: 24 #策略的版本啦,RHEL5.x的策略版本为21 Policy from config file: targeted #目前的策略是targeted [root@localhost init.d]# |
SELinux的启动与关闭
SELinux的配置文件为/etc/selinux/config
[root@localhost selinux]# more /etc/selinux/config
# This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=enforcing # SELINUXTYPE= can take one of these two values: # targeted - Targeted processes are protected, # mls - Multi Level Security protection. SELINUXTYPE=targeted
[root@localhost selinux]# |
如果由enforcing或permissive改为disable,或由disable改为其他两个,必须要重新启动系统。
查看内核有无关闭SELinux,需要确认/boot/grub/menu.lst文件内容中是否有selinux=0字样,等于0表示告诉内核忽略/etc/selinux/config的设置值,而直接略过SELinux的加载,所以你的SELinuxo模式就会变成disable。
SELinux模式的切换
setenforce [0|1]
0:转换成permissive宽容模式
1:转换成enforcing强制模式
如果你已经处于enforcing的模式,但是可能由于一些设置的问题导致SELinux让某些服务无法正常运行,此时,你可以将enforcing的模式改为许可permissive的模式,让selinux只会告警,而不会直接抵挡主进程的读取权限。
在某些特殊的情况底下,你从 Disabled 切换成 Enforcing 之后,竟然有一堆服务无法顺利启动,都会跟你说在 /lib/xxx 里面的数据没有权限读取,所以启动失败。这大多是由于在重新写入 SELinux type (Relable) 出错之故,使用 Permissive 就没有这个错误。那如何处理呢?最简单的方法就是在 Permissive 的状态下,使用『 restorecon -Rv / 』重新还原所有 SELinux 的类型,就能够处理这个错误!
首先是开启httpd的web服务
service httpd start
创建首页
echo "This is my first web page." > /var/www/html/index.html
开启iptables防火墙关于httpd的访问控制(如未开启见黄色背景字体)
[root@localhost html]# more /etc/sysconfig/iptables # sample configuration for iptables service # you can edit this manually or use system-config-firewall # please do not ask us to add additional ports/services to this default configuration *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT [root@localhost html]# |
这时你可以正常访问页面了,查看一下/var/www/html/index.html上下文信息
[root@localhost html]# ll -Z /var/www/html/ -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html [root@localhost html]# |
安全上下文的httpd实验
在root的家目录下创建所需的首页,并将其移至/var/www/html目录
[root@localhost ~]#echo "My 2nd web page..." > index.htm [root@localhost ~]#ls –Z -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 index.htm [root@localhost ~]#mv index.htm /var/www/html #不能使用cp,cp将改变上下文信息 [root@localhost ~]# ll -Z /var/www/html/ -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 index.htm -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html [root@localhost ~]# |
(4)SELinux type的修改
cp和mv对SELinux type的影响
当你单纯使用cp复制文件或目录时,SELinux的type字段是会继承目标目录,使用cp –a参数将不是;
当你使用mv移动文件或目录时,SELinux的type字段是不会继承目标目录;
chcon修改安全上下文type值
chcon [-R] [-t type] [-u user] [-r role]文件 chcon [-R] --reference 范例文件 被实施文件 参数 -R:连同该目录下的子目录也同时修改 -t:后面接安全上下文的类型字段!例如httpd_sys_content_t; -u:后面接身份识别Identify例如system_u; -r:后面接角色role,例如system_r; --reference=:范例文件,拿某个文件当范例来修改后续接的文件的类型;
将该才的index.htm类型改为httd_sys_content_t的类型,注意黄色背景的字符由原来的admin_home_t类型,改为httpd_sys_content_t类型了,这样在IE中就可以正常访问index.htm文件了。
[root@localhost ~]# chcon -t httpd_sys_content_t /var/www/html/index.htm [root@localhost ~]# ll /var/www/html/ -Z -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.htm -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html [root@localhost ~]#
--reference参数的应用 以/etc/passwd为范例,将index.html修改成该类型。 [root@localhost ~]# chcon --reference=/etc/passwd /var/www/html/index.htm [root@localhost ~]# ll -Z /var/www/html/index.htm -rw-r--r--. root root system_u:object_r:passwd_file_t:s0 /var/www/html/index.htm [root@localhost ~]# |
restorecon还原系统默认的安全上下文命令type值
restorecon [-Rv] 文件或目录 参数 -R:连同子目录一起修改 -v:将过程显示到屏幕上
[root@localhost ~]# restorecon -Rv /var/www/html/ restorecon reset /var/www/html/index.htm context system_u:object_r:passwd_file_t:s0->system_u:object_r:httpd_sys_content_t:s0 [root@localhost ~]# ll -Z /var/www/html/index.htm -rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.htm [root@localhost ~]# |
上下文设置错误的原因很可能是因为该文件有其他位置复制或移动过来所导致的,因此要善用restorecon及chcon来处理这方面的问题。
默认目录的安全上下文查询与修改
通过上面这几个练习,你就会知道,SELinux type恐怕会在档案的复制/移动时产生一些变化,因此需要善用chcon和restorecon等指令来镜像修订。那你应该还会想到一件事,那就是,restorecon怎么会知道每个目录记载的默认type类型呢?这是因为系统有记录,是记录在/etc/selinux/targeted/contexts/这个目录,但该目录内有很多数据,要使用文本编辑器去查阅很麻烦,因此,我们可以使用semanage这个指令的功能来查询与修改。
semanage {login|user|port|interface|fcontext|translation} -l
semanage fcontext -{a|d|m} [-frst] file_spec
选项与参数:
fcontext :主要用在安全性本文方面的用途, -l 为查询的意思;
-a :增加的意思,你可以增加一些目录的默认安全性本文类型设定;
-m :修改的意思;
-d :删除的意思。
# 范例:查询一下 /var/www/ 的预设安全性本文设定为何!
[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
....(后面省略)....
制订 /srv/vbird 成为 public_content_t 的类型时,应该如何指定呢?
[root@www ~]# semanage fcontext -a -t public_content_t "/srv/vbird(/.*)?"
有默认值,以后用 restorecon 来修改比较简单!
[root@www ~]# restorecon -Rv /srv/vbird* <==尝试恢复默认值
(5)SELinux的策略与规则管理
策略查阅seinfo命令
seinfo命令 参数 --all:列出SELinux的状体、规则布尔值、身份识别、角色、类型等多有信息; -t:列出SELinux的所有类型(type)种类; -r:列出SELinux的所有角色(role)种类; -u:列出SELinux的所有身份标识(user)种类; -b:列出所有规则的种类(布尔值)
列出SELinux在此策略下的统计状态 [root@localhost html]# seinfo
Statistics for policy file: /etc/selinux/targeted/policy/policy.24 Policy Version & Type: v.24 (binary, mls)
Classes: 81 Permissions: 235 Sensitivities: 1 Categories: 1024 Types: 3663 Attributes: 328 Users: 9 Roles: 12 Booleans: 201 Cond. Expr.: 236 Allow: 303548 Neverallow: 0 Auditallow: 121 Dontaudit: 222306 Type_trans: 31626 Type_change: 38 Type_member: 48 Role allow: 20 Role_trans: 312 Range_trans: 4277 Constraints: 90 Validatetrans: 0 Initial SIDs: 27 Fs_use: 22 Genfscon: 82 Portcon: 434 Netifcon: 0 Nodecon: 0 Permissives: 73 Polcap: 2
安全上下文有3663个,针对网络服务的规则booleans有201个 [root@localhost html]# seinfo -t | wc -l 3665 #有空行和描述行,因此统计数据为2665
列出与httpd规则相关的type类型有哪些 [root@localhost html]# seinfo -t | grep httpd_sys httpd_sys_content_t httpd_sys_htaccess_t httpd_sys_ra_content_t httpd_sys_rw_content_t httpd_sys_script_t httpd_sys_script_exec_t [root@localhost html]# |
布尔值的查询与修改
布尔值的查询
getsebool –a #查询本系统内所有的布尔值设置情况
启动关闭布尔值
启动布尔值
setsebool –P httpd_enable_homedirs=1
关闭布尔值
setsebool –P httpd_enable_homedirs=0
(6)SELinux排错
使用messages排错
我们的 CentOS 6.x 有提供几支侦测的服务在登录 SELinux 产生的错误喔!那就是 auditd 与 setroubleshootd。
setroubleshoot --> 错误讯息写入 /var/log/messages
setroubleshoot这个服务会将关于 SELinux 的错误讯息与克服方法记录到 /var/log/messages 与 /var/log/setroubleshoot/* 里头,所以你一定得要启动这个服务才好。启动这个服务之前当然就是得要安装它啦! 这玩意儿总共需要两个软件,分别是 setroublshoot 与 setroubleshoot-server,如果你没有安装,请自行使用 yum 安装吧!
此外,原本的 SELinux 信息本来是以两个服务来记录的,分别是 auditd 与 setroubleshootd。既然是同样的信息, 因此 CentOS 6.x 将两者整合在 auditd 当中啦!所以,并没有 setroubleshootd 的服务存在了喔!因此, 当你安装好了 setroubleshoot-server 之后,请记得要重新启动 auditd,否则 setroubleshootd 的功能不会被启动的。
如下,页面/var/www/html/index.html文件的上下文不正确,导致页面无法访问,最简单的办法就是查看/var/log/messages,如下提示就是上下文不匹配导致无法访问。
[root@localhost html]# ll -Z -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 index.html [root@localhost html]# [root@localhost html]# tail /var/log/messages J Jul 22 13:38:21 localhost setroubleshoot: SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/index.html. For complete SELinux messages. run sealert -l 84c5f2b9-1af0-4d92-a548-49adff1f1e44 Jul 22 13:38:21 localhost setroubleshoot: SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/index.html. For complete SELinux messages. run sealert -l 84c5f2b9-1af0-4d92-a548-49adff1f1e44
[root@localhost html]# sealert -l 84c5f2b9-1af0-4d92-a548-49adff1f1e44 SELinux is preventing /usr/sbin/httpd from getattr access on the 文件 /var/www/html/index.html.
***** 插件 restorecon (99.5 置信度) 建议 ******************************************
If 您想要修复标签。 /var/www/html/index.html 默认标签应为 httpd_sys_content_t。 Then 您可以运行 restorecon。 Do # /sbin/restorecon -v /var/www/html/index.html
***** 插件 catchall (1.49 置信度) 建议 ********************************************
If 您确定应默认允许 httpd getattr 访问 index.html file。 Then 您应该将这个情况作为 bug 报告。 您可以生成本地策略模块允许这个访问。 Do 请执行以下命令此时允许这个访问: # grep httpd /var/log/audit/audit.log | audit2allow -M mypol # semodule -i mypol.pp
[root@localhost html]#
以上的建议说的很清楚了,也就是在redhat6.x,你需要安装setroubleshott,以及需要auditd守护进程重启,才可以好到SELinux的提示解决办法。 |
用 email 或在指令列上面直接提供 setroubleshoot 错误讯息
如果每次测试都得要到 /var/log/messages 去分析,那真是挺麻烦的啊!没关系,我们可以透过 email 或 console 的方式来将信息产生!也就是说,我们可以让 setroubleshoot 主动的发送产生的信息到我们指定的 email,这样可以方便我们实时的分析喔!怎么办到?就修改 setroubleshoot 的配置文件即可。你可以查阅 /etc/setroubleshoot/setroubleshoot.cfg 这个档案的内容,我们只需要修改的地方如下:
[root@www ~]# vim /etc/setroubleshoot/setroubleshoot.cfg [email] # 大约在 81 行左右,这行要存在才行! recipients_filepath = /var/lib/setroubleshoot/email_alert_recipients
# 大约在 147 行左右,将原本的 False 修改成 True 先! console = True
[root@www ~]# vim /var/lib/setroubleshoot/email_alert_recipients root@localhost your@email.address
[root@www ~]# /etc/init.d/auditd restart |
之后你就可以透过分析你的 email 来取得 SELinux 的错误讯息啰!非常的简单吧!只是要注意,上述的填写 email 的档案中, 不能只写账号,你要连同 @localhost 都写上,这样本机上面的 root 才能收到信件喔!就这么简单哩! ^_^
命令总结
命令 |
参数 |
说明 |
setenforce |
0 |
转换成permissive宽容模式 |
setenforce |
1 |
转换成enforcing强制模式 |
getenforce |
查看当前SELinux的 模式 |
|
sestatus |
-v |
检查列于/etc/sestatus.conf内的文件与程序的安全上下文内容 |
-b |
将目前策略的规则布尔值列出,即某些规则(rule)是否要启动(0/1) |
|
ls |
-Z |
显示文件的上下文信息 |
ps |
aux -Z |
显示进程的上下文信息如:ps aux -Z | grep httpd,显示进程httpd的上下文信息 |
chcon |
-R |
|
-t |
||
-u |
||
-r |
||
restorecon |
-R |
连同子目录一起修改restorecon –Rv /var/www/html/ |
-v |
将过程显示到屏幕上 |
|
seinfo |
-all |
--all:列出SELinux的状体、规则布尔值、身份识别、角色、类型等多有信息; |
-b |
-b:列出所有规则的种类(布尔值) |
|
-t |
-t:列出SELinux的所有类型(type)种类; |
|
-u |
-u:列出SELinux的所有身份标识(user)种类; |
|
-r |
-r:列出SELinux的所有角色(role)种类; |
|
getsebool |
-a |
查询本系统内所有的布尔值设置情况 |
setsebool |
-P |
直接将设置值写入配置文件,该设置数据将会生效 |
semanage |
默认目录的安全上下文查询与修改 |
yum install policycoreutils-python #与semanage命令有关
yum install setools-console #与seinfo命令有关
yum install setroubleshoot setroubleshoot-server #与SELinux的日志排错有关
当你安装好了 setroubleshoot-server 之后,请记得要重新启动 auditd,否则 setroubleshootd 的功能不会被启动的。
Boolean布尔值(能让sshd进程能够正常运行的最小权限的集合)布尔值只有0(不限定)和1(限定)
有点像windows中的组策略管理集
setsebool控制布尔值
getsebool查看系统的布尔值-a
getsebool -a | grep httpd
[root@localhost Packages]# getsebool -a | grep allow_httpd_mod_auth_pam #查看某布尔值状态
allow_httpd_mod_auth_pam --> on
[root@localhost Packages]# setsebool allow_httpd_mod_auth_pam off #关闭某布尔值
[root@localhost Packages]# getsebool -a | grep allow_httpd_mod_auth_pam #再次查看
allow_httpd_mod_auth_pam --> off
[root@localhost Packages]#
更改文件或目录的上下文
chcon –R –t httpd_sys_content_t /www/upload
大批量把上下文恢复成默认状态restorecon,当你很长时间没有启动SELinux,忽然启动SELinux那么restorecon会自动运行
restorecon –vvFR /www/abc
SELinux排查
tail /var/ log/messages