SELinux(Security-Enhanced Linux)是美国国家安全局在Linux开源社区的帮助下开发的一个强制访问控制(MAC,Mandatory Access Control)的安全子系统。Linux系统使用SELinux技术的目的是为了让各个服务进程都受到约束,使其仅能获取到本应获取的资源。
例如,你在电脑上安装了一个美图软件,当你在全神贯注地使用它给照片进行美颜时,它却在后台默默监视着你的QQ聊天记录,而这显然不应该是它应做的事情,如果是监视电脑中的图片资源还说的过去。SELinux安全子系统就是为了杜绝此类情况而设计的,它能够从多方面监控违法行为:对服务程序的功能进行限制(SELinux域限制可以确保服务程序做不了出格的事情);对文件资源的访问限制(SELinux安全上下文确保文件资源只能被其所属的服务程序进行访问)。“SELinux域”和“SELinux安全上下文”是SELinux的双保险,使服务程序无法进行越权操作。
SELinux服务有三种运行模式,具体如下:

  • Enforcing:强制启用安全策略模式,将拦截服务的不合法请求。
  • Permissive:遇到服务越权访问时,只发出警告而不强制拦截。
  • Disabled:对于越权的行为不警告也不拦截。

selinux的配置文件位置:/etc/selinux/config,链接文件位置:/etc/sysconfig/selinux
本人的机器环境

ip地址 操作系统 安装软件
192.168.2.211 Centos 7 64位 yum方式安装httpd

1、查询selinux服务的工作状态
sestatus
SELinux使用详解
2、查看selinux的运行模式
getenforce
SELinux使用详解
3、修改selinux的运行模式

setenforce 0  #将运行模式设置为Permissive,即临时关闭selinux,重启系统后失效
setenforce 1  #将运行模式设置为Enforcing,如果配置文件里是Permissive,重启系统后失效

SELinux使用详解
4、修改配置文件,使其永久关闭selinux,重启系统后生效
注:配置文件里定义的是selinux的默认运行状态,可以理解为系统重启后的状态

sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
sed -i 's/SELINUXTYPE=targeted/#&/' /etc/selinux/config
setenforce 0

5、查询安全上下文相关命令,使用-Z参数
查看目录的安全上下文,使用ls -Z
SELinux使用详解
查看文件的安全上下文
SELinux使用详解
查看进程的安全上下文,使用ps -Z
SELinux使用详解
查看selinux用户的安全上下文,使用id -Z
SELinux使用详解
6、使用selinux需要记住的四个命令

  • semanage:该命令用于管理selinux的安全上下文,可查看、添加、修改和删除进程、文件或目录的安全上下文策略
  • restorecon:执行semanage命令后,需要使用restorecon命令将设置好的安全上下文立即生效,可以加上-Rv参数对指定的目录进行递归操作,以及显示修改过程
  • getsebool:查询selinux域的安全策略,需要加上-a参数
  • setsebool:修改selinux域的安全策略的规则,加上-P参数使其永久且立即生效

7、修改httpd服务的默认网站目录,来配置selinux
(1)安装httpd服务,并设置firewalld防火墙允许http服务

yum -y install httpd
firewall-cmd --permanent --add-service=http
firewall-cmd --reload

(2)将网站数据目录修改为/home/wwwroot目录,并创建首页文件

mkdir /home/wwwroot
echo "The New Web Directory" > /home/wwwroot/index.html

(3)修改httpd服务的配置文件
vim /etc/httpd/conf/httpd.conf
SELinux使用详解
(4)启动httpd服务,并验证效果
systemctl start httpd
SELinux使用详解
通过浏览器访问发现显示上图页面,而这正是selinux在捣鬼。
(5)查看selinux运行状态,并关闭它

getenforce
setenforce 0

SELinux使用详解
再次刷新页面,就会看到正常的网页内容了。
SELinux使用详解
我们把httpd服务的网站数据默认保存目录修改为/home/wwwroot,这显然违反了selinux的监管原则,/home目录是用来存放普通用户的家目录数据的,而现在httpd服务却要去获取普通用户家目录中的数据,selinux自然是不允许了。我们现在把selinux服务恢复到强制启用安全策略模式,然后修改selinux的安全上下文即可。
(6)启用selinux,并且对比/var/www/html和/home/wwwroot目录的安全上下文有什么区别

setenforce 1
ls -Zd /var/www/html/
ls -Zd /home/wwwroot/

SELinux使用详解
selinux安全上下文是由用户段、角色段和类型段等多个信息项组成的,用户段system_u表示系统进程的身份,角色段object_r表示文件目录的角色,类型段httpd_sys_content_t表示网站服务的系统文件。即然如此,那我们只将/home/wwwroot目录的安全上下文修改为跟原始网站目录一样就行了。
(7)安装所需命令软件包
yum -y install policycoreutils-python.x86_64
(8)将/home/wwwroot目录添加一条安全上下文

semanage fcontext -a -t httpd_sys_content_t /home/wwwroot
semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/*

SELinux使用详解
我们再通过浏览器访问一下,能正常显示网页内容,OK。
SELinux使用详解
8、开启httpd服务的个人用户主页功能,来配置selinux
(1)修改配置文件,开启个人用户主页功能
vim /etc/httpd/conf.d/userdir.conf
SELinux使用详解
(2)切换到普通用户,并且创建网站目录及首页文件

useradd xuad
su - xuad
mkdir public_html
echo "This is user's website" > public_html/index.html
chmod -Rf 755 /home/xuad/
exit
systemctl restart httpd

在浏览器地址栏里输入“http://192.168.2.223/~xuad”,不出所料,报错了
SELinux使用详解
httpd服务既然提供了个人用户主页功能,那么用户的网站目录自然是存在在用户的家目录中,所以应该不是selinux安全上下文的问题。我们前面有提到过selinux域,那么是不是被它给阻止了呢?
(3)查看与http协议相关的安全策略
getsebool -a | grep http
SELinux使用详解
这么多的安全策略规则,我们没必要逐个理解它们,只需要通过名字大致猜测出相关的策略用途就可以了。那么通过名字我们很容易能发现应该是httpd_enable_homedirs规则,而此规则是off,我们应该将其修改为on。
(4)修改selinux域策略规则,该操作永久生效,并且立即生效
setsebool -P httpd_enable_homedirs=on
然后刷新一下页面,能正常显示首页内容了。
SELinux使用详解
9、配置基于端口号的多站点,来配置selinux
(1)创建网站目录及首页文件

mkdir -p /home/wwwroot/8111
mkdir -p /home/wwwroot/8222
echo "port:8111" > /home/wwwroot/8111/index.html
echo "port:8222" > /home/wwwroot/8222/index.html

(2)修改配置文件,增加两个监听端口,并且添加两个虚拟站点配置
vim /etc/httpd/conf/httpd.conf
SELinux使用详解
SELinux使用详解
(3)查看selinux安全上下文

ls -Zd /home/wwwroot/8111/
ls -Zd /home/wwwroot/8222/

SELinux使用详解
前面我们修改了/home/wwwroot目录的安全上下文,此时我们新建的两个目录默认继承了上层目录的安全上下文,这里无须再修改了。现在重启httpd服务
systemctl restart httpd
SELinux使用详解
奇怪,启动时居然报错了。因为8111和8222端口不属于httpd服务,但现在却被httpd服务监听使用了,所以selinux会拒绝httpd服务使用这两个端口。
(4)查看与http协议相关的selinux服务允许的端口列表
semanage port -l | grep http
SELinux使用详解
显然http_port_t规则里没有8111和8222这两个端口号。
(5)往http_port_t规则里添加端口号

semanage port -a -t http_port_t -p tcp 8111
semanage port -a -t http_port_t -p tcp 8222

SELinux使用详解
此操作立即生效,且永久生效,无须使用restorecon命令。
(6)配置firewalld防火墙允许8111和8222端口

firewall-cmd --permanent --add-port=8111/tcp
firewall-cmd --permanent --add-port=8222/tcp
firewall-cmd --reload
firewall-cmd --list-ports

SELinux使用详解
(7)重启httpd服务,并通过浏览器验证
systemctl restart httpd
SELinux使用详解
SELinux使用详解
网站页面正常显示,OK。