1.简单的了解什么是SELinux:
**SELinux(Security-Enhanced Linux) 是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统。**NSA是在Linux社区的帮助下开发了一种访问控制体系,在这种访问控制体系的限制下,进程只能访问那些在他的任务中所需要文件。SELinux 默认安装在 Fedora 和 Red Hat Enterprise Linux 上,也可以作为其他发行版上容易安装的包得到。
SELinux 是 2.6 版本的 Linux 内核中提供的强制访问控制(MAC)系统。对于目前可用的 Linux安全模块来说,SELinux 是功能最全面,而且测试最充分的,它是在 20 年的 MAC 研究基础上建立的。SELinux 在类型强制服务器中合并了多级安全性或一种可选的多类策略,并采用了基于角色的访问控制概念。大部分使用 SELinux 的人使用的都是 SELinux 就绪的发行版,例如 Fedora、Red Hat Enterprise Linux (RHEL)、Debian或 Centos。它们都是在内核中启用 SELinux 的,并且提供一个可定制的安全策略,还提供很多用户层的库和工具,它们都可以使用 SELinux 的功能。
SELinux是一种基于 域-类型 模型(domain-type)的强制访问控制(MAC)安全系统,它由NSA编写并设计成内核模块包含到内核中,相应的某些安全相关的应用也被打了SELinux的补丁,最后还有一个相应的安全策略。任何程序对其资源享有完全的控制权。假设某个程序打算把含有潜在重要信息的文件扔到/tmp目录下,那么在DAC情况下没人能阻止他。SELinux提供了比传统的UNIX权限更好的访问控制。
SELinux提供了一种灵活的强制访问控制(MAC)系统,且内嵌于Linux Kernel中。SELinux定义了系统中每个【用户】、【进程】、【应用】和【文件】的访问和转变的权限,然后它使用一个安全策略来控制这些实体(用户、进程、应用和文件)之间的交互,安全策略指定如何严格或宽松地进行检查。
一般在实际生产环境之中SELinux是默认关闭的。
SELinux的特点:
1)对内核对象和服务的访问控制;
2)对进程初始化或继承和程序执行的访问控制;
3)对文件系统、目录、文件和打开文件描述的访问控制;
4)对端口、信息和网络接口的访问控制;
在Linux操作系统中所有的文件和进程都有一个值,这个值被称为安全值(也可以简单的理解为权限),当我满足或者匹配到这个安全值时,那么才能进行正常的访问。(例如:HTTP服务的默认目录是/var/www/html,当我们将这个默认的访问目录更改为默认创建的目录对应的另一个安全值时,而我们默认访问的就是第一种安全值,所以如果开启了SELinux则不能访问更改后目录的任何东西)
2.学习SELinux的作用及其权限管理机制:
2.1 SELinux 的作用:
SELinux主要作用就是最大限度地减小系统中服务进程可访问的资源(最小权限原则)。
设想一下,如果以root身份运行的网络服务存在某一漏洞的话,那么黑客就可以利用这个漏洞,以 root 的身份在您的服务器上为所欲为了。是不是很可怕?
SELinux就是来解决这个问题的。
2.2我们系统实现的访问控制一般分为以下两类:
1)DAC,在没有使用 SELinux 的操作系统中,决定一个资源是否能被访问的因素是:某个资源是否拥有对应用户的权限(读、写、执行等)。只要访问这个资源的进程符合以上的条件就可以被访问。而最致命问题是,root用户不受任何管制,它可以对系统上任何资源都可以无限制地访问。所以这种权限管理机制的主体是用户,也称为自主访问控制(DAC)。
2)MAC,在使用了 SELinux 的操作系统中,决定一个资源是否能被访问的因素除了DAC中的因素之外,还需要判断每一类进程是否拥有对某一类资源的访问权限。这样一来,即使进程是以root 身份运行的,也需要判断这个进程的类型以及允许访问的资源类型才能决定是否允许访问某个资源。进程的活动空间也可以被压缩到最小。即使是以root 身份运行的服务进程,一般也只能访问到它所需要的资源。即使程序出了漏洞,影响范围也只有在其允许访问的资源范围内,安全性大大提高。 这种权限管理机制的主体是进程,也称为强制访问控制(MAC)。而
MAC又细分为两种方式,一种叫类别安全(MCS)模式,另一种叫多级安全(MLS)模式。 以下的操作均为 MCS 模式下的操作。
3.SELinux基本概念:
3.1SELinux中的主体(Subject):可以理解为进程。(因为服务一般访问的时候,是通过某一用户身份在进程状态下读取某一资源文件的信息。所以为了方便理解,如无特别说明,以下均把进程视为主体)
3.2执行的对象(Object):被主体访问的资源。(可以是文件、目录、端口、设备等,
为了方便理解,如无特别说明,以下均把文件或者目录视为对象)
3.3 SELinux中的政策和规则(Policy & Rule):系统中通常有大量的文件和进程,为了节省时间和开销,通常我们只是选择性地对某些进程进行管制。
而哪些进程需要管制、要怎么管制是由政策决定的,一套政策里面可以有多个规则。部分规则可以按照需求启用或禁用(以下把该类型的规则称为布尔型规则)。规则是模块化、可扩展的。在安装新的应用程序时,应用程序可通过添加新的模块来添加规则。用户也可以手动地增减规则。
3.4在RHEL 7系统中,有以下三套政策:
1)targeted:对大部分网络服务进程进行管制。这是系统默认使用的政策(下文均使用此政策);
2)minimum:以targeted为基础,仅对选定的网络服务进程进行管制,一般不用;
3)mls:多级安全保护,即对所有的进程进行管制,这是最严格的政策,配置难度非常大。一般也不用,除非对安全性有极高的要求。 RHEL 7系统中的政策可以在/etc/selinux/config目录下设定。
3.5了解安全上下文(Security Context):
所有的操作系统访问控制都是通过主体和客体的相关访问控制属性来实现的,在SELINUX中,访问控制属性称为安全上下文。安全上下文是 SELinux 的核心,安全上下文我认为可以把它分为「进程安全上下文」和「文件安全上下文」。一个「进程安全上下文」一般对应多个「文件安全上下文」。只有两者的安全上下文对应上了,进程才能访问文件。它们的对应关系由政策中的规则决定。文件安全上下文由文件创建的位置和创建文件的进程所决定。而且Linux系统有一套默认值,用户也可以对默认值进行设定。
需要注意的是:
1)rpm包安装时会根据rpm包内的记录来生成安全上下文;
2)单纯的mv移动文件操作并不会改变文件的安全上下文;
3)通过cp拷贝文件的操作是会重新生成新的安全上下文的;
4)我们通过手动创建的文件会根据policy中的规定来设置安全上下文的;
3.6了解SELinux 的三种工作模式:
1)enforcing:强制模式,如果违反 SELinux 规则的行为将被阻止并记录到日志中。
2)permissive:宽容模式,如果违反SELinux 规则的行为只会记录到日志中,一般为调试时使用。
3)disabled:关闭 了SELinux;
SELinux的工作模式可以在/etc/selinux/config配置文件中进行设定,如果想从 disabled模式切换到 enforcing 模式或者 permissive 模式的话,需要重启系统,反过来也一样。
Enforcing模式和permissive模式可以通过 setenforce 1|0 命令实现模式的快速切换使用setenforce命令更改的模式只是临时生效的。我们可以通过getenforce命令来查看当前SELinux的工作模式是什么。
需要注意的是,如果系统已经在关闭 SELinux 的状态下运行了一段时间,在打开 SELinux 之后的第一次重启速度可能会比较慢。这是因为系统必须为磁盘中的文件创建安全上下文。注意:SELinux日志的记录需要借助auditd.service这个服务,请不要禁用它。
SELinux工作模式的切换:
禁用<-->强制:下次启动生效;
禁用<-->警告:下次启动生效;
强制<-->警告:即时生效;
在这里我们就可以解释一个问题,那就是在将SELinux的工作模式改为强制访问模式后重启为什么会特别的慢。这是因为SELinux在操作系统的安全体制结构上进行扩张,增加了对进程模块文件打上了一些安全标记。
4.了解Linux的安全上下文的结构及其含义:
安全上下文由四个字段组成,分别用冒号隔开,型如:system_u:object_r:admin_home_t:s0
1)system_u指的是SElinux对应的用户身份,root表示root账户身份,user_u表示普通用户无特权用户,system_u表示系统进程,通过用户可以确认身份类型,一般搭配角色使用。身份和不同的角色搭配时的权限不同,虽然可以使用su命令切换用户但对于SElinux的用户并没有发生改变,账户之间切换时此用户身份不变,在targeted策略环境下用户标识没有实质性作用。
2)object_r一般为文件目录的角色,system_r一般为进程的角色,在targeted策略环境中用户的角色一般为system_r。用户的角色类似用户组的概念,不同的角色具有不同的身份权限,一个用户可以具备多个角色,但是同一时间只能使用一个角色。在targeted策略环境下角色没有实质作用,在targeted策略环境中所有的进程文件的角色都是system_r角色。
3)admin_home标记信息值,真正匹配安全标签时的字段,admin_home表示类型,文件和进程都有一个类型,SElinux依据类型的相关组合来限制存取权限。
4)s0是跟MLS、MCS相关的东西,s0代表应用了类别安全模式,而没有应用多级安全模式。
注意:当我们忘记了Linux操作系统的登录密码,通过破译密码进行登录时,有一步是Touch
/.autorelabel,这是因为系统当中默认启用了SELinux去读取一个取值文件,而这个文件里是否由内容它都要去读,读完之后它会给系统默认的文件设置安全值。通过修改context值,使系统跨过这一步,所以系统就可以正常启动了。
5.了解SELinux的配置文件及配置命令:
#SElinux的配置文件/etc/selinux/config
#查看当前系统上SELinux的工作模式
[[email protected] ~]# getenforce
#使用命令行快速切换切换SELinux的工作模式
[[email protected] ~]#setenforce 0
[[email protected] ~]#setenforce 1
#通过编辑配置文件修改SELinux的工作模式(注意修改配置文件后重启系统才能生效)
[[email protected] ~]# vim /etc/selinux/config
SELINUX=enforcing
#查看selinux状态
[[email protected] ~]# sestatus
#查看selinux安全上下文的值
[[email protected] /]# ll –Z
#查看context值的变化
[[email protected] /]# touch hehe
[[email protected] /]# ll –Z
-rw-r--r--. root root unconfined_u:object_r:etc_runtime_t:s0 hehe
[[email protected] /]# mkdir test
[[email protected] /]# cp hehe /test/
[[email protected] /]# cd test/
[[email protected] test]# ll-Z
-rw-r--r--. root root unconfined_u:object_r:default_t:s0 hehe
#更改SELinux的context值的相关命令
semanage fcontext –a(表示重新添加) –t(表示context值的类型) "(/.*)?"
#目录或文件的默认安全上下文可以通过 semanage fcontext -l 命令配合 grep过滤查看
[[email protected] ~]# semanage port -l | grep "\b80\b"
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
#一般更改SELinux的context值通过以下命令修改较为简单,一般建议使用
chcon -t context值的类型 文件名
[[email protected] test]# chcon -t user_tmp_t hehe
#改变目录的context值需要加上-R选项,表示递归修改
chcon -t context值 directory -R
#恢复一个文件的context值
[[email protected] ~]# restorecon -v filename
[[email protected] ~]# mkdir /test2
[[email protected] test]# touch file
[[email protected] test]# ll -Z
-rw-r--r--. root root unconfined_u:object_r:default_t:s0 file
[[email protected] ~]# cp /test/file /test2/
[[email protected] ~]# ll -Z /test2
-rw-r--r--. root root unconfined_u:object_r:default_t:s0 file
[[email protected] ~]# chcon -t admin_home_t /test2/file
[[email protected] ~]# ll -Z /test2/file
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 /test2/file
[[email protected] ~]# restorecon -v /test2/file
restorecon reset /test2/file context unconfined_u:object_r:admin_home_t:s0->unconfined_u:object_r:default_t:s0
[[email protected] ~]# ll -Z /test2/file
-rw-r--r--. root root unconfined_u:object_r:default_t:s0 /test2/file
#查看进程的context值
[[email protected] ~]# ps -Z
LABEL PID TTY TIME CMD
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 11566 pts/1 00:00:00 bash
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 45783 pts/1 00:00:00 ps
6.SELinux相关案例解析:
案例一:使用HTTP服务演示context值的设定。
#确保防火墙开启
[[email protected] ~]# systemctl status firewalld.service
#添加防火墙策略对web服务实行放行规则
[[email protected] ~]# firewall-cmd --permanent --add-service=http
[[email protected] ~]# firewall-cmd --reload
#确保SELinux开启
[[email protected] ~]# getenforce
Enforcing
#配置HTTP服务
[[email protected] ~]# echo this is haha > /var/www/html/index.html
#配置完成重启服务
[[email protected] ~]# systemctl restart httpd
#查看HTTP服务默认路径下的context值
[[email protected] ~]# ll -Z /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html
#通过Windows客户端浏览器进行访问测试
#配置HTTP服务创建新的访问路径进行测试
[[email protected] ~]# mkdir /www
[[email protected] ~]# echo this is www > /www/index.html
[[email protected] ~]# vim /etc/httpd/conf.d/vhosts.conf
<Directory /www>
allowOverride none
Require all granted
</Directory>
<VirtualHost 192.168.10.206:80>
DocumentRoot /www
ServerName 192.168.10.206
</VirtualHost>
#配置完成Windows客户端浏览器进行访问测试
#由上图我们可以发现我们的HTTP服务配置是没有问题的,下面我们通过对SELinux的context的设定实现正常访问
#首先我们查看以下我们自定义访问路径的context值
[[email protected] ~]# ll -Z /www/index.html
-rw-r--r--. root root unconfined_u:object_r:default_t:s0 /www/index.html
#修改我们自定义访问路径的context值,如下:
[[email protected] ~]# chcon -t httpd_sys_content_t /www/index.html
[[email protected] ~]# ll -Z /www/index.html
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /www/index.html
#context值修改完成Windows客户端浏览器进行访问测试
#如果在重启服务时,日志提示DNS解析失败时,按如下办法解决:
[[email protected] ~]# vi /etc/hosts
192.168.10.206 web
#如果有布尔值的提示,请输入以下命令进行处理
[[email protected] ~]# setsebool -P httpd_can_network_relay 1
#布尔值,当你配置一个服务时,在SELinux开启的情况下,你这个服务的有些功能是用不了的,而bool值相当于是一个开关,你把这个功能开关按上就好了。
#查看布尔值
[[email protected] ~]# getsebool -a
#查看ftp相关的布尔值
[[email protected] ~]# getsebool -a | grep ftp
#设置布尔值
[[email protected] ~]#setsebool -P ftp_home_dir on
案例二:使用HTTP服务端口的改变来演示针对端口的设定
#创建一个8888端口的WEB服务目录和默认页面
[[email protected] ~]# mkdir -pv /www/8888
mkdir: 已创建目录 "/www/8888"
[[email protected] ~]# echo welcome to 8888 > /www/8888/index.html
#在上个案例的页面中添加如下内容:
LISTEN 8888
<VirtualHost 192.168.10.206:8888>
DocumentRoot "/www/8888"
</VirtualHost>
#保存退出后,重启服务。
[[email protected] ~]# systemctl restart httpd
#查看端口状态
[[email protected] ~]# lsof -i:8080
[[email protected] ~]# netstat -lntp | grep 8080
#然后通过浏览器查看该web页面是否能正常访问,正常情况下,应该无法访问,首先,我们在防火墙添加允许该端口的策略
[[email protected] ~]# firewall-cmd --permanent --add-port=8080/tcp
[[email protected] ~]# firewall-cmd --reload
#SELinux中添加该自定义端口为服务端口
[[email protected] ~]# semanage port -a(添加) -t http_port_t -p tcp 8888
#再通过浏览器进行查看该web服务,即可正常查看
案例三:使用FTP服务演示布尔值的设定
#首先添加防火墙允许策略
[[email protected] ~]# firewall-cmd --permanent --add-service=ftp
success
[[email protected] ~]# firewall-cmd --reload
Success
#安装FTP服务对应的程序软件包
[[email protected] ~]# yum install vsftpd -y
#开启vsftp服务,配置为本地用户允许读写家目录,不允许遍历其他目录
配置如下:
[禁止匿名用户]
anonymous_enable=no
[禁止遍历]
#首先开启chroot选项
allow_writeable_chroot=YES
#打开chroot选项
chroot_list_enable=YES
#指定打开的chroot_list文件
chroot_list_file=/etc/vsftpd/chroot_list
#确保以下选项参数无误
local_enable=YES
write_enable=YES
#编辑chroot_list文件
[[email protected] ~]# vim /etc/vsftpd/chroot_list
redhat
#查看/home目录的权限
[[email protected] ~]# getsebool -a | grep ftp_home_dir
ftp_home_dir --> off //ftp_home_dir代表指定用户是否可以访问其家目录
tftp_home_dir --> off
#通过Windows客户端浏览器进行测试
#修改布尔值,打开/home目录的权限
[[email protected] ~]# setsebool -P ftp_home_dir on
[[email protected] ~]# getsebool -a | grep ftp_home_dir
ftp_home_dir --> on
tftp_home_dir --> off
#通过Windows客户端浏览器进行测试
7.使用SElinux图形界面实现SELinux的相应配置操作(注意,要使用SELinux的图形界面SELinux的工作模式绝不能为disable):
#安装SELinux图形界面对应的软件包policycoreutils-gui
[[email protected] ~]# yum policycoreutils-gui -y
#客户端执行system-config-selinux命令进入SELinux图形界面
[[email protected] ~]# system-config-selinux
注意:在SELinux图形界面中,我们可以对SELinux的状态设定、布尔值设定及网络端口设置默认的已选参数进行相应的了解记忆。