Linux的安全问题与安全增强系统

    作者/ 赵鑫磊,Jie Zhang
    赵鑫磊,阿里巴巴集团资深Linux系统专家。自1998年开始使用Linux,曾参与国内著名的Linux社区发行版MagicLinux的开发工作,是一个土生土长的东北人。工作经历丰富,开过小网吧、大学讲过课、发过小广告(时在阿里妈妈)、干过铁路工(开发铁路车载电视系统)、当过副总裁,但始终没有放弃对Linux的探索与研究。
    Jie Zhang(张洁),阿里巴巴集团支付宝网络技术有限公司高级专家。曾在美国、日本、加拿大和中国的多家高科技企业担任过技术总监等职。参与研发的Jack of Spades Combo卡于1999年3月获得北美权威的PC Magazine杂志的Editors' Choice奖,并赢得PC Computing MVP Finalist Award奖。自1998年开始从事Linux开发,研发基于Linux平台的网络、多媒体、通讯和电子商务等多领域的高科技产品与项目,获中国国家科技进步三等奖,并拥有多项国家发明专利。

    Linux的安全问题与安全增强系统 - 图1

    Linux的安全问题

    计算机安全领域的先驱——Robert Morris 曾经说过:“确保计算机安全的三条黄金定律是:不要拥有计算机,不要打开计算机,不要使用计算机。”按照这个说法,世界上就没有安全的计算机。即使是普遍被认为“安全”的 Linux系统,在这方面也存在严重的不足之处。事实就是这样的,不管有多么残酷,您都得照单收着,还得享受着,要不您能咋办?

    下面我准备从三个方面来阐述一下 Linux 系统所面临的安全问题,还都挺恐怖的! Linux可能会说自己很冤,可是没有办法,毕竟这种事儿就发生在你身上了。

    黑客入侵

    对于个人使用的 Linux系统其实是不必太在意这个问题的。因为你就是那么一小撮儿,而且很可能是被黑客们不太“看得起”的苦逼程序猿。这等于在你身上没啥油水可捞,所以他们是不会打你的主意的。但是作为企业用户就不同,这背后会涉及巨大的商业利益在里面,没有不心动的黑客。而企业又是 Linux 系统应用的大户,所以就成了重灾区。

    那么黑客们是如何入侵企业的Linux主机呢?一些类似于密码暴力破解的方法就没必要说了,因为即便现在最傻的系统管理员也知道把密码设置得长一点,所以是基本无用的。当然,那些五花八门的黑客秘籍一类的书上花费 90%篇幅所介绍的什么监听啊、端口扫描啊、等等的一些伎俩,都是骗你银子的,也基本无用。因为现在大家都在使用 ssh 一类的远程控制工具,监听、扫描有什么用呢?我要说的是基于“漏洞”的入侵方式。这种方式一直都是黑客们行之有效,屡试不爽的高招。

    要说这些“漏洞”是怎么被黑客们发现的呢?三个字——试,分析。经过不断地尝试和分析,在目前任何一台运行着的 Linux 系统主机上都能找出安全漏洞来。我完全没有夸大的意思,这是事实情况。原因就在于不管什么系统都是人设计和开发出来的,你见过没犯过错误的人吗?“漏洞”就是开发人员所犯下的错误,而且是非常难于被察觉的错误。你还千万别不服气,认为自己十数年的开发工作所积累下来的优良经验,不可能犯下能够产生严重安 全问题的错误。

    一个最典型的故事就发生在 Jon Bently的身边,并在他的《编程珠玑》一书中描述过。他说:在多年的时间里先后让上百位专业程序员实现二分查找法,而且每次都是在给出算法的基础描述后,很慷慨地让他们用两个小时的时间去实现它,而且允许他们使用自己所擅长的高级语言(包括伪代码)。令人惊讶地是,大约只有 10%的专业程序员正确地实现了二分查找法。Donald Knuth 也说过:尽管第一次二分查找算法早在 1946 年就被发表,但第一个没有 Bug 的二分查找算法却是十二年后才被发表出来。 可以说,如果一个简单的二分查找算法没有被正确实现的话,就很有可能产生一个严重危及安全的漏洞。不信,那就先看一下代码 1,我用 C 来实现。

    代码 1:

    static int binary_search( int target, int array[], int size )
    {
    int l = 0, r = size -1;
    int h = 0;
    if( size <= 0 )
    return -1;
    while( l <= r ) {
    h = ( l + r ) / 2;
    if ( target > array[h] )
    l = h + 1;
    else if( target < array[h] )
    r = h - 1;
    else
    return target;
    }
    return -1;
    }

    这段代码看起来非常严谨,但是却有着非常严重的问题,你看出来了吗?最关键的是:

    h = ( 1 + r ) / 2;

    因为 h 是int类型,在 32位或 64 位的机器上,它最大能表示的数是 2147483647,如果l 与 r 的和大于这个数会出现什么问题呢?加法溢出,会得到一个负数。如果用一个负数作为数组的下标会出现啥情况?有人说:访问越界,系统崩溃。要我说这还是很优美的方式呢。如果传递给它的数组是在堆中分配①的,系统就会崩溃;但是如果是在栈中分配的,你的堆 栈中的内容就可能泄露了,虽然大多是情况下是无关紧要的,但谁敢保证“有心人”的努力会白费呢?正确的写法应该是:

    h = l + ( ( r - l ) / 2 );

    如果使用 Java 语言,可以是:

    h = ( l + r ) >>> 1;

    当然,很多人会认为这种错误即便发生了,也不会造成太大损失,毕竟黑客要想从这个漏洞中获取点什么有用的信息甚至入侵到系统中,还是需要付出很多时间代价去剖析或者拥有极大的运气。但是不要忘记,大多数能够被黑客有效利用并成功入侵系统的漏洞,基本上都是这种看似“无关紧要”的错误引发的,比如缓冲区溢出、SQL 代码注入等。而且,你不能认为黑客们就没有中 500 万的运气,也不能低估他们因为利益的驱动而产生耐心的程度。

    我给出这个例子要说明的是,很多严重的安全漏洞并不是因为你的粗心大意带来的。因为像上述代码这样简单的例子都要全体计算机工作者们经过 12 年的实践才能发现。而作为Linux 这样一个复杂的软件系统,又有哪些隐患至今还是不为人知的呢?而且一个很实际的问题就是,随着 Linux系统的广泛应用,其所暴露出来的安全漏洞也越来越多了。

    “病毒泛滥”

    如果严格说 Linux 病毒泛滥是很冤枉的,只是我们将病毒、木马、流氓软件等统统称为了病毒罢了。在我看来,它们不但是计算机病毒,而且还是这个社会的毒瘤。因为现在的病毒制造者根本就不是什么喜欢恶作剧的电脑神童,其真实的本质是趋炎附势的财奴。不但危害着企业的利益,还侵害着我们这些兢兢业业、艰苦奋斗的房奴。

    就 Linux 本身而言,从科学层面定义的计算机病毒是很难在 Linux 系统中长期生存下去的。从历史上看,1996 年秋诞生了 Linux 上的第一个病毒 Staog,后来在 1997 年初又诞生了第二个病毒 Bliss,它们两者之所以能够成为病毒是因为当时 Linux 内核存在某种缺陷,而当缺陷被修正了之后,它们就随之消亡了。直到现在,十几年过去了,没有发生任何实质性的Linux 病毒大流行的情况出现,更谈不上“泛滥成灾”。可以说 Linux 的病毒基本就是人们茶余饭后的谈资罢了,因为一个成功的Linux病毒必须是手法高超且具有非凡创意的软件作品,这留给真正的天才们去创造吧,那些财奴们才懒得做这样的事情呢。

    但是 Linux上的恶意软件却有愈发疯狂的趋势。虽然 Linux是以开放源代码著称,但是普通用户有几个能有那么大把的时间和能力,每个软件都从源代码安装,且能够对每一个常用软件的代码都了如指掌呢?这就给某些财奴们创造了机会,而且有时候还能冒充正义的化身,高喊着支持开源软件运动,而在背后却实行着他们不可告人的勾当。使得很多无辜的开发者成为他们替罪的羔羊,很多善良的人们沦为他们赚取大把钞票的工具。随着Android这样的基于 Linux 平台的移动操作系统的普及,以及 Google 等这样极度崇尚所谓“美式自由”的公司允许人们任意开设应用商店的境况出现,使得这种现象开始有愈演愈烈的趋势。

    可是,很多问题并不是财奴们单方面就能掀起这么大风浪的。毕竟中国的一句古话是:“一个巴掌拍不响”。很多 Linux 用户也有自身的问题。总是不爱受到限制,喜欢使用 root 账号,这使得病毒、木马、流氓软件有了在Linux 下生根的更广阔的空间和养分。我仅能在这本文中卑微地呼吁一下:亲们,善待 Linux,慎用 root 账号,保护你自身的权益!

    拒绝服务攻击

    拒绝服务攻击也叫 DoS(Denial Of Service)攻击,这跟曾经十分流行的操作系统没有半毛钱关系。这是一种非常缺德地侵犯计算机系统安全的行为。虽然遭到这种攻击的用户不会爆出什么“艳照门”来引爆大众的眼球,但损失依然会很惨重。之所以说 DoS 很缺德,是因为它如果针对你个人,你将无法正常使用你的计算机,除非断开网络,但是没有网络我们还怎么活啊?要是它攻击某些商业性服务器,那么不单提供服务的系统会瘫痪,所有需要得到服务的用户也将失去服务。然而实行这种攻击的“人”却得不到什么实际的好处。我之所以将人字加上引号,就是因为这种“损人不利己”的行为应该已经超出人类的价值观了,虽然有些情况是出于某种所谓“商业”目的。 其实以现在个人计算机的运算能力,加之 Linux 系统优秀的 TCP/IP 协议栈实现,普通的 DoS 攻击并不会带来什么特别大的威胁。面对强大的商业服务器系统,DoS 自然也不在话下了。这是 Linux 的一种优势。但是,当前“黑客”(依然要用引号)们已经变换了策略,采取了更为恐怖的 DDoS(Distributed Denial of Service),翻译过来是分布式拒绝服务攻击。

    这种攻击的危害相当可怕,让很多 DoS 攻击源同时向某个计算机发起攻击,犹如洪水猛兽一般势不可挡,而且甚至与被攻击计算机处于同一网络的其他无辜计算机也会受累。国内最为著名的发生于 2009 年5 月19 日的“暴风门”事件就是一起规模空前的 DDoS 攻击,直接导致了中国电信的大面积网络瘫痪,面积覆盖大半个中国。足可见 DDoS 的可怕之处。

    面对这种类型的攻击,可以说任何操作系统都是无能为力的。因为这涉及了一个计算机科学历史性的“巨大 Bug”—— TCP协议的机制问题。TCP协议是一种面向连接的协议。两台计算机通过 TCP 协议通信时,这两台主机要负责维护这个连接。这必然会消耗一定的计算资源和操作系统资源,比如文件描述符。作为服务端的计算机往往需要同时维护多个 TCP 连接,但是这个数量是有限制的,因为文件描述符会占用 内存,纵使可以放开描述符的限制也会遇到内存上的限制,这个你没法放开。DoS 或 DDoS攻击就利用了这个“漏洞”,把计算机系统的全部资源都消耗干净而让它无法继续工作。当然,这还是很普通的手法。更厉害的还有 TCP Sync Flood、UDP Flood 等,本文就不一一介绍了。总之是防不胜防。

    虽然DoS或DDoS 从原理上讲是目前互联网技术无法解决的,但是 Linux 的开发者们,包括其他操作系统的开发者们,依然在试图改进一些 TCP/IP 协议的实现算法,来提高系统本身对抗这种攻击的能力。根据我的经验,Linux 在这方面不如 Windows做得好。在我的从业经验中,Windows 2003 的服务器在遇到这类攻击时的存活时间往往比 Linux 服务器要长。 而且有些版本的 Linux内核在遇到这种攻击后,会出现“Kernel panic”,整个系统彻底崩溃。Windows 2003 却从来没遇到过。换句话说,在攻击结束之后,Linux 服务器需要重启才能继续工作,而 Windows 2003 服务器能够立即开始工作。这就相当于 Linux系统在遇到类似问题时,往往需要更长的系统修复时间,使得整套系统的可靠性下降。虽然 Linux有免费的优 势,但是在遇到这种问题的时候,对于某些用户来说,Windows 2003 会更划算。

    虽然我在介绍 Linux,但是在这里却一直赞扬 Windows 很强。并不是我有什么叛逆的心态,只是不爱护短罢了。同时也是想让大家了解 Linux 在安全方面相较于其他系统还是有不足的地方的,不要去迷信。

    安全增强系统

    在大多数用户的眼里,每次登录 Linux 系统都必须输入密码,而且除了 root 之外,一个普通用户不能随意读写其他用户的文件,也不能更改系统设置,应该足够安全了。当了解到PAM那样细致入微的用户认证机制之后,更加坚定了对 Linux 系统安全性的信心,似乎从此以后就可以高枕无忧了。且慢,有关安全性的讨论我们才刚刚开始,危机依旧四伏,而且问题很多时候就恰恰出现在 PAM 那看似细致入微的机制中。

    什么?PAM 机制不安全?并不是,只是因为 PAM 是用户认证机制,而不是用户授权机制。真正的用户授权机制在 Linux的内核,而且这套机制存在问题。

    主动访问控制DAC

    Linux 内核的用户授权机制也叫访问控制机制,用户身份问题和文件管理方式就是受控于这种机制。Linux 系统中的用户主要分为 root(系统管理员)和普通用户两种,并将他/她们划分到不同的群组中。而这两种用户是否能够访问系统中的某个文件则与该文件的 rwx 权限属性有关。如果某个程序想要访问这个文件,Linux内核会根据该程序的拥有者的UID和所属群组的GID与该文件UID和GID的rwx权限属性进行对 比来决定是否允许操作。

    Linux 这种控制文件访问的机制有一个非常好听的名字——主动访问控制,英文的叫法是 Discretionary Access Control,简称DAC。名字虽然好听,但是缺陷可一点都不少:

    • root 拥有特权

    特权这种事儿,在任何时候都是十分可怕的。root 在 DAC 中不受任何限制,如果某个拥有 root 权限的程序被一小撮别有用心的人所控制,那么他就可以利用这个程序在你的系统上干任何事情,而且你还不知道。

    • SUID程序的权限升级

    Linux 为了实现类似让用户能够修改自己密码的操作(影子文件只能由 root 存取),只能给某些程序开启一个后门,这个后门就是 SUID。这可是特权的直接产物,因为有特权就会有人通过特权走捷径。虽然设计良好的带有 SUID的程序都会集成PAM,但是万一在实现上有什么闪失的话,依然会被一小撮别有用心的人所利用,并且很容易就能将权限提升到 root,那么他就可以利用这样的程序在你的系统上干任何事情,而且你还是什么都不知道。

    • 用户可以利用程序来更改文件的存取权限

    如果某个年轻的 Linux 用户为了自己的方便,将某个目录的权限设定为 777,那么该目录就可以被所有人任意访问。这可是一件非常危险的事情,别人想在这个目录下干什么就干什么,你依然是什么都不知道。

    其实缺陷还有很多,但是已经无需多举了,这已经足够让所有人倒吸一口凉气了。而且对于这些缺陷更为要命的是,防火墙、入侵监测系统等完全无能为力,是不是该擦擦背后的冷汗了呢?

    那么 Linux 是否在面对安全问题时就完全缴械投降了呢?没有,因为还有 MAC。千万不要以为这是“乔帮主”的发明,也跟网卡的物理地址无关,它是……

    强制访问控制MAC

    与主动访问控制相对应的是强制访问控制,英文的叫法是 Mandatory Access Control,简称 MAC。

    MAC 可以规避 DAC 的所有问题。因为 MAC 针对特定的程序与特定的文件进行关联性地访问控制。即便你是 root,在使用不同的程序的时候,你所能访问的文件也只是那个程序所能访问的文件。换句话说,MAC 控制的主体是程序而不是使用者,MAC 规定了一个程序能够访问哪些文件,而跟使用这个程序的用户无关。

    但是,一个 Linux 系统中的程序数量比它的用户数量多个几十倍是一点都不奇怪的,那么每个程序都使用 MAC 来控制似乎不太现实。Linux 系统采用了一个折中的方案——DAC与 MAC 结合使用。

    对于大多数与安全无关的程序就使用 DAC 来控制好了。对于那些安全攸关的程序,比如 passwd、httpd 等则采用 MAC 来控制,只能让它们读取/etc/shadow 文件或访问/var/www目录,即便它们存在某些问题能够被那些别有用心的人所利用,又能掀起多大的风浪呢?而且即便是使用 MAC 控制的程序,也首先要进行一次 DAC 的控制。这样,整个系统的访问控制能力不但细腻得多,安全得多,也容易使用了。

    那么 Linux 是怎么实现 MAC 的,我们又该怎么使用呢?不用着急,答案马上揭晓。就像 DAC 那样,MAC 也是由 Linux 内核来实现的,比较经典的有 SELinux、AppArmor 和Grsecurity,其中 SELinux 已经包含在 CentOS RHEL Fedora Linux、Debian / Ubuntu、Suse、Slackware 等很多发行版中,我们就以 SELinux 来认识一下访问控制是如何提供强健的安全保证和防御未知攻击的吧。

    SELinux——Linux的MAC实现

    作为 Linux新老用户如果你说不认识它,那我就会怀疑你之前用的是Linux 吗?因为这个东西在 Linux 下扎根已经有 10 年(到 2013 年)的时间了,而且所处的位置也是十分显耀的根目录下。但是也不管你是 Linux 新用户还是老用户,不知道 SELinux 是 MAC 也完全不奇怪,甚至老用户们根据过往的经验还会十分讨厌 SELinux。那么从现在起,我就让新用户了解它,老用户喜欢它。

    1. SELinux 到底是什么?

    首先,SELinux 是一种基于策略的 MAC 安全系统,是以 Linux 内核可加载模块的形式提供的。

    其次,SELinux 的全称是 Security Enhanced Linux,翻译过来就是安全强化 Linux,是Linux 上最杰出的新型安全子系统。

    另外,SELinux 的来头也着实不小。是由美国国家安全局(NSA,The National Security Agency)和SCC(Secure Computing Corporation)开发,所以它的能力是不容小觑的。

    最后,SELinux 是在 2.6 版本的 Linux 内核中开始被引用。对于目前可用的各种 Linux安全模块来说,SELinux是功能最全面,而且是测试最充分的,是在超过 20 年的 MAC 研究基础上建立起来的。自从 Linux 拥有了 SELinux,大型企业和政府部门才真正地开始考虑采用 Linux 作为其主要的操作系统。可以说 SELinux是 Linux的一个十分显耀的卖点。这也说 明但凡能叫得响的 Linux 发行版,基本上都会集成 SELinux。

    1. 开启 SELinux

    非常遗憾的一件事情是,搜遍 Google 和百度,看到的都是如何关闭 SELinux。或许它真的给你带来了不小的麻烦,但是如果你是一个十分谨慎的人,那么就从现在起,开启SELinux 吧。

    但是当我准备提笔的时候,却突然发现不知道该如何下手了。因为不同的 Linux发行版开启 SELinux 的方式有很大不同,而且即便是相同的发行版的不同版本也会有很大变化。这的确是一个非常难办的事情。就冲着这一点,我认为大部分用户都迫切地要关闭 SELinux 并不是盲目的行为,因为它真的很“讨人厌”。但是话分两头说,SELinux 在配置的时候虽然有些烦人,但是安全性那可是杠杠地,从日益恶化的安全局面上看,还真的很难找出不开启SELinux 的理由。

    那么所幸我就找一个比较通用的Linux发行版做为例子吧,如果你选择了其他的发行版,那就问问 Google 和百度吧,虽然都是告诉你如何关闭SELinux 的,但是反向操作不就是开启了吗?哦,差点忘记说了,我选择了 CentOS 6.x 作为参考例子。选择它的原因是因为这玩意儿本身就是RHEL,多数企业用的都是它。而且在后面所讲解的所有内容,也都是基于它的。

    好了,废话不多说了。打开/etc/sysconfig/selinux这个文件,你可能会看到下面的内容:

    #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=disabled
    # SELINUXTYPE= can take one of these two values:
    # targeted - Targeted processes are protected,
    # mls - Multi Level Security protection.
    SELINUXTYPE=targeted

    如果不是这样,可能你并没有关闭 SELINUX,看看是不是跟下面的差不多:

    # 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

    发现什么地方有变化了吗?就是将 SELINUX=disable 变更成SELINUX=enforcing 了。

    disable 很好理解,就是关闭嘛!那么 enforcing 对于 SELinux 意味着什么呢?它代表了一种工作模式,强制 SELinux 使用你所定义的所有安全策略。那么与 enforcing 模式相对应的是 permissive 模式。如果 SELinux工作在 permissive 模式之下,则并不代表系统已经真正受到 SELinux 的保护了,因为它只要求显示一些相关的信息状态,余下的就什么都不做了。

    开启和关闭 SELinux 都要重新启动系统,因为这个需要内核本身被重新加载。如果你不确定 SELinux 是否已经成功开启了,可以使用 setatus 命令来确认,在我的系统下,会得到这样的结果:

    SELinux status: enabled
    SELinuxfs mount: /selinux
    Current mode: enforcing
    Mode from config file: enforcing
    Policy version: 24
    Policy from config file: targeted

    虽然开启或关闭 SELinux 要重启系统,但是在 enforcing 和permissive 模式之间进行切换就很方便了。只需要使用 setenforce命令就可以,给它一个参数0或1。0就代表 permissive模式,那么 1 就代表 enforcing 模式啦。如果要查看当前 SELinux 工作在什么模式下,可以 使用 getenforce 命令来获得。

    需要注意的是,一旦你开启了 SELinux,而且设置它工作在 enforcing 模式之下,很可能会有悲剧发生,你有一堆服务无法顺利启动。最主要的提示信息是/lib 目录下的某些文件没有读取权限而导致启动失败。一旦发生这种悲剧,可以将 SELinux 设置为 permissive 模式,然后使用“restorecon -Rv/”命令。如果有人很倒霉或者出于好奇将SELINUXTYPE=targeted设置成了 SELINUXTPE=mls,那可能会是更大的悲剧,因为你都无法登录系统也无法关机。

    如果尝试断电的话,就更加悲剧了,单用户模式你都进不去了。这个时候怎么办呢?动用内核启动参数吧,我们之前介绍过了。在 GRUB 的交互界面中指定内核参数 enforcing=0 就行。启动之后就是喜剧了:)

    如果你在读完本节的内容之后,还是觉得 SELinux 有些累赘,不妨将它设置为permissive 模式,这样当你的系统受到安全威胁的时候可以使用 dmesg 命令来查有关信息。当然,这个模式并不是真的让你这么干的,它存在的目的是让你能够调试一下你所设置的策略是否合理。

    至于后面那个 SELINUXTYPE=targeted 或者 SELINUXTYPE=mls 是怎么回事,我们后面再做详细探讨。

    1. 安全上下文

    在进一步讲述 SELinux之前,我们先来了解一下它的最基本的概念——安全环境,或者说是安全上下文(context)。

    安全上下文实际上是一个标签,如果系统中开启了 SELinux,那么系统中所有的文件、目录、进程、套接字、乃至用户本身就会带有这个标签。这个标签由:用户、角色、域/类型、敏感度和类别这五个部分构成,并使用冒号“:”分割。这五个部分并不总是全部出现,具体的要根据你选择了何种策略。使用“id -Z”命令可以查看当前用户的安全上下文,在我的系统中是这个样子的:

    unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

    要查看进程的安全上下文,可以使用“ps -Z”命令,至于文件或目录的安全上下文,可以使用“ls -Z”命令。

    安全上下文中的第一个部分是用户。它与 Linux本身的用户是完全不同的概念。它们可以共存,而且很多时候还会被人们弄混。因为一个 SELinux 的用户会与 Linux 本身的用户使用相同的文本表达(登录名)。但是不管怎样,都要记住它们两个完全不是一回事儿。使用su 命令并不能改变 SELinux 的用户。

    每一个 Linux 本身的用户可以和一个 SELinux 的用户相对应,也就是说当他/她通过合法途径登录了一个 Linux 系统,那么同时就会分配给他/她一个 SELinux 用户。可以通过“semanage login -l”命令来查看这种对应关系,在我的系统中是这个样子:

    Login Name SELinux User MLS/MCS Range
    default unconfined_u s0-s0:c0.c1023
    root unconfined_u s0-s0:c0.c1023
    system_u system_u s0-s0:c0.c1023

    安全上下文中的第二个部分是角色。角色规定了用户能干什么,这跟我们现实社会中的角色很像,比如:有些人是医生、有些人是教师、有些人是官员……一个人如果有了社会角色,那么他/她就会得到某些别的角色无法获得的资源,比如:医生可以给病人下处方、教师可以授予学生学位、官员可以决定你是不是医生或是教师……

    每一个 SELinux 用户都会有它对应的角色,而且还可以对应多个角色,现实社会是这样的,比如:一个医生也可以是老师,去培养新一代的医生。

    1. 身份

    在 SELinux中,身份的概念与传统的 Linux UID是完全不同的,它们可以共存。但是在很多时候会被人们弄混,因为一个 SELinux 的身份会跟标准的 Linux 登录名使用相同的文本表达(大多数情况都是这样),但是不管怎样都要记住,它们两个完全不是一回事儿。在SELinux 中身份是安全上下文的一部分,它会决定什么可以被执行。运行 su 命令是不会改变SELinux的身份的。

    1. SELinux 的策略

    一开始我们就说 SELinux 是一种基于策略的 MAC安全系统,那么它都提供了什么策略呢?回答这个问题是很难的,因为 SELinux 的策略可以有千百种,我却完全不知道你到底喜欢哪一种。

    但是对于 SELINUXTYPE 这个配置项留给我们的选择并不多,因为 Linux 发行商们已经为我们编制好了一些策略套件,拿来直接使用或做一些小幅度的改动就可以放心地使用了。而这个 SELINUXTYPE 配置项就是用于选择策略套件的。可是话又说回来,既然已经编制好了,干嘛还要给我们选择呢?只能说安全这玩意儿,真是众口难调啊!

    对于 CentOS 6.x,它提供了三个策略套件,分别是 targeted、mls 和 minimum,也分别代表了不同的侧重点。targeted 是最常用的策略套件,也是 CentOS 6.x 默认的。它侧重的是对网络服务的严格限制,用来在没有严重影响用户体验的情况下尽可能多的保护关键进程,在 CentOS 4只有 15 个已经定义好的 targets 存在,包括 httpd、named、dhcpd、和 mysqld,而后来的 CentOS 版本受保护的对象越来越多,targets 数量猛增,现已超过了 200 个。在保护安全的同时 targeted 策略也期望能达到这么一种境界,大多数用户没有感觉到 SELinux 在运行而它却在默默起着保护作用。至于其他没有被 SELinux保护的行为仍旧只能要靠古老稳定的 UNIX 安全系统来保障了。SELinux 还允许用户使用多策略,我们可以使用 mls 套件来实现。它能做到不需要对安全策略进行破坏性地改变就能使 MLS 生效,我们需要在文件/etc/sysconfig/selinux中把SELINUXTYPE=targeted这行改成SELINUXTYPE=mls,使用chcon或 semanage 命令重新标签上下文,然后重启系统。如果有的用户只想使用一个“小”的SELinux 在内存不多的虚拟机上运行,他可以采用 targeted 策略慢慢删除不需要的软件包,但是这样白手起家地开始工作迟早有一天会让他泄气的。所以针对这种需求,SELinux 推出了和 targeted策略一样的 minimum软件包,先只要求安装 base policy软件包,然后包含所有targeted 策略的 selinux-policy-minimum rpm包进行后安装再加载到内核里。

    小结

    除了通过用户认证机制和访问控制机制提高 Linux 系统的安全性外,把入侵检测系统(LIDS)集成到 Linux 内核中,可以进一步加强 Linux 内核的安全性。

    另外,“亡羊补牢,为时不晚”,sysylogd 被用来处理系统日志。虽然这已经是事后诸葛亮,但是它是系统安全与管理的一个重要方面,帮助我们排查错误原因防止类似的问题再次发生。syslogd 记录的日志一般在/var/log/下,当然也有存储在另外的服务器上的。它可以记录 who、when、where 和 what 等要素,这样你就可以知道系统什么时候重新引导过、软硬 件错误、系统运行的服务信息等。

    有时日志还会包含一些敏感数据,例如本地启用了哪些服务,用户账号和配置数据,在这种情况下需要考虑加密存储与传输数据。

    Linux的安全问题与安全增强系统 - 图2

    《Linux就是这个范儿》通俗易懂、深入浅出,从Linux设计思想的角度出发,授人以渔。同时,又密切结合应用案例,透彻展示出Linux的系统架构设计是如何在实际中贯穿的,从而让读者真正掌握Linux的强大之处。书中不含较为复杂的技术理论问题,一切从实际出。本文选自《Linux就是这个范儿》