SELinux

来自Shiyin's note
跳到导航 跳到搜索

Selinux 基础

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

对于 Apache 、Samba、NFS 数据库来说,Selinux 仅仅开放了最基本的运行需求。至于连接外部网络、运行脚本、访问用户目录、共享文件等,必须经过一定的 Selinux 策略调整才能充分发挥网络服务器的作用,在安全和性能直接获取平衡。


SELinux 环境下的 Apache 配置

Apache 的 SELinux 的文件类型

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

下面的示例演示的是 SELinux 下的 httpd 进程。

   $ ps -eZ | grep httpd
    unconfined_u:system_r:httpd_t:s0 2850 ?        00:00:00 httpd
    unconfined_u:system_r:httpd_t:s0 2852 ?        00:00:00 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 还针对 httpd 定义了一些文件类型:

  • httpd_sys_content_t 主要用于提供静态内容服务的文件,如 HTML 静态网站使用的文件。这种类型的标记文件可以访问(只读)httpd 和执行脚本 httpd。默认情况下,这种类型的文件和目录标记不能被写入或修改 httpd 或其他进程。 注意:默认情况下,创建的文件或复制到的 /var/www/html/httpd_sys_content_t 类型的标记。
  • httpd_sys_script_exec_t 主要用于设置 /var/www/cgi-bin/ 目录下的 cgi 脚本。默认情况下 SELinux 策略防止 httpd 执行 CGI 脚本。
  • httpd_sys_content_rw_t 使用 httpd_sys_content_rw_t 的类型标签读取和写脚本标记文件 httpd_sys_script_exec_t 的类型。
  • httpd_sys_content_ra_t 使用 httpd_sys_content_ra_t 的类型标签将读取和附加标记的脚本文件 httpd_sys_script_exec_t 类型。

如果需要修改文件和目录的 SELinux 类型属性时可以使用三个命令:chcon、 semanage fcontext 和 restorecon 命令 。

说明:使用 chcon 命令来对文件的类型进行重新标识。然而,这样的标识不是永久性的修改,一旦系统重启,该标识就会改变回去。对于文件类型的永久性改变,需要采用 semanage 命令。chcon、 semanage fcontext 和 restorecon 三个命令是本文的重点下面首先介绍一下使用方法:

chcon 命令

作用:chcon 命令用来改变 SELinux 文件属性即修改文件的安全上下文
用法:chcon [ 选项 ] CONTEXT 文件
主要选项 :
   -R:递归改变文件和目录的上下文。
   --reference:从源文件向目标文件复制安全上下文
   -h, --no-dereference:影响目标链接。
   -v, --verbose:输出对每个检查文件的诊断。
   -u, --user=USER:设置在目标用户的安全上下文。
   -r,--role=ROLE:设置目标安全领域的作用。
   -t, --type=TYPE:在目标设定的安全上下文类型。
   -l, --range=RANGE:设置 set role ROLE in the target security context 目标安全领域的范围。
   -f:显示少量错误信息。

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:强制恢复文件安全语境。
说明;restorecon 命令和 chcon 命令类似,但它基于当前策略默认文件上下文文件设置与文件有关的客体的安全上下文,因此,用户没有指定一个安全上下文,相反,restorecon 使用文件上下文文件的条目匹配文件名,然后应用特定的安全上下文,在某些情况下,它是在还原正确的安全上下文。

semanage fcontext 命令

作用:管理文件安全上下文
用法:
semanage fcontext [-S store] -{a|d|m|l|n|D} [-frst] file_spec
semanage fcontext [-S store] -{a|d|m|l|n|D} -e replacement target
主要选项 :
-a:添加
-d:删除
-m:修改
-l:列举
-n:不打印说明头
-D:全部删除
-f:文件
-s:用户
-t:类型
r:角色

Apache 的 SELinux 的布尔变量

对于网络服务而言,SElinux 仅仅开放了最低运行需求,为了发挥 Apache 服务器的功能还必须把布尔值必须打开,以允许某些行为包括允许 httpd 脚本网络访问, 允许 httpd 访问 NFS 和 CIFS 文件系统, 允许执行通用网关接口(CGI)脚本 。可以使用命令 getsebool 查询当前布尔变量。然后可以使用下面的 setsebool 命令开放布尔变量:

#setsebool – P  httpd_enable_cgi on

下面是常用的布尔变量:

  • allow_httpd_anon_write 禁用时这个布尔变量允许的 httpd 到只有标记文件 public_content_rw_t 类型的读取访问。启用此布尔变量将允许的 httpd 写入到文件标记与一个公共文件目录包含一个公共文件传输服务,如 public_content_rw_t 类型。
  • allow_httpd_mod_auth_pam 启用此布尔变量允许 mod_auth_pam 模块访问 httpd。
  • allow_httpd_sys_script_anon_write 这个布尔变量定义 HTTP 脚本是否允许写访问到文件标记在一个公共文件传输服务 public_content_rw_t 类型。
  • httpd_builtin_scripting 这个布尔变量定义 httpd 的脚本的访问。在这个布尔变量启用,往往需要为 PHP 内容。
  • httpd_can_network_connect 禁用时这个布尔变量防止从网络或远程端口发起连接的 HTTP 脚本和模块。打开这个布尔变量允许这种访问。
  • httpd_can_network_connect_db 禁用时这个布尔变量防止发起一个连接到数据库服务器的 HTTP 脚本和模块。打开这个布尔变量允许这种访问。
  • httpd_can_network_relay 打开这个当布尔变量的 httpd 正在使用正向或反向代理。
  • httpd_can_sendmail 禁用时这个布尔变量防止发送邮件的 HTTP 模块。这可以防止垃圾邮件的攻击漏洞中发现的 httpd。打开这个布尔变量允许 HTTP 模块发送邮件。
  • httpd_dbus_avahi 关闭时这个布尔变量拒绝服务的 avahi 通过 D-BUS 的 httpd 访问。打开这个布尔变量允许这种访问。
  • httpd_enable_cgi 禁用时这个布尔变量防止 httpd 的执行 CGI 脚本。打开这个布尔变量让 httpd 的执行 CGI 脚本。
  • httpd_enable_ftp_server 开放这个布尔变量会容许的 httpd 作为 FTP 服务器的 FTP 端口和行为。
  • httpd_enable_homedirs 禁用时这个布尔变量阻止访问用户主目录的 httpd。打开这个布尔变量允许 httpd 访问用户主目录。
  • httpd_execmem 启用时这个布尔变量允许 httpd 的执行程序需要的内存地址。建议不要启用这个布尔变量从安全角度来看,因为它减少了对缓冲区溢出,但是某些模块和应用程序(如 Java 和 Mono 应用)的保护需要这种特权。
  • httpd_ssi_exec 这个布尔变量定义服务器端包含(SSI)的网页中的元素是否可以执行。
  • httpd_tty_comm 这个布尔变量定义的 httpd 是否被允许访问的控制终端。这种访问通常是不需要的,但是,如配置 SSL 证书文件的情况下,终端访问所需的显示和处理一个密码提示。
  • httpd_use_cifs 打开这个布尔变量允许 httpd 访问 CIFS 文件系统上标记的文件,如通过 Samba 挂载的文件系统,cifs_t 类型。
  • httpd_use_nfs 打开这个布尔变量允许 httpd 访问 NFS 文件系统上的标记文件 nfs_t 类型,如文件系统,通过 NFS 挂载。

配置实例

运行一个静态 web 网页

假设使用如下命令:mkdir /mywebsite ,建立一个文件夹作为 Apache 服务器的文档根目录。可以使用如下命令查看其文件属性:

# ls -dZ /mywebsite
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 /mywebsite

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

# chcon -R -t httpd_sys_content_t /mywebsite
# touch /mywebsite/index.html
# ls -Z /mywebsite /website/index.html
-rw-r--r--  root root unconfined_u:object_r:httpd_sys_content_t:s0 /mywebsite /index.html

下面修改 /etc/httpd/conf/httpd.conf 文件,改为:

#DocumentRoot "/var/www/html"
DocumentRoot "/mywebsite"

然后重启 Apache 服务器。 如果要要彻底修改 /mywebsite 的文件类型属性,使之重新启动后设置还有效,可以使用 semanage fcontext 和 restorecon 命令

# semanage fcontext -a -t httpd_sys_content_t "/mywebsite(/.*)?"
# restorecon -R -v /mywebsite

共享 NFS 和 CIFS 文件系统

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

例如使用 setsebool 命令打开 httpd_use_nfs 布尔变量后,httpd 即可访问 nfs-t 类型的 nfs 共享资源了:

# setsebool -P httpd_use_nfs on

例如使用 setsebool 命令打开 httpd_use_cifs 布尔变量后,httpd 即可访问 cifs_t 类型的 cifs 共享资源了:

# setsebool -P httpd_use_cifs on

更改端口号

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

# semanage port -l | grep -w http_port_t
http_port_t tcp 80, 443, 488, 8008, 8009, 8443

可以看到默认情况下,SELinux 允许 HTTP 侦听 TCP 端口 80,443,488,8008,8009 或 8443。假设要把端口号 80 修改为 12345 ,下面看看修改端口号的方法: 修改配置文件 /etc/httpd/conf/httpd.conf 为

  # Change this to Listen on specific IP addresses as shown below to
  # prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
  # Listen 12.34.56.78:80
    Listen 10.0.0.1:12345

使用命令修改:

# semanage port -a -t http_port_t -p tcp 12345

然后确认一下:

 # semanage port -l | grep -w http_port_t
 http_port_t      tcp      12345, 80, 443, 488, 8008, 8009, 8443

SELinux 环境下 Samba 配置

Samba 的 SELinux 的文件类型

SELinux 环境中,Samba 服务器的 smbd 和 nmbd 守护进程都是在受限的 smbd_t 域中运行。并且和其他受限的网络服务相互隔离。下面的示例演示的是 SELinux 下的 smb 进程

$ ps -eZ | grep smb
unconfined_u:system_r:smbd_t:s0 16420 ?        00:00:00 smbd
unconfined_u:system_r:smbd_t:s0 16422 ?        00:00:00 smbd

缺省情况下,smbd 只能读写 samba_share_t 类型的文件 , 不能读写 httpd_sys_content_t 类型的文件。如果希望 smbd 能读写 httpd_sys_content_t 类型的文件,可以重新标记文件的类型。另外还可以修改布尔值如允许 Samba 提供 NFS 文件系统等共享资源。如果需要修改文件和目录的 SELinux 类型属性时可以使用三个命令:chcon、 semanage fcontext 和 restorecon 命令 。

Samba 的 SELinux 的布尔变量

SELinux 也为 Samba 提供了一些布尔变量用来调整 SELinux 策略,如果希望 Samba 服务器共享 NFS 文件系统,可以使用如下命令:

# setsebool -P samba_share_nfs on

下面是常用的布尔变量;

  • allow_smbd_anon_write 开放此布尔变量启用允许 smbd 保留一个区域的共同文件。
  • samba_create_home_dirs 开放此布尔变量启用允许 Samab 独立创建新的主目录。这通常是用于 PAM 机制。
  • samba_domain_controller 当启用此布尔变量时允许 Samba 作为域控制器,以及赋予它的权限执行相关的命令,如使用 useradd,groupadd 的 和 passwd 。
  • samba_enable_home_dirs 启用此布尔变量允许 Samba 共享用户的主目录。
  • samba_export_all_rw 启用此布尔变量允许公布任何文件或目录,允许读取和写入权限。
  • samba_run_unconfined 启用此布尔变量允许允许的 Samba 运行 / var / lib/samba/ scripts 目录中的脚本。
  • samba_share_nfs 启用此布尔变量将允许 Samba 共享 NFS 文件系统。
  • use_samba_home_dirs 启用此布尔变量可以使用远程服务器 Samba 的主目录。
  • virt_use_samba 允许虚拟机访问 CIFS 文件。

配置实例

共享一个新建的目录

受限创建一个目录作为 Samba 的共享资源,然后在目录下建立一个文件检验共享是否成功。

#mkdir /yeslab
#touch /yeslab/file1

设置创建目录和目录中文件的类型

#semanage fcontext -a -t samba_share_t "/yeslab(/.*)?"
# restorecon -R -v /yeslab

修改 Samba 配置文件 /etc/samba/smb.conf,添加共享资源定义包括如下行::

   [yeslab]
    comment = yeslab
    path = /yeslab
    public = yes
    writeable = yes

创建一个 samba 用户

    # smbpasswd -a testuser
    New SMB password: Enter a password
    Retype new SMB password: Enter the same password again
    Added user testuser.

启动 Samba 服务

service smb start

查询可以使用的共享资源:

$ smbclient -U testuser -L localhost

使用 mount 命令挂载共享资源,并且检验文件:

#mount //localhost/yeslab /test/ -o user= testuser
# ls /test/

共享一个网页

如果要共享一个网页文件目录如 Apache 服务器的 /var/www/html,是不能使用文件类型的。此时可以使用samba_export_all_ro 和 samba_export_all_rw 两个布尔值变量,达到共享目录和文件的目的。步骤如下:

修改 samba 配置文件,添加如下行:

   [website]
    comment = Sharing a website
    path = /var/www/html/
    public = yes
    writeable = yes

开放 samba_export_all_ro 布尔值变量

#setsebool -P samba_export_all_ro on

设置权限:

#chmod 777 /var/www/html/

共享目录:

#mount //localhost/yeslab /test/ -o user= testuser
# ls /test/


SELinux 环境下 NFS 配置

NFS 的 SELinux 的文件类型

SELinux 环境中,nfs 服务器的守护进程都是在受限的 nfs_t 域中运行。并且和其他受限的网络服务相互隔离。SELinux 策略不允许使用 NFS 共享远程文件。如果一定要共享远程文件,可以使用 nfs_export_all_ro 和 nfs_export_all_rw 等布尔值变量调整 SELinux 的策略。按照 SELinux 的策略规定客户端安装 NFS 文件系统采用的默认文件系统是 nfs_t,此外 SELinux 还针对 nfsd 定义了一些文件类型:

•var_lib_nfs_t 这种类型用于现有的和新的文件复制或在创建的 /var/lib/nfs 目录中。在正常运行这种类型应该不需要改变。要恢复到默认设置,可以使用超级用户权限运行命令:restorecon -R -v /var/lib/nfs。

•nfsd_exec_t /usr/sbin/rpc.nfsd 程序文件和其他涉及到 NFS 可执行文件和库都是这种类型。其他文件不使用此类型的任何文件。

NFS 的 SELinux 的布尔变量

SELinux 提供了几个布尔变量用来调整 NFS,你可以在系统安全和 NFS 功能之间取得平衡。

下面是常用的布尔变量;

 *  allow_ftpd_use_nfs 当启用时这个布尔变量允许 ftpd 访问 NFS 挂载。
 *  allow_nfsd_anon_write 当启用时这个布尔变量允许写入到一个公共目录匿名 nfsd。
 *  httpd_use_nfs 当启用时这个布尔变量容许的 httpd 访问一个 NFS 文件系统上存储的文件。
 *  nfs_export_all_ro 当启用时这个布尔变量允许任何文件或目录通过 NFS 导出,允许只读权限。
 *  nfs_export_all_rw 当启用时这个布尔变量允许任何通过 NFS 导出的文件或目录,允许读取和写入权限。
 *  qemu_use_nfs 当启用时这个布尔变量允许 QEMU 使用 NFS 文件系统。
 *  samba_share_nfs 启用此布尔变量将允许 Samba 共享 NFS 文件系统。
 *  use_nfs_home_dirs 当启用时这个布尔变量允许将支持 NFS 主目录。
 *  virt_use_nfs 当启用时这个布尔变量允许虚拟机访问 NFS 文件。
 *  xen_use_nfs 当启用时这个布尔变量允许 Xen 使用 NFS 文件。

实例

将本机的 NFS 共享设置成可读可写,需要开放相关布尔值变量:

#setsebool -P nfs_export_all_rw on

如果你想要将远程 NFS 的家目录共享到本机,需要开放相关布尔值变量:

#setsebool -P use_nfs_home_dirs on

接下来的这个例子中 NFS 服务器的 IP 地址 192.168.1.1,NFS 客户端的 IP 地址为 192.168.1.10,两台主机在同一子网(192.168.1.0/24)。

首先在 NFS 服务器端使用 setsebool 命令确保 nfs_export_all_rw 布尔变量已经打开,使得 NFS 客户端能够以只读的方式安装 NFS 文件系统。然后创建一个顶级目录,作为共享资源,然后在目录中建立一个文件提供给客户端访问,命令如下:

    #setsebool  -P nfs_export_all_rw on
    #mkdir – p /share/nfs
    #cp /etc/profile /share/nfs/test
    #chmod  - R 777 /share/nfs

下面编辑 /etc/exports 文件把共享资源加入。

/share/nfs    192.168.1.10(rw)

确保防火墙修改设置正确。然后启动 nfs 服务

    # service nfs start
    Starting NFS services:      [  OK  ]
    Starting NFS quotas:         [  OK  ]
    Starting NFS daemon:         [  OK  ]
    Starting NFS mountd:         [  OK  ]

运行 exports 命令确保共享资源公布,使用 showmount 命令查询共享资源。

    #exportfs -rv
    exporting 192.168.1.10:/share/nfs
    # showmount -e
    Export list for nfs-srv:
    /share/nfs 192.168.1.10

下面在 NFS 客户端可以使用命令挂载 NFS 服务器的共享资源了 :

    # mount.nfs 192.168.1.1:/share/nfs /mnt
    # ls /mnt
    total 0
    -rwxrwxrwx.  1 root root 0 2012-7-22 06:27 test