SELinux基本使用

来源:互联网 发布:淘宝恶意骚扰怎么判定 编辑:程序博客网 时间:2024/06/04 18:53

SELinux实例:使用安全增强的Linux 学习网址:http://book.51cto.com/art/200810/94193.htm !!!

介绍SELinux(Security-Enhanced Linux)的简单配置,涉及SELinux的工作模式、配置文件修改、查看和修改上下文信息,以及恢复文件或目录的上下文信息。

工具/原料

  • 如何查看文件包含的SELinux信息
  • 如何恢复文件SELinux上下文信息

方法/步骤

  1. SELinux工作模式介绍

    这里不对SELinux做过多的介绍,下面是来自百度的一些介绍:SELinux(Security-Enhanced Linux) 是美国国家安全局(NSA)对于强制访问控制的实现,是2.6版本的Linux内核后提供的强制访问控制系统。

    简单的说SELinux增强了传统的UGO权限模型,使用SELinux的策略后,SELinux能够控制哪个进程只能访问哪个文件。

    SELinux有三个工作模式:

    -强制(enforcing):对于违反策略的行为全部禁止,并且作内核记录。-允许(permission):对违反策略的行为只给出警告。-禁用(disable):关闭SELinux。

  2. 如何查看文件包含的SELinux信息

    使用”ps -Z”可以查看SELinux的域信息,使用”ls -Z”可以查看SELinux配置信息,请看下面的实例:

  3. 1/*命令返回信息中第一部分LABEL就是进程对应的SELinux信息*/

    2[root@QingSword.COM ~]# ps -Z

    3 LABEL                                                PID TTY     TIME   CMD

    4unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 1974 pts/0 00:00:00 su

    5unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 1981 pts/0 00:00:00 bash

    6unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2035 pts/0 00:00:00 ps

    8/*

    9 * 命令返回的第四部分是这个文件的SELinux信息,

    10 * “unconfined_u:object_r:admin_home_t:s0” 用冒号分割的四部分解释如下:

    11 *  [用户user]:[角色role]:[类型type(SELinux默认预设规则)]:[MLS、MCS]

    12 */

    13[root@QingSword.COM ~]# ls -Z

    14-rw-------. root root unconfined_u:object_r:admin_home_t:s0 anaconda-ks.cfg

    15[root@QingSword.COM ~]#

  4. 如何修改SELinux模式配置文件

    SELinux的模式配置文件位置:

    -在Fedora、Red Hat、CentOS上的位置为“/etc/sysconfig/selinux”-在ubuntu、debian上的位置为“/etc/selinux/config”

    下面的实例演示如何查看与修改SELinux工作模式(使用CentOS举例):

  5. 1/*查看SELinux工作模式,默认为Enforcing*/

    2[qing@QingSword.COM ~]$ getenforce

    3Enforcing

    5/*

    6 * 切换到超级管理员,临时改变SELinux工作模式为Permissive,

    7 * setenforce后面的参数1代表Enforcing,0代表Permissive

    8 */

    9[qing@QingSword.COM ~]$ su -

    10[root@QingSword.COM ~]# setenforce 0

    11[root@QingSword.COM ~]# getenforce

    12Permissive

    13 

    14/*上面的修改方法只是临时的,重启后失效,如果想永久改变SELinux工作模式,可以使用vim更改SELinux配置文件*/

    15[qing@QingSword.COM ~]$ vim /etc/sysconfig/selinux

    16....

    17SELINUX=enforcing  //更改SELINUX=后的参数对应工作模式“强制、允许、禁用”

    18/*如果想彻底关闭SELinux,可以将上面这句改为:*/

    19SELINUX=disabled

    20 

    21/*除此之外,SELinux的日志与报错信息保存位置为*/

    22[root@QingSword.COM ~]# tail /var/log/audit/audit.log

  6. 对SELinux配置文件的更改,需要重启计算机才能生效。

  7. 如何恢复文件SELinux上下文信息

    可以使用restorecon(restore context)命令来恢复某文件或文件夹的SELinux配置信息,为了让大家更好的理解,这里举一个例子,假设CentOS安装了apache,网页默认的主目录是/var/www/html,我们经常遇到这样的问题,在其他目录中创建了一个网页文件,然后用mv移动到网页默认目录/var/www/html中,但是在浏览器中却打不开这个文件,这很可能是因为这个文件的SELinux配置信息是继承原来那个目录的,与/var/www/html目录不同,使用mv移动的时候,这个SELinux配置信息也一起移动过来了,从而导致无法打开页面,具体请看下面的实例:

  8. 1/*使用CentOS举例,如果默认没有安装apache,确保网络连接,使用下面的命令安装*/

    2[root@QingSword.COM ~]# yum install httpd

    4/*我们在root的家目录新建一个html文件*/

    5[root@QingSword.COM ~]# pwd

    6/root

    7[root@QingSword.COM ~]# vi index.html

    8/*随便输入一段文字,保存退出*/

    9welcome to www.qingsword.com

    10 

    11/*将这个文件mv到网页默认目录下*/

    12[root@QingSword.COM ~]# mv index.html /var/www/html/

    13 

    14/*

    15 * 这个时候我们使用firefox浏览器输入127.0.0.1/index.html发现打不开,

    16 * 查看一下SELinux的日志文件,发现了下面这一段报错信息,从这个报错信息不难看出,

    17 * 进程httpd访问网页主目录中的index.html时被SELinux阻止,原因是因为,SELinux配置信息不正确,

    18 * 正确的SELinux配置信息应该是scontext=后面的部分,

    19 * 而index.html文件的SELinux配置信息却是tcontext=后面的部分,

    20 * 从tcontext=的第三段“admin_home_t”不难看出,这个文件的SELinux配置信息是root用户家目录的。

    21 */

    22type=AVC msg=audit(1378974214.610:465): avc:  denied  { open } for pid=2359 comm="httpd" path="/var/www/html/index.html" dev="sda1"ino=1317685 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file

    23 

    24/*使用ls -Z也可以看出,文件和目录的SELinux信息不匹配*/

    25[root@QingSword.COM html]# ls -Z /var/www/html/

    26.... unconfined_u:object_r:admin_home_t:s0 index.html

    27[root@QingSword.COM html]# ls -Zd /var/www/html/

    28.... system_u:object_r:httpd_sys_content_t:s0 /var/www/html/

    29 

    30/*使用restorecon来恢复网页主目录中所有文件的SELinux配置信息(如果目标为一个目录,可以添加-R参数递归)*/

    31[root@QingSword.COM html]# restorecon -R /var/www/html/

  9. 9

    恢复后,index.html页面就能正常打开了。

  10. 10

    如何修改文件SELinux上下文信息

    可以根据某个参照文件去修改另外一个文件的SELinux配置信息:

  11. 11

    1/*和文章第四部分介绍的restorecon效果相同,chcon可以根据一个参照文件或目录修改,将index.html的SELinux配置信息修改成和/var/www/html目录相同*/

    2[root@QingSword.COM html]# chcon --reference=/var/www/html /var/www/html/index.html

  12. 在了解selinux之间,我们需要知道DAC和CS的概念,它们是linux系统本身的安全机制。

    DAC:自主访问控制

    每一个用户为了能够实现和其他用户共享文件,在使用ACL之前,只能通过改变这个文件其他用户的权限,但是这中方法给系统安全带来了无穷的隐患。

     

    CS(安全上下文):取决于发起用户的权限和文本本身的权限

     

    CS+DAC给系统的安全机制带来了漏洞,事想apache用户可以查看/etc/passwd,如果它有写权限,就可能被利用进而就修改passwd文件,危害系统安全。

     

    所有才又了MAC强制访问控制的概念

    MAC: Mandatory Access Control  强制访问控制,它是selinux实现访问控制的基础

    还通过httpd服务来说明它的原理:

    SELINUX通过type enforce (TE)强制类型策略将httpd的工作目录定义在一个特定的目录/var/www用户如果在定义其他目录,将不允许访问,从而实现mac的强制访问控制。

     

     

    selinux是怎么工作的

    它通过operation (操作)的主和宾打一个“标签”,在一个“类型”里只能由特定的目录或用户执行。这样可以限定一个进程的执行范围只能在一个“沙箱”(sandbox)内了(最小权限法则)

     

    ###operation: 读,写,执行,等。其实是一个主谓宾的结构 Subject Operation Object

    ###最小权限法则:例如定义Sbjiect httpd   的目录/var/www 为public_content_t类型,

    这样,httpd只能访问有这个特定类型的文件或目录,这些文件就叫沙箱“sendbox”

                       使用selinx,必须精心设计一套访问法则

     

    给不同的进程打上不同的“域”,给不同的目录打上不同的”类型“通过定义“类型”和“域”的对应规则,来实现。selinx需要域和标签的对应关系,一对一对应     。但是系统上有上千个进程,实现起来很麻烦,所以一般情况下,并不是用selinx作为安全防范

                                                                                                           

    selinux的实现机制有两种

    strict:       任何进程都受selinux的控制,一般不用,太难设定

    targeted:   红帽开发,指定选定的进程来受SELINUX,这种机制使得selinx更加容易受到控制

     

    policy: 规则组合起来就叫策略

    规则通常是以二进制文件存在的(编辑完转换成二进制),这样可以降低系统资源占用

    ll /etc/selinxu/policy

    MLS  muiti level scurity


    selinxu把一些规则里面可以方便控制的功能设定为on或者off,这些都成为布尔类型

    getsebool -a   可以显示这些布尔型的内容

     

    fcontext 规定目录属于哪个进程的范围


     

    启动使用selinux

    1.启用selinux

    [cpp] view plaincopy
    1. vim /etc/sysconfig/selinux  
    2. SELINUX=enforcing      #任何进程都受selinux控制  
    3.                                      permissive    #仍然受控制,但是进程进入了别的目录会记录到日志  
    4.                                      disable           #干净彻底的关闭  
    5. setenforce  
    6. genenforce  

    2.显示标签

    [cpp] view plaincopy
    1. ls -Z           显示文件的标签  
    2.                    一共五段     角色:selinux里另外定义的用户  
    3.                                                           object_r: 有点类似于组  
    4.                                                           user_home_t: 域或者类型(最重要)通过改变它可以控制访问。类型强制的机制就是通过它实现的  
    5. ps -Z          显示进程的标签  
    6. 所有显示unconfined_t都表示不受selinux控制  
    7. ps auxZ | grep httpd  
    8. ls -dZ  

    在不同的目录建立的文件类型是不一样的,归不同的进程管理。

     

    3.改变一个类型的标签

    [cpp] view plaincopy
    1. chcon     chage contex  改变上下文  
    2. chcon -t    改类型,指定为特定类型  
    3.                 -u     
    4.                 -R   递归修改,可以改变目录下所有目录  
    5.                       --reference=   以某个文件的标签为参照改变成一样的标签  
    6. chcon -R --reference=/var/www/html /www  
    7. chcon -t default_t /www/index.html  


    4.恢复默认安全上下文及修改

    [cpp] view plaincopy
    1. restorecon  
    2.                    -R                   递归  
    3.                    -F                                           强制  
    4.                    -v                                           显示详细信息     
    5. restorecon -R -v -F /www             # 显示/www目录的详细CS信息                       
    6. semange  
    7.                    -d                  删除  
    8.                    -m                 修改  
    9.                    -r  
    10.                   -a                   附加  
    11.                    -t                    类型  
    12.    

    6.开启布尔类型

    [cpp] view plaincopy
    1. getsebool -a  | grep httpd                   #查看某个对应的布尔类型的值  
    2. setsebool httpd_enable_cgi=on          # 加上-p选项永久有效  


    下面通过添加一个samba目录来测试selinux控制


    1.添加tools文件夹

    [cpp] view plaincopy
    1. vim /etc/samba/smb.conf  
    2. [tools]  
    3.        path = /share                        #没有的话事前创建一个  
    4.        public = yes  
    5.         write list = @mygrp                 #只允许mygrp组具有创建文件的权限  
    6.        browseable = yes  
    7. service smb start  


    2.添加用户gentoo,并设置samba密码,允许器登陆samba服务器在tools下创建文件

    [cpp] view plaincopy
    1.   
    [cpp] view plaincopy
    1. groupadd mygrp  
    2. useradd gentoo -g mygrp  
    3. [root@station32 var]# smbpasswd -a gentoo  
    4. New SMB password:  
    5. Retype new SMB password:  
    6. Added user gentoo.  
    7. smbclient -L 192.168.0.32 -U gentoo          # 查看samba服务器的内容  


    3.我们查看下/shared目录的CS,并且开启selinux

    [cpp] view plaincopy
    1. ls -dZ /share/  
    2. drwxrwxr-x root mygrp root:object_r:default_t          /share/  
    3. setenforce 1  

    4.开启selinux后,再使用smbclient命令就会报错,我们看下配置文件里面有这样一行 # To set a label use the following: chcon-t samba_share_t /path ,所以我们必须把/shared文件夹的CS修改后才能正常使用samba

    [cpp] view plaincopy
    1. chcon -t samba_share_t  /share  

     

    5.我们关闭samba里关于访问家目录的布尔类型

    [ruby] view plaincopy
    1. setsebool samba_enable_home_dirs off  

     

    这个时候使用win网络邻居,以用户gentoo登陆后,就不能进入gentoo家目录了


    6.我们将它开启就又能访问了,命令如下:

    [ruby] view plaincopy
    1. setsebool samba_enable_home_dirs on 

    二、SELinux 如何工作          
     
    SELinux 如何工作呢?SELinux 的方法实际上非常普通。每一个重要的内核对象,比如每个文件系统对象和每个进程,都有一个关联到它们的“安全上下文(security context)”。安全上下文可以基于军事安全层级(如不保密的、保密的和高度保密的)、基于用户角色、基于应用程序(这样,一个 Web 服务器可以拥有它自己的安全上下文),或者基于很多其他内容。当它执行另一个程序时,进程的安全上下文可以改变。甚至,取决于调用它的程序,一个给定的程序可以在不同的安全上下文中运行,即使是同一个用户启动了所有程序。

    然后系统管理员就可以创建一个指定哪些特权授与哪个安全上下文的“安全策略(security policy)”。当发生系统调用时,SELinux 去检查是否所有需要的特权都已经授与了——如果没有,它就拒绝那个请求。

    例如,要创建一个文件,当前进程的安全上下文必须对父目录的安全上下文的“搜索(search)”和“add_name”特权,而且它需要有对于(要创建的)文件的安全上下文的“创建(create)”特权。同样,那个文件的安全上下文必须有特权与文件系统“关联(associated)”(所以,举例来说,“高度保密”的文件不能写到一个“不保密”的磁盘)。还有用于套接字、网络接口、主机和端口的网络访问控制。如果安全策略为那些全部授与了权限,那么请求就会被 SELinux 所允许。否则,就会被禁止。如果按部就班地去做所有这些检查将会较慢,不过有很多优化方案(基于多年的研究)使其变得很迅速。

    这一检查完全独立于类 UNIX 系统中的通常的权限位;在 SELinux 系统中,您必须 既 有标准的类 UNIX 权限, 又 有 SELinux 权限才能去做一些事情。不过,SELinux 检查可以做很多对传统的类 UNIX 权限来说难以完成的事情。使用 SELinux,您可以方便地创建一个只能运行特定程序并且只能在特定的上下文中写文件的 Web 服务器。更有趣的是,如果一个攻击者攻入了 Web 服务器并成为 root,攻击者不会获得整个系统的控制权——如果有一个好的安全策略的话。

    那就有了困难:为了使 SELinux 有效,您需要有一个好的安全策略来由 SELinux 执行。大部分用户将需要一个他们容易修改的实用的初始策略。几年前我开始体验 SELinux;那时,初始策略还不成熟,有很多问题。例如,在那些以前的日子中我发现早期的样例策略不允许系统更新硬件时钟(最后我提交了一个补丁以解决这一问题)。设计好的初始安全策略类似对产品分类, NSA 希望由商业界来做,而且看起来是要这样做。Red Hat、一些 Debian 开发者、Gentoo 以及其他人正在使用基本的 SELinux 框架,并且正在创建初始安全策略,这样用户可以马上开始使用它。的确,Red Hat 计划为所有用户在他们的 Fedora 内核中都启用 SELinux,并提供简单的工具来使得非专业用户可以通过选择一些常见选项来修改他们的安全策略。Gentoo 有一个可引导的 SELinux LiveCD。这些团体将使得最小化程序特权变得更简单,而不需要大量代码。

    在这里我们又回到了原处。SELinux 只有当程序执行时才允许发生安全传输,它控制进程的权限(不是一个进程的一部分)。所以,为了充分发挥 SELinux 的潜力,您需要将您的应用程序分解为独立的进程和程序,只有一些小的有特权的组件—— 这恰恰如同如何在没有 SELinux 的情况开发安全的程序。像 SELinux 这样的工具让您可以更好地控制授与的权限,并这样创建一个更强有力的防御,但是,您仍需要将您的程序拆分为更小的组件,以使得那些控制能发挥最大的效用。

    普通的Linux 与SELinux相比较

    普通的Linux系统的安全性是依赖内核的,这个依赖是通过setuid/setgid产生的。在传统的安全机制下,暴露了一些应用授权问题、配置问题或进程运行造成整个系统的安全问题。这些问题在现在的操作系统中都存在,这是由于他们的复杂性和与其它程序的互用性造成的。

    SELinux只单单依赖于系统的内核和安全配置政策。一旦你正确配置了系统,不正常的应用程序配置或错误将只返回错误给用户的程序和它的系统后台程序。其它用户程序的安全性和他们的后台程序仍然可以正常运行,并保持着它们的安全系统结构。

    用简单一点的话说就是:没有任何的程序配置错误可以造成整个系统的崩溃。

    SELinux 在 Linux 上是一项十分重要的技术!当我第一次面对它的时候,有当年我遇见 LDAP 时的情况,好象没有见面的老朋友再次见面一样。

    在自己内刚学习 Linux 的时候,就被人问起一个 Unix 中的核心问题︰

    * 为什幺 root 的权力是无限大的。
    * 有没有办法令 root 的权力受到限制。

    这虽然不是 SELinux 的主要课题,但是 SELinux 却对这两个问题有很好的回答。

    在安全方面 SELinux 也对 Linux 本身加强了安全级数, Linux 的安全级数一直是 C 级或 C+ 级,和 Windows 服务器的级数相同,但是 SELinux 却有望把 Linux 的安全级数提升至 B 级。

    所以你想 SELinux 是否在未来是一个必学的课题。

    MAC 是 SELinux 的精要所在,也是很多人在学习 SELinux 最不习惯的地方。(包括我在内。)

    什么叫做 MAC ?

    我想你可能会知道什么叫做 chroot 的。 chroot 就是把某程序置于文件系统下的某一处,而当运行的时候,就不会离开这个文件系统的部份。(也就是不会影响整个的文件系统。)bind 是最喜欢使用这个方式来增进他的安全级数的。

    那 MAC 和 chroot 有什么部份是相似的?这部份你可以想想如果把所有的程序都分开不同的层次来运行( domain )。而不同的 domain 却各自独立,而且如果没有经过授权是不可以由 domain A 跳到 domain B ,情况就如 chroot 一样。

    很多人都问为什系统下的 root 在系统下却有什事情无法做?!

    其实说穿了是因为 root 所属的 domain type (如 sysadm_t 或者 staff_t )他们没有授权「跳到」所需要执行某程序的 domain type 下。

    如果无法做这样的「跳」,也就无法做希望的工作。因些 root 的权力就受到限制了!

    谁定下这些 domain 和权限呢?

    其实这是在 SELinux 的开机的时候会 load 起一个叫做 policy,* 的政策权限文件,这文件内中就定义了这些权限。如果你的 SELinux 是不能在开机后转回 permissive 模式的话,那你的 root 也可能无法修改当中的设定!

    那 MAC 有什么好处?

    其实好处就如 chroot 一样把系统内任何东西都加上一层保护层。那就算是入侵进入了你的计算机,也很有可能无法有任何事情能做!

    例如︰你的 imapd 和 popd 服务器是以 root 的权限执行的!如果某天发现了一个极严重的 bug ,而使得入侵者可以从这两个服务器进入系统!

    如果你的 Linux 系统有被 SELinux 保护的话,那么入侵者仍没有办法拿到 Linux 系统下完整的 root 的权限,因为它被 imapd 或者 popd 所属的 domain type 所限制,因此他的 Linux 系统仍被 SELinux 系统保护。

    但是没有 SELinux 保护的系统,它就可能因为 imapd 或者 popd 服务器入侵而令到系统进入而产生不可预期的安全问题。
     
    三、设计思想介绍:得让两方面都满意
        Linux安全模块(LSM)的设计必须尽量满足两方面人的要求:让不需要它的人尽可能少的因此得到麻烦;同时让需要它的人因此得到有用和高效的功能。

        以Linus Torvalds为代表的内核开发人员对Linux安全模块(LSM)提出了三点要求:

    ·       真正的通用,当使用一个不同的安全模型的时候,只需要加载一个不同的内核模块

    ·       概念上简单,对Linux内核影响最小,高效,并且

    ·       能够支持现存的POSIX.1e capabilities逻辑,作为一个可选的安全模块

        另一方面,各种不同的Linux安全增强系统对Linux安全模块(LSM)提出的要求是:能够允许他们以可加载内核模块的形式重新实现其安全功能,并且不会在安全性方面带来明显的损失,也不会带来额外的系统开销。

        为了满足这些设计目标,Linux安全模块(LSM)采用了通过在内核源代码中放置钩子的方法,来仲裁对内核内部对象进行的访问,这些对象有:任务,inode结点,打开的文件等等。用户进程执行系统调用,首先游历Linux内核原有的逻辑找到并分配资源,进行错误检查,并经过经典的UNIX自主访问控制,恰好就在Linux内核试图对内部对象进行访问之前,一个Linux安全模块(LSM)的钩子对安全模块所必须提供的函数进行一个调用,从而对安全模块提出这样的问题"是否允许访问执行?", 安全模块根据其安全策略进行决策,作出回答:允许,或者拒绝进而返回一个错误。

        另一方面,为了满足大多数现存Linux 安全增强系统的需要,Linux安全模块(LSM)采取了简化设计的决策。Linux安全模块(LSM)现在主要支持大多数现存安全增强系统的核心功能:访问控制;而对一些安全增强系统要求的其他安全功能,比如安全审计,只提供了的少量的支持。Linux安全模块(LSM)现在主要支持"限制型"的访问控制决策:当Linux内核给予访问权限时,Linux安全模块(LSM)可能会拒绝,而当Linux内核拒绝访问时,就直接跳过Linux安全模块 (LSM);而对于相反的"允许型"的访问控制决策只提供了少量的支持。对于模块功能合成,Linux安全模块(LSM)允许模块堆栈,但是把主要的工作 留给了模块自身:由第一个加载的模块进行模块功能合成的最终决策。所有这些设计决策可能暂时影响了Linux安全模块(LSM)的功能和灵活性,但是大大 降低了Linux安全模块(LSM)实现的复杂性,减少了对Linux内核的修改和影响,使得其进入Linux 内核成为安全机制标准的可能性大大提高;等成为标准后,可以改变决策,增加功能和灵活性。

    四、实现方法介绍:对Linux内核的修改
        Linux安全模块(LSM)目前作为一个Linux内核补丁的形式实现。其本身不提供任何具体的安全策略,而是提供了一个通用的基础体系给安全模块,由安全模块来实现具体的安全策略。其主要在五个方面对Linux内核进行了修改:

    ·       在特定的内核数据结构中加入了安全域

    ·       在内核源代码中不同的关键点插入了对安全钩子函数的调用

    ·       加入了一个通用的安全系统调用(未发现??)

    ·       提供了函数允许内核模块注册为安全模块或者注销

    ·       将capabilities逻辑的大部分移植为一个可选的安全模块

        下面对这五个方面的修改逐个做简要的介绍。

        安全域是一个void*类型的指针,它使得安全模块把安全信息和内核内部对象联系起来。下面列出被修改加入了安全域的内核数据结构,以及各自所代表的内核内部对象:

    ·       task_struct结构:代表任务(进程)

    ·       linux_binprm结构:代表程序

    ·       super_block结构:代表文件系统

    ·       inode结构:代表管道,文件,或者Socket套接字

    ·       file结构:代表打开的文件

    ·       sk_buff结构:代表网络缓冲区(包)

    ·       net_device结构:代表网络设备

    ·       kern_ipc_perm结构:代表Semaphore信号,共享内存段,或者消息队列

    ·       msg_msg:代表单个的消息

        另外,msg_msg结构,msg_queue结构,shmid_kernel结构被移到include/linux/msg.h和include/linux/shm.h这两个头文件中,使得安全模块可以使用这些定义。

       Linux安全模块(LSM)提供了两类对安全钩子函数的调用:一类管理内核对象的安全域,另一类仲裁对这些内核对象的访问。对安全钩子函数的调用通过钩子来实现,钩子是全局表 security_ops中的函数指针,这个全局表的类型是security_operations结构,这个结构定义在 include/linux/security.h这个头文件中,这个结构中包含了按照内核对象或内核子系统分组的钩子组成的子结构,以及一些用于系统操作的顶层钩子。在内核源代码中很容易找到对钩子函数的调用:其前缀是security_ops->。对钩子函数的详细说明留到后面。

        /*Linux安全模块(LSM)提供了一个通用的安全系统调用,允许安全模块为安全相关的应用编写新的系统调用,其风格类似于原有的Linux系统调用socketcall(),是一个多路的系统调用。这个系统调用为security(),其参数为(unsigned int id, unsigned int call, unsigned long *args),其中id代表模块描述符,call代表调用描述符,args代表参数列表。这个系统调用缺省的提供了一个sys_security()入口函数:其简单的以参数调用sys_security()钩子函数。如果安全模块不提供新的系统调用,就可以定义返回-ENOSYS的 sys_security()钩子函数,但是大多数安全模块都可以自己定义这个系统调用的实现。*/

        在内核引导的过程中,Linux安全模块(LSM)框架被初始化为一系列的虚拟钩子函数,以实现传统的UNIX超级用户机制。当加载一个安全模块时,必须使用     register_security ()函数向Linux安全模块(LSM)框架注册这个安全模块:这个函数将设置全局表 security_ops,使其指向这个安全模块的钩子函数指针,从而使内核向这个安全模块询问访问控制决策。一旦一个安全模块被加载,就成为系统的安全策略决策中心,而不会被后面的register_security()函数覆盖,直到这个安全模块被使用unregister_security()函数向框架注销:这简单的将钩子函数替换为缺省值,系统回到UNIX超级用户机制。另外,Linux安全模块(LSM)框架还提供了函数 mod_reg_security()和函数mod_unreg_security(),使其后的安全模块可以向已经第一个注册的主模块注册和注销,但其策略实现由主模块决定:是提供某种策略来实现模块堆叠从而支持模块功能合成,还是简单的返回错误值以忽略其后的安全模块。这些函数都提供在内核源代码文件 security/security.c中。

        Linux内核现在对POSIX.1e capabilities的一个子集提供支持。Linux安全模块(LSM)设计的一个需求就是把这个功能移植为一个可选的安全模块。POSIX.1e capabilities提供了划分传统超级用户特权并赋给特定的进程的功能。Linux安全模块(LSM)保留了用来在内核中执行capability 检查的现存的capable()接口,但把capable()函数简化为一个Linux安全模块(LSM)钩子函数的包装,从而允许在安全模块中实现任何需要的逻辑。Linux安全模块(LSM)还保留了task_struck结构中的进程capability集(一个简单的位向量),而并没有把它移到安全域中去。Linux内核对capabilities的支持还包括两个系统调用:capset()和capget()。Linux安全模块(LSM)同样保留了这些系统调用但将其替换为对钩子函数的调用,使其基本上可以通过security()系统调用来重新实现。Linux安全模块(LSM)已经开发并且移植了相当部分的capabilities逻辑到一个capabilities安全模块中,但内核中仍然保留了很多原有capabilities的残余。这些实现方法都最大程度的减少了对Linux内核的修改影响,并且最大程度保留了对原有使用capabilities的应用程序的支持,同时满足了设 计的功能需求。以后要使capabilities模块完全独立,剩下要做的主要步骤是:把位向量移到task_struct结构中合适的安全域中,以及重新定位系统调用接口。

    五、接口说明:给内核开发人员和安全研究人员使用的钩子
        Linux 安全模块(LSM)对于内核开发人员和安全研究人员的价值就在于:可以使用其提供的接口将现存的安全增强系统移植到这一框架上,从而能够以可加载内核模块的形式提供给用户使用;或者甚至可以直接编写适合自己需要的安全模块。Linux安全模块(LSM)提供的接口就是钩子,其初始化时所指向的虚拟函数实现 了缺省的传统UNIX超级用户机制,模块编写者必须重新实现这些钩子函数来满足自己的安全策略。下面简要介绍Linux安全模块(LSM)提供的钩子,详 细情况请参考源代码,特别是include/linux/security.h头文件中security_operations结构的定义。至于具体如何根据自己需要的安全策略编写安全模块,可以参考SELinux,DTE,LIDS等系统的安全模块实现。

        首先是任务钩子,Linux安全模块(LSM)提供了一系列的任务钩子使得安全模块可以管理进程的安全信息并且控制进程的操作。模块可以使用 task_struct结构中的安全域来维护进程安全信息;任务钩子提供了控制进程间通信的钩子,例如kill();还提供了控制对当前进程进行特权操作的钩子,例如setuid();还提供了对资源管理操作进行细粒度控制的钩子,例如setrlimit()和nice()。

        其次是程序装载钩子。很多安全模块,包括 Linux capabilities,SELinux,DTE都需要有在一个新程序执行时改变特权的能力。因此Linux安全模块(LSM)提供了一系列程序装载钩子,用在一个execve()操作执行过程的关键点上。linux_binprm结构中的安全域允许安全模块维护程序装载过程中的安全信息;提供了钩子用于允许安全模块在装载程序前初始化安全信息和执行访问控制;还提供了钩子允许模块在新程序成功装载后更新任务的安全信息;还提供了钩子用来控制程序执行过 程中的状态继承,例如确认打开的文件描述符。

        再次是进程间通信IPC钩子。安全模块可以使用进程间通信IPC钩子来对System V IPC的安全信息进行管理,以及执行访问控制。IPC对象数据结构共享一个子结构kern_ipc_perm,并且这个子结构中只有一个指针传给现存的 ipcperms()函数进行权限检查,因此Linux安全模块(LSM)在这个共享子结构中加入了一个安全域。为了支持单个消息的安全信息,Linux 安全模块(LSM)还在msg_msg结构中加入了一个安全域。Linux安全模块(LSM)在现存的ipcperms()函数中插入了一个钩子,使得安全模块可以对每个现存的Linux IPC权限执行检查。由于对于某些安全模块,这样的检查是不足够的,Linux安全模块(LSM)也在单个的IPC操作中插入了钩子。另外还有钩子支持对通过System V消息队列发送的单个消息进行细粒度的访问控制。

        下面是文件系统钩子。对于文件操作,定义 了三种钩子:文件系统钩子,inode结点钩子,以及文件钩子。Linux安全模块(LSM)在对应的三个内核数据结构中加入了安全域,分别是: super_block结构,inode结构,file结构。超级块文件系统钩子使得安全模块能够控制对整个文件系统进行的操作,例如挂载,卸载,还有 statfs()。Linux安全模块(LSM)在permission()函数中插入了钩子,从而保留了这个函数,但是也提供了很多其他inode结点钩子来对单个inode结点操作进行细粒度访问控制。文件钩子中的一些允许安全模块对read()和write()这样的文件操作进行额外的检查;还有文 件钩子允许安全模块控制通过socket IPC接收打开文件描述符;其他的文件钩子对像fcntl()和ioctl()这样的操作提供细粒度访问控制。

        接下来是网络钩子。对网络的应用层访问使 用一系列的socket套接字钩子来进行仲裁,这些钩子基本覆盖了所有基于socket套接字的协议。由于每个激活的用户socket套接字有伴随有一个 inode结构,所以在socket结构或是更底层的sock结构中都没有加入安全域。socket套接字钩子对有关进程的网络访问提供了一个通用的仲裁,从而显著扩展了内核的网络访问控制框架(这在网络层是已经由Linux内核防火墙netfilter进行处理的)。例如sock_rcv_skb钩子 允许在进入内核的包排队到相应的用户空间socket套接字之前,按照其目的应用来对其进行仲裁。另外 Linux安全模块(LSM)也为IPv4,UNIX域,以及Netlink协议实现了细粒度的钩子,以后还可能实现其他协议的钩子。网络数据以包的形式被封装在sk_buff结构(socket套接字缓冲区)中游历协议栈,Linux安全模块(LSM)在sk_buff结构中加入了一个安全域,使得能够在包的层次上对通过网络层的数据的安全信息进行管理,并提供了一系列的sk_buff钩子用于维护这个安全域的整个生命周期。硬件和软件网络设备被封装在一个net_device结构中,一个安全域被加到这个结构中,使得能够在设备的层次上维护安全信息。

       最后是其他的钩子。Linux安全模块 (LSM)提供了两种其他系列的钩子:模块钩子和顶层的系统钩子。模块钩子用来控制创建,初始化,清除内核模块的内核操作。系统钩子用来控制系统操作,例如设置主机名,访问I/O端口,以及配置进程记帐。虽然现在的Linux内核通过使用capability检查对这些系统操作提供了一些支持,但是这些检 查对于不同操作差别很大并且没有提供任何参数信息。

    六、模块说明:给普通用户使用的现成的安全功能
        Linux 安全模块(LSM)对于普通用户的价值就在于:可以提供各种安全模块,由用户选择适合自己需要加载到内核,满足特定的安全功能。Linux安全模块 (LSM)本身只提供增强访问控制策略的机制,而由各个安全模块实现具体特定的安全策略。下面简要介绍一些已经实现的安全模块。

        SELinux。这是一个Flask灵活访问控制体系在Linux上的实现,并且提供了类型增强,基于角色的访问控制,以及可选的多级安全策略。 SELinux原来是作为一个内核补丁实现的,现在已经使用Linux安全模块(LSM)重新实现为一个安全模块。SELinux可以被用来限制进程为最小特权,保护进程和数据的完整性和机密性,并且支持应用安全需求。

        POSIX.1e capabilities。Linux内核中已经存在有POSIX.1e capabilities逻辑,但是Linux安全模块(LSM)把这个逻辑划分到了一个安全模块中。这样的修改使得不需要的用户可以从他们的内核中把这个功能略去;也使得capabilities逻辑的开发可以脱离内核开发获得更大的独立性。


0 0
原创粉丝点击