SELinux

时间:2024-11-13 08:31:28

目录

  • 概念
    • 作用
    • SELinux与传统的权限区别
  • SELinux工作原理
    • 名词解释
    • 文件安全上下文查看
      • 分析
      • seinfo命令
  • SELinux的启动、关闭与查看
    • 三种配置模式
    • 原理图:
    • 模式管理
    • 查看selinux的状态
  • selinux配置文件
  • 修改安全上下文
    • chcon命令
    • 示例
    • restorecon命令
    • semanage命令
  • 实验1
  • 实验2

概念

  • SELinux(Security-Enhanced Linux)是美国国家安全局在 Linux 开源社区的帮助下开发的一个强制访问控制(MAC,Mandatory Access Control)的安全子系统,用于各个服务进程都受到约束,使其仅获取到本应获取的资源
  • 例如,电脑上下载了一个美图软件,当您全神贯注地使用它给照片进行美颜的时候,它却在后台默默监听着浏览器中输入的密码信息,而这显然不应该是它应做的事情

作用

  • SELinux 域限制:对服务程序的功能进行限制,以确保服务程序做不了出格的事情
  • SELinux 安全上下文:对文件资源的访问限制,确保文件资源只能被其所属的服务程序访问

SELinux与传统的权限区别

  • 传统的文件权限与账号的关系:属于自主访问控制DAC(Discretionary Access Control),当某个进程想要对文件进行访问时,系统就会根据该进程的所有者/用户组,并比较文件的权限,若通过权限检查,就可以访问该文件,注意:各种权限设置对root用户是无效的
  • SELinux的以策略规则制定特定程序读取特定文件:属于强制访问控制MAC(Mandatory Access Control),可以针对特定的进程与特定的文件资源来进行权限的控制,即使你是root在使用不同的进程时,你所能取得的权限并不一定是root,而得要看当时该进程的设置而定,则就可以针对进程来进行访问控制

SELinux工作原理

名词解释

  • 主体(Subject)

    • 主体就是想要访问文件或目录资源的进程。
    • 进程得到资源流程:由用户调用命令,由命令产生进程,由进程去访问文件或目录资源。
    • 自主访问控制系统中(Linux 默认权限中),靠权限控制的主体是用户
    • 强制访问控制系统中(SELinux 中),靠策略规则控制的主体则是进程
  • 目标(Object)

    • 目标就是需要访问的文件或目录资源
  • 策略(Policy)

    • Linux 系统中进程与文件的数量庞大,限制进程是否可以访问文件的 SELinux 规则数量就更加烦琐,如果每个规则都需要管理员手工设定,那么 SELinux 的可用性就会极低,所以SELinux 默认定义了两个策略来制订规则
    • 2个默认策略
    • -targeted:默认策略,用于限制网络服务(dhcpd,httpd,named,nscd,ntpd,portmap,snmpd,squid,以及 syslogd),对本机系统的限制极少
    • -mls:多级安全保护策略,该策略限制更为严格
  • 安全上下文(Security Context)

    • 所有进程、文件和目录都有自己的安全上下文

    • 进程是否能够访问文件或目录,就要其安全上下文是否匹配

    • 例:找对象时,男人看作主体,女人就是目标,男人是否可以追到女人(主体是否可以访问目标),主要看两人的性格是否合适(主体和目标的安全上下文是否匹配),但两个人的性格是否合适,是需要靠生活习惯、为人处世、家庭环境等具体的条件来进行判断的(安全上下文是否匹配是需要通过策略中的规则来确定的)

    • 关系图:在这里插入图片描述

    • 解释:

      • 当主体(进程)访问目标(文件)时,首先和 SELinux 中定义好的策略进行匹配
      • 若符合定义的规则,且主体的安全上下文和目标的安全上下文匹配则允许访问文件
      • 若安全上下文比较失败,则拒绝访问,并通过 AVC(Access Vector Cache,访问向量缓存,主要用于记录所有和 SELinux 相关的访问统计信息)生成拒绝访问信息
      • 注意:最终是否可以访问到目标文件,还要匹配产生进程(主体)的用户是否对目标文件拥有合理的rwx权限

文件安全上下文查看

  • 命令
[root@server ~]# ls -Z
system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
[root@server ~]# ll -Z
总用量 4
-rw-------. 1 root root system_u:object_r:admin_home_t:s0 1229  826 22:11 anaconda-ks.cfg

分析

  • 重点为:system_u:object_r:admin_home_t:s0

  • 安全上下文用冒号分为四个字段

  • 身份标识(Identify):相当于账号方面的身份标识,有三种类型:

    • root:安全上下文的身份是 root,默认会映射为unconfined_u ,可以通过以下命令查看映射关系:

    • [root@server ~]# semanage login -l
      
      登录名                  SELinux 用户           MLS/MCS 范围           服务
      
      __default__          unconfined_u         s0-s0:c0.c1023       *
      root                 unconfined_u         s0-s0:c0.c1023       *
      
    • system_u:系统用户身份,其中“_u”代表 user

    • 普通用户名_u:普通用户身份(用户id1000-65535),用户数据的user字段是user_u

      • 注意:user 字段只用于标识数据或进程被哪个身份所拥有,系统数据的 user 字段是 system_u,用户数据 user 字段是 user_u
  • 角色(role):表示此数据是进程还是文件或目录包含(了解就行)

    • object_r:代表该数据是文件或目录,r代表 role(角色的意思)
    • system_r:进程r代表 role
  • 类型(type):

    • 最重要,进程是否可以访问文件,主要就是看进程的安全上下文类型字段是否和文件的安全上下文类型字段相匹配

    • 在默认的targeted策略中

    • 类型字段在主体(进程)的安全上下文中被称作域(domain)

    • 类型字段在目标(文件或目录)的安全上下文中被称作类型(type)

    • 进程的域与文件的类型是否匹配需要查询策略规则

  • 灵敏度:用 s0、s1、s2 来命名,数字为灵敏度分级,数值越大,灵敏度越高

seinfo命令

作用:查询身份,角色等信息,需要安装才能使用

[root@server ~]# yum install setools-console -y

格式:

[root@server ~]# seinfo -参数

参数:

-u: 列出SELinux中所有的身份(user);
-r: 列出SELinux中所有的角色(role);
-t: 列出SELinux中所有的类型(type);
-b: 列出所有的布尔值(也就是策略中的具体规则名称);
-x: 显示更多的信息;
[root@server ~]# seinfo -u

Users: 8
   guest_u
   root
   staff_u
   sysadm_u
   system_u
   unconfined_u
   user_u
   xguest_u
[root@server ~]# seinfo -r

Roles: 14
   auditadm_r
   dbadm_r
   guest_r
   logadm_r
   nx_server_r
   object_r
   secadm_r
   staff_r
   sysadm_r
   system_r
   unconfined_r
   user_r
   webadm_r
   xguest_r
[root@server ~]# seinfo -t | wc -l
5051
  • 例子:查看http的默认网页文件信息
[root@server ~]# yum  install httpd  -y
[root@server ~]# ls -Zd /var/www/html   #-d当遇到目录时列出目录本身而非目录内的文件
system_u:object_r:httpd_sys_content_t:s0 /var/www/html

SELinux的启动、关闭与查看

三种配置模式

  • enforcing:强制模式,启用SELinux,将拦截服务的不合法请求
  • permissive:宽容模式,启用SELinux,遇到服务越权访问时,只发出警告而不强制拦截
  • disabled:关闭模式,SELinux没有运行

原理图:

在这里插入图片描述

模式管理

  • 查看当前工作模式
[root@server ~]# getenforce
  • 临时开启/关闭selinux
[root@server ~]# getenforce
Enforcing
[root@server ~]# setenforce  0  # 临时关闭进入宽容模式
[root@server ~]# getenforce
Permissive
[root@server ~]# setenforce  1  # 临时开启
[root@server ~]# getenforce
Enforcing
  • 永久性关闭
[root@server ~]# vim /etc/selinux/config
SELINUX=disabled
  • 注意
    • enforcing状态与permissive状态之间切换时,不需要重启系统
    • enforcing、permissive与disabled之间切换时,必须重启系统才会生效

查看selinux的状态

  • 命令
[root@server ~]# sestatus
  • 分析
[root@server ~]# sestatus
SELinux status:                 enabled   # 是否启用
SELinuxfs mount:                /sys/fs/selinux   # selinux临时文件系统的挂载点
SELinux root directory:         /etc/selinux   # 启动目录,配置文件目录位置
Loaded policy name:             targeted    # 策略类型
										# targeted:只保护目标进行,默认
										# minimum:少数选定进程进行保护
										# mls:多级安全。*
Current mode:                   permissive   # 执行的模式,重要
Mode from config file:          permissive    # 配置文件的模式
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)
Max kernel policy version:      33

selinux配置文件

  • selinux的配置文件/etc/selinux/config
  • 注意/etc/sysconfig/selinux文件与上述配置文件内容相同,选择一个配置即可
[root@server ~]# vim  /etc/selinux/config 
SELINUX=enforcing         # 设置模式
SELINUXTYPE=targeted      # 设置策略类型

修改安全上下文

chcon命令

  • 作用
    手动修改目标的上下文策略
  • 格式
# 方法1
[root@server ~]# chcon  [-R] [-t  type]  [-u  user]  [-r  role]  文件名
-R:递归修改,当前目录及目录下的所有文件都同时设置
-t:后面接安全上下文件的类型字段(重要)
-u:后面接身份标识
-r:后面接角色
-v:显示变动结果
# 方法2:会把范例文件的4个字段全部进行参照,即全部修改
[root@server ~]# chcon  -R  --reference=范例文件  文件名

示例

  • 例1:使用方法1单独修改
[root@server ~]# touch test

[root@server ~]# ls
anaconda-ks.cfg  test

[root@server ~]# ls -Z test
system_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 test
system_u:object_r:net_conf_t:s0 test
  • 例2:使用方法2修改
[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
  • 例3:使用httpd服务演示安全上下文值的设定
# 恢复快照
# 开启selinux
# 查看状态
[root@server ~]# getenforce
Permissive

[root@server ~]# yum install nginx -y
[root@server ~]# mkdir /web
[root@server ~]# vim /etc/nginx/nginx.conf
        root         /web;
[root@server ~]# systemctl restart nginx
# 测试,windows中浏览器输入本机ip,只会看到nginx的欢迎页,说明selinux对/web1的安全上下文检测未通过

[root@server ~]# ls -Zd /usr/share/nginx/html/
system_u:object_r:httpd_sys_content_t:s0 /usr/share/nginx/html/

[root@server ~]# ls -Zd /web
unconfined_u:object_r:default_t:s0 /web

[root@server ~]# chcon -Rv -t httpd_sys_content_t /web

[root@server ~]# ls -Zd /web
unconfined_u:object_r:httpd_sys_content_t:s0 /web

[root@server ~]# systemctl restart nginx

restorecon命令

  • 作用
    • 让文件的Selinux类型恢复为默认的selinux类型
    • 默认的SELinux类型与semanage命令有关,其参考semanage命令所查询的默认SELinux类型
  • 格式
[root@server ~]# restorecon  [-Rv]  文件或目录
-R:连同子目录一起修改;
-v:将过程显示到屏幕上
  • 例1
    将/web恢复默认类型
[root@server ~]# ls -Zd /web
unconfined_u:object_r:httpd_sys_content_t:s0 /web
[root@server ~]# restorecon -Rv /web

[root@server ~]# ls -Zd /web
unconfined_u:object_r:default_t:s0 /web

semanage命令

  • 作用
    • 用于管理selinux的策略,查询/修改/增加/删除文件的默认selinux安全上下文,管理网络端口、消息接口等
  • 格式
[root@server ~]# semanage   选项    参数   文件
选项:
	login
	user
	port
	interface
	fcontext  #注意:fcontext查询默认安全上下文(重要)
	translation
	boolean
参数:
	 -l :查询;
	 -a :添加
	 -m :修改
	 -d :删除
	 -D :全部删除
	 -t :类型
	 -r :角色
	 -s :用户
	 -f :文件
文件:
	文件或目录
  • 常用命令组
    1.查询出默认的安全上下文
#命令找不到时,可先下载以下数据包
[root@server ~]# yum install policycoreutils-python-utils -y

[root@server ~]# semanage  fcontext  -l |  grep  文件名
[root@server ~]# semanage fcontext -l | grep /etc/passwd
/etc/passwd[-\+]?                                  regular file       system_u:obj
/etc/passwd\.OLD                                   regular file       system_u:obj
/etc/passwd\.adjunct.*                             regular file       system_u:obj
/etc/passwd\.lock                                  regular file       system_u:obj

2.查看允许访问的端口

[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

实验1

  • 使用nginx服务的端口演示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  # 重启服务成功
# 测试:192.168.160.137:7777

实验2

  • 使用ssh设置新端口号,设置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  # 重启成功

# 新建会话输入以下内容测试
PS C:\Users\13289> ssh root@192.168.80.130 -p 2222
或
PS C:\Users\13289> ssh -p 2222 root@192.168.80.130
#测试成功