1.背景
SELinux是「Security-Enhanced Linux」的简称,是美国国家安全局「NSA=The National Security
Agency」 和SCC(Secure Computing Corporation)研发的
Linux的一个扩张强制访问控制安全模块。原先是在Fluke上研发的,2000年以 GNU GPL 发布。
目前以Linux作为因特网服务器是越来越普遍的事了。在我这几年作过的项目里,WEB的研发基本都是基于Linux的,这里有给大公司做的,也给政府部
门做的,当然更多的是中小企业做的。这其中给政府做的,我们把SELinux作为一个卖点,接受了不少项目。
2.我们需要安全操作系统的理由
目前不论是政府还是民间企业,大家对信息安全问题是越来越关心了,因为企业的业务平台的服务器上存储着大量的商务机密,个人资料,个人资料他直接关系到个
人的隐私问题。特别是我们政府的网站,作为信息公开的平台,他的安全就更显得重要了。这些连到互连网的服务器,不可避免的要受到来自世界各地的各种威胁。
最坏的时候我们的服务器被入侵,主页文件被替换,机密文件被盗走。除了来自外部的威胁外,内部人员的不法访问,攻击也是不可忽视的。对于这些攻击或说是威
胁,当然有非常多的办法,有防火墙,入侵检测系统,打补丁等等。因为Linux也和其他的商用UNIX相同,不断有各类的安全漏洞被发现。我们对付这些漏
洞不得不花非常多的人力来堵住他。在这些手段之中,提高OS系统自身的牢固性就显得非常的重要。
2.1传统的Linux OS的不足之处
虽然Linux 比起 视窗系统 来说,他的可靠性,稳定定要好得多,不过他也是和其他的UNIX 相同,有以下这些不足之处。
1)存在特权用户root
所有人只要得到root的权限,对于整个系统都能为所欲为。这一点视窗系统也相同。
2)对于文件的访问权的划分不够细
在linux系统里,对于文件的操作,只有「所有者」,「所有组」,「其他」这3类的划分。
对于「其他」这一类里的用户再细细的划分的话就没有办法了。
3)SUID程式的权限升级
如果设置了SUID权限的程式有了漏洞的话,非常容易被攻击者所利用。
4)DAC(Discretionary Access Control)问题
文件目录的所有者能对文件进行所有的操作,这给系统整体的管理带来不便。
对于以上这些的不足,防火墙,入侵检测系统都是无能为力的。
在这种背景下,对于访问权限大幅强化的OS SELinux来说,他的魅力的无穷的。
2.2 SELinux的好处
SELinux系统比起通常的Linux系统来,安全性能要高的多,他通过对于用户,进程权限的最小化,即使受到攻击,进程或用户权限被夺去,也不会对整
个系统造成重大影响。
接下来我来介绍SELinux的一些特点。
特点1:MAC(Mandatory Access Control)―――对访问的控制完全化
对于所有的文件,目录,端口这类的资源的访问,都能是基于策略设定的,这些策略是由管理员制定的、一般用户是没有权限更改的。
特点2: TE (Type Enforcement)――― 对于进程只付和最小的权限
Te概念在 SELinux里非常的重要。他的特点是对所有的文件都赋予一个叫type的文件类型标签,对于所有的进程也赋予各自的一个叫
domain的 标签。Domain标签能够执行的操作也是由access vector在策略里定好的。
我们熟悉的apache服务器,httpd进程只能在httpd_t 里运行,这个httpd_t
的domain能执行的操作,比如能读网页内容文件赋予httpd_sys_content_t, 密码文件赋予shadow_t,
TCP的80端口赋予 http_port_t等等。如果在access vector里我们不允许
http_t来对http_port_t进行操作的花,Apache启动都启动不了。反过来说,我们只允许80端口,只允许读取被标为
httpd_sys_content_t的文件,httpd_t就不能用别的端口,也不能更改那些被标为httpd_sys_content_t的文件
(read only)。
特点3: domain迁移 ―― 防止权限升级
在用户环境里运行点对点下载软件azureus,你当前的domain是fu_t,
不过,你考虑到安全问题,你打算让他在azureus_t里运行,你要是在terminal里用命令启动azureus的话,他的进程的domain就会
默认继承你实行的shell的fu_t。
有了domain迁移的话,我们就能让azureus在我们指定的azureus_t里运行,在安全上面,这种做法更可取,他不会影响到你的fu_t。
下面是domain迁移指示的例子:
domain_auto_trans(fu_t, azureus_exec_t, azureus_t)
意思就是,当在 fu_t domain里,实行了 被标为 azureus_exec_t的文件时,domain 从fu_t迁移到
azureus_t 。下面是Apache启动的迁移图。注意了,因为从哪一个domain能迁移到httpd_t是在策略里定好了,所以要是我们手动
(/etc/init.d/httpd
start)启动apache的话,可能仍然留在sysadm_t里,这样就不能完成正确的迁移。要用run_init命令来手动启动。
特点4: RBAC(role base access control) ――――― 对于用户只付和最小的权限
对于用户来说,被划分成一些ROLE,即使是ROOT用户,你要是不在sysadm_r里,也还是不能实行sysadm_t管理操作的。因为,那些
ROLE能执行那些domain也是在策略里设定的。ROLE也是能迁移的,不过也只能安策略规定的迁移。
3. 控制转换
从fedora core 2开始, 2.6内核的版本都支持selinux.我们看看 Fedora core 5
里的/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 - SELinux is fully disabled.
SELINUX=enforcing
#SELINUX=disabled
# SELINUXTYPE= type of policy in use. Possible values are:
# targeted - Only targeted network daemons are protected.
# strict - Full SELinux protection.
SELINUXTYPE=targeted
SELINUX有「disabled」「permissive」,「enforcing」3种选择。
Disabled就不用说了,permissive就是Selinux有效,不过即使你违反了策略的话他让你继续操作,不过把你的违反的内容记录下来。在
我们研发策略的时候非常的有用。
相当于Debug模式。
Enforcing就是你违反了策略,你就无法继续操作下去。
SELINUXTYPE呢,目前主要有2大类,一类就是红帽子研发的targeted,他只是对于,主要的网络服务进行保护,比如 apache
,sendmail,
bind,postgresql等,不属于那些domain的就都让他们在unconfined_t里,可导入性高,可用性好不过不能对整体进行保护。
另一类是Strict,是NAS研发的,能对整个系统进行保护,不过设定复杂,我认为虽然他复杂,不过一些基本的会了,还是能玩得动的。
我们除了在/etc/sysconfig/selinux设他有效无效外,在启动的时候,也能通过传递参数selinux给内核来控制他。(Fedora
5默认是有效)
kernel /boot/vmlinuz-2.6.15-1.2054_FC5 ro root=LABEL=/ rhgb quiet
selinux=0
上面的变更能让他无效。
[root@python sysconfig]# /usr/sbin/getenforce
Enforcing
确认有效后重新对文件系统赋予标签:
[root@python sysconfig]# /sbin/fixfiles relabel
或
[root@python /]# touch /.autorelabel
然后 reboot ,你就在secure的Linux环境下工作了。
4. SELinux的基本操作
SELinux是个经过安全强化的Linux操作系统,实际上,基本上原来的运用软件没有必要修改就能在他上面运行。真正做了特别修改的RPM包只要50
多个。像文件系统EXT3都是经过了扩展。对于一些原有的命令也进行了扩展,另外还增加了一些新的命令,接下来我们就来看看这些命令。
4.1 文件操作
1)ls命令
在命令后加个 -Z 或加 –context
[root@python azureus]# ls -Z
-rwxr-xr-x fu fu user_u:object_r:user_home_t azureus
-rw-r--r-- fu fu user_u:object_r:user_home_t Azureus2.jar
-rw-r--r-- fu fu user_u:object_r:user_home_t Azureus.png
2)chcon
更改文件的标签
[root@python tmp]# ls --context test.txt
-rw-r--r-- root root root:object_r:staff_tmp_t test.txt
[root@python tmp]# chcon -t etc_t test.txt
[root@python tmp]# ls -lZ test.txt
-rw-r--r-- root root root:object_r:etc_t test.txt
3)restorecon
当这个文件在策略里有定义是,能恢复原来的 文件标签。
4)setfiles
跟chcon相同能更改一部分文件的标签,不必对整个文件系统重新设定标签。
5)fixfiles
一般是对整个文件系统的, 后面一般跟 relabel,对整个系统
relabel后,一般我们都重新启动。如果,在根目录下有.autorelabel空文件的话,每次重新启动时都调用 fixfiles
relabel
6)star
就是tar在SELinux下的互换命令,能把文件的标签也一起备份起来。
7)cp
能跟 -Z, --context=CONTEXT 在拷贝的时候指定目的地文件的security context
8)find
能跟 –context 查特定的type的文件。
例子:
find /home/fu/ --context fu:fu_r:amule_t -exec ls -Z {} \:
9)run_init
在sysadm_t里手动启动一些如Apache之类的程式,也能让他正常进行,domain迁移。
4.2进程domain的确认
程式目前在那个domain里运行,我们能在ps 命令后加 -Z
[root@python /]# ps -eZ
LABEL PID TTY TIME CMD
system_u:system_r:init_t 1 ? 00:00:00 init
system_u:system_r:kernel_t 2 ? 00:00:00 ksoftirqd/0
system_u:system_r:kernel_t 3 ? 00:00:00 watchdog/0
4.3ROLE的确认和变更
命令id能用来确认自己的 security context
[root@python ~]# id
uid=0(root) gid=0(root)
groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
context=root:staff_r:staff_t
这里,虽然是ROOT用户,但也只是在一般的ROLE和staff_t里运行,如果在enforcing模式下,这时的ROOT对于系统管理工作来说,是
什么也干不了。
[root@python ~]# newrole -r sysadm_r
Authenticating root.
口令:
[root@python ~]# id
uid=0(root) gid=0(root)
groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
context=root:sysadm_r:sysadm_t
4.4模式转换
1)getenforce
得到当前的SELINUX值
[root@python bin]# getenforce
Permissive
2)setenforce
更改当前的SELINUX值 ,后面能跟 enforcing,permissive 或 1, 0。
[root@python bin]# setenforce permissive
3)sestatus
显示当前的 SELinux的信息
[root@python bin]# sestatus -v
SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: permissive
Mode from config file: permissive
Policy version: 20
Policy from config file: refpolicy
Process contexts:
Current context: user_u:user_r:user_t
Init context: system_u:system_r:init_t
/sbin/mingetty system_u:system_r:getty_t
/usr/sbin/sshd system_u:system_r:sshd_t
File contexts:
Controlling term: user_u:object_r:user_devpts_t
/etc/passwd system_u:object_r:etc_t
/etc/shadow system_u:object_r:shadow_t
/bin/bash system_u:object_r:shell_exec_t
/bin/login system_u:object_r:login_exec_t
/bin/sh system_u:object_r:bin_t -> system_u:object_r:shell_exec_t
/sbin/agetty system_u:object_r:getty_exec_t
/sbin/init system_u:object_r:init_exec_t
/sbin/mingetty system_u:object_r:getty_exec_t
4.5其他重要命令
1)Audit2allow
非常重要的一个以python写的命令,主要用来处理日志,把日志中的违反策略的动作的记录,转换成 access
vector,对研发安全策略非常有用。在refpolicy里,他的功能比以前有了非常大的扩展。
[root@python log]# cat dmesg | audit2allow -m local > local.te
2)checkmodule -m -o local.mod local.te
编译模块
[root@python log]# checkmodule -m -o local.mod local.te
checkmodule: loading policy configuration from local.te
checkmodule: policy configuration loaded
checkmodule: writing binary representation (version 5) to local.mod
3)semodule_package
创建新的模块
[root@python log]# semodule_package -o local.pp -m local.mod
4)semodule
能显示,加载,删除 模块
加载的例子:
[root@python log]# semodule -i local.pp
5)semanage
这是个功能强大的策略管理工具,有了他即使没有策略的原始码,也是能管理安全策略的。因为我主要是介绍用原始码来修改策略的,周详用法大家能参考他的
man页。
5. 制定策略
FC4,RHEL4等都是采用策略1.X版本的,并且是提供策略原始码的RPM包。从FC5开始策略的版本从1.X
升级到2.X。2.X版本的refpolicy(reference policy)最大的一个变化就是引进模块(module)这个概念,
同一套策略原始码就能支持Multi-LevelSecurity(MLS)和non-MLS。
标准的FC5里不提供原始码的RPM包。FC5提供的audit2allow,semanage,semodule也是能研发一些简单的策略模块的。不
过,要是作策略模块的研发,增加一个ROLE之类的,最佳还是下载refpolicy的原始码。
5.1策略源文件的安装
从CVS服务器下载的原始码是最新的,如果遇见象make的时候出错,那么最佳就是把你系统里和SELinux有关的那些包更新到最新的状态。
从source Forge的CVS服务器下载原始码
[root@python src]# cd /usr/local/src
[root@python src]# cvs
-d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/serefpolicy login
[root@python src]# cvs -z3
-d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/serefpolicy co -P
refpolicy
[root@python src]# cd refpolicy/
[root@python src]# make install-src
安装好了的原始码目录结构如下图所示:
每一个模块有3个文件构成,比如上图的sudo.fc 就是和 命令sudo相关的文件的定义标签,(file context
rabel),sudo.te是Type Enforcement定义,包括TE访问规则等,sudo.if是个外部模块调用这个模块的接口定义。
[root@python src]# cd /etc/selinux/refpolicy/src/policy
[root@python policy]# cp build.conf build.conf.org
[root@python policy]# vi build.conf
[root@python policy]# diff build.conf build.conf.org
32c32
< DISTRO = redhat
---
> #DISTRO = redhat
43c43
< MONOLITHIC=n
---
> MONOLITHIC=y
[root@python src]# make conf
[root@python src]# make
这样,在/etc/selinux/refpolicy/src/policy下生成非常多的以pp为后缀的文件,这些就是SELinux模块。接下来我
们修改/etc/sysconfig/selinux,设成SELINUXTYPE=refpolicy,然后reboot.
启动后,确认策略的适用情况, 目前的版本是20。
[fu@python ~]$ /usr/sbin/sestatus
SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: permissive
Mode from config file: permissive
Policy version: 20
Policy from config file: refpolicy
5.2给程式制定domain
研发程式策略的一般步骤
1.给文件,端口之类的object赋予type 标签
2.设置 Type Enforcement (Domain 迁移,访问许可)
3.策略加载
4.permissive模式下运行程式
5.确认日志,用audit2allow生成访问许可
6.重复1,2,3,4,5动作,直到没有违反的日志出现
7.转换到enforcing模式,正式运用
因为我们所常用的那些服务的策略模块都已有了,修改的时候也比较简单。在这里我就举个一般的例子。用点对点下载的朋友估计都跟我相同,在Linux上用
azureus,Amule来下载东西吧。
接下来以azureus为例,介召怎么在FC5里追加一个azureus.pp模块。我们在追加azureus.pp模块之前,azureus是在系统给
用户设好的user_t domain里运行。
[fu@python azureus]$ ps -efZ|grep azureus
user_u:user_r:user_t fu 1751 1732 0 22:28 pts/3 00:00:00 /bin/bash
./azureus
接下来我们在追加3个文件。
1)azureus.fc
在这里我只定义一个文件,实际要是真的用的,还要定义azureus_t能写的目录等。
[root@python apps]# more azureus.fc
/home/fu/azureus -- gen_context(user_u:object_r:azureus_exec_t,s0)
2)azureus.te
[root@python apps]# more azureus.te
policy_module(azureus,1.0.0)
type azureus_t;
type azureus_exec_t;
role user_r types azureus_t;
require {
type user_t;
};
domain_type(azureus_t)
domain_entry_file(azureus_t, azureus_exec_t)
domain_auto_trans(user_t, azureus_exec_t, azureus_t)
3)azureus.if
实际上没有别的模块要调用azureus,所以这个文件就是空文件也不要紧。
[root@python apps]# more azureus.if
# policy/modules/apps/azureus.if
## Myapp example policy
##
## Execute a domain transition to run azureus.
##
##
## Domain allowed to transition.
##
interface(`azureus_domtrans’,`
gen_requires(`
type azureus_t, azureus_exec_t;
’)
domain_auto_trans($1,azureus_exec_t,azureus_t)
allow $1 azureus_t:fd use;
allow azureus_t $1:fd use;
allow $1 azureus_t:fifo_file rw_file_perms;
allow $1 azureus_t:process sigchld;
’)
在/etc/selinux/refpolicy/src/policy/policy/module.conf 里加入下面一行
[root@python policy]# tail -1 modules.conf
azureus = module
确认/etc/selinux/refpolicy/src/policy里MONOLITHIC=n
最后make , make load
[root@python policy]# pwd
/etc/selinux/refpolicy/src/policy
[root@python policy]# make;make load
正常终了后,我们能用 semodule命令来确认 azureus.pp下载下去了没有。
[root@python policy]# semodule -l |grep azureus
azureus 1.0.0
看样子是没有问题。好了我们再看看 /home/fu/azureus/azureus的security
context,我们刚才在azureus.fc里是期望他是 user_u:object_r:azureus_exec_t
,可是他这个时候还是继承了默认的 user_u:object_r:user_home_t
,如果不是我们期望的文件标签的话,domain是无法从user_t迁移到azureus_t的,因为relabel的话,会对整个文件系统进行重新设
标签,非常花时间,所以我们用在上面介绍过文件标签更改的命令chcon命令来改标签。
[root@python azureus]# chcon -t azureus_exec_t azureus
再看看这次的新标签,果然如我们期望的,变成azureus_exec_t了。
[root@python policy]# ls -lZ /home/fu/azureus/
-rwxr-xr-x fu fu user_u:object_r:azureus_exec_t azureus
-rw-r--r-- fu fu user_u:object_r:user_home_t Azureus2.jar
接下来退出ROOT用户,以用户fu登录,运行azureus命令。
[root@python azureus]# ps -efZ|grep azureus
user_u:user_r:azureus_t fu 8703 8647 0 23:23 pts/1 00:00:00 /bin/bash
./azureus
user_u:user_r:azureus_t fu 8717 8703 4 23:24 pts/1 00:01:29 java
-Djava.ext.dirs=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre/lib/ext -Xms16m
-Xmx128m -cp /home/fu/azureus/Azureus2.jar:/home/fu/azureus/swt.jar
-Djava.library.path=/home/fu/azureus
-Dazureus.install.path=/home/fu/azureus org.gudy.azureus2.ui.swt.Main
user_u:user_r:user_t root 9347 1956 0 23:59 pts/2 00:00:00 grep azureus
高兴吧! 成功了。
在这里我只是演示怎么让domain迁移,至于azureus的严格的access vector的设置我都忽略了。
5.3 给自己增加个专用的ROLE
在这里我们要增加一个叫madia的ROLE,在追加时要对一些文件进行修改。
5.3.1 /etc/selinux/refpolicy/src/policy/policy/modules/kernel下的文件修改
1) kernel.te
[root@python kernel]# vi kernel.te
在role user_r 的下面加上一行
role madia_r;
2) domain.te
[root@python kernel]# vi domain.te
在 role user_r types domain; 的下面加上一行
role madia_r type domain;
5.3.2 /etc/selinux/refpolicy/src/policy/policy/modules/system下的文件修改
[root@python system]# vi userdomain.te
在第5行追加madia_r,如下所示:
role sysadm_r, staff_r, user_r,madia_r;
在unpriv_user_template(user)下面加上下面的一行。
unpriv_user_template(madia)
5.3.3 /etc/selinux/refpolicy/src/policy/policy下的文件修改
1)user
users和策略1.X里的users差不多。定义用户能利用的ROLE。
[root@python policy]# vi users
gen_user(madia, madia, madia_r, s0, s0)
2)rolemap
[root@python policy]# vi rolemap
在user_r user user_t下面加上一行
madia_r madia madia_t
5.3.4 重新make 策略
[root@python policy]# make load
5.3.5 /etc/selinux/refpolicy/seusers 文件的修改
Seusers是系统一般用户和SELinux的用户映射。
[root@python refpolicy]# vi seusers
madia:madia
5.3.6 /etc/selinux/refpolicy/contexts下的文件修改
1)default_type
决定用户登录时的默认ROLE。
[root@python refpolicy]# vi contexts/default_type
madia_r:madia_t
2)default_contexts
决定用户登录时的默认security context
[root@python refpolicy]# vi contexts/default_contexts
system_r:local_login_t madia_r:madia_t staff_r:staff_t user_r:user_t
sysadm_r:sysadm_t
5.3.7 以madia用户重新登录
最后以用户madia登录,查看是不是 进入madia_t了。
[madia@python ~]$ id
uid=501(madia) gid=501(madia) groups=501(madia)
context=madia:madia_r:madia_t
以上我们能看出,madia用户确实是进入了madia_t 运行了。
我们在以上的操作中,实际上更有修改遗漏的地方,每当重新make的时候,seusers都会回到原来的设定,有兴趣的朋友能自己找出哪里还需要修改。
6.最后
我们目前主要还是targeted策略,因为我们的服务器,基本上也就跑apache,postgresql,tomcat,bind,postfix这
几个服务。Targeted能够保护他。我们的目标是将一些影响比较小的,服务比较单一的服务器移植到能运行strict策略的服务器上。当然,即使我们
用SELinux,对于系统的安全也不能掉以轻心,认为有了SELinux就100%安全。
比如targeted里有unconfined_t,所有在这个domain里运行的都是不被保护的。更有,系统管理员对TE的设置错误造成不能非常好的
保护,还内核的漏洞,Dos攻击等,SELinux也是无能为力的。
除了SELinux外,更有LIDS ,TOMOYO
LINUX,AppArmor等安全操作系统。大家对LIDS和AppArmor有可能比较熟悉,TOMOYO是
日本NTT数据公司研发的。也许有朋友在选择的时候不知道该用那个好。
安全级别高<----------------------------------->易用性高
SELINUX >> TOMOYO >> LIDS >> AppArmor
个人觉得,SELinux虽然设置起来麻烦了点,不过能达到军事安全级别,要玩的就话,还是SELinux有魅力。
目前也有人在研发策略的GUI编辑器,如SEEDIT,是日本日立软件工程公司的一个叫中村雄一为中心研发的。有了这些GUI的工具,将来制定策略会越来
越容易的。
本人近10年没用中文写东西了,有不对的地方请多多包涵!
<参考>
1.
2.
3.
4.http://www.linuxtopia.org/online_books/linux_security_index.html
以上内容由
搜集整理,如转载请注明原文出处,并保留这一部分内容。
阅读(907) | 评论(0) | 转发(0) |