说到SELinux大家都有种望而生畏的感觉,因为不论是各种教程还是我们平时操作遇到问题的第一反应就是先关闭SELinux,直觉会告诉我们这个东西很难了解,而且实际的用处并不多,直接关闭即可。但是在RHCE的考试中,要求开启SELinux,并且有相关的操作要考试,听着是不是很可怕?笔者一开始也是这么认为。但在咬牙学习后发现,并没有那么难!下面跟着笔者脚步,一块来学习下。
一、文章大纲
- SELinux是什么
- SELinux三种模式
- SELinux模式切换
- SELinux相关配置
- 文件创建和拷贝target标签的变化
- 修改ssh端口后配置
- 修改httpd端口和文件后的配置
- SELinux小结
二、SELinux是什么
百科上对于SELinux介绍是这样的“SELinux(Security-Enhanced Linux) 是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统。” 这句话说得太官方,什么美国国家安全局,什么历史上最杰出,看上去就让人感觉太高大上太复杂了,让人望而生畏。
首先你别怕,想想我们的学习目标并不是要成为SELinux专家,我们目标有两个:1、日常Linux操作过程中涉及到SELinux会简单操作,不至于每次遇上就直接关闭掉。2、能够掌握RHCE中SELinux考试知识,能够顺利通过考试。所以基于这两个目标,我们对SELinux有一个感性的认识和掌握基础操作便可,不求甚解。
前面也提及到了,SELinux是一个强制访问控制的功能实现。可以类比为操作系统的防火墙,例如:需要对外开放8080端口的web服务,虽然httpd服务监听8080端口,用户还是没办法访问8080端口,需要管理员将8080端口在防火墙上放开。那么这个过程就是强制访问控制,httpd服务没办法决定自己开放到外部,需要管理员手动配置,且要管理员配置哪些端口才可以开放哪些端口。与防火墙不同在于:防火墙作用于网络层协议和端口,而SELinux可以通过SELinux标签作用于端口、文件和进程等等,比防火墙的控制细粒度更高,也就更加安全,更加复杂。
三、SELinux三种模式
SELinux共有三种工作模式:
- enforcing 强制模式:只要是违反策略就会被阻止,并记录日志。
- permissive 宽容模式:如果违反策略,只记录日志,不阻止。
- disabled 禁用模式:关闭selinux。
四、SELinux模式切换
默认状态下SELinux为强制模式状态,我们可以通过命令行对模式进行切换。
#查看当前SELinux模式,为强制模式
[root@localhost ~]# getenforce
Enforcing
#临时切换为宽容模式,只记录日志,不会阻止
[root@localhost ~]# setenforce 0
[root@localhost ~]# getenforce
Permissive
#切换回强制模式
[root@localhost ~]# setenforce 1
[root@localhost ~]# getenforce
Enforcing
#通过命令行操作只是临时生效,设备重启会恢复默认的配置,如果要永久生效需要编辑配置文件
#编辑配置文件/etc/selinux/config
[root@localhost ~]# cat /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 #如果设置为disabled后,重启服务器就永久关闭selinux
# SELINUXTYPE= can take one of three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
模式切换过程中有两点需要注意:
- 只有在强制模式下切换模式才能实时生效,如果默认是禁用状态,需要重启使SELinux生效后才能切换模式。
- 永久关闭SELinux修改配置文件项SELINUX=disabled,注意是SELINUX不是SELINUXTYPE,修改错误可能会导致机器起不来。SELINUXTYPE保持默认状态就可以,一般情况下都不会修改。
五、SELinux相关配置
基础操作
注:一些最小化安装的系统可能没有semanage命令,需要先使用yum命令安装 [root@localhost ~]# semanage port -l|grep http -bash: semanage: command not found
[root@localhost ~]# yum install policycoreutils-python
1、使用-Z参数查看文件selinux标签
查看文件2、使用Z参数查看进程selinux标签
查看进程3、使用-Z参数查看用户的selinux标签
查看用户修改ssh端口后配置
#编辑ssh配置文件,新增端口1022端口
[root@localhost ~]# vi /etc/ssh/sshd_config
#
Port 22
Port 1022
#AddressFamily any
#ListenAddress 0.0.0.0
#查看监听端口,发现配置没有生效
[root@localhost ~]# ss -lnp|grep sshd
u_dgr UNCONN 0 0 * 40490 * 9502 users:(("sshd",pid=21614,fd=4))
u_dgr UNCONN 0 0 * 49367 * 9502 users:(("sshd",pid=21618,fd=4))
tcp LISTEN 0 128 *:22 *:* users:(("sshd",pid=21553,fd=3))
tcp LISTEN 0 128 :::22 :::* users:(("sshd",pid=21553,fd=4))
#查看服务日志信息,提示绑定1022端口权限被拒绝了
[root@localhost ~]# systemctl status sshd
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2023-06-21 16:06:44 CST; 1h 53min ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 21553 (sshd)
CGroup: /system.slice/sshd.service
└─21553 /usr/sbin/sshd -D
Jun 21 16:06:44 localhost.localdomain systemd[1]: Starting OpenSSH server daemon...
Jun 21 16:06:44 localhost.localdomain sshd[21553]: error: Bind to port 1022 on 0.0.0.0 failed: Permission denied.
Jun 21 16:06:44 localhost.localdomain sshd[21553]: error: Bind to port 1022 on :: failed: Permission denied.
Jun 21 16:06:44 localhost.localdomain sshd[21553]: Server listening on 0.0.0.0 port 22.
Jun 21 16:06:44 localhost.localdomain sshd[21553]: Server listening on :: port 22.
Jun 21 16:06:44 localhost.localdomain systemd[1]: Started OpenSSH server daemon.
Jun 21 17:59:34 localhost.localdomain sshd[21614]: Accepted password for root from 172.17.128.1 port 54078 ssh2
Jun 21 17:59:34 localhost.localdomain sshd[21618]: Accepted password for root from 172.17.128.1 port 54080 ssh2
#权限不足因为没有配置selinux标签
#其实在sshd_config配置文件中也说明了
cat /etc/ssh/sshd_config
# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
Port 22
Port 1022
#先查看ssh开放端口标签
[root@localhost ~]# semanage port -l|grep ssh
ssh_port_t tcp 22
#添加我们需要修改的端口
[root@localhost ~]# semanage port -a -t ssh_port_t -p tcp 1022
# -a 表示添加
# -t 指定要添加的标签名
# -p 后面接协议和端口号
#重启服务
[root@localhost ~]# systemctl restart sshd
#查看sshd服端口监听情况,目前已经成功监听1022端口
[root@localhost ~]# ss -lnp|grep sshd
u_dgr UNCONN 0 0 * 47776 * 9502 users:(("sshd",pid=21716,fd=4))
u_dgr UNCONN 0 0 * 48434 * 9502 users:(("sshd",pid=21720,fd=4))
tcp LISTEN 0 128 *:22 *:* users:(("sshd",pid=21898,fd=5))
tcp LISTEN 0 128 *:1022 *:* users:(("sshd",pid=21898,fd=3))
tcp LISTEN 0 128 :::22 :::* users:(("sshd",pid=21898,fd=6))
tcp LISTEN 0 128 :::1022 :::* users:(("sshd",pid=21898,fd=4))
#这个时候还有最后一步,开通防火墙
[root@localhost ~]# firewall-cmd --permanent --zone=public --add-port=1022/tcp
success
##更新防火墙规则使规则生效
[root@localhost ~]# firewall-cmd --reload
success
修改httpd端口和文件后的配置
#安装httpd
[root@localhost ~]# yum install -y httpd
#配置开机自启并启动httpd,注意RHCE考试服务都需要配置开机自启,否则机器重启服务没起来不给分
[root@localhost ~]# systemctl enable --now httpd
#测试服务,可以正常访问
[root@localhost ~]# curl http://127.0.0.1|head
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 4897 100 4897 0 0 3644k 0 --:--:-- --:--:-- --:--:-- 4782k
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Apache HTTP Server Test Page powered by CentOS</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- Bootstrap -->
<link href="/noindex/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="noindex/css/open-sans.css" type="text/css" />
#在tmp目录创建3个测试文件
[root@localhost ~]# touch file{1..3}
[root@localhost ~]# mv file1 /var/www/html/
[root@localhost ~]# cp file2 file3 /var/www/html/
[root@localhost ~]# cd /var/www/html/
[root@localhost html]# ls -lZ
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 file1
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file2
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file3
[root@localhost html]# echo "hello world" > file1
[root@localhost html]# echo "hello world" > file2
[root@localhost html]# echo "hello world" > file3
#修改配置,增加端口85
[root@localhost html]# vi /etc/httpd/conf/httpd.conf
Listen 80
Listen 85
#与ssh添加端口相同,将85端口加入selinux标签
#查看http端口标签
[root@localhost ~]# 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
#添加tcp85端口
[root@localhost ~]# semanage port -a -t http_port_t -p tcp 85
#再次查看,已添加成功
[root@localhost ~]# 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 85, 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989
#修改配置后记得重启服务
[root@localhost ~]# systemctl restart httpd
#可成功访问
[root@localhost ~]# curl http://127.0.0.1:85
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Apache HTTP Server Test Page powered by CentOS</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- Bootstrap -->
<link href="/noindex/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="noindex/css/open-sans.css" type="text/css" />
<style type="text/css"><!--
#访问file1文件,提示无权限
[root@localhost ~]# curl http://127.0.0.1:85/file1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /file1
on this server.</p>
</body></html>'
#文件file2和file3可以正常访问
[root@localhost ~]# curl http://127.0.0.1:85/file2
hello world
[root@localhost ~]# curl http://127.0.0.1:85/file3
hello world
#为啥出现上面情况,原因就在于selinux标签
#查看文件标签,file1由于我们是从root目录下移动,文件保留了原有标签。file2和file3是拷贝的,文件继承了目录的标签
[root@localhost html]# ll -Z
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 file1
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file2
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file3
#修改文件file1标签
#方式一:使用chcon命令修改
[root@localhost html]# ll -Z
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 file1
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file2
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file3
[root@localhost html]# chcon -t httpd_sys_content_t file1
[root@localhost html]# ll -Z
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file1
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file2
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file3
#方式二:使用 semanage fcontext修改规则库
[root@localhost html]# ll -Z
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 file1
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file2
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file3
#使用semanage fcontext修改规则库,-m参数为修改,如果没有规则会报错,可以使用-a参数添加
[root@localhost html]# semanage fcontext -m -t httpd_sys_content_t file1
#只是修改规则库,文件属性没有直接生效
[root@localhost html]# ll -Z
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 file1
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file2
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file3
#使用restorecon更新后,才能生效
[root@localhost html]# restorecon -R file1
[root@localhost html]# ll -Z
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file1
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file2
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file3
#方式三:直接使用restorecon,恢复目录下文件属性
[root@localhost html]# ll -Z
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 file1
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file2
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file3
[root@localhost html]# pwd
/var/www/html
#恢复目录下文件属性
[root@localhost html]# restorecon -Rv /var/www/html/
restorecon reset /var/www/html/file1 context unconfined_u:object_r:admin_home_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
[root@localhost html]# ll -Z
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file1
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file2
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 file3
#再次测试可正常访问
[root@localhost html]# curl http://127.0.0.1:85/file1
hello world
六、SELinux小结
通过上述的操作不难看出,RHCE考试是非常贴合实践操作。没有额外无用操作,全部都很实用,总结来说有两类:
- 对于端口个性化修改需要同步修改SELinux Port标签,如http服务要修改8080端口,ssh服务要修改1022端口。
- 对于移动文件导致SELinux fcontext标签不一致情况,需要修改文件fcontext。
如上,关于SELinux学习就结束啦,上面知识已经足以应对日常的操作和RHCE考试,恭喜你战胜心中的纸老虎,预祝考试顺利。
网友评论