Chinaunix首页 | 论坛 | 博客
  • 博客访问: 313569
  • 博文数量: 84
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 890
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-13 16:46
文章分类

全部博文(84)

文章存档

2017年(2)

2016年(4)

2015年(78)

我的朋友

分类: LINUX

2015-10-10 10:21:11

  1. 概念

    产考: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。

  1. 首先,我们触发一个可执行的目标文件,那就是具有httpd_exec_t这个类型的/usr/sbin/httpd文件;
  2. 该文件的类型会让这个文件所造成的主体进程(subject)具有httpd这个域(domain),我们的策略针对这个域制定了许多规则,其中包括这个域可以读取的目标资源类型
  3. 由于httpd domain被设置为可以图区httpd_sys_content_t这个类型的目标文件Object;因此你的网页放置到/var/www/html目录下,就能够被httpd那个进程所读取了;
  4. 但最终能不能读到正确的数据,还得要看rwx是否符合Linux权限的规范!

上述流程几个重点:第一个是策略内需要制订详细的domain/type相关性;第二个是若文件的type设置错误,那么及时权限设置为777,该主体进程也无法读取目标文件资源。

  1. SELinux的启动、关闭与查看

    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 的类型,就能够处理这个错误!

  1. 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 ~]#

此时你使用IE客户端输入 style="font-size:12px;font-family:NSimSun;color:#000000;">,将提示You don't have permission,你没有权限,这就是上下文的作用啦。为什么在/var/www/html下直接创建的index.html会有正确的上下文信息,而手动移至过去的index.htm就没有正确的上下文关系,是因为targeted策略里面有设置


(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

阅读(4035) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~