zoukankan      html  css  js  c++  java
  • selinux简介

    selinux概念

    由美国国家安全局(NSA)和SCC联合开发的,强制访问控制的安全模块。2000年以GPL开源,linux2.6内核后集成在内核里。

    不启用selinux时,访问模式叫:DAC(discretionary access control)自由访问控制

    在DAC模式下的进程能够访问哪些资源是由启用这个进程的用户身份决定的,这个用户能访问的,这个进程都可以访问。

    启用selinux时,访问模式叫:MAC(Mandatory access control)强制访问控制

    在MAC模式下的进程能够访问哪些资源是由selinux设定的。

    selinux的工作类型

    selinux的工作类型定义在/etc/selinux/config文件中

    centos7:

    # 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
    # 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
    

    centos6:

    # 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
    # SELINUXTYPE= can take one of these two values:
    #     targeted - Targeted processes are protected,
    #     mls - Multi Level Security protection.
    SELINUXTYPE=targeted
    
    • targeted:保护常见的网络服务(默认工作类型)
    • minimum:只对选择的服务保护

    selinux安全上下文

    • 传统linux,一切皆文件,由用户,组,权限控制访问

    • 在selinux中,一切皆对象(object),由存放在inode的扩展属性域的安全元素所访问控制。

      查看inode的扩展属性域的命令:ls -Zps -Z

      这些属性起名叫标签或context。

      ls:

      # ls -lZ
      -rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
      -rw-r--r--. root root system_u:object_r:admin_home_t:s0 initial-setup-ks.cfg
      -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 linux-3.10.67.tar.xz
      drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 scripts
      

      ps:

      # ps auxZ
      LABEL                           USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
      system_u:system_r:init_t:s0     root         1  0.0  0.1 193788  6904 ?        Ss   05:25   0:06 /usr/lib/systemd/systemd --swit
      system_u:system_r:kernel_t:s0   root         2  0.0  0.0      0     0 ?        S    05:25   0:00 [kthreadd]
      system_u:system_r:kernel_t:s0   root         3  0.0  0.0      0     0 ?        S    05:25   0:00 [ksoftirqd/0]
      
    • 所以文件,端口,进程都具备安全标签:安全上下文(security context)

    • 安全上下位由5个元素组成:user:role:type:sensitivity:category

      • user:登录系统的用户类型
        • root:root用户
        • user_u:普通用户
        • system_u:系统用户
        • unconfined_t:自由进程/文件。多数本地进程都属于此。
      • role:定位文件,进程和用户的用途。文件:object_r;进程和用户:system_r
      • type:数据类型。最常用的属性,target策略就是根据type的值,控制可以访问/不可访问哪些资源。但是有个问题,每个资源只有唯一的type,当有多个别的东西想访问同一个资源的时候就麻烦了,就要修改type成public_content_t(只读,不可以修改这个资源);public_content_rw_t(读写)
      • sensitivity:默认是s0
      • category:target工作类型下,不使用。
    • 标签/context分实际的标签和期望标签

      • 实际标签:使用ls -Z和ps -Z看到的标签。

      • 期望标签:安装操作系统后,系统给的标签。标签是可以修改的,所以有期望标签,修改了某个文件的标签后,这个文件的期望标签和实际标签就不一样了。

        查看文件,进程,端口的期望标签:semanage fcontext -l

        # semanage fcontext -l | grep "/var/log/messages"
        /var/log/messages[^/]*                             all files          system_u:object_r:var_log_t:s0
        # ls -Z /var/log/messages
        -rw-------. root root system_u:object_r:var_log_t:s0   /var/log/messages
        

        期望标签存放在:/etc/selinux/targeted/contexts/files/目录

        # ls /etc/selinux/targeted/contexts/files/
        file_contexts           file_contexts.homedirs.bin  file_contexts.subs
        file_contexts.bin       file_contexts.local         file_contexts.subs_dist
        file_contexts.homedirs  file_contexts.local.bin     media
        

    selinux策略

    • object:所以可以读取的对象,包括文件,目录,进程,端口
    • subject:进程
    • 当一个subject要访问object时,selinux执行AVC(access vector cache)检查,在AVC中,subject和object的权限被缓存。
    • 安全策略:定义subject读取object的规则数据库,规则中记录了哪个类型的(type)的subject使用哪个方法读取哪一个object是允许的还是拒绝的,并且定义了哪种行为是允许或拒绝的。

    启用selinux

    查看selinux是启用还是禁用

    # getenforce
    Enforcing
    [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
    # 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
    

    enforcing:启用状态

    permissive:没启用,但是违反了selinux的规则,只出警告信息而已。

    disabled:禁用状态。

    • 临时启用:

      # setenforce 1
      # getenforce
      Enforcing
      
    • 临时禁用:

      # setenforce 0
      # getenforce
      Permissive
      

      注意:使用命令setenforce,只能在Enforcing和Permissive间切换。不能从disabled状态切换成Enforcing。

    永久修改selinux启用或禁用:修改文件/etc/selinux/config,重启才生效。

    禁用后(disabled而不是permissive)创建的文件就没有标签了,

    而且【-rw-r--r--】后面没有点,有点就说明有标签。

    # sestatus
    SELinux status:                 disabled
    # setenforce 1
    setenforce: SELinux is disabled
    # touch temp2
    [root@localhost ~]# ls -Z temp2
    -rw-r--r-- root root ?                                temp2
    

    从disabled切换到enabled后,在看刚才创建的temp2文件:

    有点了,但是type是unlabeled_t

    # getenforce
    Enforcing
    # ls -Z temp2
    -rw-r--r--. root root system_u:object_r:unlabeled_t:s0 temp2
    

    查看详细状态信息:

    # sestatus
    SELinux status:                 enabled
    SELinuxfs mount:                /sys/fs/selinux
    SELinux root directory:         /etc/selinux
    Loaded policy name:             targeted
    Current mode:                   permissive//当前是禁用的
    Mode from config file:          enforcing//配置文件是启用的
    Policy MLS status:              enabled
    Policy deny_unknown status:     allowed
    Max kernel policy version:      31
    

    定义的策略存放在:SELinuxfs mount /sys/fs/selinux

    avc缓存在avc目录。

    # ls /sys/fs/selinux/
    access    checkreqprot          context       disable           load    null                 policyvers      status
    avc       class                 create        enforce           member  policy               reject_unknown  user
    booleans  commit_pending_bools  deny_unknown  initial_contexts  mls     policy_capabilities  relabel
    

    安全布尔值存放在:/sys/fs/selinux/booleans

    # pwd
    /sys/fs/selinux/booleans
    [root@localhost booleans]# ll ftp*
    -rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_anon_write
    -rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_connect_all_unreserved
    -rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_connect_db
    -rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_full_access
    -rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_use_cifs
    -rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_use_fusefs
    -rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_use_nfs
    -rw-r--r--. 1 root root 0 Feb 28 16:44 ftpd_use_passive_mode
    

    文件ftpd_anon_write里的内容是2个0。从文件名字可以看出来是ftp的匿名写,值是0,说明不允许匿名写。

    # cat ftpd_anon_write
    0 0
    

    管理文件安全标签

    1,修改标签中的type:chcon-t file

    测试标签中type的作用,/var/log/messages文件的标签中的type是var_log_t。

    手动使用logger命令,往它里面写东西,发现是可以写进去的。

    修改它的type成tmp_t,再用logger写,发现写不进去了。

    # ll /var/log/messages -Z
    -rw-------. root root system_u:object_r:var_log_t:s0   /var/log/messages
    # logger "test  sdf "
    # tail -1 /var/log/messages
    Feb 29 18:33:32 localhost root: test  sdf
    # chcon -t tmp_t /var/log/messages
    # ll -Z /var/log/messages
    -rw-------. root root system_u:object_r:tmp_t:s0       /var/log/messages
    # logger "test  2222sdf "
    # grep "test  2222sdf " /var/log/messages
    

    根据某个文件的标签,修改:chcon --reference f1 f2

    把文件f2的标签修改成和文件f1完全一样。

    # ll -Z /tmp/website/
    -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 aa
    -rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html
    # chcon --reference /tmp/website/index.html /tmp/website/aa
    # ll -Z /tmp/website/
    -rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 aa
    -rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html
    
    

    选项-R:递归修改目录所有的文件

    # ls /tmp/website/d1
    11  22
    # ll /tmp/website/d1/11 -Z
    -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /tmp/website/d1/11
    # ll /tmp/website/d1/22 -Z
    -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /tmp/website/d1/22
    # ll /tmp/website/d1/ -Zd
    drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 /tmp/website/d1/
    # chcon -R --reference /var/www/html/ /tmp/website/d1/
    # ll /tmp/website/d1/ -Zd
    drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /tmp/website/d1/
    # ll /tmp/website/d1/ -Z
    -rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 11
    -rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 22
    

    2,cp命令和mv命令多标签的影响。

    cp命令type会改变。

    # ll -Z /var/log/messages
    -rw-------. root root system_u:object_r:var_log_t:s0   /var/log/messages
    # cp /var/log/messages /root/
    # ll -Z messages
    -rw-------. root root unconfined_u:object_r:admin_home_t:s0 messages
    

    mv命令不改变type

    # mv messages /tmp/
    # ll /tmp/messages  -Z
    -rw-------. root root unconfined_u:object_r:admin_home_t:s0 /tmp/messages
    

    3,修改回原来的type,但是忘了原来的type是啥了怎么办,去看期望(原始)策略是啥。

    # semanage fcontext -l | grep "/var/log/message"
    /var/log/messages[^/]*       all files       system_u:object_r:var_log_t:s0
    

    还有一种更简单的方法:restorecon

    # chcon -t tmp_t /var/log/messages
    # ll -Z /var/log/messages
    -rw-------. root root system_u:object_r:tmp_t:s0       /var/log/messages
    # restorecon /var/log/messages
    # ll -Z /var/log/messages
    -rw-------. root root system_u:object_r:var_log_t:s0   /var/log/messages
    

    把/var/log/messages回复成原来的标签后,有可能还log还是写不进去,这时就要重启服务了。systemctl rsyslog restart

    4,修改httpd的默认根目录,导致selinux标签不对,网页文件无法访问。

    • 修改httpd的配置文件/etc/httpd/conf/httpd.conf,把服务的目录修改成/tmp/website/

      # ll -Z /tmp/website/ -d
      drwxr-xr-x. root root unconfined_u:object_r:user_tmp_t:s0 /tmp/website/
      

      type是user_tmp_t

    • 在/tmp/website/建立index.html文件

      # ll -Z /tmp/website/
      -rw-r--r--. root root unconfined_u:object_r:user_tmp_t:s0 index.html
      

      type是user_tmp_t

    • 启动httpd

    • 在浏览器访问index.html

    • 结果是访问不到

    原因:/tmp/website/index.html的标签的type不符合selinux对httpd的要求,所以httpd进程无法访问它。

    httpd能够访问的标签是:httpd_sys_content_t。

    而/tmp/website/index.html文件的type是user_tmp_t,所以httpd不可以访问它,被selinux给挡住了。

    # ll -Zd /var/www/
    drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/
    

    解决办法:

    1,安装桌面小程序,能够把selinux相关的信息显示出来。(不安装也无所谓)

    2,添加/tmp/website/目录的期望(默认)策略,到selinux。

    添加选项:-a

    指明type:-t

    /tmp/website(/.*)?:正则表达式/tmp/website目录自身和目录下的所有文件的意思。

    # semanage fcontext -a -t httpd_sys_content_t "/tmp/website(/.*)?"
    # semanage fcontext -l | grep "/tmp/website"
    tmp/website(/.*)?                                  all files          system_u:object_r:httpd_sys_content_t:s0
    

    3,由于/tmp/website/有了期望策略,所以恢复/tmp/website/的标签成,默认标签。

    选项-R:递归修改目录下的所有文件。

    # restorecon -R /tmp/website/
    # ll -Zd /tmp/website/
    drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /tmp/website/
    # ll -Z /tmp/website/
    -rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html
    

    4,重启httpd

    5,当不想让/tmp/website/是httpd的根目录了,删除它在selinux里的期望策略

    删除选项:-d

    # semanage fcontext -d -t httpd_sys_content_t "/tmp/website(/.*)?"
    

    管理端口标签

    1,查看端口期望(默认)策略:

    http协议的端口的期望(默认)策略:80, 81, 443, 488, 8008, 8009, 8443, 9000是可以使用的。

    所以不能把其他的端口用于http服务。

    # semanage port -l
    SELinux Port Type              Proto    Port Number
    
    afs3_callback_port_t           tcp      7001
    afs3_callback_port_t           udp      7001
    # semanage port -l | grep http
    http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
    

    2,添加端口到默认策略

    选项-a:添加

    选项-t:指定type

    选项-p:指定传输层的协议(tcp或udp)类型

    # semanage port -a -t http_port_t -p tcp 9932
    [root@localhost ~]# semanage port -l | grep "^http_port_t"
    http_port_t          tcp      9932, 80, 81, 443, 488, 8008, 8009, 8443, 9000
    

    3,从默认策略里删除端口

    # semanage port -d -t http_port_t -p tcp 9932
    # semanage port -l | grep "^http_port_t"
    http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
    

    4,把端口策略里的某个端口,移动到另一个策略

    让9000端口也能用于ssh服务。

    # semanage port -l | grep "^http_port_t"
    http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
    # semanage port -m -t ssh_port_t -p tcp 9000
    # semanage port -l | grep "^ssh_port_t"
    ssh_port_t                     tcp      9000, 22
    # semanage port -l | grep "^http_port_t"
    http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443
    

    管理selinux布尔值开关

    布尔值的作用:细化控制某个服务里的某个小功能是否可以使用。

    1,查看布尔值

    State:是当前的状态(内存中的)

    Default:是默认值(本地磁盘存储的)

    # semanage boolean -l
    SELinux boolean                State  Default Description
    
    privoxy_connect_any            (on   ,   on)  Allow privoxy to connect any
    smartmon_3ware                 (off  ,  off)  Allow smartmon to 3ware
    

    比如:

    httpd_enable_cgi:控制httpd的cgi功能是否可用。

    httpd_enable_homedirs:控制httpd是否可以访问家目录。

    # semanage boolean -l | grep httpd_enable
    httpd_enable_cgi               (on   ,   on)  Allow httpd to enable cgi
    httpd_enable_homedirs          (off  ,  off)  Allow httpd to enable homedirs
    

    另一种命令:getsebool

    选项-a:查看全部布尔值

    # getsebool -a | grep httpd_use
    httpd_use_cifs --> off
    httpd_use_fusefs --> off
    

    2,修改布尔值:setsebool

    只修改当前状态(重启后,恢复成default):

    # setsebool httpd_enable_homedirs=on
    # semanage boolean -l | grep httpd_enable
    httpd_enable_cgi               (on   ,   on)  Allow httpd to enable cgi
    httpd_enable_homedirs          (on   ,  off)  Allow httpd to enable homedirs
    httpd_enable_ftp_server        (off  ,  off)  Allow httpd to enable ftp server
    

    既修改当前状态,也修改default状态:

    # semanage boolean -l | grep httpd_enable
    httpd_enable_homedirs          (off  ,  off)  Allow httpd to enable homedirs
    # setsebool -P httpd_enable_homedirs=on
    # semanage boolean -l | grep httpd_enable
    httpd_enable_homedirs          (on   ,   on)  Allow httpd to enable homedirs
    

    3,查看都修改过哪些布尔值

    # semanage boolean -l -C
    SELinux boolean                State  Default Description
    
    httpd_enable_homedirs          (on   ,   on)  Allow httpd to enable homedirs
    

    管理日志

    日志工具: yum install -y setroubleshoot。有图形界面。

    使用下面命令启动图形界面:

    # sealert
    

    1,查看由selinux的限制导致的服务不好用的日志,日志文件:/var/log/message

    由selinux的限制导致的服务不好用的日志的特点是有:setroubleshoot字样,并告诉使用sealert命令去查看详细的日志。选项-l后面的串是这条日志的标识。

    Mar  1 00:04:05 localhost python: SELinux is preventing in 。。。。。。。。
    sealert -l 0d882054-5ff7-4693-bf09-7b02f763df6c
    

    使用sealert查看:

    # sealert -l 0d882054-5ff7-4693-bf09-7b02f763df6c
    

    使用sealert输出的日志是保存在文件: /var/log/audit/audit.log

    2,整理/var/log/audit/audit.log文件,输出可读的格式

    # sealert -a /var/log/audit/audit.log
    

    查看selinux帮助

    安装selinux帮助文档:

    # yum install selinux-policy-doc
    

    查看与selinux相关的帮助文档有哪些:

    # man -k _selinux
    

    如果没有显示出来,说明没有更新man的数据库,使用下面的命令更新:

    • centos6:makewhatis
    • centos7:mandb

    查看与ftp相关的selinux帮助:

    # man 8 ftpd_selinux
    
    # c/c++ 学习互助QQ群:877684253 ![](https://img2018.cnblogs.com/blog/1414315/201811/1414315-20181106214320230-961379709.jpg) # 本人微信:xiaoshitou5854
  • 相关阅读:
    再次梳理css3动画部分知识
    node搭环境
    微信小程序可用的第三方库
    省市区三级联动下拉框效果分析
    jq回到顶部效果分析
    jq案例中遇到的知识点总结(会飞的小鸟和三级联动)
    js正则表达式大全
    js中表达式 >>> 0 浅析
    为什么js中要用void 0 代替undefined
    npm install、npm install --save、npm install --save --dev、npm install -S、npm install -D的区别
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/12387549.html
Copyright © 2011-2022 走看看