正文

(转)Solaris RBAC系统简介2009-06-29 19:57:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/billgacsli/44855.html

分享到:

Solaris RBAC(Role-Based Access Control)系统简介 转自http://blogs.sun.com/maxzhen/entry/solaris_rbac_role_based_access 众所周知,Solaris的安全性是世界领先的。而Solaris的RBAC系统(基于角色的存取控制系统)则为其领先性提供了强大的技术保证。最近因为一个项目需要,我有幸接触了一下RBAC系统,发现其复杂性估计也是世界第一了(天下没有免费的午餐啊)。 记得那天需要做项目中有关安全方面的设计,由于自己安全方面的相关知识十分缺乏(只知道root能干所有的事情,non-root只能缩在自己的home目录里面,权限少的可怜),只得去咨询一位安全方面的资深工程师。原以为在他办公室门口几分钟就可以问清楚的问题,结果,硬是被他揪到一个会议室里面连讲带画图的说了两个小时。最后,他告诉我两条结论:第一,我们项目目前的模块设计无法保证安全,需要重新进行功能模块划分;第二,按照他以往的经验,如果我出门不马上把他给我讲的写下来,通常情况下,24小时后就基本上忘的差不多了。 现在已经过了n个24小时了,记忆已经模糊。我必须把我还记得的一些写出来,以免下次再去问同样的问题^_*。 RBAC系统和以往root包打天下的系统最大的不同就是定义了许多特权(privileges(5))。我们可以把这些特权都集中在root身上(那就是和以前的系统一样了),也可以把他们分配给不同的用户(于是,普通用户也就可以拥有部分的特权了)。其实,在本质上,我们是把特权分配给在系统中运行的用户进程,使得他们可以通过系统调用来请求操作系统内核来完成程序运行需要的功能。 在一台机器上,操作系统内核是真正的主宰者,拥有权力执行任何指令。保证一台机器的安全,从某种意义上来说就是保证操作系统内核不被怀有恶意的用户程序(通过系统调用)滥用。在RBAC系统中,请求执行某个系统调用,要求该用户进程拥有相应的特权。如果不具备相应的特权,系统调用的执行将会失败。 例如,root用户可以改写任何其他用户拥有的文件,这是因为root用户拥有“file_dac_write”的特权。当write()系统调用被执行的时候,内核将检查用户进程是否有file_dac_write特权,从而决定是否完成这个写操作。如果我们将“file_dac_write”特权赋予了一个普通的用户(用户进程),即使他不是以root的身份在运行,该进程也可以修改别人的文件了(是不是开始觉得有可能钻空子了,呵呵)。 别激动,特权不是轻易可以得到的。目前Solaris里面定义了几十种特权,用来和上百种系统调用相对应。除了privileges(5) 的man page中列出的那几个组成“基本特权”的特权之外,普通用户的特权都是需要经过分配才可以得到的(root通常有权利来进行特权分配,但这也不是绝对的)。如何使得一个用户进程拥有某种特权以便该进程能够正确的运行呢?本质上讲,某个用户进程所拥有的特权是继承自他的父进程的。也就是说,如果某个用户进程的父进程没有某一个特权,该用户进程是无法从系统中获得该特权了(setuid程序除外)。用户进程的启动运行通常有两种形式: 1)作为一种守护进程(daemon)在系统启动时运行。 2)由某一个登录用户发起执行。 在第一种情况下,用户进程通常是获得了全部的特权(大家都是init的孩子嘛,init是拥有全部特权的^_^)。一个符合Solaris安全标准的守护进程,在他开始运行时所做的第一件事情就是把不需要的特权放弃掉!如果不这样写代码,在code review的过程中会受到质疑的,呵呵。 在第二种情况下,用户登录时所得到的shell本身就已经只具有该用户被赋予的特权了。那么,用户执行的任何命令也就都无法获得更多的特权了。那么,如何给一个non-root用户赋予一定的特权呢?最原始的办法是把需要赋予某一个用户的全部特权都写入/etc/user_attr(user_attr(4))。这样,在用户登录后就具有相应的特权了。为了方便管理,Solaris不建议采用这种方式,而是采用一种更加复杂的方式来进行特权分配。 Solaris将特权进行了分类。把进行某一类操作(例如:对机器上的网络环境进行配置)所需要的特权赋予一个profile,记录在/etc/security/prof_attr(prof_attr(4))中。然后,再以profile为单位进行管理,把多个profile赋予一个特定的用户角色(role),记录在/etc/user_attr中(注意:用户角色和用户都记录在/etc/user_attr中,但是他们有很大的区别。用户角色带有“type=role”的标识,而普通的用户条目不带。而且,普通的用户是可以登录系统的,但是,用户角色是不可以作为一个用户登录的)。这样,就可以以用户角色为单位来进行管理了。可以修改/etc/user_attr文件,最终是把一个或多个用户角色赋予普通的用户,从而将特权在普通用户中进行分配。 为了贯彻“用户进程永远只应获得必需特权”的思想,Solaris中还添加了一种机制来限制用户的特权,只在用户执行某个特定程序的时候赋予所需要的特权,在运行其他程序时,不具有特权。同样,还是使用刚才的分配方式,在/etc/security/exec_attr(exec_attr(4))中为某一个相应的profile加入这种profile将有可能用到的程序,以及所需的特权。于是,当这个profile被最终赋予给了一个用户,该用户就在运行指定程序的时候就被赋予指定的特权了。这里有一点需要注意:当用户运行命令的时候需要使用“pfexec+命令”的方式。直接在一个普通的shell中运行命令的话,前面讲的profile和role的机制将不会起作用,也就无法获得所需的特权了(pfexec(1))。 当我们在编写一个程序的时候,往往很难预先知道这个程序运行过程中到底需要那些特权。因此,Solaris给特权程序的调试提供了一个工具:ppriv(1)。我们可以用ppriv -e -D -s EIPL=basic + program 的方式来一步步的确定程序运行的时候缺少的特权。 把特权分散赋给多个用户的思想是为了避免特权集中在某一个用户(例如:root)身上。否则,一旦该用户密码被破解,整个系统就完全暴露在了破解者的面前。但是,将特权分散也带来了问题:增加了某一个或几个特权被滥用的概率(例如:用户编写程序利用自身的特权错误使用了某个系统调用)。于是,Solaris又增加了一个机制来使得这种风险大大降低。 这种机制称为授权(authorization)。有了授权机制,Solaris可以尽量将特权集中在某些可信赖的程序身上,这些程序通常是系统守护进程,在系统启动时就运行了。当用户需要完成某一特定任务(这种任务相对于系统调用的粒度更粗,例如,开启或关闭某一个SMF服务)的时候,便向相应的守护进程发送执行任务的请求。用户无需知道完成这个任务的细节,例如,需要什么特权,如何进行系统调用操作。守护进程根据用户的请求进行具体操作,从而完成所要求的任务。当然,这就要求守护进程本身具有所需要的特权。但是,守护进程在执行用户请求的之前要进行授权检查,从而确认用户拥有正确的授权来执行该任务。Solaris的授权都定义在/etc/security/auth_attr(auth_attr(4))文件中。我们用同样的机制把授权也分类整理,写入profile。于是,授权也就可以最终被分配到特定的用户了。大家可以看出,定义授权机制其实是把特权机制进行了更粗粒度的封装,在调用系统调用之前就进行检查。这样,用户就可以尽量使用授权,而不是特权来运行程序。这使得特权被滥用的几率大大降低,保护了操作系统的安全。 有了这些机制,操作系统的安全性的保证就有了基础。而我们,操作系统研发工程师,的责任就是要利用好这些机制,从而设计出没有安全漏洞的系统程序。 嗯,我还是暂时少花点时间blog,多花点时间研究一下如何设计出一个优秀的系统程序吧。也许下次blog,就可以给大家提出一些好的建议了。 ( Apr 24 2008, 06:19:16 AM PDT ) Permalink

阅读(2109) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册