安全增强型 Linux(Security-Enhanced Linux)简称 SELinux,SELinux 主要由美国国家安全局开发,它是一个 Linux 内核模块,也是 Linux 的一个安全子系统。SELinux 主要由美国国家安全局开发。2.6 及以上版本的 Linux 内核都已经集成了 SELinux 模块。SELinux的主要作用是增强Linux操作系统的安全性。它通过在系统内核中实施强制访问控制,限制进程和用户对系统资源的访问。
SELinux有两种工作模式:DAC(自主访问控制):在没有使用 SELinux 的操作系统中,决定一个资源是否能被访问的因素是:某个资源是否拥有对应用户的权限(读、写、执行)。只要访问这个资源的进程符合上的条件就可以被访问。以及MAC(强制访问控制):在使用了 SELinux 的操作系统中,决定一个资源是否能被访问的因素除了上述因素之外,还需要判断每一类进程是否拥有对某一类资源的访问权限。如此,即使进程是以 root 身份运行,也需要判断这个进程的类型以及允许访问的资源类型才能决定是否允许访问某个资源。进程的活动空间也可以被压缩到最小。
SELinux 基本概念中的基本概念:主体(Subject):可以完全等同于进程。对象(Object):被主体访问的资源。可以是文件、目录、端口、设备等。政策和规则(Policy & Rule):系统中通常有大量的文件和进程,为了节省时间和开销,通常我们只是选择性地对某些进程进行管制。而哪些进程需要管制、要怎么管制是由政策决定的。一套政策里面有多个规则。部分规则可以按照需求启用或禁用(以下把该类型的规则称为布尔型规则)。规则是模块化、可扩展的。在安装新的应用程序时,应用程序可通过添加新的模块来添加规则。用户也可以手动地增减规则。
SELinux 的工作模式:1. enforcing:强制模式。违反 SELinux 规则的行为将被阻止并记录到日志中。2. permissive:宽容模式。违反 SELinux 规则的行为只会记录到日志中。一般为调试用。3. disabled:关闭 SELinux,不可取
然后是SELinux的核心部分,安全上下文。
SELinux 管理过程中,进程是否可以正确地访问文件资源,取决于它们的安全上下文。进程和文件都有自己的安全上下文,SELinux 会为进程和文件添加安全信息标签,比如 SELinux 用户、角色、类型、类别等,当运行 SELinux 后,所有这些信息都将作为访问控制的依据。
首先是如何查看文件和目录的安全上下文,命令如下:
[root@localhost ~]# ls -Z
-rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
如果想要查看目录本身而非子文件的安全上下文,需要添加“-d”选项:
[root@localhost www]# ls -Zd /var/www/html/
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/
使用ps 命令查看进程的安全上下文。命令如下:
[root@localhost www]# ls -Zd /var/www/html/
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/
只要进程和文件的安全上下文匹配,该进程就可以访问该文件资源。安全上下文使用“:”分隔为 5 个字段,最后一个“类别”字段是可选的,比如:
[system_u:object_r:httpd_sys_content_t:s0:[类别]
#身份字段:角色:类型:灵敏度:[类别]
然后是这个五个字段的说明
1. 身份字段(user)
代表了该数据被哪个身份所拥有,这个字段并没有特别的作用,常见的身份类型有:
- root:表示安全上下文的身份是 root。
- system_u:表示系统用户身份
- user_u:表示与一般用户账号相关的身份
也可以使用seinfo命令来查询selinux的身份字段
[root@localhost ~]# seinfo -u
Users:9
sysadm_u
system_u
xguest_u
root
guest_u
staff_u
user_u
unconfined_u
git_shell_u
Seinfo也可以用来查询其他字段,格式如下:
[root@localhost ~]# seinfo [选项]
选项:
-u: 列出SELinux中所有的身份(user);
-r: 列出SELinux中所有的角色(role);
-t: 列出SELinux中所有的类型(type);
-b: 列出所有的布尔值(也就是策略中的具体规则名称);
-x: 显示更多的信息;
2. 角色字段(role)
表示此数据是进程还是文件或目录。这个字段在实际使用中也不需要修改,常见的角色有:
1.- object_r:代表该数据是文件或目录
2.- system_r:代表该数据是进程
使用seinfo命令来查询selinux的角色字段
[root@localhost ~]# seinfo -r
Roles:12
guest_r
staff_r
user_r
git_shell_r
logadm_r
object_r
sysadm_r
system_r
webadm_r
xguest_r
nx_server_r
unconfined_r
3. 类型字段(type)
然后是很重要的类型字段,在主体(Subject)的安全上下文中,这个字段被称为域;在目标(Object)的安全上下文中,这个字段被称为类型。进程是否可以访问文件,主要就是看域和类型(进程的安全上下文类型字段和文件的安全上下文类型字段)是否匹配。
通过 seinfo 命令查询selinux类型字段:
[root@localhost ~]# seinfo -t | more
Types:3488
bluetooth_conf_t
cmirrord_exec_t
foghorn_exec_t
jacorb_port_t
sosreport_t
etc_runtime_t
…
一个例子,已知 apache 进程可以访问 /var/www/html/目录中的网页文件,所以 apache 进程的域和 /var/www/html/ 目录的类型应该是匹配的
[root@localhost ~]# ps auxZ | grep httpd
unconfined_u:system_r:httpd_t:s0 root 25620 0.0 0.5 11188 3304 ? Ss
03:44 0:02 /usr/sbin/httpd
[root@localhost ~]# ls -dZ /var/www/html/
drwxr-xr-x.root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/
apache 进程的域是 httpd_t,/var/www/html/ 目录的类型是 httpd_sys_content_t,经过策略规则的比对,这个域是和目标的类型匹配的,所以 apache 进程可以访问 /var/www/html/ 目录。要知道进程的域和文件的类型是否匹配的话,就需要查询具体的策略规则,使用sesearch指令来查询相关规则
[root@localhost ~]# sesearch [选项] [规则类型] [表达式]
选项:
-h:显示帮助信息;
规则类型:
--allow:显示允许的规则;
--neverallow:显示从不允许的规则;
--all:显示所有的规则;
表达式:
-s 主体类型:显示和指定主体的类型相关的规则,s是source
-t 目标类型:显示和指定目标的类型相关的规则,t是target
-b 规则名:显示规则的具体内容;
比如显示 httpd_t (-s xx)域允许(--allow)访问的规则
[root@localhost ~]# sesearch -s httpd_t --allow
Found 1916 semantic av rules:
allow httpd_t antivirus_t : process transition ;
allow httpd_t public_content_t : dir { ioctl read getattr lock search open } ;
allow daemon init_t : netlink_crypto_socket { ioctl read write getattr getopt setopt } ;
allow httpd_t git_sys_content_t : dir { ioctl read getattr lock search open } ;
allow httpd_t httpd_unconfined_script_t : process { transition sigchld sigkill sigstop signull signal } ;
allow httpd_t httpd_tmpfs_t : fifo_file { ioctl read write create getattr setattr lock append unlink link rename open } ;
...
比如查询httpd_d域和httpd_sys_content_t类型
[root@localhost www]# sesearch --allow -s httpd_t -t httpd_sys_content_t
Found 29 semantic av rules:
allow httpd_t httpd_sys_content_t : lnk_file { read getattr } ;
allow httpd_t httpd_sys_content_t : dir { ioctl read getattr lock search open } ;
allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock map open } ;
allow httpd_t httpd_content_type : file { ioctl read getattr lock map open } ;
allow httpd_t httpd_content_type : dir { getattr search open } ;
allow httpd_t file_type : dir { getattr search open } ;
...
#可以清楚地看到httpd_t域是允许访间和使用httpd_sys_content_t类型的
4. 灵敏度
灵敏度一般是用 s0、s1、s2 来命名的,数字代表用户的敏感级别。
5. 类别
这个字段不是必须有的,就不做介绍了
SELinux安全上下文的修改和设置
主要通过chcon和restore命令来实现
chcon的命令格式:
灵敏度一般是用 s0、s1、s2 来命名的,数字代表用户的敏感级别。
[root@localhost ~]# chcon [选项] 文件或目录
选项:
-R: 递归,当前目录和目录下的所有子文件同时设置;
-t: 修改安全上下文的类型字段,最常用;
-u: 修改安全上下文的身份字段;
-r: 修改安全上下文的角色字段;
下面是一个修改selinux安全上下文的例子
[root@localhost ~]# echo'test page!!!' >> /var/www/html/index.html
#建立一个网页文件,并写入“test page!!!”
Pic
然后修改该网页类型
[root@localhost ~]# ls -Z /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html
#这个网页文件的模式类别是httpd_sys_content_t
[root@localhost ~]# seinfo -t I grep var_t
#查询SELinun中所有的类型、发现有一个类型叫var_t
[root@localhost ~]# chcon -t var_t /var/www/html/index.html
#把网页文件的类型修改为var_t类型
[root@localhost ~]# ls -Z /var/www/html/index.html
-rw-r--r--. toot root unconfined_u:object_r:var_t:s0 /var/www/html/index.html
#这个网页的类型已经被修改了
就会发现无法访问刚才的网页了
Pic
然后可以通过chcon命令将安全上下文类型再修改回来,也可以使用命令restore命令把文件的安全上下文恢复成默认的安全上下文,如下:
#把网页文件的类型修改为var_t类型
[root@localhost ~] # restorecon [选项】 文件或目录
选项:
-R:递归.当前目录和目录下所有的子文件同时恢复;
-V:把恢复过程显示到屏幕上;
将刚才的网页类型改回去:
[root@1ocalhost ~]# restorecon -Rv /var/www/html/index.html
restorecon reset /var/www/html/index.html context
unconfined_u:object_r:var_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
#这里已经提示了安全上下文从var_t恢复成了httpd_sys_content_t
[root@1ocalhost ~]# ls -Z /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html
#查看一下,安全上下文已经恢复正常了.网页的访问也已经恢复正常了
SELinux默认安全上下文的查询和修改(semange)
刚才说restorecon可以将文件恢复成默认的安全上下文,说明每个文件和目录都有自己的默认安全上下文,然后可以使用semange命令查询和修改默认的安全上下文,如下
[root@localhost ~]# semanage [login|user|port|interface|fcontext|translation] -l
[root@localhost ~]# semanage fcontext [选项] [-first] file_spec
选项:
-a: 添加默认安全上下文配置;
-d: 删除指定的默认安全上下文;
-m: 修改指定的默认安全上下文;
-t: 设定默认安全上下文的类型;
查询默认安全上下文
[root@localhost ~]# semanage fcontext -l
#查询所有的默认安全上下文
…
/var/www(/.*)? all files
system_u:object_r:httpd_sys_content_t:s0
…#可以看到/var/www/目录下所有内容的默认安全上下文都是httpd_sys_content_t
添加默认安全上下文配置
…#可以看到/var/www/目录下所有内容的默认安全上下文都是httpd_sys_content_t
[root@localhost ~]# mkdir /www
#新建/www/目录
[root@localhost ~]# semanage fcontext -a -t httpd_sys_content_t "/www(/.*)?"
#将/www/目录及目录下的所有内容设定默认安全上下文类型是httpd_sys_content_t
[root@localhost ~# semanage fcontext -l | grep "/www"
…
/www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0
#/www/目录的默认安全上下文就有了
关于selinux的安全上下文就说到这
最后还有一个比较重要的添加某类进程允许访问端口的方法,
semanage port -a -t -p
比如卫星服务就要给nginx添加端口80的权限用于http服务
semanage port -a -t http_port_t -p tcp 80