SELinux
什么是SELinux呢?其实它是【Security-Enhanced Linux】的英文缩写,字母上的意思就是安全强化Linux的意思。
SELinux是由美国国家安全局(NSA)开发的,当初开发的原因是很多企业发现,系统出现问题的原因大部分都在于【内部员工的资源误用】,实际由外部发动的攻击反而没有那么严重。那么什么是【员工资源误用】呢?举例来说,如果有个不是很懂系统的系统管理员为了自己设置的方便,将网页所在目录【/var/www/html/】的权限设置为【drwxrwxrwx】。
那么如果【/var/www/html】设置为777,代表所有进程均可对该目录读写,万一你真的启动了WWW服务器软件,那么该软件所触发的进程将可以写入该目录,而该进程却是对整个Internet提供服务的。只要有心人接触到这个进程,而且该进程刚好又提供了用户进行写入的功能,那么外部的人很可能就会想你的系统写入些莫名其妙的东西。
为了管理这方面的权限与进程的问题,美国国家安全局开始着手处理操作系统这方面的管理。由于Linux是自由软件,程序代码都是公开的,因此它们便使用Linux来作为研究的目标,最后更将研究结果整合到Linux内核中,那就是SELinux。所以说,SELinux是整合到内核的一个模块。
主体(Subject)
主体就是想要访问文件或目录资源的进程。
进程得到资源的流程:由用户调用命令,由命令产生进程,由进程去访问文件或目录资源。
自主访问控制系统中(Linux 的默认权限),靠权限控制的主体是用户
强制访问控制系统中(SELinux 中),靠策略规则控制的主体则是进程
目标(object)
系统中的资源,包括文件、目录、网络、设备等。在SELinux中,每个对象都有自己的安全上下文,其中包含了对象的类型信息、安全级别等。
策略(policy)
Linux 系统中进程与文件的数量庞大,所以限制进程是否可以访问文件的 SELinux 规则数量就更加烦琐,如果每个规则都需要管理员手工设定,那么 SELinux 的可用性就会极低,所以SELinux 默认定义了两个策略来制订规则
selinux的2个默认策略
-targeted:默认策略,用于限制网络服务(dhcpd,httpd,named,nscd,ntpd,portmap,snmpd,squid,以及 syslogd),对本机系统的限制极少
-mls:多级安全保护策略,该策略限制更为严格
安全上下文
安全上下文是 SELinux 的核心。安全上下文我自己把它分为「进程安全上下文」和「文件安全上下文」。一个「进程安全上下文」一般对应多个「文件安全上下文」。只有两者的安全上下文对应上了,进程才能访问文件。它们的对应关系由政策中的规则决定。
文件安全上下文由文件创建的位置和创建文件的进程所决定。而且系统有一套默认值,用户也可以对默认值进行设定。需要注意的是,单纯的移动文件操作并不会改变文件的安全上下文。
查询安全上下文
ls -Z 文件/目录
ps auxZ | grep -v grep | grep nginx
身份标识(identify):相当于账号的身份标识,有三种类型:
root:安全上下文的身份是root(用户编号为0),默认会映射为unconfined_u,可以通过以下命令查看映射关系:
[root@server ~]# semanage login -l
system_u:系统用户身份(用户id1-999),其中u代表user
普通用户名_u:普通用户身份(用户id1000-65535),用户数据的user字段是user_u
注意:user字段只用于标识数据或进程被哪个身份所拥有,比如系统数据的user字段是system_u
角色(role):表示此数据是进程还是文件或目录包含(了解就行)
object_r:代表该数据是文件或目录,r代表 role(角色的意思)
system_r:进程,r代表 role
类型(type):
最重要,进程是否可以访问文件,主要就是看进程的安全上下文类型字段是否和文件的安全上下文类型字段相匹配
在默认的targeted策略中
类型字段在主体(进程)的安全上下文中被称作域(domain)
类型字段在目标(文件或目录)的安全上下文中被称作类型(type)
进程的域与文件的类型是否匹配需要查询策略规则
灵敏度:用 s0、s1、s2 来命名,数字为灵敏度分级,数值越大,灵敏度越高,管的越多
SELinux的三种工作模式
enforcing模式
enforcing模式是SELinux的默认工作模式,也是最常用的工作模式。在enforcing模式下,SELinux会强制执行安全策略,阻止未经授权的访问。如果进程试图访问未授权的资源,SELinux会禁止该进程的访问,并且在系统日志中记录相关信息
permissive模式
permissive模式是SELinux的一种辅助模式,它不会阻止任何访问,但会记录下未经授权的访问行为。在permissive模式下,SELinux只是记录违规行为,而不会强制执行安全策略。这种模式通常用于测试和调试,以便管理员了解哪些访问是被禁止的
disabled模式
disabled模式是指完全禁用SELinux。在disabled模式下,SELinux不会执行任何安全策略,所有访问都会被允许。这种模式通常用于解决一些特殊的问题,但不建议在生产环境中使用
[root@server ~]# setenforce 1 #临时开启
[root@server ~]# getenforce
Enforcing
[root@server ~]# setenforce 0 #临时关闭进入宽容模式
[root@server ~]# getenforce
Permissive
永久性开启selinux
[root@server ~]# vim /etc/selinux/config
SELINUX=enforcing 或 enabled
永久性关闭selinux
[root@server ~]# vim /etc/selinux/config
SELINUX=disabled
selinux配置文件
[root@server ~]# vim /etc/selinux/config
SELINUX=enforcing # 设置模式
SELINUXTYPE=targeted # 设置策略类型
修改安全上下文
[root@server ~]# chcon [-R] [-t type] [-u user] [-r role] 文件名
-R:递归修改,当前目录及目录下的所有文件都同时设置
-t:后面接安全上下文件的类型字段(重要)
-u:后面接身份标识
-r:后面接角色
-v:显示变动结果
[root@server ~]# chcon -R --reference=范例文件 文件名
[root@server ~]# touch test
[root@server ~]# ls
公共 模板 视频 图片 文档 下载 音乐 桌面 anaconda-ks.cfg test
[root@server ~]# ls -Z test
unconfined_u:object_r:admin_home_t:s0 test
[root@server ~]# ls -Z /etc/hosts
system_u:object_r:net_conf_t:s0 /etc/hosts
[root@server ~]# chcon -v -t net_conf_t /root/test
正在更改 '/root/test' 的安全上下文
[root@server ~]# ls -Z /root/test
unconfined_u:object_r:net_conf_t:s0 /root/test
[root@server ~]# touch temp
[root@server ~]# ls
公共 模板 视频 图片 文档 下载 音乐 桌面 anaconda-ks.cfg temp test
[root@server ~]# ls -Z temp
unconfined_u:object_r:admin_home_t:s0 temp
[root@server ~]# ls -Z /etc/passwd
system_u:object_r:passwd_file_t:s0 /etc/passwd
[root@server ~]# chcon -v --reference=/etc/passwd ~/temp
正在更改 '/root/temp' 的安全上下文
[root@server ~]# ls -Z temp
system_u:object_r:passwd_file_t:s0 temp
# 恢复快照
# 开启selinux
# 查看状态
[root@server ~]# getenforce
Enforcing
[root@server ~]# yum install httpd -y
[root@server ~]# mkdir /web1
# 使用mobaxterm将zy网页文件上传
[root@server ~]# systemctl start httpd
[root@server ~]# vim /etc/httpd/conf/httpd.conf
DocumentRoot "/web1"
<Directory "/web1">
[root@server ~]# systemctl restart httpd
# 测试:Windows中浏览器中输入server主机的IP地址,只会看到apache的欢迎页,说明selinux对/web1的安全上下文检测未通过
[root@server ~]# ls -Zd /var/www/html # 查看默认网页目录的安全上下文
system_u:object_r:httpd_sys_content_t:s0 /var/www/html
[root@server ~]# ls -Zd /web1
unconfined_u:object_r:default_t:s0 /web1
# 将/web1的类型修改为默认网页目录的类型
[root@server ~]# chcon -Rv -t httpd_sys_content_t /web1
[root@server ~]# ls -Zd /web1
unconfined_u:object_r:httpd_sys_content_t:s0 /web1
[root@server ~]# systemctl restart httpd
# 测试:此时输入IP地址则可以浏览
[root@server ~]# restorecon [-Rv] 文件或目录
-R:连同子目录一起修改;
-v:将过程显示到屏幕上
[root@server ~]# ls -Zd /web1
unconfined_u:object_r:httpd_sys_content_t:s0 /web1
[root@server ~]# restorecon -Rv /web1
[root@server ~]# ls -Zd /web1
unconfined_u:object_r:default_t:s0 /web1
semanage
命令(管理SELinux策略)
semanage
命令用于管理SELinux策略。SELinux(Security-Enhanced Linux)是一个Linux内核安全模块,提供了强大的安全策略,可以限制进程的权限,以防止恶意软件的传播
以下是一些常用的 semanage
命令:
semanage login -l:列出所有的登录名
semanage login -a -s user_u:为用户添加一个新的登录名
semanage login -d -s user_u:删除用户的登录名
semanage user -l:列出所有的用户
semanage user -a -r s0-s0:c0.c1023:为用户添加一个新的角色
semanage user -d -r s0-s0:c0.c1023:删除用户的角色
semanage port -l:列出所有的端口
semanage port -a -t http_port_t -p tcp 8080:为端口添加一个新的类型
semanage port -d -t http_port_t -p tcp 8080:删除端口的类型
[root@server ~]# semanage fcontext -l | grep 文件名
[root@server ~]# semanage fcontext -l | grep /etc/passwd
/etc/passwd[-\+]? regular file system_u:object_r:passwd_file_t:s0
/etc/passwd\.OLD regular file system_u:object_r:passwd_file_t:s0
/etc/passwd\.adjunct.* regular file system_u:object_r:passwd_file_t:s0
/etc/passwd\.lock regular file system_u:object_r:passwd_file_t:s0
[root@server ~]# semanage port -l | grep 协议
[root@server ~]# semanage port -l | grep http
http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
http_cache_port_t udp 3130
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989
[root@server ~]# semanage port -l | grep ssh
ssh_port_t tcp 22
getsebool
命令(获取SELinux布尔值的当前状态)
getsebool -a
#-a 选项用于显示所有的SELinux布尔值的当前状态
getsebool -a | grep httpd
#查询与 httpd 有关的布尔型规则
getsebool httpd_can_network_connect
#获取 httpd_can_network_connect 布尔值的当前状态
setsebool
命令(设置SELinux布尔值的状态)
setsebool -P httpd_can_network_connect 1
#启用 httpd_can_network_connect 布尔值
使用端口selinux的设定
#先把/web1的安全上下文类型修改为httpd_sys_content_t
[root@server ~]# ls -Zd /web1
unconfined_u:object_r:default_t:s0 /web1
[root@server ~]# ls -Zd /var/www/html
system_u:object_r:httpd_sys_content_t:s0 /var/www/html
[root@server ~]# chcon -R -t httpd_sys_content_t /web1
[root@server ~]# ls -Zd /web1
unconfined_u:object_r:httpd_sys_content_t:s0 /web1
[root@server ~]# vim /etc/httpd/conf/httpd.conf
Listen 7777 # 修改80端口为7777
[root@server ~]# systemctl restart httpd # 报错
Job for httpd.service failed because the control process exited with error code.
See "systemctl status httpd.service" and "journalctl -xeu httpd.service" for details.
[root@server ~]# semanage port -l | grep http
http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
http_cache_port_t udp 3130
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000 # 7777端口未在放行列表中
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989
[root@server ~]# systemctl status httpd.service # 查看日志
[root@server ~]# semanage port -a -t http_port_t -p tcp 7777 # 添加新端口
[root@server ~]# semanage port -l | grep http
http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
http_cache_port_t udp 3130
http_port_t tcp 7777, 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989
[root@server ~]# systemctl restart httpd # 重启服务成功
[root@server ~]#
# 测试:192.168.48.130:7777
设置selinux端口策略
[root@server ~]# semanage port -l | grep ssh
ssh_port_t tcp 22
[root@server ~]# vim /etc/ssh/sshd_config
Port 2222 # 去掉#,修改端口号
[root@server ~]# systemctl restart sshd # 重启失败
[root@server ~]# semanage port -a -t ssh_port_t -p tcp 2222 # 添加新端口
[root@server ~]# semanage port -l | grep ssh
ssh_port_t tcp 2222, 22
[root@server ~]# systemctl restart sshd # 重启成功