基于最近RHCE中考察到SELINUX,本文简单介绍SELinux的一些设置,深入的暂不考虑,不对的地方欢迎指出!

SELinux介绍:

SELinux是美国国家安全局为linux设计的一项开放源代码的项目,主要是希望将其做为系统的最后一道防线,来抵御黑客的进攻和入侵系统。

Selinux 的安全防护措施主要集中在各种网络服务的访问控制,

Selinux是一个在内核中执行,提供MAC能力的子系统,以提供传统DAC架构的不足,SELinux子系统以“类型强制性”读取控制机制为主,并融合RBAC、MLS和MCS3种MAC读取控制机制的特性。

1、DAC

Discretionary Access Control(任意读取控制),在DAC的架构下,每个对象都会记录一个拥有者的信息,只要是该对象的拥有者,就可以获得该对象的完全控制权限。其他需要读取该对象时候必须授予适当权限,每个对象仅有一组拥有者信息。

2、MAC

Mandatory Access Control(强制性读取控制),在MAC的架构下,会为每一个对象添置一个安全上下文(security context),进程和用户除了具备传统的权限之外,还必须获得selinux的授权,才能读取对象。

3、“类型强制性”读取控制机制

在SElinux里定义了许多的类型,每一个进程、文件、设备、网络链线等都必须表示其所属类型,进程仅能读取相同类型的文件,如果非相关的类型,切SELinux不允许读取时,则无法读取。

SELinux配置文件:

配置文件:/etc/selinux/config,它还有个链接文件:/etc/sysconfig/selinux 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@justin ~] # cat /etc/selinux/config 
 
# 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
#SELINUX=disabled
# SELINUXTYPE= can take one of these two values:
#     targeted - Targeted processes are protected, ;控制关键网络服务
#     mls - Multi Level Security protection.   ;控制所有服务
SELINUXTYPE=targeted    ;切换类型需reboot
 
 
[root@justin ~] #

SELinux状态设置:

临时设置SELinux---重启失效

1、查看SELinux状态---sestatus/getenforce

1
2
3
4
5
6
7
8
9
10
[root@justin ~] # sestatus
SELinux status:                 enabled
SELinuxfs  mount :                 /selinux
Current mode:                   enforcing
Mode from config  file :          enforcing
Policy version:                 24
Policy from config  file :        targeted
[root@justin ~] # getenforce 
Enforcing
[root@justin ~] #

2、设置SELinux状态---setenforce

1
2
3
4
5
6
7
8
9
[root@justin ~] # setenforce 
usage:  setenforce [ Enforcing | Permissive | 1 | 0 ]
[root@justin ~] # setenforce 0
[root@justin ~] # getenforce 
Permissive
[root@justin ~] # setenforce enforcing
[root@justin ~] # getenforce 
Enforcing
[root@justin ~] #

3、查看SELinux加载模块--semodule

1
[root@justin ~] # semodule -l

4、图像化管理SELinux

1
[root@justin ~] # system-config-selinux

5、查看SELinux策略policy

命令seinfo从规则policy.conf或二进制规则policy.21中提取策略的规则数量统计信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@justin yum.repos.d] # seinfo
- bash : seinfo:  command  not found
[root@justin yum.repos.d] # yum -y install setools*
[root@justin yum.repos.d] # seinfo 
 
Statistics  for  policy  file /etc/selinux/targeted/policy/policy .24
Policy Version & Type:  v .24 (binary, mls)
 
    Classes:            81    Permissions:       235
    Sensitivities:       1    Categories:       1024
    Types:            3488    Attributes:        273
    Users:               9    Roles:              12
    Booleans:          187    Cond. Expr.:       222
    Allow:          273919    Neverallow:          0
    Auditallow:         96    Dontaudit:      199904
    Type_trans:      23469    Type_change:        38
    Type_member:        48    Role allow:         20
    Role_trans:        291    Range_trans:      3993
    Constraints:        87    Validatetrans:       0
    Initial SIDs:       27    Fs_use:             22
    Genfscon:           81    Portcon:           426
    Netifcon:            0    Nodecon:             0
    Permissives:        59    Polcap:              2
 
[root@justin yum.repos.d] #

永久性SELinux设置

上面设置的selinux的状态reboot后失效,要reboot生效需要修改配置文件,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@justin ~] # vim /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=enforcing    ;disabled与enforcing、permissive切换需要reboot
# SELINUXTYPE= can take one of these two values:
#     targeted - Targeted processes are protected,
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

开启SELinux后需要通过两部来完成设置,一个是安全上下文,另个是策略值(也叫bool值),策略值是对安全上下文的补充

设置安全上下文

ls -Z、ps -Z、id -Z分别可以查看文件、进程、用户的上下文属性;默认下,mv操作保持安全上下文不变,创建和拷贝的文件继承父目录的安全上下文。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@justin ~] # ls -lZ|tail -3
-rwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 script.sh
drwxr-xr-x. root root system_u:object_r:admin_home_t:s0 Templates
drwxr-xr-x. root root system_u:object_r:admin_home_t:s0 Videos
[root@justin ~] # ls --scontext|tail -3      ;--scontext只显示安全上下文
unconfined_u:object_r:admin_home_t:s0 script.sh
system_u:object_r:admin_home_t:s0 Templates
system_u:object_r:admin_home_t:s0 Videos
[root@justin ~]
[root@justin ~] # ps -Z|tail -3
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2075 pts /0  00:00:01  bash
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2816 pts /0  00:00:01  ps
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2817 pts /0  00:00:00  tail
[root@justin ~] # id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@justin ~] #

unconfined未定义的类型,表示不受selinux控制,它的权限模型仍是DAC

由5部分组成:属主域(user):角色域(object role):类型域(user type):敏感度:类别

通常显示3部分:user_u:object_u:user_home_t

临时修改安全上下文

chcon---change context,临时修改是的type值

命令格式:

   Chcon [OPTIONS…] CONTEXT FILES…..     CONTEXT 为要设置的安全上下文    FILES 对象(文件)

   Chcon [OPTIONS…] –reference=PEF_FILES FILES…     -reference 参照的对象;PEF_FILES 参照文件上下文(源文件);FILES 应用参照文件上下文为我的上下文(目标文件)。

 OPTIONS 如下:

        -f          强迫执行

        -R         递归地修改对象的安全上下文

        -r ROLE    修改安全上下文角色的配置

        -t TYPE    修改安全上下文类型的配置

        -u USER   修改安全上下文用户的配置

        -v         显示冗长的信息

        -l, --range=RANGE    修改安全上下文中的安全级别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@justin home] # ll -Zd harry/
drwx------. harry harry unconfined_u:object_r:user_home_dir_t:s0 harry/
[root@justin home] # ll -Zd /var/www/html/
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0  /var/www/html/
[root@justin home] # chcon --reference=/var/www/html/ harry/
[root@justin home] # ll -Zd harry/
drwx------. harry harry system_u:object_r:httpd_sys_content_t:s0 harry/
[root@justin home] # restorecon harry/
[root@justin home] # ll -Zd harry/
drwx------. harry harry system_u:object_r:user_home_dir_t:s0 harry/
[root@justin home] # chcon -t httpd_sys_content_t harry/
[root@justin home] # ll -Zd harry/
drwx------. harry harry system_u:object_r:httpd_sys_content_t:s0 harry/
[root@justin home] #

restorecon---恢复 SELinux 文件属性文件属性即恢复文件的安全上下文

用法:
      restorecon [-iFnrRv] [-e excludedir ] [-o filename ] [-f filename | pathname...]
参数:
-i:忽略不存在的文件。
-f:infilename 文件 infilename 中记录要处理的文件。
-e:directory 排除目录。
-R -r:递归处理目录。
-n:不改变文件标签。
-o outfilename:保存文件列表到 outfilename,在文件不正确情况下。
-v:将过程显示到屏幕上。
-F:强制恢复文件安全语境

semanage---SELinux Policy Management tool

File contexts

       Add file-context for everything under /web

       # semanage fcontext -a -t httpd_sys_content_t "/web(/.*)?"

       # restorecon -R -v /web

-a:添加

-d:删除

-m:修改

-l:列举

-n:不打印说明头

-D:全部删除


-f:文件

-t:类型

-s:用户


SELinux 环境下的 Apache 配置

当启用 SELinux时,Apache HTTP 服务器(httpd)默认情况下在受限的 httpd_t 域中运行,并和其他受限制的网络服务分开。即使一个网络服务被攻击者破坏,攻击者的资源和可能造成的损害是有限的。下面的示例演示的是 SELinux 下的 httpd 进程。

1
2
3
4
[root@Zabbix_server html] # ps auxZ|grep httpd
system_u:system_r:httpd_t:s0    root      1807  0.0  0.8  34584  8868 ?        Ss   Aug21   0:05  /usr/sbin/httpd
system_u:system_r:httpd_t:s0    apache    1876  0.0  0.4  34584  5012 ?        S    Aug21   0:00  /usr/sbin/httpd
......

和 SELinux 上下文相关的 httpd 进程是 system_u:system_r:httpd_t:s0。 httpd 进程都运行在 httpd_t 域中。文件类型必须正确设置才能让 httpd 访问 。例如 httpd 可以读取文件类型是 httpd_sys_content_t,但不能写和修改。此外 httpd 不能访问 samba_share_t 类型的文件(Samba 访问控制的文件),也不能访问用户主目录中被标记为与 user_home_t 文件类型,主要是防止 httpd 读写用户主目录中的文件并且继承其访问权限。httpd 可以读写的文件类型是 httpd_sys_content_rw_t。Apache 默认的文档根目录类型是 httpd_sys_content_t。除非另外设置 httpd 只能访问 / var/www/html/ 目录中的 httpd_sys_content_t 类型的文件和子目录。对于网络服务而言,SElinux 仅仅开放了最低运行需求,为了发挥 Apache 服务器的功能还必须把布尔值必须打开,以允许某些行为。

Apache 的 SELinux 的布尔变量

eg.允许执行通用网关接口(CGI)脚本

1、查询当前的布尔值,使用getsebool -a可以查询当前所有的布尔值

1
2
3
4
5
6
[root@Zabbix_server html] # getsebool -a|grep -i cgi
git_cgi_enable_homedirs --> off
git_cgi_use_cifs --> off
git_cgi_use_nfs --> off
httpd_enable_cgi --> off
[root@Zabbix_server html] #

2、开启httpd 可执行 CGI 脚本

1
2
3
4
[root@Zabbix_server html] # setsebool -P httpd_enable_cgi on
[root@Zabbix_server html] # getsebool -a|grep httpd_enable_cgi
httpd_enable_cgi --> on
[root@Zabbix_server html] #

参数-P 使设置永久生效,不加重启失效

Apache 的 SELinux 的上下文

eg.变更主目录为/newhtml

1
2
3
4
5
6
[root@Zabbix_server ~] # mkdir /newhtml
[root@Zabbix_server ~] # ll -dZ /newhtml/
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0  /newhtml/
[root@Zabbix_server ~] # ll -Zd /var/www/html/
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0  /var/www/html/
[root@Zabbix_server ~] #

按照 SELinux 策略规定和继承原则,/newhtml 目录和其中的文件会具有 default_t 类型,,包括以后创建的文件或者子目录也会继承和拥有这种类型,这样受限的 httpd 进程是不能访问的,可以使用 semanage fcontext/chcon 和 restorecon 命令修改 /newhtml 的文件类型属性,确保之后建立的文件和复制的文件具有相同 httpd_sys_content_t 的类型,从而使受限的 httpd 进程能够访问。

1
2
3
4
5
6
7
8
9
10
11
[root@Zabbix_server ~] # semanage fcontext -a -t httpd_sys_content_t "/newhtml(/.*)?"
[root@Zabbix_server ~] # rest
restart      restorecon   restorecond  
[root@Zabbix_server ~] # restorecon -R -v /newhtml/
restorecon reset  /newhtml  context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
[root@Zabbix_server ~] # ll -Zd /newhtml/
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0  /newhtml/
[root@Zabbix_server ~] # vim /etc/httpd/conf/httpd.conf 
  292  #DocumentRoot "/var/www/html"
  293 DocumentRoot  "/newhtml"
  [root@Zabbix_server ~] # service httpd restart

eg.共享nfs和cifs文件系统

默认情况下,在客户端的 NFS 挂载 NFS 文件系统默认的上下文标记使用 nfs_t 类型,Samba 共享客户端上默认的上下文使用 cifs_t 类型。根据 SELinux 策略配置,Apache 服务可能无法读取 nfs_t 或 cifs_t 类型。通过设置布尔值开启或关闭来控制哪个服务被允许访问 nfs_t 和 cifs_t 类型。

1
2
3
4
5
6
7
8
9
10
11
[root@Zabbix_server var] # getsebool -a|grep -i httpd|egrep -i "nfs|cifs"
httpd_use_cifs --> off
httpd_use_nfs --> off
[root@Zabbix_server var] # setse
setsebool  setserial  
[root@Zabbix_server var] # setsebool -P httpd_use_cifs on
[root@Zabbix_server var] # setsebool -P httpd_use_nfs on
[root@Zabbix_server var] # getsebool -a|grep -i httpd|egrep -i "nfs|cifs"
httpd_use_cifs --> on
httpd_use_nfs --> on
[root@Zabbix_server var] #

eg.更改端口

根据策略配置,服务可能只被允许运行在特定的端口号 。试图改变服务运行的端口,在不改变政策,可能导致启动失败的服务。首先查看一下 SELinux 允许 HTTP 侦听 TCP 端口,使用命令:

1
2
3
[root@Zabbix_server home] # semanage port -l|grep -w http_port_t
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
[root@Zabbix_server home] #

可以看到默认情况下,SELinux 允许 HTTP 侦听 TCP 端口 80,81,443,488,8008,8009 9000或 8443。假设要把端口号 80 修改为 12345 ,下面看看修改端口号的方法:

1
2
3
4
5
6
7
8
[root@Zabbix_server home] # vi /etc/httpd/conf/httpd.conf 
     135  #Listen 12.34.56.78:80
     136  #Listen 80
     137 Listen 12345
[root@Zabbix_server home] # semanage port -a -t http_port_t -p tcp 12345
[root@Zabbix_server home] # semanage port -l|grep -w http_port_t
http_port_t                    tcp      12345, 80, 81, 443, 488, 8008, 8009, 8443, 9000
[root@Zabbix_server home] #