Red Hat Training
A Red Hat training course is available for Red Hat Enterprise Linux
SELinux 用户和管理员指南
Security-Enhanced Linux(SELinux)的基本和高级配置
摘要
部分 I. SELinux
第 1 章 简介
_t
结尾。例如,Web 服务器的类型名称是 httpd_t
。通常位于 /var/www/html/
中的文件和目录的类型上下文是 httpd_sys_content_t
。通常位于 /tmp 和 /var/tmp/
中的文件和目录的类型上下文是
tmp_t
。Web 服务器端口的类型上下文是 http_port_t
。
httpd_t
运行的 Web 服务器进程)访问通常位于 /var/www/html/
及其他 Web 服务器目录(httpd_sys_content_t
)中的文件和目录。策略中没有针对通常位于 /tmp 和 /var/tmp
/
中的文件的允许规则,因此不允许访问。有了 SELinux,即使 Apache 被破坏并且恶意的脚本可以访问,它仍然无法访问 /tmp
目录。
图 1.1. SELinux 允许以 httpd_t 身份运行的 Apache 进程访问 /var/www/html/ 目录,并且它拒绝同一进程访问 /data/mysql/ 目录,因为 httpd_t 和 mysqld_db_t 类型上下文没有允许规则。另一方面,作为 mysqld_t 运行的 MariaDB 进程能够访问 /data/mysql/ 目录,SELinux 也正确拒绝类型为 mysqld_t 的进程,以访问标记为 httpd_sys_content_t 的 /var/www/html/ 目录。
[D]
其它资源
- apropos
selinux 命令列出的 selinux
(8)手册页 和 man page。
1.1. 运行 SELinux 的好处
- 所有进程和文件都被标记。SELinux 策略规则定义了进程如何与文件交互,以及进程如何相互交互。只有存在明确允许的 SELinux 策略规则时,才能允许访问。
- 精细访问控制。传统的 UNIX 通过用户的授权、基于 Linux 的用户和组进行控制。而 SELinux 的访问控制基于所有可用信息,如 SELinux 用户、角色、类型以及可选的安全级别。
- SELinux 策略由系统管理员进行定义,并在系统范围内强制执行。
- 改进了权限升级攻击的缓解方案。进程在域中运行,因此是相互分离的。SELinux 策略规则定义了如何处理访问文件和其它进程。如果某个进程被破坏,攻击者只能访问该进程的正常功能,而且只能访问已被配置为可以被该进程访问的文件。例如:如果 Apache HTTP 服务器被破坏,攻击者无法使用该进程读取用户主目录中的文件,除非添加或者配置了特定的 SELinux 策略规则允许这类访问。
- SELinux 可以用来强制实施数据机密性和完整性,同时保护进程不受不可信输入的影响。
- 防病毒软件,
- 用来替换密码、防火墙和其它安全系统,
- 多合一的安全解决方案。
1.2. 示例
- 默认操作为 deny(拒绝)。如果 SELinux 策略规则不存在允许访问(如允许进程打开一个文件),则拒绝访问。
- SELinux 可以限制 Linux 用户。SELinux 策略中包括很多受限制的 SELinux 用户。可将 Linux 用户映射到受限制的 SELinux 用户,以便利用其使用的安全规则和机制。例如,将 Linux 用户映射到 SELinux
user_u
用户,会导致 Linux 用户无法运行(除非另外配置)设置用户 ID(setuid)应用程序,如 sudo 和 su。如需更多信息,请参阅 第 3.3 节 “受限制和未限制的用户”。 - 增加进程和数据的分离。进程在自己的域中运行,阻止进程访问其他进程使用的文件,并阻止进程访问其他进程。例如:在运行 SELinux 时,除非有其他配置,攻击者将无法侵入 Samba 服务器,然后使用 Samba 服务器作为攻击向量读取和写入其它进程使用的文件(如 MariaDB 数据库)。
- SELinux 可帮助缓解配置错误带来的破坏。不同的 DNS 服务器通常会在彼此间复制信息,这被称为区传输(zone transfer).攻击者可以利用区传输来更新 DNS 服务器使其包括错误的信息。当在 Red Hat Enterprise Linux 中将 Berkeley Internet 名称域(BIND)作为 DNS 服务器运行时,即使管理员忘记限制哪些服务器可以执行区域传输,默认的 SELinux 策略也会阻止区域文件 [1] 通过 BIND
命名
守护进程本身和其他进程,使用区域传送进行更新。 - 请参阅 NetworkWorld.com 文章 A Stbelt for server 软件:SELinux 阻止实际利用[2]有关 SELinux 的背景信息,以及 SELinux 已阻止的各种漏洞的信息。
1.3. SELinux Architecture
1.4. SELinux 状态和模式
~]# getenforce
Enforcing
~]# setenforce 0 ~]# getenforce Permissive
~]# setenforce 1 ~]# getenforce Enforcing
httpd_t
域为 permissive 模式:
~]# semanage permissive -a httpd_t
1.5. 其它资源
第 2 章 SELinux Contexts
~]$
ls -Z file1
-rwxrw-r-- user1 group1 unconfined_u:object_r:user_home_t:s0 file1
- SELinux user
- SELinux 用户身份是策略已知的身份,它授权用于一组特定的角色,以及特定的 MLS/MCS 范围。每个 Linux 用户都使用 SELinux 策略映射到 SELinux 用户。这允许 Linux 用户继承对 SELinux 用户的限制。映射的 SELinux 用户身份在该会话中进程的 SELinux 上下文中使用,以定义它们可以进入哪些角色和级别。以 root 身份输入以下命令,查看 SELinux 和 Linux 用户帐户之间的映射列表(您需要安装 policycoreutils-python 软件包):
~]#
semanage login -l Login Name SELinux User MLS/MCS Range Service __default__ unconfined_u s0-s0:c0.c1023 * root unconfined_u s0-s0:c0.c1023 * system_u system_u s0-s0:c0.c1023 *输出可能因系统稍有不同:Login Name
列中列出了 Linux 用户。SELinux 用户
列中列出了 Linux 用户映射至哪个 SELinux 用户。对于进程,SELinux 用户限制可以访问哪些角色和级别。MLS/MCS Range
列是多级别安全(MLS)和多类别安全(MCS)使用的级别。Service
列决定了正确的 SELinux 上下文,在该上下文中,Linux 用户应当登录该系统。默认情况下,使用星号(*
)字符,它代表任何服务。
- role
- SELinux 的一部分是基于角色的访问控制(RBAC)安全模型。该角色是 RBAC 的一个属性。SELinux 用户获得角色的授权,并且域对角色进行了授权。该角色充当域和 SELinux 用户之间的中介。可以输入的角色决定了可以输入哪些域;最后,这控制可以访问哪些对象类型。这有助于降低对特权升级攻击的漏洞。
- type
- type 是 Type Enforcement 的属性。类型定义进程的域,以及文件的类型。SELinux 策略规则定义类型如何互相访问,无论是访问某一类型的域还是访问其他域的域。只有在存在允许访问的特定 SELinux 策略规则时才允许访问。
- level
- 级别是 MLS 和 MCS 的属性。MLS 范围是一对级别,如果级别不同,则写为 低级别-高级别 ,如果级别相同(
s0-s0
与s0
相同)。每个级别都是敏感度类别对,类别是可选的。如果有类别,则该级别被写为 敏感度:category-set。如果没有类别,它将被写为 敏感度。如果设置的类别是连续的序列,则可缩写它。例如,c0.c3
与c0,c1,c2,c3
相同。/etc/selinux/targeted/setrans.conf
文件将级别(s0:c0)
映射到人类可读形式(即CompanyConfidential
)。在红帽企业 Linux 中,目标策略强制 MCS,在 MCS 中,只有一个敏感度s0。
红帽企业 Linux 中的 MCS 支持 1024 个不同的类别:c0
到c1023
。s0-s0:c0.c1023
具有敏感度s0
,并授权所有类别。MLS 强制执行 Bell-La Padula Mandatory 访问模型,用于标记安全保护配置文件(LSPP)环境。要使用 MLS 限制,请安装 selinux-policy-mls 软件包,并将 MLS 配置为默认 SELinux 策略。Red Hat Enterprise Linux 附带的 MLS 策略省略了不属于评估配置的许多程序域,因此桌面工作站上的 MLS 不可用(不支持 X Window 系统);但是,可以构建包含所有程序域的 MLS 策略。有关 MLS 配置的详情请参考 第 4.13 节 “多级别安全(MLS)”。
2.1. 域转换
入口点
类型的应用,过渡到另一个域。入口点
权限用于 SELinux 策略,并控制哪些应用程序可用于进入域。以下示例演示了一个域转换:
过程 2.1. 域转换示例
- 用户想要更改其密码。为此,他们将运行
passwd
实用程序。/usr/bin/passwd
可执行文件使用passwd_exec_t
类型标记:~]$
ls -Z /usr/bin/passwd -rwsr-xr-x root root system_u:object_r:passwd_exec_t:s0 /usr/bin/passwdpasswd
实用程序访问/etc/shadow
,其标有shadow_t
类型:~]$
ls -Z /etc/shadow -r--------. root root system_u:object_r:shadow_t:s0 /etc/shadow - SELinux 策略规则规定,在
passwd_t
域中运行的进程被允许读取和写入使用shadow_t
类型标记的文件。shadow_t
类型仅应用于密码更改所需的文件。这包括/etc/gshadow
、/etc/shadow
及其备份文件。 - SELinux 策略规则指出,
passwd_t
域的入口点
权限设置为passwd_exec_t
类型。 - 用户运行
passwd
实用程序时,用户的 shell 进程将过渡到passwd_t
域。使用 SELinux 时,由于默认操作是拒绝,并且存在允许passwd_t
域中运行的(其他事情)应用访问shadow_t
类型的文件的规则,passwd应用
被允许访问/etc/shadow
,并更新用户的密码。
passwd_t
域中运行的主题访问标有 shadow_t
文件类型的对象,但必须满足其他 SELinux 策略规则,才能让使用者转换到新域。在本例中,Type Enforcement 可确保:
passwd_t
域只能通过执行标有passwd_exec_t
类型的应用来输入;只能从授权的共享库(如lib_t
类型)执行;并且无法执行任何其他应用。- 只有授权的域(如
passwd_t
)可以写入到带有shadow_t
类型标记的文件。即使其他进程使用超级用户特权运行,这些进程也无法写入带有shadow_t
类型标记的文件,因为它们不在passwd_t
域中运行。 - 只有授权的域可以转换到
passwd_t
域。例如,在sendmail
_t 域中运行的 sendmail
进程没有执行 passwd 的合法原因;因此,它永远不会转换到passwd_t
域。 - 在
passwd_t
域中运行的进程只能读取和写入授权类型,例如使用etc_t 或
类型标记的文件。这可防止shadow_t
passwd
应用被欺骗为读取或编写任意文件。
2.2. 进程的 SELinux 上下文
过程 2.2. 查看 passwd
实用程序的 SELinux 上下文
- 打开终端,如 Applications → System Tools → Terminal。
- 运行
passwd
实用程序。不要输入新密码:~]$
passwd Changing password for user user_name. Changing password for user_name. (current) UNIX password: - 打开一个新标签页或其他终端,再输入以下命令。输出结果类似以下:
~]$
ps -eZ | grep passwd unconfined_u:unconfined_r:passwd_t:s0-s0:c0.c1023 13212 pts/1 00:00:00 passwd - 在第一个标签页/终端中,按
Ctrl+C
以取消passwd
工具。
passwd
实用程序(使用 passwd_exec_t
类型标记)时,用户的 shell 进程将过渡到 passwd_t
域。请记住,类型定义了进程的域,以及文件的类型。
ps
实用程序。请注意,以下是输出结果的截断示例,在您的系统上可能有所不同:
]$
ps -eZ
system_u:system_r:dhcpc_t:s0 1869 ? 00:00:00 dhclient
system_u:system_r:sshd_t:s0-s0:c0.c1023 1882 ? 00:00:00 sshd
system_u:system_r:gpm_t:s0 1964 ? 00:00:00 gpm
system_u:system_r:crond_t:s0-s0:c0.c1023 1973 ? 00:00:00 crond
system_u:system_r:kerneloops_t:s0 1983 ? 00:00:05 kerneloops
system_u:system_r:crond_t:s0-s0:c0.c1023 1991 ? 00:00:00 atd
system_r
角色用于系统进程,如守护进程。类型强制随后分隔每个域。
2.3. 用户的 SELinux 上下文
~]$
id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
unconfined_u
用户,以 unconfined_r
角色运行,并在 unconfined_t
域中运行。s 0-s0
是 MLS 范围,本例中仅与 s0
相同。用户有权访问的类别由 c0.c1023
定义,这是所有类别(c0
到 c1023
)。
第 3 章 目标策略
unconfined_t
域中运行,由 init 启动的系统进程在 unconfined_service_t
域中运行;这两个域都是未限制的。
3.1. 受限制的进程
sshd
或 httpd
)都受到 Red Hat Enterprise Linux 的限制。此外,大多数以 root 用户身份运行并执行用户任务的进程(如 passwd
实用程序)都会受限制。当进程受限制时,它会在自己的域中运行,如 httpd
_t 域中运行的 httpd
进程。如果一个受攻击者限制的进程受到 SELinux 策略配置的影响,攻击者对资源的访问权限和可能受到的破坏会受到限制。
过程 3.1. 如何验证 SELinux 状态
- 确认 SELinux 已启用,正在以强制模式运行,并且正在使用 targeted 策略。正确的输出应类似如下:
~]$
sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: enforcing Mode from config file: enforcing Policy MLS status: enabled Policy deny_unknown status: allowed Max kernel policy version: 30有关更改 SELinux 模式的详情,请查看 第 4.4 节 “SELinux 状态和模式中的永久性更改”。 - 以 root 用户身份,在
/var/www/html/
目录中创建一个文件:~]#
touch /var/www/html/testfile - 输入以下命令查看新创建的文件的 SELinux 上下文:
~]$
ls -Z /var/www/html/testfile -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/testfile默认情况下,Linux 用户在 Red Hat Enterprise Linux 中运行没有限制,这就是为何testfile
文件带有 SELinuxunconfined_u
用户标记的原因。RBAC 用于进程,而非文件。角色对文件没有意义;object_r
角色是用于文件的通用角色(在持久存储和网络文件系统上)。在/proc
目录下,与进程相关的文件可以使用system_r
角色。httpd_sys_content_t
类型允许httpd
进程访问此文件。
httpd
)读取未正确标记的文件,例如供 Samba 使用的文件。这是个示例,不应在生产环境中使用。它假定已安装了 httpd 和 wget 软件包,使用了 SELinux 目标策略,并且 SELinux 处于强制模式。
过程 3.2. 受限进程示例
- 以 root 用户身份,启动
httpd
守护进程:~]#
systemctl start httpd.service确认 服务正在运行。输出中应包括以下信息(只有时间戳有所不同):~]$
systemctl status httpd.service httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled) Active: active (running) since Mon 2013-08-05 14:00:55 CEST; 8s ago - 更改到 Linux 用户对其具有写入权限的目录,并输入以下命令。除非对默认配置进行了更改,否则这个命令会成功:
~]$
wget http://localhost/testfile --2009-11-06 17:43:01-- http://localhost/testfile Resolving localhost... 127.0.0.1 Connecting to localhost|127.0.0.1|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 0 [text/plain] Saving to: `testfile' [ <=> ] 0 --.-K/s in 0s 2009-11-06 17:43:01 (0.00 B/s) - `testfile' saved [0/0] - chcon 命令重新标记文件;但是,当文件系统重新标记时,此类标签更改不会保留。若要在文件系统重新标记后保留永久更改,请使用
semanage
实用程序,稍后将对此进行讨论。以 root 用户身份,输入以下命令将类型更改为 Samba 使用的类型:~]#
chcon -t samba_share_t /var/www/html/testfile输入以下命令查看更改:~]$
ls -Z /var/www/html/testfile -rw-r--r-- root root unconfined_u:object_r:samba_share_t:s0 /var/www/html/testfile - 请注意,当前的 DAC 权限允许
httpd
进程访问testfile
。更改到您的用户具有写入访问权限的目录,并输入以下命令。除非对默认配置进行了更改,否则这个命令会失败:~]$
wget http://localhost/testfile --2009-11-06 14:11:23-- http://localhost/testfile Resolving localhost... 127.0.0.1 Connecting to localhost|127.0.0.1|:80... connected. HTTP request sent, awaiting response... 403 Forbidden 2009-11-06 14:11:23 ERROR 403: Forbidden. - 以 root 用户身份,删除
testfile
:~]#
rm -i /var/www/html/testfile - 如果您不需要
httpd
以 root 用户身份运行,请输入以下命令停止它:~]#
systemctl stop httpd.service
httpd
进程在第 2 步中访问 testfile
,因为该文件使用 httpd
进程无法访问的类型进行标记,但 SELinux 会拒绝访问。
auditd
守护进程正在运行,类似如下的错误会记录到 /var/log/audit/audit.log
中:
type=AVC msg=audit(1220706212.937:70): avc: denied { getattr } for pid=1904 comm="httpd" path="/var/www/html/testfile" dev=sda5 ino=247576 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:samba_share_t:s0 tclass=file type=SYSCALL msg=audit(1220706212.937:70): arch=40000003 syscall=196 success=no exit=-13 a0=b9e21da0 a1=bf9581dc a2=555ff4 a3=2008171 items=0 ppid=1902 pid=1904 auid=500 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=1 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
/var/log/httpd/error_log
中:
[Wed May 06 23:00:54 2009] [error] [client 127.0.0.1] (13)Permission denied: access to /testfile denied
3.2. 未限制的进程
init
执行的非限制服务最终在 unconfined_service_t
域中运行,内核执行的无限制服务最终在 kernel_t
域中运行,未限制的 Linux 用户执行的无限制服务最终在 unconfined_t
域中运行。对于不受限制的进程,会应用 SELinux 策略规则,但存在允许无限制域中运行的进程的策略规则几乎所有访问权限。在不受限制的域中运行的进程只能回退到使用 DAC 规则。如果不受限制的进程受到破坏,SELinux 不会阻止攻击者获得系统资源和数据的访问权限,当然,仍会使用 DAC 规则。SELinux 是 DAC 规则基础上的安全增强 - 它不会取代它们。
)
如何访问供 Samba 使用的数据。请注意,在 Red Hat Enterprise Linux 中,默认情况下 httpd
进程在受限的 httpd_t
域中运行。这是个示例,不应在生产环境中使用。它假定已安装了 httpd、wget、dbus 和 audit 软件包,使用了 SELinux targeted 策略,并且 SELinux 处于强制模式。
过程 3.3. Unconfined 进程示例
- chcon 命令重新标记文件;但是,当文件系统重新标记时,此类标签更改不会保留。若要在文件系统重新标记后保留永久更改,请使用
semanage
实用程序,稍后将对此进行讨论。以 root 用户身份,输入以下命令将类型更改为 Samba 使用的类型:~]#
chcon -t samba_share_t /var/www/html/testfile查看更改:~]$
ls -Z /var/www/html/testfile -rw-r--r-- root root unconfined_u:object_r:samba_share_t:s0 /var/www/html/testfile - 输入以下命令确认
httpd
进程没有在运行:~]$
systemctl status httpd.service httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled) Active: inactive (dead)如果输出不同,以 root 用户身份输入以下命令停止httpd
进程:~]#
systemctl stop httpd.service - 要使
httpd
进程以 root 用户身份运行不受限制,请输入以下命令将/usr/sbin/httpd
文件的类型更改为没有转换到受限域的类型:~]#
chcon -t bin_t /usr/sbin/httpd - 确认
/usr/sbin/httpd
使用bin_t
类型标记:~]$
ls -Z /usr/sbin/httpd -rwxr-xr-x. root root system_u:object_r:bin_t:s0 /usr/sbin/httpd - 以 root 用户身份,启动
httpd
进程并确认它已成功启动:~]#
systemctl start httpd.service~]#
systemctl status httpd.service httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled) Active: active (running) since Thu 2013-08-15 11:17:01 CEST; 5s ago - 输入以下命令查看在
unconfined_service_t
域中运行的httpd
:~]$
ps -eZ | grep httpd system_u:system_r:unconfined_service_t:s0 11884 ? 00:00:00 httpd system_u:system_r:unconfined_service_t:s0 11885 ? 00:00:00 httpd system_u:system_r:unconfined_service_t:s0 11886 ? 00:00:00 httpd system_u:system_r:unconfined_service_t:s0 11887 ? 00:00:00 httpd system_u:system_r:unconfined_service_t:s0 11888 ? 00:00:00 httpd system_u:system_r:unconfined_service_t:s0 11889 ? 00:00:00 httpd - 更改到 Linux 用户对其具有写入权限的目录,并输入以下命令。除非对默认配置进行了更改,否则这个命令会成功:
~]$
wget http://localhost/testfile --2009-05-07 01:41:10-- http://localhost/testfile Resolving localhost... 127.0.0.1 Connecting to localhost|127.0.0.1|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 0 [text/plain] Saving to: `testfile' [ <=> ]--.-K/s in 0s 2009-05-07 01:41:10 (0.00 B/s) - `testfile' saved [0/0]虽然httpd
进程无法访问使用samba_share_t
类型标记的文件,但httpd
在未限制的unconfined_service_t
域中运行,并返回使用 DAC 规则,因此 wget 命令可以 成功运行。如果httpd
在受限的httpd_t
域中运行,wget 命令会失败。 restorecon
实用程序恢复文件的默认 SELinux 上下文。以 root 用户身份,输入以下命令恢复/usr/sbin/httpd
的默认 SELinux 上下文:~]#
restorecon -v /usr/sbin/httpd restorecon reset /usr/sbin/httpd context system_u:object_r:unconfined_exec_t:s0->system_u:object_r:httpd_exec_t:s0确认/usr/sbin/httpd
使用httpd_exec_t
类型标记:~]$
ls -Z /usr/sbin/httpd -rwxr-xr-x root root system_u:object_r:httpd_exec_t:s0 /usr/sbin/httpd- 以 root 身份,输入以下命令来重启
httpd
。重启后,确认httpd
是否在受限的httpd_t
域中运行:~]#
systemctl restart httpd.service~]$
ps -eZ | grep httpd system_u:system_r:httpd_t:s0 8883 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 8884 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 8885 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 8886 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 8887 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 8888 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 8889 ? 00:00:00 httpd - 以 root 用户身份,删除
testfile
:~]#
rm -i /var/www/html/testfile rm: remove regular empty file `/var/www/html/testfile'? y - 如果您不需要
httpd
运行,请以 root 用户身份输入以下命令来停止httpd
:~]#
systemctl stop httpd.service
3.3. 受限制和未限制的用户
~]#
semanage login -l
Login Name SELinux User MLS/MCS Range Service
__default__ unconfined_u s0-s0:c0.c1023 *
root unconfined_u s0-s0:c0.c1023 *
system_u system_u s0-s0:c0.c1023 *
__default__
登录,这映射到 SELinux unconfined_u
用户。下面一行定义了默认映射:
__default__ unconfined_u s0-s0:c0.c1023
unconfined_u
用户。它假设 root 用户运行没有限制,这与 Red Hat Enterprise Linux 中的默认设置相同:
过程 3.4. 将新 Linux 用户映射到 SELinux unconfined_u
用户
- 以 root 用户身份,输入以下命令创建一个名为
newuser
的新 Linux 用户:~]#
useradd newuser - 要将密码分配给 Linux
newuser
用户:以 root 用户身份输入以下命令:~]#
passwd newuser Changing password for user newuser. New UNIX password: Enter a password Retype new UNIX password: Enter the same password again passwd: all authentication tokens updated successfully. - 从当前会话注销,然后以 Linux
newuser
用户身份登录。登录时,pam_selinux PAM 模块会自动将 Linux 用户映射到 SELinux 用户(本例中为unconfined_u
),并设置生成的 SELinux 上下文。然后,将使用此上下文启动 Linux 用户的 shell。输入以下命令查看 Linux 用户的上下文:[newuser@localhost ~]$
id -Z unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023注意如果您不再需要系统上的newuser
用户,请注销 Linuxnewuser
的会话,使用您的帐户登录,然后以 root 用户身份运行 userdel -r newuser 命令。它将删除新用户
及其主目录。
~]$
seinfo -u
Users: 8
sysadm_u
system_u
xguest_u
root
guest_u
staff_u
user_u
unconfined_u
unconfined_t
域转换到其自身限制域的应用程序,则未限制的 Linux 用户仍会受到那个受限制域的限制。这样做的安全优点是,即使 Linux 用户的运行没有限制,但应用程序仍受限制。因此,对应用程序中漏洞的利用会被策略限制。
表 3.1. SELinux 用户功能
用户 | 角色 | 域 | X 窗口系统 | su 或 sudo | 在主目录和 /tmp 中执行(默认) | 网络 |
---|---|---|---|---|---|---|
sysadm_u | sysadm_r | sysadm_t | 是 | su 和 sudo | 是 | 是 |
staff_u | staff_r | staff_t | 是 | 仅 sudo | 是 | 是 |
user_u | user_r | user_t | 是 | 否 | 是 | 是 |
guest_u | guest_r | guest_t | 否 | 否 | 是 | 否 |
xguest_u | xguest_r | xguest_t | 是 | 否 | 是 | 仅 Firefox |
user_t、guest_t
和
xguest_t
域中的 Linux 用户只能在 SELinux 策略允许的情况下运行 set 用户 ID(setuid)应用(如passwd
)。这些用户无法运行 su 和 sudo setuid 应用程序,因此无法使用这些应用程序成为 root 用户。sysadm_t、
staff_t
、user_t
和xguest_t
域中的 Linux 用户可以使用 X Window 系统和终端登录。- 默认情况下,
staff_t
中的 Linux 用户、user_t
、guest_t
和xguest_t
域中的 Linux 用户可以在其主目录和/tmp
中执行应用程序。要防止他们在他们有写入访问权限的目录中执行应用程序(继承用户的权限),将guest_exec_content
和xguest_exec_content
布尔值设置为off
。这有助于防止有缺陷或恶意的应用程序修改用户的文件。有关允许和阻止用户在主目录和/tmp
中执行应用程序的详情,请查看 第 6.6 节 “用户执行应用程序的布尔值”。 xguest_t
域中的唯一网络访问 Linux 用户是 Firefox 连接到网页。
system_u
是系统进程和对象的特殊用户身份。它绝对不能和 Linux 用户关联。此外,unconfined_u
和 root
是未限制的用户。因此,它们没有包括在上述 SELinux 用户功能表中。
webadm_r
只能管理与 Apache HTTP 服务器相关的 SELinux 类型。如需更多信息,请参阅 第 13.2 节 “类型”。dbadm_r
只能管理与 MariaDB 数据库和 PostgreSQL 数据库管理系统相关的 SELinux 类型。如需更多信息,请参阅 第 20.2 节 “类型” 和 第 21.2 节 “类型”。logadm_r
只能管理与syslog
和auditlog
进程相关的 SELinux 类型。secadm_r
只能管理 SELinux。auditadm_r
只能管理与audit
子系统相关的进程。
~]$
seinfo -r
3.3.1. sudo 转换和 SELinux 角色
staff _u
和 sysadm_u
SELinux 受限用户可以使用 sudo。当此类用户通过 sudo 执行命令时,可以根据 /etc/sudoers 配置文件中指定的规则或在 /etc/su
doers.d/
目录中相应的规则更改其角色(如果存在此类文件)。
过程 3.5. 配置 sudo 转换
- 创建一个新的 SELinux 用户,并为这个用户指定默认 SELinux 角色和一个补充的受限管理员角色:
~]#
semanage user -a -r s0-s0:c0.c1023 -R "default_role_r administrator_r" SELinux_user_u - 设置默认的 SElinux 策略上下文文件。例如,若要与
staff_u SELinux 用户使用相同的 SELinux 规则
,请复制staff_u
上下文文件:~]#
cp /etc/selinux/targeted/contexts/users/staff_u /etc/selinux/targeted/contexts/users/SELinux_user_u - 将新创建的 SELinux 用户映射到现有 Linux 用户:
semanage login -a -s SELinux_user_u -rs0:c0.c1023 linux_user
- 在
/etc/sudoers.d/
目录中,使用与您的 Linux 用户相同的名称创建新配置文件,并将以下字符串添加到其中:~]#
echo "linux_user ALL=(ALL) TYPE=administrator_t ROLE=administrator_r /bin/bash " > /etc/sudoers.d/linux_user - 使用
restorecon
工具重新标记 linux_user 主目录:~]#
restorecon -FR -v /home/linux_user - 以新创建的 Linux 用户身份登录到该系统,检查用户是否标记了默认的 SELinux 角色:
~]$
id -Z SELinux_user_u:default_role_r:SELinux_user_t:s0:c0.c1023 - 运行 sudo 将用户的 SELinux 上下文更改为
/etc/sudoers.d/linux_user
中指定的辅助 SELinux 角色。与 sudo 一起使用的-i
选项会导致执行交互式 shell:~]$
sudo -i~]#
id -Z SELinux_user_u:administrator_r:administrator_t:s0:c0.c1023
例 3.1. 配置 sudo 转换
confined_u
,默认分配的 staff_r
,使用 sudo 将 confined_u
从 staff_r
的角色更改为 webadm_r
。
- 以 root 用户身份在
sysadm_r
或unconfined_r
角色中输入所有命令。~]#
semanage user -a -r s0-s0:c0.c1023 -R "staff_r webadm_r" confined_u~]#
cp /etc/selinux/targeted/contexts/users/staff_u /etc/selinux/targeted/contexts/users/confined_u~]#
semanage login -a -s confined_u -rs0:c0.c1023 linux_user~]#
restorecon -FR -v /home/linux_user~]#
echo "linux_user ALL=(ALL) ROLE=webadm_r TYPE=webadm_t /bin/bash " > /etc/sudoers.d/linux_user - 以新创建的 Linux 用户身份登录到该系统,检查用户是否标记了默认的 SELinux 角色:
~]$
id -Z confined_u:staff_r:staff_t:s0:c0.c1023~]$
sudo -i~]#
id -Z confined_u:webadm_r:webadm_t:s0:c0.c1023
第 4 章 使用 SELinux
4.1. SELinux 软件包
- policycoreutils 提供
restorecon
、secon
、setfiles
、semodule
、load_policy
和setsebool
等实用程序,用于操作和管理 SELinux。 - selinux-policy 提供 基本目录结构、
selinux-policy.conf
文件和 RPM 宏。 - selinux-policy-targeted 提供了 SELinux targeted 策略。
- libselinux - 为 SELinux 应用程序提供 API.
- libselinux-utils 提供
avcstat
、getenforce
、getsebool
、matchpathcon
、selinuxconlist
、selinuxdefcon
、selinuxenabled
和setenforce
实用程序。 - libselinux-python 为开发 SELinux 应用程序提供 Python 绑定。
- selinux-policy-devel 提供用于创建自定义 SELinux 策略和策略模块的实用程序。
- selinux-policy-doc 提供说明如何使用各种服务配置 SELinux 的 man page。
- selinux-policy-mls 提供了 MLS(多级安全性)SELinux 策略。
- setroubleshoot-server 会在 SELinux 拒绝访问时将拒绝消息转换为此软件包中也提供的 sealert 实用程序可以查看的详细信息。
- setools-console 提供 Tresys Technology SETools 分发、用于分析和查询策略、审计日志监控和报告以及文件上下文管理的实用程序和库。 setools 软件包是 SETools 的 meta-package。setools-gui 软件包提供了 apol
和
seaudit
实用程序。setools-console 软件包提供了sechecker
、sediff
、seinfo
、sesearch
和findcon
命令行实用程序。有关这些工具的信息,请参阅 Tresys Technology SETools 页面。请注意,只有启用 Red Hat Network Optional 频道时才会提供 setools 和 setools-gui 软件包。如需更多信息 ,请参阅覆盖范围详情。 - mcstrans 级别(如
s0-s0:c0.c1023
)转换为更易于阅读的形式,如SystemLow-SystemHigh
。 - policycoreutils-python 提供 semanage、audit 2allow、audit 2why 和 chcat 等实用程序,用于操作和管理 SELinux。
- policycoreutils-gui 提供 system-config-selinux,这是一个用于管理 SELinux 的图形实用程序。
4.2. 使用哪个日志文件
auditd
守护进程正在运行,则 SELinux 拒绝信息会默认写入 /var/log/audit/audit.log
:
type=AVC msg=audit(1223024155.684:49): avc: denied { getattr } for pid=2000 comm="httpd" path="/var/www/html/file1" dev=dm-0 ino=399185 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:samba_share_t:s0 tclass=file
/var/log/message
文件中:
May 7 18:55:56 localhost setroubleshoot: SELinux is preventing httpd (httpd_t) "getattr" to /var/www/html/file1 (samba_share_t). For complete SELinux messages. run sealert -l de7e30d6-5488-466d-a606-92c9f40d316d
setroubleshootd
不再作为服务持续运行。但是,它仍用于分析 AVC 信息。两个新程序可在需要时启动 setroubleshoot
:
sedispatch
实用程序作为audit
子系统的一部分运行。当返回 AVC 拒绝消息时,sedispatch
使用dbus
发送消息。如果这些消息已在运行
,这些消息会直接设置。如果没有运行,则sedispatch 会自动
启动它。seapplet
实用程序在系统工具栏中运行,等待setroubleshootd
中的 dbus 消息。它启动通知 bubble,允许用户查看 AVC 消息。
过程 4.1. 自动启动守护进程
- 要将
auditd
和rsyslog
守护进程配置为在引导时自动启动,以 root 用户身份输入以下命令:~]#
systemctl enable auditd.service~]#
systemctl enable rsyslog.service - 要确保启用了守护进程,在 shell 提示符后输入以下命令:
~]$
systemctl is-enabled auditd enabled~]$
systemctl is-enabled rsyslog enabled或者,使用 systemctl status service-name.service 命令并搜索命令输出中启用
的关键字,例如:~]$
systemctl status auditd.service | grep enabled auditd.service - Security Auditing Service Loaded: loaded (/usr/lib/systemd/system/auditd.service; enabled)
systemd
守护进程如何管理系统服务的信息,请参阅《系统管理员指南》中的管理系统服务 章节。
4.3. 主配置文件
/etc/selinux/config
文件是主要的 SELinux 配置文件。它控制 SELinux 是否已启用或禁用,以及使用了哪个 SELinux 模式和 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=
SELINUX
选项设置 SELinux 是否已禁用或启用,以及在哪个模式下( enforcing 或 permissive)正在运行:- 使用
SELINUX=enforcing
时,SELinux 策略强制实施,SELinux 根据 SELinux 策略规则拒绝访问。记录拒绝消息。 - 使用
SELINUX=permissive
时,不会强制执行 SELinux 策略。SELinux 不会拒绝访问,但会记录对于在强制模式下运行 SELinux 时拒绝的操作。 - 当使用
SELINUX=disabled
时,SELinux 被禁用,SELinux 模块没有在 Linux 内核中注册,仅使用 DAC 规则。
SELINUXTYPE=
SELINUXTYPE
选项设置要使用的 SELinux 策略。targeted 策略是默认策略。只有在您想要使用 MLS 策略时,才更改这个选项。有关如何启用 MLS 策略的详情请参考 第 4.13.2 节 “在 SELinux 中启用 MLS”。
4.4. SELinux 状态和模式中的永久性更改
Enforcing
、Pmissive 或
Disabled
。
~]$
sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 30
4.4.1. 启用 SELinux
- 以 permissive 模式启用 SELinux。如需更多信息,请参阅 第 4.4.1.1 节 “Permissive 模式”。
- 重启您的系统。
- 检查 SELinux 拒绝信息。如需更多信息,请参阅 第 11.3.5 节 “搜索和查看地址”。
- 如果没有拒绝的操作,切换到 enforcing 模式。如需更多信息,请参阅 第 4.4.1.2 节 “强制模式”。
- 在
unconfined_service_t
域中运行您的应用程序。如需更多信息,请参阅 第 3.2 节 “未限制的进程”。 - 为应用程序编写新策略。如需更多信息,请参阅编写自定义 SELinux 策略知识库文章。
4.4.1.1. Permissive 模式
过程 4.2. 进入许可模式
- 编辑
/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=permissive # SELINUXTYPE= can take one of these two values: # targeted - Targeted processes are protected, # mls - Multi Level Security protection. SELINUXTYPE=targeted
- 重启系统:
~]# reboot
4.4.1.2. 强制模式
过程 4.3. 进入强制模式
rpm -q package_name
- 编辑
/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 # SELINUXTYPE= can take one of these two values: # targeted - Targeted processes are protected, # mls - Multi Level Security protection. SELINUXTYPE=targeted
- 重启系统:
~]# reboot
在下一次引导中,SELinux 会重新标记系统中的所有文件和目录,并为禁用 SELinux 时创建的文件和目录添加 SELinux 上下文。
~]# ausearch -m AVC,USER_AVC,SELINUX_ERR -ts today
~]# grep "SELinux is preventing" /var/log/messages
4.4.2. 禁用 SELinux
过程 4.4. 禁用 SELinux
- 在
/etc/selinux/config
文件中配置SELINUX=disabled
:# 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
- 重启您的系统。重启后,确认 getenforce 命令返回
Disabled
:~]$
getenforce Disabled
4.5. 在引导时更改 SELinux 模式
- enforcing=0
- 设置此参数可让系统以 permissive 模式启动,这在进行故障排除时非常有用。如果您的文件系统被破坏,使用 permissive 模式可能是唯一的选择。在 permissive 模式中,系统将继续正确创建标签。在这个模式中产生的 AVC 信息可能与 enforcing 模式不同。在 permissive 模式中,只报告来自于同一拒绝的一系列操作的第一个拒绝信息。然而,在 enforcing 模式中,您可能会得到一个与读取目录相关的拒绝信息,应用程序将停止。在 permissive 模式中,您会得到相同的 AVC 信息,但应用程序将继续读取目录中的文件,并为因为每个拒绝额外获得一个 AVC。
- selinux=0
- 这个参数会导致内核不载入 SELinux 构架的任意部分。初始化脚本会注意到系统使用
selinux=0
参数引导,并更改/.autorelabel
文件。这会导致系统在下次使用 SELinux enabled 模式引导时自动重新标记。重要红帽不推荐使用selinux=0
参数。要调试您的系统,首选使用 permissive 模式。 - autorelabel=1
- 这个参数强制系统使用类似以下命令的重新标记:
~]# touch /.autorelabel ~]# reboot
如果系统标签包含大量错误,您可能需要以 permissive 模式引导,以便自动标签成功。
checkreqprot
,请查看 /usr/share/doc/kernel-doc-<KERNEL_VER>/Documentation/kernel-parameters.txt
文件。本文档随 kernel-doc 软件包一起安装。使用安装的内核的版本号替换 <KERNEL_VER> 字符串,例如:
~]# yum install kernel-doc ~]$ less /usr/share/doc/kernel-doc-3.10.0/Documentation/kernel-parameters.txt
4.6. 布尔值
4.6.1. 列出布尔值
~]#
semanage boolean -l
SELinux boolean State Default Description
smartmon_3ware (off , off) Determine whether smartmon can...
mpd_enable_homedirs (off , off) Determine whether mpd can traverse...
SELinux 布尔值
列中列出了布尔值名称。Description
列中列出了布尔值是 on 还是 off,以及它们的作用。
~]$
getsebool -a
cvs_read_shadow --> off
daemons_dump_core --> on
~]$
getsebool cvs_read_shadow
cvs_read_shadow --> off
~]$
getsebool cvs_read_shadow daemons_dump_core
cvs_read_shadow --> off
daemons_dump_core --> on
4.6.2. 配置布尔值
setsebool boolean_name on/off
表单中运行 setsebool 实用程序来启用或禁用布尔值。
httpd_can_network_connect_db
布尔值:
过程 4.5. 配置布尔值
- 默认情况下,httpd
_can_network_connect_db
布尔值是 off,阻止 Apache HTTP 服务器脚本和模块连接到数据库服务器:~]$
getsebool httpd_can_network_connect_db httpd_can_network_connect_db --> off - 要临时启用 Apache HTTP 服务器脚本和模块来连接到数据库服务器,以 root 用户身份输入以下命令:
~]#
setsebool httpd_can_network_connect_db on - 使用
getsebool
工具验证该布尔值是否已启用:~]$
getsebool httpd_can_network_connect_db httpd_can_network_connect_db --> on这允许 Apache HTTP 服务器脚本和模块连接到数据库服务器。 - 此更改在重新启动后不会保留。要在重启后保留更改,以 root 用户身份在命令 中运行 setsebool -P boolean-name :[3]
~]#
setsebool -P httpd_can_network_connect_db on
4.6.3. Shell 自动完成
getsebool、setsebool 和
semanage
实用程序使用 shell 自动完成。将自动完成与 getsebool 和
setsebool
一起使用以完成命令行参数和布尔值。要只列出命令行参数,请在命令名称后面添加连字符("-"),然后按 Tab 键 :
~]#
setsebool -[Tab]
-P
~]$
getsebool samba_[Tab]
samba_create_home_dirs samba_export_all_ro samba_run_unconfined
samba_domain_controller samba_export_all_rw samba_share_fusefs
samba_enable_home_dirs samba_portmapper samba_share_nfs
~]#
setsebool -P virt_use_[Tab]
virt_use_comm virt_use_nfs virt_use_sanlock
virt_use_execmem virt_use_rawip virt_use_usb
virt_use_fusefs virt_use_samba virt_use_xserver
semanage
实用程序与多个命令行参数一同使用,这些参数逐个完成。semanage 命令的第一个参数是一个 选项,用于指定管理 SELinux 策略的哪个部分:
~]#
semanage [Tab]
boolean export import login node port
dontaudit fcontext interface module permissive user
~]#
semanage fcontext -[Tab]
-a -D --equal --help -m -o
--add --delete -f -l --modify -S
-C --deleteall --ftype --list -n -t
-d -e -h --locallist --noheading --type
~]#
semanage fcontext -a -t samba<tab>
samba_etc_t samba_secrets_t
sambagui_exec_t samba_share_t
samba_initrc_exec_t samba_unconfined_script_exec_t
samba_log_t samba_unit_file_t
samba_net_exec_t
~]#
semanage port -a -t http_port_t -p tcp 81
4.7. SELinux 上下文 - 标记文件
~]$
ls -Z file1
-rw-rw-r-- user1 group1 unconfined_u:object_r:user_home_t:s0 file1
unconfined_u
)、角色(object_r
)、类型(user_home_t
)和级别(s0)
。此信息用于制定访问控制决策。在 DAC 系统上,访问权限根据 Linux 用户和组群 ID 进行控制。在 DAC 规则后检查 SELinux 策略规则。如果 DAC 规则首先拒绝访问,则不会使用 SELinux 策略规则。
/etc
目录中使用 etc_t
类型创建新文件时,新文件将继承同一类型:
~]$ ls -dZ - /etc drwxr-xr-x. root root system_u:object_r:etc_t:s0 /etc
~]# touch /etc/file1
~]# ls -lZ /etc/file1 -rw-r--r--. root root unconfined_u:object_r:etc_t:s0 /etc/file1
matchpathcon
。
4.7.1. 临时更改:chcon
快速参考
- 运行 chcon -t 类型 file-name 命令更改文件类型,其中 type 是 SELinux 类型,如
httpd_sys_content_t
,file-name 是文件或目录名称:~]$
chcon -t httpd_sys_content_t file-name - 运行 chcon -R -t 类型 directory-name 命令以更改目录及其内容的类型,其中 type 是 SELinux 类型,如
httpd_sys_content_t
,directory-name 是目录名称:~]$
chcon -R -t httpd_sys_content_t directory-name
过程 4.6. 更改文件或目录的类型
file1
是目录。
- 更改到您的主目录。
- 创建新文件并查看其 SELinux 上下文:
~]$
touch file1~]$
ls -Z file1 -rw-rw-r-- user1 group1 unconfined_u:object_r:user_home_t:s0 file1在本例中,file1 的
SELinux 上下文包括 SELinuxunconfined_u
用户、object_r
角色、user_home_t
类型和s0
级别。有关 SELinux 上下文的每个部分的描述,请参阅 第 2 章 SELinux Contexts。 - 输入以下命令将类型更改为
samba_share_t
。t
选项仅更改类型。然后查看更改:~]$
chcon -t samba_share_t file1~]$
ls -Z file1 -rw-rw-r-- user1 group1 unconfined_u:object_r:samba_share_t:s0 file1 - 使用以下命令恢复
file1
文件的 SELinux 上下文。使用-v
选项查看哪些更改:~]$
restorecon -v file1 restorecon reset file1 context unconfined_u:object_r:samba_share_t:s0->system_u:object_r:user_home_t:s0在本例中,上一类型samba_share_t
已恢复到正确的user_home_t
类型。使用目标策略(Red Hat Enterprise Linux 中的默认 SELinux 策略)时,restorecon 命令读取/etc/selinux/targeted/contexts/files/
目录中的文件,以查看应具有哪些 SELinux 上下文文件。
过程 4.7. 更改目录及其内容类型
/var/www/html/
),则使用本示例中的配置:
- 以 root 用户身份,在此目录中创建一个新的
Web/
目录,再创建 3 个空文件(
和file1
、file2file3
)。其中包含的web/
目录和文件使用default_t
类型标记:~]#
mkdir /web~]#
touch /web/file{1,2,3}~]#
ls -dZ /web drwxr-xr-x root root unconfined_u:object_r:default_t:s0 /web~]#
ls -lZ /web -rw-r--r-- root root unconfined_u:object_r:default_t:s0 file1 -rw-r--r-- root root unconfined_u:object_r:default_t:s0 file2 -rw-r--r-- root root unconfined_u:object_r:default_t:s0 file3 - 以 root 用户身份,输入以下命令将
web/
目录(及其内容)的类型改为httpd_sys_content_t
:~]#
chcon -R -t httpd_sys_content_t /web/~]#
ls -dZ /web/ drwxr-xr-x root root unconfined_u:object_r:httpd_sys_content_t:s0 /web/~]#
ls -lZ /web/ -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 file1 -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 file2 -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 file3 - 要恢复默认 SELinux 上下文,以 root 用户身份使用
restorecon
工具程序:~]#
restorecon -R -v /web/ restorecon reset /web context unconfined_u:object_r:httpd_sys_content_t:s0->system_u:object_r:default_t:s0 restorecon reset /web/file2 context unconfined_u:object_r:httpd_sys_content_t:s0->system_u:object_r:default_t:s0 restorecon reset /web/file3 context unconfined_u:object_r:httpd_sys_content_t:s0->system_u:object_r:default_t:s0 restorecon reset /web/file1 context unconfined_u:object_r:httpd_sys_content_t:s0->system_u:object_r:default_t:s0
4.7.2. 持久性更改:semanage fcontext
~]# semanage fcontext -C -l
setfiles
实用程序,并且 restorecon
实用程序恢复默认 SELinux 上下文。这意味着 semanage fcontext 所做的更改是持久的,即使文件系统被重新标记。SELinux 策略控制用户是否能够修改任何给定文件的 SELinux 上下文。
快速参考
- 输入以下命令,记得使用文件或目录的完整路径:
~]#
semanage fcontext -a options file-name|directory-name - 使用
restorecon
程序应用上下文更改:~]#
restorecon -v file-name|directory-name
将正则表达式与 semanage fcontext 搭配使用
PCRE2_DOTALL
,这使得 .
通配符匹配任何内容,包括新行。代表路径的字符串被处理为字节,这意味着非 ASCII 字符不会被单个通配符匹配。
file_contexts.local
中的本地文件上下文修改的优先级高于策略模块。这意味着,每当 file_contexts.local
中找到与给定文件路径的匹配时,不会考虑其他文件上下文定义。
semanage-fcontext(8)手册页
。
过程 4.8. 更改文件或目录的类型
file1
是目录。
- 以 root 用户身份,在
/etc
目录中创建一个新文件。默认情况下,/etc
中新创建的文件使用etc_t
类型标记:~]#
touch /etc/file1~]$
ls -Z /etc/file1 -rw-r--r-- root root unconfined_u:object_r:etc_t:s0 /etc/file1要列出有关目录的信息,请使用以下命令:~]$
ls -dZ directory_name - 以 root 身份,输入以下命令将
file1
类型更改为samba_share_t
。a选项
添加新记录,而-t 选项则
定义类型(samba_share_t
)。请注意,运行这个命令不会直接更改类型;file1
仍然使用etc_t
类型进行标记:~]#
semanage fcontext -a -t samba_share_t /etc/file1~]#
ls -Z /etc/file1 -rw-r--r-- root root unconfined_u:object_r:etc_t:s0 /etc/file1~]$ semanage fcontext -C -l /etc/file1 unconfined_u:object_r:samba_share_t:s0
- 以 root 用户身份,使用
restorecon
实用程序更改类型。因为semanage
向/etc/file1
的 file_contexts.local
中添加了一个条目,所以restorecon
会将类型改为samba_share_t
:~]#
restorecon -v /etc/file1 restorecon reset /etc/file1 context unconfined_u:object_r:etc_t:s0->system_u:object_r:samba_share_t:s0
过程 4.9. 更改目录及其内容类型
/var/www/html/
,则使用这个示例中的配置:
- 以 root 用户身份,在此目录中创建一个新的
Web/
目录,再创建 3 个空文件(
和file1
、file2file3
)。其中包含的web/
目录和文件使用default_t
类型标记:~]#
mkdir /web~]#
touch /web/file{1,2,3}~]#
ls -dZ /web drwxr-xr-x root root unconfined_u:object_r:default_t:s0 /web~]#
ls -lZ /web -rw-r--r-- root root unconfined_u:object_r:default_t:s0 file1 -rw-r--r-- root root unconfined_u:object_r:default_t:s0 file2 -rw-r--r-- root root unconfined_u:object_r:default_t:s0 file3 - 以 root 身份,输入以下命令将
web/
目录的类型及其文件更改为httpd_sys_content_t
。a选项
添加新记录,-t
选项定义类型(httpd_sys_content_t
)。"/web(/.*)?"
正则表达式会导致semanage
对web/
以及其中的文件应用更改。请注意,运行这个命令不会直接更改类型;其中的web/
和文件仍使用default_t
类型进行标记:~]#
semanage fcontext -a -t httpd_sys_content_t "/web(/.*)?"~]$
ls -dZ /web drwxr-xr-x root root unconfined_u:object_r:default_t:s0 /web~]$
ls -lZ /web -rw-r--r-- root root unconfined_u:object_r:default_t:s0 file1 -rw-r--r-- root root unconfined_u:object_r:default_t:s0 file2 -rw-r--r-- root root unconfined_u:object_r:default_t:s0 file3semanage fcontext -a -t httpd_sys_content_t "/web(/.*)?" 命令将以下条目添加到/etc/selinux/targeted/contexts/files/file_contexts.local
中:/web(/.*)? system_u:object_r:httpd_sys_content_t:s0
- 以 root 用户身份,使用
restorecon
实用程序更改web/
的类型,以及其中的所有文件。r 用于递归,这意味着web/
下的所有文件和目录都标有
httpd_sys_content_t
类型。因为semanage
向file.contexts.local
为/web(/.*)?
添加了一个条目,所以restorecon
将类型改为httpd_sys_content_t
:~]#
restorecon -R -v /web restorecon reset /web context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0 restorecon reset /web/file2 context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0 restorecon reset /web/file3 context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0 restorecon reset /web/file1 context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0请注意,默认情况下,新创建的文件和目录继承其父目录的 SELinux 类型。
过程 4.10. 删除添加的上下文
/web(/.*)?
,请在正则表达式两处使用引号:
~]#
semanage fcontext -d "/web(/.*)?"
- 要删除上下文,请输入以下命令,其中 file-name |directory-name 是
file_contexts.local
中的第一个部分:~]#
semanage fcontext -d file-name|directory-name以下是file_contexts.local
中的上下文示例:/test system_u:object_r:httpd_sys_content_t:s0
第一部分被测试
。要在运行 restorecon 后,或文件系统重新标记后,要防止test/
目录被标记为httpd_sys_content_t
,请以 root 身份输入以下命令从file_contexts.local 中删除
上下文:~]#
semanage fcontext -d /test - 以 root 用户身份,使用
restorecon
实用程序恢复默认 SELinux 上下文。
4.7.3. 如何确定文件上下文
.fc
文件)。根据系统策略,semanage
生成 file_contexts.homedirs
和 file_contexts
文件。
file_contexts.local
文件中。
matchpathcon
或 restorecon)
确定给定路径的正确标签时,它会首先搜索本地更改(file_contexts.local
)。如果实用程序找不到匹配的模式,它将搜索 file_contexts.homedirs
文件,最后搜索 file_contexts
文件。但是,每当找到与给定文件路径的匹配项时,搜索结束时,实用程序会查找任何其他文件上下文定义。这意味着与主目录相关的文件上下文的优先级高于其余的优先级,本地自定义会覆盖系统策略。
系统策略
指定的 文件上下文定义(file_contexts.homedir s 和
file_contexts
文件的内容)按照句子长度(在任意通配符之前修复路径前缀)进行排序。这意味着选择最具体的路径。但是,使用 semanage fcontext 指定的文件上下文定义按照其定义方式顺序进行反序评估:最新的条目首先评估,而不考虑时间长度。
- 使用
chcon
更改文件的上下文,请参阅 第 4.7.1 节 “临时更改:chcon”。 - 使用 semanage fcontext 更改并添加文件上下文定义,请参阅 第 4.7.2 节 “持久性更改:semanage fcontext”。
- 通过 system-policy 操作更改并添加文件上下文定义,请参阅 第 4.10 节 “维护 SELinux 标签” 或 第 4.12 节 “优先处理和禁用 SELinux 策略模块”。
4.8. file_t 和 default_t 类型
的文件系统时,file_t
类型是尚未分配 EA 值的默认文件类型。这个类型仅用于此目的,且在正确标记的文件系统中不存在,因为运行 SELinux 的系统上的所有文件都应具有适当的 SELinux 上下文,并且 file_t
类型永远不会在文件上下文配置中使用[4].
default_t
类型用于与 file-context 配置中任何模式不匹配的文件,以便这些文件能够与磁盘上没有上下文的文件区分,并且通常对受限制的域无法访问。例如,如果您创建新的顶级目录,如 mydirectory/
,则可以使用 default_t 类型标记此目录。如果服务需要访问此目录,您需要更新此位置的 file-contexts 配置。有关在 file-context 配置中添加上下文的详情,请查看 第 4.7.2 节 “持久性更改:semanage fcontext”。
/etc/selinux/targeted/contexts/files/
目录中的文件定义了文件和目录的上下文。restorecon
读取此目录中的文件,并将 文件实用程序设置为将
文件和目录恢复到其默认上下文。
4.9. 挂载文件系统
context 选项指定的上下文
不会写入磁盘:原始上下文将被保留,如果文件系统最初具有扩展属性,则在不带 上下文
挂载时会看到。
4.9.1. 上下文挂载
nfs_t
类型。如果不使用其他挂载选项,这可能会阻止使用其他服务(如 Apache HTTP 服务器)共享 NFS 卷。以下示例挂载了 NFS 卷,以便可以使用 Apache HTTP 服务器进行共享:
~]#
mount server:/export /local/mount/point -o \ context="system_u:object_r:httpd_sys_content_t:s0"
-o 上下文指定的 SELinux 上下文
。但是,由于这些更改不会写入磁盘,因此使用此选项指定的上下文不会在挂载之间保留。因此,这个选项必须与每个挂载中指定的相同上下文一起使用,以保持所需的上下文。有关使上下文挂载持久的更多信息,请参阅 第 4.9.5 节 “使上下文挂载持久”。
-o 上下文覆盖 SELinux 上下文时,
请使用 SELinux system_u
用户和 object_r
角色,并专注于类型。如果您不使用 MLS 策略或多类别安全性,请使用 s0
级别。
上下文
选项挂载文件系统时,禁止用户和进程进行上下文更改。例如,在通过 上下文
选项挂载的文件系统中运行 chcon 命令会导致 Operation not supported
错误。
4.9.2. 更改默认上下文
file_t
类型。如果需要使用其他默认上下文,请使用 defcontext
选项挂载文件系统。
/dev/sda2
上新创建的文件系统挂载到新创建的 test/
目录。它假设 /etc/selinux/targeted/contexts/files/
中没有为 test/
目录定义上下文的规则:
~]#
mount /dev/sda2 /test/ -o defcontext="system_u:object_r:samba_share_t:s0"
- 挂载后,文件系统
的根目录(test/
)将被视为使用defcontext
指定的上下文标记(此标签不存储在磁盘上)。这会影响test/
下创建文件的标签:新文件继承samba_share_t
类型,这些标签存储在磁盘上。 - 当使用
defcontext
选项挂载文件系统时,在test/
下创建的文件保留其标签。
4.9.3. 挂载 NFS 卷
nfs_t
类型。根据策略配置,Apache HTTP 服务器和 MariaDB 等服务可能无法读取使用 nfs_t
类型标记的文件。这可能会导致标记为此类型的文件系统被挂载,然后被其他服务读取或导出。
上下文
选项来覆盖 nfs_t
类型。使用以下上下文选项挂载 NFS 卷,以便可以使用 Apache HTTP 服务器共享它们:
~]#
mount server:/export /local/mount/point -o context="system_u:object_r:httpd_sys_content_t:s0"
上下文
选项挂载文件系统外,也可启用布尔值,以允许服务访问使用 nfs_t
类型标记的文件系统。有关配置布尔值以允许服务访问 nfs_t
类型的步骤,请参阅 第 II 部分 “管理受限服务”。
4.9.4. 多个 NFS 挂载
导出/
,它有两个子目录 web/
和 database/
。以下命令尝试从一个 NFS 导出中尝试两个挂载,并尝试覆盖每个导出的上下文:
~]#
mount server:/export/web /local/web -o context="system_u:object_r:httpd_sys_content_t:s0"
~]#
mount server:/export/database /local/database -o context="system_u:object_r:mysqld_db_t:s0"
/var/log/messages
:
kernel: SELinux: mount invalid. Same superblock, different security settings for (dev 0:15, type nfs)
-o nosharecache,context
选项。以下示例从单个 NFS 导出挂载多个挂载,每个挂载都有不同的上下文(允许单个服务访问每个导出):
~]#
mount server:/export/web /local/web -o nosharecache,context="system_u:object_r:httpd_sys_content_t:s0"
~]#
mount server:/export/database /local/database -o \ nosharecache,context="system_u:object_r:mysqld_db_t:s0"
:/export/web
在本地挂载到 /local/web/
目录,所有文件都使用 httpd_sys_content_t
类型进行标记,允许 Apache HTTP 服务器访问。server:/export/database
在本地挂载到 /local/database/
,所有文件都被标记为 mysqld_db_t
类型,允许 MariaDB 访问。这些类型更改不会写入磁盘。
nosharecache
选项允许您多次挂载具有不同上下文的导出同一子目录,例如多次挂载 /export/web/
。不要多次使用不同的上下文从导出中挂载同一子目录,因为这会产生重叠挂载,其中文件可在两个不同的上下文下访问。
4.9.5. 使上下文挂载持久
/etc/fstab
文件或自动挂载程序映射中添加文件系统条目,并使用所需的上下文作为挂载选项。以下示例为 NFS 上下文挂载在 /etc/fstab
中添加一个条目:
server:/export /local/mount/ nfs context="system_u:object_r:httpd_sys_content_t:s0" 0 0
4.10. 维护 SELinux 标签
4.10.1. 复制文件和目录
user_home_t
类型进行标记:
~]$
touch file1
~]$
ls -Z file1
-rw-rw-r-- user1 group1 unconfined_u:object_r:user_home_t:s0 file1
/etc
,则根据 /etc
的默认标记规则创建新文件。在没有附加选项的情况下复制文件可能无法保留原始上下文:
~]$
ls -Z file1
-rw-rw-r-- user1 group1 unconfined_u:object_r:user_home_t:s0 file1
~]#
cp file1 /etc/
~]$
ls -Z /etc/file1
-rw-r--r-- root root unconfined_u:object_r:etc_t:s0 /etc/file1
file1
复制到 /etc
时,如果 /etc/file1
不存在,则创建 /etc/file1
作为新文件。如上例所示,根据 default-labeling 规则,/etc/file1
使用 etc_t
类型进行标记。
--preserve=context
。SELinux 策略可能会阻止在复制期间保留上下文。
过程 4.11. 在不保留 SELinux 上下文的情况下复制
- 在用户的主目录中创建文件。该文件使用
user_home_t
类型标记:~]$
touch file1~]$
ls -Z file1 -rw-rw-r-- user1 group1 unconfined_u:object_r:user_home_t:s0 file1 /var/www/html/
目录使用httpd_sys_content_t
类型标记,如下所示:~]$
ls -dZ /var/www/html/ drwxr-xr-x root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/- 将
file1
复制到/var/www/html/
时,它会继承httpd_sys_content_t
类型:~]#
cp file1 /var/www/html/~]$
ls -Z /var/www/html/file1 -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/file1
过程 4.12. 复制时保留 SELinux 上下文
--preserve=context
选项来保留上下文。
- 在用户的主目录中创建文件。该文件使用
user_home_t
类型标记:~]$
touch file1~]$
ls -Z file1 -rw-rw-r-- user1 group1 unconfined_u:object_r:user_home_t:s0 file1 /var/www/html/
目录使用httpd_sys_content_t
类型标记,如下所示:~]$
ls -dZ /var/www/html/ drwxr-xr-x root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/- 使用
--preserve=context
选项可在复制操作期间保留 SELinux 上下文。如下所示,文件复制到
类型:/var/www/html/
时保留user_home_t
的文件1~]#
cp --preserve=context file1 /var/www/html/~]$
ls -Z /var/www/html/file1 -rw-r--r-- root root unconfined_u:object_r:user_home_t:s0 /var/www/html/file1
过程 4.13. 复制和更改上下文
--context
选项更改目标副本的上下文。以下示例在用户的主目录中执行:
- 在用户的主目录中创建文件。该文件使用
user_home_t
类型标记:~]$
touch file1~]$
ls -Z file1 -rw-rw-r-- user1 group1 unconfined_u:object_r:user_home_t:s0 file1 - 使用
--context
选项来定义 SELinux 上下文:~]$
cp --context=system_u:object_r:samba_share_t:s0 file1 file2 - 如果没有
--context
,file2
将使用unconfined_u:object_r:user_home_t
上下文标记:~]$
ls -Z file1 file2 -rw-rw-r-- user1 group1 unconfined_u:object_r:user_home_t:s0 file1 -rw-rw-r-- user1 group1 system_u:object_r:samba_share_t:s0 file2
过程 4.14. 使用现有文件复制文件
- 以 root 用户身份,在
/etc
目录中创建一个新文件 file1
。如下所示,该文件使用etc_t
类型进行标记:~]#
touch /etc/file1~]$
ls -Z /etc/file1 -rw-r--r-- root root unconfined_u:object_r:etc_t:s0 /etc/file1 - 在
/tmp
目录中创建另一个文件 file2
。如下所示,该文件使用user_tmp_t
类型进行标记:~]$
touch /tmp/file2~$
ls -Z /tmp/file2 -rw-r--r-- root root unconfined_u:object_r:user_tmp_t:s0 /tmp/file2 - 使用
file
:2 覆盖 file
1~]#
cp /tmp/file2 /etc/file1 - 复制后,以下命令显示使用
etc_t
类型标记的file1
,而不是替换 /etc/file1
的/tmp/file2
中的user_tmp_t
类型:~]$
ls -Z /etc/file1 -rw-r--r-- root root unconfined_u:object_r:etc_t:s0 /etc/file1
4.10.2. 移动文件和目录
/var/www/html/
目录,供 Apache HTTP 服务器使用。因为文件被移动,所以不会继承正确的 SELinux 上下文:
过程 4.15. 移动文件和目录
- 更改到您的主目录,并在其中创建文件。该文件使用
user_home_t
类型标记:~]$
touch file1~]$
ls -Z file1 -rw-rw-r-- user1 group1 unconfined_u:object_r:user_home_t:s0 file1 - 输入以下命令查看
/var/www/html/
目录的 SELinux 上下文:~]$
ls -dZ /var/www/html/ drwxr-xr-x root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/默认情况下,/var/www/html/
被标记为httpd_sys_content_t
类型。在/var/www/html/
下创建的文件和目录继承此类型,因此,它们使用此类型进行标记。 - 以 root 身份,将
file1
移到/var/www/html/
。因为这个文件被移动,它会保留当前的user_home_t
类型:~]#
mv file1 /var/www/html/~]#
ls -Z /var/www/html/file1 -rw-rw-r-- user1 group1 unconfined_u:object_r:user_home_t:s0 /var/www/html/file1
user_home_t
类型的文件。如果组成 Web 页面的所有文件都标有 user_home_t
类型,或者 Apache HTTP 服务器无法读取的其他类型,则尝试使用 Web 浏览器(如 Mozilla Firefox )访问它们时将拒绝权限。
4.10.3. 检查默认 SELinux 上下文
matchpathcon
实用程序检查文件和目录是否有正确的 SELinux 上下文。此实用程序查询 系统策略
,然后提供与文件路径关联的默认安全性上下文。[6] 以下示例演示了使用 matchpathcon 验证 /var/www/html/
目录中的文件是否已正确标记:
过程 4.16. 使用 matchpathcon
检查默认 SELinux Conxtext
- 以 root 用户身份,在
/var/www/html/
目录中创建三个文件(file1
、file2
和 file3/var/www/html/
中的httpd_sys_content_t
类型:~]#
touch /var/www/html/file{1,2,3}~]#
ls -Z /var/www/html/ -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 file1 -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 file2 -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 file3 - 以 root 身份,将
file1
类型更改为samba_share_t
。请注意,Apache HTTP 服务器无法读取标有samba_share_t
类型的文件或目录。~]#
chcon -t samba_share_t /var/www/html/file1 matchpathcon
-V
选项可将当前 SELinux 上下文与 SELinux 策略中正确的默认上下文进行比较。输入以下命令检查/var/www/html/
目录中的所有文件:~]$
matchpathcon -V /var/www/html/* /var/www/html/file1 has context unconfined_u:object_r:samba_share_t:s0, should be system_u:object_r:httpd_sys_content_t:s0 /var/www/html/file2 verified. /var/www/html/file3 verified.
file1
被标记为 samba_share_t
类型,但应使用 httpd_sys_content_t
类型进行标记:
/var/www/html/file1 has context unconfined_u:object_r:samba_share_t:s0, should be system_u:object_r:httpd_sys_content_t:s0
file1
,请使用 restorecon
实用程序:
~]#
restorecon -v /var/www/html/file1
restorecon reset /var/www/html/file1 context unconfined_u:object_r:samba_share_t:s0->system_u:object_r:httpd_sys_content_t:s0
4.10.4. 使用 tar
归档文件
tar
实用程序不保留扩展属性。由于 SELinux 上下文存储在扩展属性中,因此存档文件时可能会丢失上下文。使用 tar --selinux 命令创建保留上下文的归档并从存档中恢复文件。如果 tar
归档包含没有扩展属性的文件,或者您希望扩展属性与系统默认值匹配,请使用 restorecon
工具:
~]$
tar -xvf archive.tar | restorecon -f -
restorecon
。
tar
归档:
过程 4.17. 创建 tar 归档
- 进入
/var/www/html/
目录并查看其 SELinux 上下文:~]$
cd /var/www/html/html]$
ls -dZ /var/www/html/ drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 . - 以 root 用户身份,在
/var/www/html/
中创建三个文件(file1
、file2
和 file3/var/www/html/
中的httpd_sys_content_t
类型:html]#
touch file{1,2,3}html]$
ls -Z /var/www/html/ -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 file1 -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 file2 -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 file3 - 以 root 身份,输入以下命令创建名为
test.tar
的tar
存档。使用--selinux
保留 SELinux 上下文:html]#
tar --selinux -cf test.tar file{1,2,3} - 以 root 用户身份,创建一个名为
test/
的新目录,然后允许所有用户对其进行完全访问:~]#
mkdir /test~]#
chmod 777 /test/ - 将
test.tar
文件复制到test/
中:~]$
cp /var/www/html/test.tar /test/ - 更改到
test/
目录。在该目录中后,输入以下命令提取tar
存档。再次指定--selinux
选项,否则 SELinux 上下文将更改为default_t
:~]$
cd /test/test]$
tar --selinux -xvf test.tar - 查看 SELinux 上下文。
httpd_sys_content_t
类型已被保留,而不是更改为default_t
,如果--selinux
没有被使用,这会发生这样的情况:test]$
ls -lZ /test/ -rw-r--r-- user1 group1 unconfined_u:object_r:httpd_sys_content_t:s0 file1 -rw-r--r-- user1 group1 unconfined_u:object_r:httpd_sys_content_t:s0 file2 -rw-r--r-- user1 group1 unconfined_u:object_r:httpd_sys_content_t:s0 file3 -rw-r--r-- user1 group1 unconfined_u:object_r:default_t:s0 test.tar - 如果不再需要
test/
目录,以 root 用户身份输入以下命令删除它,以及其中的所有文件:~]#
rm -ri /test/
tar
的详情请参考 tar(1) 手册页,如保留所有扩展属性的 --xattrs
选项。
4.10.5. 使用 星级
归档文件
实用程序
不保留扩展属性。由于 SELinux 上下文存储在扩展属性中,因此存档文件时可能会丢失上下文。使用 星 -xattr -H=exustar 命令创建保留上下文的存档。默认情况下不安装 星级 软件包。要安装 星形,请以 root 用户身份运行 yum install star 命令。
的星级
归档:
过程 4.18. 创建 星级
存档
- 以 root 用户身份,在
/var/www/html/
中创建三个文件(file1
、file2
和 file3/var/www/html/
中的httpd_sys_content_t
类型:~]#
touch /var/www/html/file{1,2,3}~]#
ls -Z /var/www/html/ -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 file1 -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 file2 -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 file3 - 更改到
/var/www/html/
目录。在这个目录中,以 root 身份输入以下命令来创建一个名为test.star
的星
级存档:~]$
cd /var/www/htmlhtml]#
star -xattr -H=exustar -c -f=test.star file{1,2,3} star: 1 blocks + 0 bytes (total of 10240 bytes = 10.00k). - 以 root 用户身份,创建一个名为
test/
的新目录,然后允许所有用户对其进行完全访问:~]#
mkdir /test~]#
chmod 777 /test/ - 输入以下命令将
test.star 文件复制到 test
/
中:~]$
cp /var/www/html/test.star /test/ - 更改为
test/
。在这个目录中后,输入以下命令提取星级
归档:~]$
cd /test/test]$
star -x -f=test.star star: 1 blocks + 0 bytes (total of 10240 bytes = 10.00k). - 查看 SELinux 上下文。
httpd_sys_content_t
类型已被保留,而不是更改为default_t
,如果未使用-xattr -H=exustar
选项,则会发生这种情况:~]$
ls -lZ /test/ -rw-r--r-- user1 group1 unconfined_u:object_r:httpd_sys_content_t:s0 file1 -rw-r--r-- user1 group1 unconfined_u:object_r:httpd_sys_content_t:s0 file2 -rw-r--r-- user1 group1 unconfined_u:object_r:httpd_sys_content_t:s0 file3 -rw-r--r-- user1 group1 unconfined_u:object_r:default_t:s0 test.star - 如果不再需要
test/
目录,以 root 用户身份输入以下命令删除它,以及其中的所有文件:~]#
rm -ri /test/ - 如果不再需要
星号
,请以 root 用户身份删除软件包:~]#
yum remove star
星号
的详情,请查看 star(1) 手册页。
4.11. 收集工具的信息
avcstat
/sys/fs/selinux/avc/cache_stats
,您可以使用 -f /path/to/file
选项指定不同的缓存文件。
~]#
avcstat
lookups hits misses allocs reclaims frees
47517410 47504630 12780 12780 12176 12275
seinfo
info
是使用 policy.conf
文件、二进制策略文件、模块列表或策略列表作为输入的命令行实用程序。您必须安装 setools-console 软件包才能使用 seinfo
工具程序。
seinfo 的
输出结果会因二进制和源文件而异。例如,策略源文件使用 { }
方括号将多个规则元素分组到一行中。个属性也会产生类似的效果,其中单个属性可扩展到一个或多个类型。由于这些已扩展且在二进制策略文件中不再相关,因此搜索结果中的返回值为零。但是,规则数量会显著增加,因为每个之前使用方括号的行规则现在是多个单独的行。
~]#
seinfo
Statistics for policy file: /sys/fs/selinux/policy
Policy Version & Type: v.28 (binary, mls)
Classes: 77 Permissions: 229
Sensitivities: 1 Categories: 1024
Types: 3001 Attributes: 244
Users: 9 Roles: 13
Booleans: 158 Cond. Expr.: 193
Allow: 262796 Neverallow: 0
Auditallow: 44 Dontaudit: 156710
Type_trans: 10760 Type_change: 38
Type_member: 44 Role allow: 20
Role_trans: 237 Range_trans: 2546
Constraints: 62 Validatetrans: 0
Initial SIDs: 27 Fs_use: 22
Genfscon: 82 Portcon: 373
Netifcon: 0 Nodecon: 0
Permissives: 22 Polcap: 2
seinfo
工具还可使用 domain 属性列出类型数量,从而估算不同受限制的进程数量:
~]#
seinfo -adomain -x | wc -l
550
unconfined_domain
属性:
~]#
seinfo -aunconfined_domain_type -x | wc -l
52
--permissive
选项计算 permissive 域:
~]#
seinfo --permissive -x | wc -l
31
sesearch
sesearch
实用程序搜索策略中的特定规则。可以搜索策略源文件或二进制文件。例如:
~]$
sesearch --role_allow -t httpd_sys_content_t
Found 20 role allow rules:
allow system_r sysadm_r;
allow sysadm_r system_r;
allow sysadm_r staff_r;
allow sysadm_r user_r;
allow system_r git_shell_r;
allow system_r guest_r;
allow logadm_r system_r;
allow system_r logadm_r;
allow system_r nx_server_r;
allow system_r staff_r;
allow staff_r logadm_r;
allow staff_r sysadm_r;
allow staff_r unconfined_r;
allow staff_r webadm_r;
allow unconfined_r system_r;
allow system_r unconfined_r;
allow system_r user_r;
allow webadm_r system_r;
allow system_r webadm_r;
allow system_r xguest_r;
sesearch
工具可以提供 允许 规则的数量:
~]#
sesearch --allow | wc -l
262798
~]#
sesearch --dontaudit | wc -l
156712
4.12. 优先处理和禁用 SELinux 策略模块
/etc/selinux/ 中的
SELinux 模块存储允许对 SELinux 模块使用优先级。以 root 用户身份输入以下命令显示两个具有不同优先级的模块目录:
~]#
ls /etc/selinux/targeted/active/modules
100 400 disabled
例 4.1. 使用 SELinux 策略模块优先级
sandbox.pp
。
~]#
semodule -X 400 -i sandbox.pp~]#
semodule --list-modules=full | grep sandbox 400 sandbox pp 100 sandbox pp
~]#
semodule -X 400 -r sandbox
libsemanage.semanage_direct_remove_key: sandbox module at priority 100 is now active.
禁用系统策略模块
系统策略
模块,以 root 用户身份输入以下命令:
semodule -d MODULE_NAME
系统策略
模块,它会在您的系统存储上删除,您无法再次载入它。为避免不必要的重新安装 selinux-policy-targeted 软件包来恢复 所有系统策略
模块,请使用 semodule -d 命令。
4.13. 多级别安全(MLS)
图 4.1. 国家级别
[D]
图 4.2. 使用 MLS 允许的数据流
[D]
4.13.1. MLS 和系统特权
4.13.2. 在 SELinux 中启用 MLS
过程 4.19. 启用 SELinux MLS 策略
- 安装 selinux-policy-mls 软件包:
~]#
yum install selinux-policy-mls - 在启用 MLS 策略之前,必须使用 MLS 标签重新标记文件系统中的每个文件。重新标记文件系统时,可能会拒绝访问受限域,这可能会妨碍系统正确启动。要防止发生这种情况,请在
/etc/selinux/config
文件中配置SELINUX=permissive
。另外,通过配置SELINUXTYPE=mls
来启用 MLS 策略。您的配置文件应如下所示:# 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=permissive # SELINUXTYPE= can take one of these two values: # targeted - Targeted processes are protected, # mls - Multi Level Security protection. SELINUXTYPE=mls
- 确保 SELinux 以 permissive 模式运行:
~]#
setenforce 0~]$
getenforce Permissive - 使用 fixfiles 脚本创建包含
-F
选项的/.autorelabel
文件,以确保在下次重启时重新标记文件:~]#
fixfiles -F onboot - 重启您的系统。在下一次启动期间,将根据 MLS 策略重新标记所有文件系统。标签进程使用适当的 SELinux 上下文标记所有文件:
*** Warning -- SELinux mls policy relabel is required. *** Relabeling could take a very long time, depending on file *** system size and speed of hard drives. ***********
底部行中的每个*(星
号)字符表示 1000 个已标记的文件。在上面的示例中,十一*
字符代表 11000 个已标记的文件。标记所有文件所需的时间取决于系统上的文件数量以及硬盘驱动器的速度。在现代系统中,此过程只需 10 分钟。标签过程完成后,系统将自动重新引导。 - 在 permissive 模式中,SELinux 策略不会被强制实施,但是仍会记录在 enforcing 模式运行时会被拒绝的操作。在更改为 enforcing 模式之前,以 root 身份输入以下命令,以确认 SELinux 在上一次启动期间没有拒绝操作。如果在上一次启动期间 SELinux 没有拒绝操作,这个命令不会返回任何输出。如果在引导过程中 SELinux 拒绝访问,请参阅 第 11 章 故障排除。
~]#
grep "SELinux is preventing" /var/log/messages - 如果
/var/log/messages
文件中没有拒绝信息,或者您已解决所有现有的拒绝,请在/etc/selinux/config
文件中配置SELINUX=enforcing
:# 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=mls
- 重启您的系统并确保 SELinux 以 enforcing 模式运行:
~]$
getenforce Enforcing启用了 MLS 策略:~]#
sestatus |grep mls Policy from config file: mls
4.13.3. 使用特定 MLS 范围创建用户
过程 4.20. 使用特定 MLS 范围创建用户
- 使用 useradd 命令添加新的 Linux 用户,并将新的 Linux 用户映射到现有 SELinux 用户(本例中为
staff_u
):~]#
useradd -Z staff_u john - 为新创建的 Linux 用户分配密码:
prompt~]# passwd john
- 以 root 身份输入以下命令,以查看 SELinux 和 Linux 用户之间的映射。输出应如下:
~]#
semanage login -l Login Name SELinux User MLS/MCS Range Service __default__ user_u s0-s0 * john staff_u s0-s15:c0.c1023 * root root s0-s15:c0.c1023 * staff staff_u s0-s15:c0.c1023 * sysadm staff_u s0-s15:c0.c1023 * system_u system_u s0-s15:c0.c1023 * - 为用户
john
定义一个特定范围:~]#
semanage login --modify --range s2:c100 john - 再次查看 SELinux 和 Linux 用户之间的映射。请注意,用户
john
现在定义了特定的 MLS 范围:~]#
semanage login -l Login Name SELinux User MLS/MCS Range Service __default__ user_u s0-s0 * john staff_u s2:c100 * root root s0-s15:c0.c1023 * staff staff_u s0-s15:c0.c1023 * sysadm staff_u s0-s15:c0.c1023 * system_u system_u s0-s15:c0.c1023 * - 如果需要,请输入以下命令更正 john 主目录中的标签:
~]#
chcon -R -l s2:c100 /home/john
4.13.4. 设置 Polyinstantiated 目录
/tmp
和 /var/tmp/
目录通常由所有程序、服务和用户用于临时存储。但是,此类设置使得这些目录容易遭受竞争条件攻击,或者存在基于文件名的信息泄漏。SELinux 以 多形目录 的形式提供解决方案。这实际上意味着 /tmp 和 /
var/tmp/
都已实例化,使其对于每个用户都是私有的。启用目录实例化时,每个用户的 /tmp 和 /var/tmp
/
目录都会自动挂载到 /tmp-inst
和 /var/tmp/tmp-inst
下。
过程 4.21. 启用 Polyinstantiation 目录
- 取消注释
/etc/security/namespace.conf
文件中的最后三行,以启用/tmp
、/var/tmp/
和用户主目录的实例化:~]$
tail -n 3 /etc/security/namespace.conf /tmp /tmp-inst/ level root,adm /var/tmp /var/tmp/tmp-inst/ level root,adm $HOME $HOME/$USER.inst/ level - 在
/etc/pam.d/login
文件中确保为会话配置了pam_namespace.so
模块:~]$
grep namespace /etc/pam.d/login session required pam_namespace.so - 重启您的系统。
4.14. 文件名称转换
A_t
的进程在标有 B_t
的目录中创建指定对象类,并且指定的对象类名为 objectname
,它会获取标签 C_t
。这种机制可以更加精细地控制系统上的进程。
- 默认情况下,对象从父目录继承标签。例如,如果用户在标有
etc_t
的目录中创建文件,则该文件也会被标记etc_t
。但是,当需要在具有不同标签的目录中有多个文件时,此方法没有用处。 - 策略写入器可以在策略中编写一个规则,声明如下:如果类型为
A_t
的进程在标有B_t
的目录中创建指定对象类,则对象会获得新的C_t
标签。如果单个程序在同一目录中创建多个对象,每个对象需要单独的标签,则这种方法存在问题。此外,这些规则仅提供部分控制,因为未指定创建的对象的名称。 - 某些应用程序具有 SELinux 感知,允许此类应用程序询问系统特定路径的标签是什么。这些应用程序随后请求内核使用所需标签创建对象。识别 SELinux 的应用程序示例有 rpm 软件包管理器、restorecon 实用程序或 udev 设备管理器。但是,不能指示创建 SELinux 感知文件或目录的每个应用程序。通常需要在创建后使用正确的标签重新标记对象。否则,当受限域尝试使用该对象时,将返回 AVC 消息。
strcmp()
功能完成的完全匹配。不考虑使用正则表达式或通配符字符。
例 4.2. 使用文件名转换的策略规则编写示例
filetrans_pattern(unconfined_t, admin_home_t, ssh_home_t, dir, ".ssh")
unconfined_t
类型的进程在标有 admin_home_t
的目录中创建 ~/.ssh/
目录,则 ~/.ssh/
目录会获得标签 ssh_home_t
。
filetrans_pattern(staff_t, user_home_dir_t, httpd_user_content_t, dir, "public_html") filetrans_pattern(thumb_t, user_home_dir_t, thumb_home_t, file, "missfont.log") filetrans_pattern(kernel_t, device_t, xserver_misc_device_t, chr_file, "nvidia0") filetrans_pattern(puppet_t, etc_t, krb5_conf_t, file, "krb5.conf")
4.15. 禁用 ptrace()
ptrace()
系统调用允许一个进程观察和控制另一个进程的执行并更改其内存和寄存器。此调用主要供开发人员在调试期间使用,例如在使用 strace
实用程序时。不需要 ptrace()
时,可以禁用它来提高系统安全性。这可以通过启用 deny_ptrace
布尔值(拒绝在 unconfined_t
域中运行的进程)对其他进程使用 ptrace()
来完成。
deny_ptrace
布尔值默认为禁用。要启用它,以 root 用户身份在命令 中运行 setsebool -P deny_ptrace:
~]#
setsebool -P deny_ptrace on
~]$
getsebool deny_ptrace
deny_ptrace --> on
~]#
setsebool -P deny_ptrace off
-P
选项。
ptrace()
系统调用。要列出允许使用 ptrace()的
域,请输入以下命令。请注意,setools-console 软件包提供了 sesearch
实用程序,并且默认情况下未安装该软件包。
~]#
sesearch -A -p ptrace,sys_ptrace -C | grep -v deny_ptrace | cut -d ' ' -f 5
4.16. 缩略图保护
- /usr/bin/evince-thumbnailer
- /usr/bin/ffmpegthumbnailer
- /usr/bin/gnome-exe-thumbnailer.sh
- /usr/bin/gnome-nds-thumbnailer
- /usr/bin/gnome-xcf-thumbnailer
- /usr/bin/gsf-office-thumbnailer
- /usr/bin/raw-thumbnailer
- /usr/bin/shotwell-video-thumbnailer
- /usr/bin/totem-video-thumbnailer
- /usr/bin/whaaw-thumbnailer
- /usr/lib/tumbler-1/tumblerd
- /usr/lib64/tumbler-1/tumblerd
第 5 章 sepolicy
Suite
sepolicy
实用程序提供了一组查询已安装的 SELinux 策略的功能。这些功能是新的,或者之前由单独的实用程序(如 sepolgen 或 se
trans
)提供的。该套件允许您生成转换报告、man page 甚至新的策略模块,从而使用户能够更轻松地访问并更好地了解 SELinux 策略。
sepolicy
。以 root 用户身份输入以下命令安装 sepolicy
:
~]#
yum install policycoreutils-devel
sepolicy
套件提供以下作为命令行参数调用的功能:
表 5.1. sepolicy
功能
功能 | 描述 |
---|---|
布尔值 | 查询 SELinux 策略以查看布尔值的描述 |
通信 | 查询 SELinux 策略以查看域是否可以相互通信 |
generate | 生成 SELinux 策略模块模板 |
gui | SELinux 策略的图形用户界面 |
interface | 列出 SELinux 策略接口 |
manpage | 生成 SELinux man page |
network | 查询 SELinux 策略网络信息 |
transition | 查询 SELinux 策略并生成进程转换报告 |
5.1. sepolicy
Python Bindings
sesearch
和 seinfo
实用程序。sesearch
实用程序用于在 SELinux 策略中搜索规则,而 seinfo
实用程序允许您查询策略中的各种其他组件。
sesearch
和 seinfo
的 Python 绑定,以便您可以通过 sepolicy
套件使用这些实用程序的功能。请参见以下示例:
> python >>> import sepolicy >>> sepolicy.info(sepolicy.ATTRIBUTE) Returns a dictionary of all information about SELinux Attributes >>>sepolicy.search([sepolicy.ALLOW]) Returns a dictionary of all allow rules in the policy.
5.2. 生成 SELinux 策略模块: sepolicy generate
sepolgen
或 selinux-polgengui
实用程序用于生成 SELinux 策略。这些工具已合并到 sepolicy
套件。在 Red Hat Enterprise Linux 7 中,sepolicy generate
命令用于生成初始 SELinux 策略模块模板。
sepolgen
不同,不需要以 root 用户身份运行 sepolicy generate。此实用程序还会创建一个 RPM spec 文件,该文件可用于构建 RPM 软件包,该软件包可将策略软件包文件( NAME.pp
)和接口文件(NAME. if
)安装到正确的位置,提供 SELinux 策略安装到内核并修复标记。设置脚本将继续安装 SELinux 策略并设置标签。此外,使用 sepolicy manpage 命令生成基于已安装策略的 man page。[7] 最后,sepolicy 生成 构建并将 SELinux 策略和 man page 编译到 RPM 软件包中,并可在其他系统上安装。
sepolicy 生成
时,会生成以下文件:
NAME.te
- 键入 enforcing 文件- 此文件定义特定域的所有类型和规则。
NAME.if
- 接口文件- 此文件定义系统的默认文件上下文。它取
NAME.te
文件中创建的文件类型,并将文件路径关联到这些类型。工具(如restorecon
和rpm
)使用这些路径编写标签。 NAME_selinux.spec
- RPM spec 文件- 此文件是一个 RPM spec 文件,可安装 SELinux 策略并设置标签。此文件还会安装 interface 文件和描述策略的 man page。您可以使用 sepolicy manpage -d NAME 命令来生成 man page。
NAME.sh
- helper shell 脚本- 此脚本有助于在系统上编译、安装和修复标记。它还会根据安装的策略生成 man page,编译和构建适合在其他系统上安装的 RPM 软件包。
policy 会生成
从源域到目标域的所有生成的路径。有关 sepolicy 生成
的详情,请查看 sepolicy-generate(8) 手册页。
5.3. 了解域 转换:SEpolicy 转换
setrans
实用程序用于检查两个域或进程类型之间是否可以转换,并打印出用于在这些域或进程间转换的所有中间类型。在 Red Hat Enterprise Linux 7 中,se trans
作为 sepolicy
套件的一部分提供,现在使用 sepolicy transition
命令。
sepolicy transition
命令查询 SELinux 策略并创建进程转换报告。sepolicy transition 命令需要两个命令行参数,即源域(通过 -s
选项指定)和目标域(通过 -t
选项指定)。如果只输入源域,se policy transition 将
列出源域可以转换到的所有可能域。以下输出不包含所有条目。“@” 字符表示 “执行” :
~]$
sepolicy transition -s httpd_t
httpd_t @ httpd_suexec_exec_t --> httpd_suexec_t
httpd_t @ mailman_cgi_exec_t --> mailman_cgi_t
httpd_t @ abrt_retrace_worker_exec_t --> abrt_retrace_worker_t
httpd_t @ dirsrvadmin_unconfined_script_exec_t --> dirsrvadmin_unconfined_script_t
httpd_t @ httpd_unconfined_script_exec_t --> httpd_unconfined_script_t
policy 转换将检查
SELinux 策略,了解从源域到目标域的所有转换路径并列出这些路径。以下输出不完整:
~]$
sepolicy transition -s httpd_t -t system_mail_t
httpd_t @ exim_exec_t --> system_mail_t
httpd_t @ courier_exec_t --> system_mail_t
httpd_t @ sendmail_exec_t --> system_mail_t
httpd_t ... httpd_suexec_t @ sendmail_exec_t --> system_mail_t
httpd_t ... httpd_suexec_t @ exim_exec_t --> system_mail_t
httpd_t ... httpd_suexec_t @ courier_exec_t --> system_mail_t
httpd_t ... httpd_suexec_t ... httpd_mojomojo_script_t @ sendmail_exec_t --> system_mail_t
sepolicy 迁移的详情,请查看 sepolicy-transition(8) 手册页
。
5.4. 生成 man page: sepolicy manpage
sepolicy manpage
命令根据记录进程域的 SELinux 策略生成 man page。因此,此类文档始终是最新的。每个自动生成的 man page 名称都由进程域名和 _selinux
后缀组成,如 httpd_selinux
。
Entrypoints
部分包含域转换过程中需要执行的所有可执行文件。Process Types
部分列出了所有以与目标域相同的前缀开头的进程类型。Booleans
部分列出了与 域关联的布尔值。Port Types
部分中包含与域匹配的端口类型,并描述了分配给这些端口类型的默认端口号。Managed Files
部分描述了允许域写入的类型以及这些类型关联的默认路径。文件上下文
部分包含与域关联的所有文件类型,并描述了如何在系统上使用这些文件类型以及默认路径标记。共享文件
部分介绍如何使用域共享类型,如public_content_t
。
sepolicy manpage
的详情,请查看 sepolicy-manpage(8) 手册页。
第 6 章 限制用户
unconfined_u
用户。unconfined_u
运行的所有进程都在 unconfined_t
域中。这意味着用户可以在标准 Linux DAC 策略限制范围内访问系统。然而,很多受限制的 SELinux 用户在 Red Hat Enterprise Linux 中可用。这意味着可以将用户限制为有限的能力集。每个 Linux 用户都使用 SELinux 策略映射到 SELinux 用户,允许 Linux 用户继承对 SELinux 用户的限制,例如(取决于用户),无法:
- 运行 X Window 系统
- 使用网络
- 运行 setuid 应用程序(除非 SELinux 策略允许)
- 或运行 su 和 sudo 命令。
user_u
用户运行的进程位于 user_t
域中。此类进程可以连接到网络,但无法运行 su 或 sudo 命令。这有助于防止用户访问系统。有关受限制用户及其功能的详情,请查看 第 3.3 节 “受限制和未限制的用户” 表 3.1 “SELinux 用户功能”。
6.1. Linux 和 SELinux 用户映射
~]#
semanage login -l
Login Name SELinux User MLS/MCS Range Service
__default__ unconfined_u s0-s0:c0.c1023 *
root unconfined_u s0-s0:c0.c1023 *
system_u system_u s0-s0:c0.c1023 *
__default__
登录(进而映射到 SELinux unconfined_u
用户)。使用 useradd 命令创建 Linux 用户时,如果没有指定任何选项,则会将其映射到 SELinux unconfined_u
用户。下面定义了 default-mapping:
__default__ unconfined_u s0-s0:c0.c1023 *
6.2. 限制新 Linux 用户:useradd
unconfined_u
用户的 Linux 用户在 unconfined_t
域中运行。通过运行 id -Z 命令,以映射到 unconfined_u
的 Linux 用户登录来查看:
~]$
id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
unconfined_t
域中运行时,会应用 SELinux 策略规则,但存在允许 Linux 用户在 unconfined_t
域中运行的策略规则几乎所有访问权限。如果不受限制的 Linux 用户执行 SELinux 策略定义的应用程序可以从 unconfined_t
域转换到其自身限制的域,则未限制的 Linux 用户仍会受到那个受限制域的限制。这样做的安全优势在于,即使 Linux 用户运行没有限制,应用程序仍会受到限制,因此对应用程序中漏洞的利用也会受到策略的限制。
-Z
选项指定他们映射到哪个 SELinux 用户。以下示例创建了一个新的 Linux 用户 useruuser
,并将该用户映射到 SELinux user_u
用户。映射到 SELinux user_u
用户的 Linux 用户在 user_t
域中运行。在此域中,Linux 用户无法运行 setuid 应用程序,除非 SELinux 策略允许它(如 passwd
),且无法运行 su 或 sudo 命令,阻止他们使用这些命令成为 root 用户。
过程 6.1. 将新 Linux 用户限制为 user_u
SELinux 用户
- 以 root 用户身份,创建映射到 SELinux
user_u
user)。user 的新 Linux 用户(user
u~]#
useradd -Z user_u useruuser - 要查看
useruuser
和user_u
之间的映射,以 root 用户身份输入以下命令:~]#
semanage login -l Login Name SELinux User MLS/MCS Range Service __default__ unconfined_u s0-s0:c0.c1023 * root unconfined_u s0-s0:c0.c1023 * system_u system_u s0-s0:c0.c1023 * useruuser user_u s0 * - 以 root 用户身份,为 Linux
useruuser
用户分配密码:~]#
passwd useruuser Changing password for user useruuser. New password: Enter a password Retype new password: Enter the same password again passwd: all authentication tokens updated successfully. - 从当前会话注销,然后以 Linux
useruuser
用户身份登录。登录时,pam_selinux
模块会将 Linux 用户映射到 SELinux 用户(本例中为user_u
),并设置生成的 SELinux 上下文。然后,将使用此上下文启动 Linux 用户的 shell。输入以下命令查看 Linux 用户的上下文:~]$
id -Z user_u:user_r:user_t:s0 - 从 Linux
useruuser
的会话注销,然后使用您的帐户重新登录。如果您不希望 Linuxuseruuser
用户,以 root 用户身份输入以下命令删除它,及其主目录:~]#
userdel -Z -r useruuser
6.3. 限制现有 Linux 用户:semanage login
unconfined_u
用户(默认行为),并且您想要更改将其映射到哪个 SELinux 用户,请使用 semanage login 命令。以下示例创建一个名为 newuser
的新 Linux 用户,然后将该 Linux 用户映射到 SELinux user_u
用户:
过程 6.2. 将 Linux 用户映射到 SELinux 用户
- 以 root 用户身份,创建新的 Linux 用户(
新用户
)。因为这个用户使用默认映射,所以它不会出现在 semanage login -l 输出中:~]#
useradd newuser~]#
semanage login -l Login Name SELinux User MLS/MCS Range Service __default__ unconfined_u s0-s0:c0.c1023 * root unconfined_u s0-s0:c0.c1023 * system_u system_u s0-s0:c0.c1023 * - 要将 Linux
newuser
用户映射到 SELinuxuser_u
用户,以 root 用户身份输入以下命令:~]#
semanage login -a -s user_u newusera选项
添加新记录,而-s
选项指定要将 Linux 用户映射到的 SELinux 用户。最后一个参数newuser
是您要映射到指定的 SELinux 用户的 Linux 用户。 - 要查看 Linux
newuser
用户与user_u
之间的映射,请再次使用semanage
工具程序:~]#
semanage login -l Login Name SELinux User MLS/MCS Range Service __default__ unconfined_u s0-s0:c0.c1023 * newuser user_u s0 * root unconfined_u s0-s0:c0.c1023 * system_u system_u s0-s0:c0.c1023 * - 以 root 用户身份,为 Linux
newuser
用户分配密码:~]#
passwd newuser Changing password for user newuser. New password: Enter a password Retype new password: Enter the same password again passwd: all authentication tokens updated successfully. - 从当前会话注销,然后以 Linux
newuser
用户身份登录。输入以下命令查看新用户的
SELinux 上下文:~]$
id -Z user_u:user_r:user_t:s0 - 从 Linux
newuser
的会话注销,然后使用您的帐户重新登录。如果您不希望 Linuxnewuser
用户,以 root 用户身份输入以下命令删除它,及其主目录:~]#
userdel -r newuser以 root 用户身份,删除 Linuxnewuser
用户与user_u
之间的映射:~]#
semanage login -d newuser~]#
semanage login -l Login Name SELinux User MLS/MCS Range Service __default__ unconfined_u s0-s0:c0.c1023 * root unconfined_u s0-s0:c0.c1023 * system_u system_u s0-s0:c0.c1023 *
6.4. 更改默认映射
__default__
登录(进而映射到 SELinux unconfined_u
用户)。如果您希望新 Linux 用户和 Linux 用户未专门映射到 SELinux 用户,请使用 semanage login 命令更改默认映射。
unconfined_u 改为
user_u
:
~]#
semanage login -m -S targeted -s "user_u" -r s0 __default__
__default__
登录是否已映射到 user_u
:
~]#
semanage login -l
Login Name SELinux User MLS/MCS Range Service
__default__ user_u s0-s0:c0.c1023 *
root unconfined_u s0-s0:c0.c1023 *
system_u system_u s0-s0:c0.c1023 *
user_u
,如 _ default__
登录所示。
__default__
登录映射到 SELinux unconfined_u
用户:
~]#
semanage login -m -S targeted -s "unconfined_u" -r s0-s0:c0.c1023 __default__
6.5. xguest:kiosk 模式
xguest_u
,请参阅 表 3.1 “SELinux 用户功能”当您注销时,使用此帐户登录时将丢失所有更改,如创建文件或更改设置。
- 以 root 用户身份,安装 xguest 软件包。根据需要安装依赖项:
~]#
yum install xguest - 为了让各种用户使用 kiosk 帐户,该帐户不受密码保护,因此,只能在 SELinux 在强制模式下运行时,才能保护该帐户。在使用此帐户登录前,使用
getenforce
工具确认 SELinux 是否在 enforcing 模式下运行:~]$
getenforce Enforcing否则,请参阅 第 4.4 节 “SELinux 状态和模式中的永久性更改” 以了解有关切换到 enforcing 模式的信息。如果 SELinux 处于 permissive 模式或禁用,则无法使用此帐户登录。 - 您只能使用 GNOME 显示管理器(GDM)登录此帐户。安装 xguest 软件包后,将一个
guest
帐户添加到 GDM 登录屏幕。
6.6. 用户执行应用程序的布尔值
/tmp
目录中,它们有写入访问权限可以帮助防止缺陷或恶意应用程序修改用户拥有的文件。
setsebool
实用程序进行配置,后者必须以 root 身份运行。setsebool -P 命令进行永久性更改。如果您不希望在重启后保留更改,则不要使用 -P
选项:
guest_t
guest_t
域中的 Linux 用户执行其主目录和 /tmp
中的应用程序:
~]#
setsebool -P guest_exec_content off
xguest_t
xguest_t
域中的 Linux 用户执行其主目录和 /tmp
中的应用程序:
~]#
setsebool -P xguest_exec_content off
user_t
user_t
域中的 Linux 用户执行其主目录和 /tmp
中的应用程序:
~]#
setsebool -P user_exec_content off
staff_t
staff_t
域中的 Linux 用户执行其主目录和 /tmp
中的应用程序:
~]#
setsebool -P staff_exec_content off
staff_exec_content
布尔值打开 并允许 staff _t
域中的 Linux 用户在其主目录和 /tmp
中执行应用程序:
~]#
setsebool -P staff_exec_content on
第 7 章 使用 Sandbox 保护程序
7.1. 使用 Sandbox 运行应用程序
~]# yum install policycoreutils-sandbox
~]$ sandbox [options]
application_under_test
-X
选项。例如:
~]$ sandbox -X
evince
X 告知
沙盒 为应用程序设置受限的次要 X 服务器(在本例中为 evince),然后复制所需资源并在 用户的主目录
或 /tmp
目录中创建封闭的虚拟环境。
~]$ sandbox请注意,-H
sandbox/home-T
sandbox/tmp-X
firefox
sandbox/home
用于 /home
,sandbox/tmp
用于 /tmp
。不同的应用会放置在不同的受限环境中。应用以全屏模式运行,这会阻止访问其他功能。如前文所述,您无法打开或创建标记为 sandbox_x_file_t 的文件
。
sandbox_web_t
标签。例如,要启动 Firefox :
~]$ sandbox‑X
‑t
sandbox_web_t firefox
沙盒(8)
手册页,以及可用选项的完整列表。
第 8 章 sVirt
非虚拟化环境
虚拟化环境
8.1. 安全性和虚拟化
8.2. sVirt 标记
~]#
ps -eZ | grep qemu
system_u:system_r:svirt_t:s0:c87,c520 27950 ? 00:00:17 qemu-kvm
system_u:system_r:svirt_t:s0:c639,c757 27989 ? 00:00:06 qemu-system-x86
~]#
ls -lZ /var/lib/libvirt/images/*
system_u:object_r:svirt_image_t:s0:c87,c520 image1
表 8.1. sVirt Labels
类型 | SELinux Context | 描述 |
---|---|---|
虚拟机进程 | system_u:system_r:svirt_t:MCS1 | MCS1 是一个随机选择的 MCS 字段。目前支持约 500,000 个标签。 |
虚拟机镜像 | system_u:object_r:svirt_image_t:MCS1 | 只有标有相同 MCS 字段的 svirt_t 进程才能读取/写入这些镜像文件和设备。 |
虚拟机共享读取/写入内容 | system_u:object_r:svirt_image_t:s0 | 标有 svirt_t 的所有 进程都可写入 svirt_image_t:s0 文件和设备。 |
虚拟机镜像 | system_u:object_r:virt_content_t:s0 | 镜像退出时使用的系统默认标签.不允许 svirt_t 虚拟进程读取使用该标签的文件/设备。 |
第 9 章 安全 Linux 容器
virsh
命令行实用程序。
第 10 章 SELinux systemd
访问控制
systemd
守护进程控制。在之前的 Red Hat Enterprise Linux 版本中,可以通过两种方式启动守护进程:
- 在引导时,System V
init
守护进程启动了init.rc
脚本,然后此脚本启动了所需的守护进程。例如,在启动时启动的 Apache 服务器具有以下 SELinux 标签:system_u:system_r:httpd_t:s0
- 管理员手动启动
init.rc
脚本,导致 守护进程运行。例如,在 Apache 服务器上调用 service httpd restart 命令时,生成的 SELinux 标签如下所示:unconfined_u:system_r:httpd_t:s0
systemd
守护进程,转换过程会非常不同。由于 systemd
使用 init_t
类型来处理启动和停止系统上守护进程的所有调用,因此在手动重启守护进程时,它可以覆盖标签的用户部分。因此,以上这两种情况下的标签都是 system_u:system_r:httpd_t:s0
,SELinux 策略可能会被改进来控制哪些域可以控制哪些单元。
10.1. 服务的 SELinux 访问权限
systemd 启动
和停止所有服务,用户和进程使用 systemctl
实用程序与 systemd
通信。systemd
守护进程能够参考 SELinux 策略,检查调用进程的标签以及调用者尝试管理的单元文件标签,然后询问 SELinux 是否允许调用者访问。这个方法可控制对关键系统功能的访问控制,其中包括启动和停止系统服务。
systemctl
将 D-Bus 消息发送到 systemd
,后者反过来会启动或停止任何请求的服务 NetworkManager。事实上,NetworkManager 被允许执行 systemctl 可执行的
所有操作。也无法设置受限管理员,以便他们仅启动或停止特定的服务。
systemd
也充当 SELinux 访问管理器。它可以检索运行 systemctl
的进程的标签,也可以检索向 systemd
发送 D-Bus 消息的进程的标签。然后守护进程会查找进程要配置的单元文件标签。最后,如果 SELinux 策略允许进程标签和单元文件标签之间的特定访问,systemd
可以从内核检索信息。这意味着,SELinux 现在可以限制需要与 systemd
交互特定服务的被破坏的应用。策略作者也可以使用这些精细的控制来限制管理员。策略更改涉及一个名为 service
的新类,其权限如下:
class service { start stop status reload kill load enable disable }
systemd
中的访问控制操作都不匹配。一个映射被定义为带有 SELinux 访问检查的 systemd
方法调用。表 10.1 “在 SELinux 访问检查中映射 systemd 单元文件方法调用” 映射单元文件的访问检查,表 10.2 “在 SELinux 访问检查中映射 systemd 常规系统调用” 涵盖了系统访问检查。如果任一表中都没有找到匹配项,则调用 未定义的
系统检查。
表 10.1. 在 SELinux 访问检查中映射 systemd 单元文件方法调用
systemd 单元文件方法 | SELinux 访问检查 |
---|---|
DisableUnitFiles | disable |
EnableUnitFiles | 启用 |
GetUnit | status |
GetUnitByPID | status |
GetUnitFileState | status |
kill | stop |
KillUnit | stop |
LinkUnitFiles | 启用 |
ListUnits | status |
LoadUnit | status |
MaskUnitFiles | disable |
PresetUnitFiles | 启用 |
ReenableUnitFiles | 启用 |
Reexecute | start |
reload | reload |
ReloadOrRestart | start |
ReloadOrRestartUnit | start |
ReloadOrTryRestart | start |
ReloadOrTryRestartUnit | start |
ReloadUnit | reload |
ResetFailed | stop |
ResetFailedUnit | stop |
Restart | start |
RestartUnit | start |
Start | start |
StartUnit | start |
StartUnitReplace | start |
stop | stop |
StopUnit | stop |
TryRestart | start |
TryRestartUnit | start |
UnmaskUnitFiles | 启用 |
表 10.2. 在 SELinux 访问检查中映射 systemd 常规系统调用
systemd 常规系统调用 | SELinux 访问检查 |
---|---|
ClearJobs | reboot |
FlushDevices | halt |
Get | status |
GetAll | status |
GetJob | status |
GetSeat | status |
GetSession | status |
GetSessionByPID | status |
GetUser | status |
halt | halt |
introspect | status |
KExec | reboot |
KillSession | halt |
KillUser | halt |
ListJobs | status |
ListSeats | status |
ListSessions | status |
ListUsers | status |
LockSession | halt |
PowerOff | halt |
重启 | reboot |
SetUserLinger | halt |
TerminateSeat | halt |
TerminateSession | halt |
TerminateUser | halt |
例 10.1. 系统服务的 SELinux 策略
sesearch
工具,您可以列出系统服务的策略规则。例如,调用 sesearch -A -s NetworkManager_t -c service 命令返回:
allow NetworkManager_t dnsmasq_unit_file_t : service { start stop status reload kill load } ; allow NetworkManager_t nscd_unit_file_t : service { start stop status reload kill load } ; allow NetworkManager_t ntpd_unit_file_t : service { start stop status reload kill load } ; allow NetworkManager_t pppd_unit_file_t : service { start stop status reload kill load } ; allow NetworkManager_t polipo_unit_file_t : service { start stop status reload kill load } ;
10.2. SELinux 和 journald
systemd
中,journald
守护进程(也称为 systemd-journal
)是 syslog
实用程序的替代选择,后者是收集和存储日志数据的系统服务。它根据从内核收到的日志信息、使用 libc
syslog()
功能的用户进程、系统服务的标准和错误输出,或使用其原生 API,创建和维护结构化和索引化日志。它以安全的方式为每个日志消息隐式收集大量元数据字段。
systemd-journal
服务可与 SELinux 配合使用,以提高安全性。SELinux 控制进程仅允许进程执行它们所设计的操作;有时,根据策略编写者的安全目标,有时更少一些。例如,SELinux 可防止泄露的 ntpd
进程执行除处理网络时间以外的任何操作。但是,ntpd
进程会发送 syslog
消息,以便被入侵的进程能够继续发送这些消息。被泄露 的 ntpd
可能会格式化 syslog
消息以匹配其他守护进程,并可能错误地导致管理员无法正常工作,甚至更糟糕地,会读取 syslog
文件以破坏整个系统。
systemd-journal
守护进程将验证所有日志消息,此外,还为它们添加 SELinux 标签。然后可以轻松地检测日志消息中的不一致情况,并在发生之前防止这种类型的攻击。您可以使用 journalctl
实用程序查询 systemd
日志的日志。如果没有指定命令行参数,则运行此实用程序会列出日志的完整内容,从最旧的条目开始。要查看系统上生成的所有日志,包括系统组件的日志,请以 root 用户身份执行 journalctl
。如果您以非 root 用户身份执行它,则输出将仅限于与当前登录用户相关的日志。
例 10.2. 使用 journalctl
列出日志
journalctl
列出与特定 SELinux 标签相关的所有日志:例如,以下命令列出了 system_u:system_r:policykit_t:s0
标签下记录的所有日志:
~]# journalctl _SELINUX_CONTEXT=system_u:system_r:policykit_t:s0
Oct 21 10:22:42 localhost.localdomain polkitd[647]: Started polkitd version 0.112
Oct 21 10:22:44 localhost.localdomain polkitd[647]: Loading rules from directory /etc/polkit-1/rules.d
Oct 21 10:22:44 localhost.localdomain polkitd[647]: Loading rules from directory /usr/share/polkit-1/rules.d
Oct 21 10:22:44 localhost.localdomain polkitd[647]: Finished loading, compiling and executing 5 rules
Oct 21 10:22:44 localhost.localdomain polkitd[647]: Acquired the name org.freedesktop.PolicyKit1 on the system bus Oct 21 10:23:10 localhost polkitd[647]: Registered Authentication Agent for unix-session:c1 (system bus name :1.49, object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_US.UTF-8) (disconnected from bus)
Oct 21 10:23:35 localhost polkitd[647]: Unregistered Authentication Agent for unix-session:c1 (system bus name :1.80 [/usr/bin/gnome-shell --mode=classic], object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale en_US.utf8)
journalctl
的详情,请查看 journalctl(1) 手册页。
第 11 章 故障排除
audit2 创建自定义策略模块。
11.1. 拒绝访问时的 Happens
/var/log/audit/audit.log
/var/log/messages
/var/log/audit/audit.log
.易于读取的拒绝消息也发送到 /var/log/messages
setroubleshootd
和 auditd
守护进程正在运行,SELinux 拒绝访问时会显示警告:
Forbidden You don't have permission to access file name on this server
/var/log/messages
和 /var/log/audit/audit.log
的 "SELinux is prevent"
和" denied"
错误。这可以通过以 root 用户身份运行以下命令来完成:
~]#
grep "SELinux is preventing" /var/log/messages
~]#
grep "denied" /var/log/audit/audit.log
11.2. 问题最多的三种原因
11.2.1. 标记问题
/var/www/html/
用于网站,而是希望使用 /srv/myweb/
。在 Red Hat Enterprise Linux 中,/srv
目录标有 var_t
类型。在 /srv
中创建的文件和目录继承此类型。此外,顶级目录中新创建的对象(如 /myserver
)可能会使用 default_t
类型进行标记。SELinux 会阻止 Apache HTTP 服务器(httpd)
访问这两种类型。要允许访问,SELinux 必须知道 /srv/myweb/
中的文件可以被 httpd
访问:
~]#
semanage fcontext -a -t httpd_sys_content_t "/srv/myweb(/.*)?"
/srv/myweb/
目录(以及其中所有文件和目录)的上下文添加到 SELinux 文件上下文配置中[8].semanage
实用程序不会更改上下文。以 root 用户身份,运行 restorecon
工具来应用更改:
~]#
restorecon -R -v /srv/myweb
11.2.1.1. 什么是正确的上下文?
matchpathcon
实用程序检查文件路径的上下文,并将其与该路径的默认标签进行比较。以下示例演示了在包含错误标记文件的目录中使用 matchpathcon
:
~]$
matchpathcon -V /var/www/html/*
/var/www/html/index.html has context unconfined_u:object_r:user_home_t:s0, should be system_u:object_r:httpd_sys_content_t:s0
/var/www/html/page1.html has context unconfined_u:object_r:user_home_t:s0, should be system_u:object_r:httpd_sys_content_t:s0
.html
和 page1.html
文件使用 user_home_t
类型进行标记。这种类型用于用户主目录中的文件。使用 st v 命令 从您的主目录中移动文件可能会导致文件使用 user_home_t
类型进行标记。这个类型不应存在于主目录之外。使用 restorecon
实用程序将这些文件恢复到其正确类型:
~]#
restorecon -v /var/www/html/index.html
restorecon reset /var/www/html/index.html context unconfined_u:object_r:user_home_t:s0->system_u:object_r:httpd_sys_content_t:s0
-R
选项:
~]#
restorecon -R -v /var/www/html/
restorecon reset /var/www/html/page1.html context unconfined_u:object_r:samba_share_t:s0->system_u:object_r:httpd_sys_content_t:s0
restorecon reset /var/www/html/index.html context unconfined_u:object_r:samba_share_t:s0->system_u:object_r:httpd_sys_content_t:s0
matchpathcon
的详情,请查看 第 4.10.3 节 “检查默认 SELinux 上下文”。
11.2.2. 受限服务如何运行?
httpd_can_network_connect_db
布尔值:
~]#
setsebool -P httpd_can_network_connect_db on
getsebool 和
grep
实用程序查看是否有布尔值可用于允许访问。例如,使用 getsebool -a | grep ftp 命令搜索 FTP 相关的布尔值:
~]$
getsebool -a | grep ftp
ftpd_anon_write --> off
ftpd_full_access --> off
ftpd_use_cifs --> off
ftpd_use_nfs --> off
ftpd_connect_db --> off
httpd_enable_ftp_server --> off
tftp_anon_write --> off
端口号
http
相关端口:
~]#
semanage port -l | grep http
http_cache_port_t tcp 3128, 8080, 8118
http_cache_port_t udp 3130
http_port_t tcp 80, 443, 488, 8008, 8009, 8443
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989
http_port_t
端口类型定义 Apache HTTP 服务器可以侦听的端口,在本例中为 TCP 端口 80、443、488、8008、8009 和 8443。如果管理员配置了 httpd.conf
,以便 httpd
侦听端口 9876(Listen 9876
),但没有更新策略来反映这一点,以下命令会失败:
~]#
systemctl start httpd.service
Job for httpd.service failed. See 'systemctl status httpd.service' and 'journalctl -xn' for details.
~]#
systemctl status httpd.service
httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled)
Active: failed (Result: exit-code) since Thu 2013-08-15 09:57:05 CEST; 59s ago
Process: 16874 ExecStop=/usr/sbin/httpd $OPTIONS -k graceful-stop (code=exited, status=0/SUCCESS)
Process: 16870 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
/var/log/audit/audit.log
中记录类似如下的 SELinux 拒绝信息:
type=AVC msg=audit(1225948455.061:294): avc: denied { name_bind } for pid=4997 comm="httpd" src=9876 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket
~]#
semanage port -a -t http_port_t -p tcp 9876
选项
添加新记录; -t
选项定义类型; -p
选项定义协议。最后的参数是要添加的端口号。
11.2.3. 演进规则和损坏的应用程序
audit2allow
实用程序创建自定义策略模块以允许访问。有关使用 audit2allow
的详情,请查看 第 11.3.8 节 “允许访问: audit2 允许”。
11.3. 修复问题
audit2allow
创建自定义策略模块。
11.3.1. Linux 权限
~]$
ls -l /var/www/html/index.html
-rw-r----- 1 root root 0 2009-05-07 11:06 index.html
.html
归 root 用户和组所有。root 用户具有读取和写入权限(-rw
),root 组的成员具有读取权限(-r-
)。其他人没有访问权限(---
)。默认情况下,此类权限不允许 httpd
读取此文件。要解决这个问题,请使用 chown 命令更改所有者和组。这个命令必须以 root 用户身份运行:
~]#
chown apache:apache /var/www/html/index.html
httpd
以 Linux Apache 用户身份运行。如果您使用其他用户运行 httpd
,请将 apache:apache
替换为该用户。
11.3.2. 可能的 Silent Denials 原因
~]# semodule -DB
选项
禁用 dontaudit 规则; -B
选项重新构建策略。运行 semodule -DB 后,尝试判断遇到权限问题的应用程序,并查看现在是否记录与应用程序相关的 SELinux 拒绝信息。请特别注意决定允许哪些拒绝,因为有些拒绝应该被忽略并由 dontaudit 规则处理。如果不确定,或在搜索指南时,请在 SELinux 列表中联系其他 SELinux 用户和开发人员,如 fedora-selinux-list。
dontaudit 规则
,以 root 用户身份输入以下命令:
~]# semodule -B
-s 域
选项和 grep 命令缩小搜索范围。例如:
~]$
sesearch --dontaudit -s smbd_t | grep squid
dontaudit smbd_t squid_port_t : tcp_socket name_bind ;
dontaudit smbd_t squid_port_t : udp_socket name_bind ;
11.3.3. 为服务手动页面
httpd
访问 NFS 卷)。此信息可能位于标准 man page 或 man page 中,可以使用 sepolicy manpage
实用程序从每个服务域的 SELinux 策略自动生成。此类 man page 以 service-name_selinux
格式命名。selinux-policy-doc 软件包还提供此类 man page。
- Samba:例如:启用
samba_enable_home_dirs
布尔值的 samba_selinux(8) 手册页可让 Samba 共享用户主目录。 - NFS: nfsd_selinux(8) 手册页描述了 SELinux nfsd 策略,允许用户尽可能安全地设置其 nfsd 进程。
sepolicy manpage
的详情请参考 第 5.4 节 “生成 man page: sepolicy manpage”。
11.3.4. 许可域
- 它们可用于使单个进程(域)运行 permissive 模式来排除问题,而无需通过使整个系统成为许可关系而使其面临风险。
- 它们允许管理员为新应用创建策略。在以前的版本中,建议创建一个最小策略,然后整个机器都进入 permissive 模式,以便应用程序可以运行,但 SELinux 拒绝仍然被记录。
audit2allow
随后可用于帮助编写策略。这使得整个系统面临风险。使用 permissive 域时,新策略中只有域可以标记为许可,而不会使整个系统面临风险。
11.3.4.1. 创建域许可
httpd_t
域(运行 Apache HTTP 服务器的域)permissive:
~]#
semanage permissive -a httpd_t
~]#
semodule -l | grep permissive
permissive_httpd_t (null)
permissivedomains (null)
~]#
semanage permissive -d httpd_t
11.3.4.2. 禁用许可域
permissivedomains.pp
模块包含系统上呈现的所有 permissive 域声明。要禁用所有 permissive 域,以 root 用户身份输入以下命令:
~]#
semodule -d permissivedomains
~]#
semodule --list-modules=full
11.3.4.3. 拒绝许可域
ALL
消息不同。以下是来自 Apache HTTP 服务器的 AVC 拒绝(及关联的系统调用)示例:
type=AVC msg=audit(1226882736.442:86): avc: denied { getattr } for pid=2427 comm="httpd" path="/var/www/html/file1" dev=dm-0 ino=284133 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:samba_share_t:s0 tclass=file type=SYSCALL msg=audit(1226882736.442:86): arch=40000003 syscall=196 success=no exit=-13 a0=b9a1e198 a1=bfc2921c a2=54dff4 a3=2008171 items=0 ppid=2425 pid=2427 auid=502 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
_t
域不是 permissive,因此操作被拒绝,SYSC ALL
消息包含 success=no
。以下是相同情况下 AVC 拒绝的示例,但运行 semanage permissive -a httpd_t 命令以使 httpd_t
域许可:
type=AVC msg=audit(1226882925.714:136): avc: denied { read } for pid=2512 comm="httpd" name="file1" dev=dm-0 ino=284133 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:samba_share_t:s0 tclass=file type=SYSCALL msg=audit(1226882925.714:136): arch=40000003 syscall=5 success=yes exit=11 a0=b962a1e8 a1=8000 a2=0 a3=8000 items=0 ppid=2511 pid=2512 auid=502 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
SYSCALL
消息中的 success=yes
所示。
11.3.5. 搜索和查看地址
auditd
、rsyslogd
和 setroubleshootd
守护进程正在运行。有关启动这些守护进程的详情请参考 第 4.2 节 “使用哪个日志文件”。有多个实用程序可用于搜索和查看 SELinux AVC 信息,如 ausearch
、aureport
和 sealert
。
ausearch
审计
守护进程日志中的事件。[10] ausearch
工具程序访问 /var/log/audit/audit.log
,因此必须以 root 用户身份运行:
-c comm-name
选项,其中 comm-name 是可执行文件的名称,例如 httpd
用于 Apache HTTP 服务器,smb d
用于 Samba:
~]#
ausearch -m avc -c httpd
~]#
ausearch -m avc -c smbd
--interpret
(-i
)选项来简化可读性,或使用 --raw(
-r
)选项进行脚本处理。有关更多 ausearch 选项,请参阅 ausearch(8) 手册页。
aureport
report
实用程序,用于生成审计系统日志的摘要报告。[11] aureport
实用程序访问 /var/log/audit/audit.log
,因此必须以 root 用户身份运行。要查看 SELinux 拒绝消息列表以及每个消息发生的频率,请运行 aureport -a 命令。以下是包含两个拒绝的输出示例:
~]#
aureport -a
AVC Report
========================================================
# date time comm subj syscall class permission obj event
========================================================
1. 05/01/2009 21:41:39 httpd unconfined_u:system_r:httpd_t:s0 195 file getattr system_u:object_r:samba_share_t:s0 denied 2
2. 05/03/2009 22:00:25 vsftpd unconfined_u:system_r:ftpd_t:s0 5 file read unconfined_u:object_r:cifs_t:s0 denied 4
sealert
sealert
实用程序,它会读取 setroubleshoot-server 转换的拒绝消息。[12] 拒绝分配 ID,如 /var/log/messages
所示。以下是拒绝 信息的示例
:
setroubleshoot: SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket. For complete SELinux messages. run sealert -l 8c123656-5dda-4e5d-8791-9e3bd03786b7
8c123656-5dda-4e5d-8791-9e3bd03786b7
。l 选项
取 ID 作为参数。运行 sealert -l 8c123656-5dda-4e5d-8791-9e3bd03786b7 命令可以详细分析 SELinux 拒绝访问的原因,以及允许访问的可能解决方案。
setroubleshootd
、dbus
和 auditd
守护进程正在运行,SELinux 拒绝访问时会显示警告:
Show
启动 sealert
GUI,允许您对问题进行故障排除:
11.3.6. 原始审计消息
/var/log/audit/audit.log
。以下是 Apache HTTP 服务器(在 httpd_t 域中运行)尝试访问 /var/www/html/file1
文件(使用 samba_share_t
类型标记)时发生的 AVC 拒绝消息(以及关联的系统调用):
type=AVC msg=audit(1226874073.147:96): avc: denied { getattr } for pid=2465 comm="httpd" path="/var/www/html/file1" dev=dm-0 ino=284133 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:samba_share_t:s0 tclass=file type=SYSCALL msg=audit(1226874073.147:96): arch=40000003 syscall=196 success=no exit=-13 a0=b98df198 a1=bfec85dc a2=54dff4 a3=2008171 items=0 ppid=2463 pid=2465 auid=502 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=6 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
- { getattr }
- 大括号中的项目表示拒绝的权限。
getattr
条目指示源进程正在尝试读取目标文件的状态信息。这在读取文件前发生。由于访问的文件带有错误的标签,因此此操作被拒绝。通常看到的权限包括getattr
、读取和写入
。
- comm="httpd"
- 启动进程的可执行文件。可执行文件的完整路径可在系统调用(SYSC
ALL
)消息的exe=
部分中找到,本例中为exe="/usr/sbin/httpd"。
- path="/var/www/html/file1"
- 进程试图访问的对象(目标)路径。
- scontext="unconfined_u:system_r:httpd_t:s0"
- 尝试拒绝的操作的进程的 SELinux 上下文。在本例中,这是 Apache HTTP 服务器的 SELinux 上下文,它在
httpd_t
域中运行。 - tcontext="unconfined_u:object_r:samba_share_t:s0"
- 进程试图访问的对象(目标)的 SELinux 上下文。在本例中,这是
file1 的
SELinux 上下文。请注意,在httpd
类型。_t 域中运行的进程无法访问 samba_share
_t在某些情况下,tcontext
可能与scontext
匹配,例如,当进程尝试执行将更改该运行进程的特征的系统服务(如用户 ID)时。另外,当进程试图使用超出正常限值允许的资源(如内存)时,t
,从而进行安全检查以查看是否允许该进程突破这些限制。context 可能会与 scontext
匹配
CALL
)消息中,需要两个项目:
success=no
: 表示是否强制拒绝(AVC)。success=no
表示系统调用没有成功(SELinux 被拒绝的访问)。success=yes
表示系统调用是否成功。这可用于 permissive 域或未限制的域,如unconfined_service_t
和kernel_t
。exe="/usr/sbin/httpd"
:启动该进程的可执行文件的完整路径,在本例中为exe="/usr/sbin/httpd"。
scontext
)与目标上下文(tcontext
)进行比较。进程(scontext
)是否应该访问这样的对象(tcontext
)?例如: Apache HTTP 服务器(httpd_t
)应该只访问 httpd_selinux(8) 手册页中指定的类型,如 httpd_sys_content_t
、public_content_t
等等。
11.3.7. sealert 消息
/var/log/messages
所示。以下是 Apache HTTP 服务器(在 httpd_t
域中运行 )
试图访问 /var/www/html/file1
文件(使用 samba_share_t
类型标记)时发生的 AVC 拒绝示例:
hostname setroubleshoot: SELinux is preventing httpd (httpd_t) "getattr" to /var/www/html/file1 (samba_share_t). For complete SELinux messages. run sealert -l 32eee32b-21ca-4846-a22f-0ba050206786
~]$
sealert -l 32eee32b-21ca-4846-a22f-0ba050206786
SELinux is preventing httpd from getattr access on the file /var/www/html/file1.
***** Plugin restorecon (92.2 confidence) suggests ************************
If you want to fix the label.
/var/www/html/file1 default label should be httpd_sys_content_t.
Then you can run restorecon.
Do
# /sbin/restorecon -v /var/www/html/file1
***** Plugin public_content (7.83 confidence) suggests ********************
If you want to treat file1 as public content
Then you need to change the label on file1 to public_content_t or public_content_rw_t.
Do
# semanage fcontext -a -t public_content_t '/var/www/html/file1'
# restorecon -v '/var/www/html/file1'
***** Plugin catchall (1.41 confidence) suggests **************************
If you believe that httpd should be allowed getattr access on the file1 file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'httpd' --raw | audit2allow -M my-httpd
# semodule -i my-httpd.pp
Additional Information:
Source Context system_u:system_r:httpd_t:s0
Target Context unconfined_u:object_r:samba_share_t:s0
Target Objects /var/www/html/file1 [ file ]
Source httpd
Source Path httpd
Port <Unknown>
Host hostname.redhat.com
Source RPM Packages
Target RPM Packages
Policy RPM selinux-policy-3.13.1-166.el7.noarch
Selinux Enabled True
Policy Type targeted
Enforcing Mode Enforcing
Host Name hostname.redhat.com
Platform Linux hostname.redhat.com
3.10.0-693.el7.x86_64 #1 SMP Thu Jul 6 19:56:57
EDT 2017 x86_64 x86_64
Alert Count 2
First Seen 2017-07-20 02:52:11 EDT
Last Seen 2017-07-20 02:52:11 EDT
Local ID 32eee32b-21ca-4846-a22f-0ba050206786
Raw Audit Messages
type=AVC msg=audit(1500533531.140:295): avc: denied { getattr } for pid=24934 comm="httpd" path="/var/www/html/file1" dev="vda1" ino=31457414 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:samba_share_t:s0 tclass=file
Hash: httpd,httpd_t,samba_share_t,file,getattr
- 概述
- 被拒绝操作的简短概述。这与
/var/log/messages
中的拒绝相同。在本例中,httpd进程
被拒绝访问文件(文件1
),该文件使用samba_share_t
类型进行标记。 - 详细描述
- 更为详细的描述。在本例中,file
1 使用
samba_share_t
类型进行标记。此类型用于您要使用 Samba 导出的文件和目录。描述建议将类型更改为 Apache HTTP 服务器和 Samba 可访问的类型(如果需要此类访问)。 - 允许访问
- 有关如何允许访问的建议。这可以是重新标记文件、启用布尔值或创建本地策略模块。在这种情况下,建议使用 Apache HTTP 服务器和 Samba 可访问的类型标记该文件。
- 修复命令
- 建议将 命令允许访问并解决拒绝。在本例中,它提供了 命令将
file1
类型更改为public_content_t
命令,后者可供 Apache HTTP 服务器和 Samba 访问。 - 其它信息
- 错误报告中有用的信息,如策略软件包名称和版本(selinux
-policy-3.13.1-166.el7.noarch
),但可能不适用于解决拒绝的原因。 - 原始审计消息
- 与拒绝关联的
/var/log/audit/audit.log
中的原始审计消息。有关 AVC 拒绝中每个项目的信息,请参阅 第 11.3.6 节 “原始审计消息”。
11.3.8. 允许访问: audit2 允许
audit2allow
实用程序的使用。
audit2allow
实用程序从被拒绝的操作日志中收集信息,然后生成 SELinux 策略允许规则。[13] 根据 第 11.3.7 节 “sealert 消息” 分析拒绝信息后,如果没有标签更改或布尔值允许访问,请使用 audit2allow
创建本地策略模块。当 SELinux 拒绝访问时,运行 audit2 会生成允许
之前拒绝的访问的 Type Enforcement 规则。
audit2allow
生成本地策略模块作为您的第一个选项。故障排除应该先检查是否有标记问题。第二个最常见的情况是您更改了进程配置,并且忘记了要让 SELinux 了解它。如需更多信息,请参阅 SELinux 错误的四个关键原因 白皮书。
audit2allow
创建策略模块:
- 拒绝信息和相关系统调用记录到
/var/log/audit/audit.log
文件中:type=AVC msg=audit(1226270358.848:238): avc: denied
{ write }
for pid=13349comm="certwatch"
name="cache" dev=dm-0 ino=218171 scontext=system_u:system_r:certwatch_t:s0tcontext=system_u:object_r:var_t:s0
tclass=dir type=SYSCALL msg=audit(1226270358.848:238): arch=40000003 syscall=39 success=no exit=-13 a0=39a2bf a1=3ff a2=3a0354 a3=94703c8 items=0 ppid=13344 pid=13349 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="certwatch" exe="/usr/bin/certwatch" subj=system_u:system_r:certwatch_t:s0 key=(null)在本例中,certwatch 被拒绝了对标有var_t
类型的目录的写入访问。根据 第 11.3.7 节 “sealert 消息” 分析拒绝消息。如果没有标签更改或布尔值被允许访问,请使用audit2allow
创建本地策略模块。 - 输入以下命令生成人类可读的描述,说明为什么拒绝访问。
audit2allow
工具读取/var/log/audit/audit.log
,因此必须以 root 用户身份运行:~]#
audit2allow -w -a type=AVC msg=audit(1226270358.848:238): avc: denied { write } for pid=13349 comm="certwatch" name="cache" dev=dm-0 ino=218171 scontext=system_u:system_r:certwatch_t:s0 tcontext=system_u:object_r:var_t:s0 tclass=dir Was caused by: Missing type enforcement (TE) allow rule. You can use audit2allow to generate a loadable module to allow this access.a 命令行
选项可使所有审计日志被读取。w 选项
生成人类可读的描述。如上所示,缺少 Type Enforcement 规则,因此访问被拒绝。 - 输入以下命令查看允许拒绝访问的 Type Enforcement 规则:
~]#
audit2allow -a #============= certwatch_t ============== allow certwatch_t var_t:dir write;重要缺少 Type Enforcement 规则通常由 SELinux 策略中的错误导致,应在 Red Hat Bugzilla 中报告。对于 Red Hat Enterprise Linux,针对Red Hat Enterprise Linux
产品创建程序错误,然后选择selinux-policy
组件。在此类错误报告中,包括 audit2allow -w -a 和 audit2allow -a 命令的输出。 - 要使用 audit2allow -a 显示的规则,以 root 用户身份输入以下命令来创建自定义模块。在当前工作目录中
,
使用-M
指定的名称创建一个 Type Enforcement 文件(.te
):~]#
audit2allow -a -M mycertwatch ******************** IMPORTANT *********************** To make this policy package active, execute: semodule -i mycertwatch.pp - 此外,
audit2 允许将 Type Enforcement 规则编译
到策略软件包(.pp
)中:~]#
ls mycertwatch.pp mycertwatch.te要安装模块,以 root 用户身份输入以下命令:~]#
semodule -i mycertwatch.pp重要使用audit2 允许
创建的模块可能会允许超过所需的访问权限。建议通过audit2allow
创建的策略发布到上游 SELinux 列表中以供审核。 如果您认为策略中存在错误,请在 Red Hat Bugzilla 中创建一个错误。
grep
实用程序缩小对 audit2allow
的输入范围。以下示例演示了使用 grep
仅通过 audit2allow
发送与 certwatch
相关的拒绝信息:
~]#
grep certwatch /var/log/audit/audit.log | audit2allow -R -M mycertwatch2
******************** IMPORTANT ***********************
To make this policy package active, execute:
semodule -i mycertwatch2.pp
第 12 章 更多信息
12.1. 贡献者
- Dominick Grift - 技术编辑器
- Murray McAllister - 红帽产品安全
- James Morris - 技术编辑器
- Eric Malaysia - 技术编辑器
- Scott Radvan - 红帽客户内容服务
- Daniel Walsh - 红帽安全工程
12.2. 其他资源
Fedora
- Fedora SELinux https://fedoraproject.org/wiki/SELinux_FAQ 常见问题:
国家安全局(NSA)
- 主 SELinux 网站: https://www.nsa.gov/what-we-do/research/selinux/
Tresys Technology
SELinux GitHub 存储库
- SELinux 项目: https://github.com/SELinuxProject
- Tresys 技术: https://github.com/TresysTechnology/
SELinux Project Wiki
- 用户资源,包括文档、邮件列表、网站和工具链接: http://selinuxproject.org/page/User_Resources
SELinux 笔记本 - 基础 - 第 4 版
DigitalOcean:CentOS 7 中的 SELinux 简介
IRC
- #selinux
- #fedora-selinux
部分 II. 管理受限服务
第 13 章 Apache HTTP 服务器
~]$ rpm -q httpd
package httpd is not installed
yum
工具来安装它:
~]# yum install httpd
13.1. Apache HTTP 服务器和 SELinux
httpd
)默认运行限制。受限制的进程在其自己的域中运行,并且与其他受限制的进程隔开。如果一个受攻击者限制的进程受到 SELinux 策略配置的影响,攻击者对资源的访问权限和可能受到的破坏会受到限制。以下示例演示了在自己的域中运行的 httpd
进程。本例假设安装了 httpd、setroubleshoot、setroubleshoot-server 和 policycoreutils-python 软件包:
- 运行 getenforce 命令确认 SELinux 是否以强制模式运行:
~]$ getenforce Enforcing
当 SELinux 以强制模式运行时,该命令将返回强制
。 - 以 root 用户身份输入以下命令启动
httpd
:~]# systemctl start httpd.service
确认 服务正在运行。输出中应包括以下信息(只有时间戳有所不同):~]# systemctl status httpd.service httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled) Active: active (running) since Mon 2013-08-05 14:00:55 CEST; 8s ago
- 要查看
httpd
进程,请执行以下命令:~]$ ps -eZ | grep httpd system_u:system_r:httpd_t:s0 19780 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 19781 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 19782 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 19783 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 19784 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 19785 ? 00:00:00 httpd
与httpd
进程关联的 SELinux 上下文是system_u:system_r:httpd_t:s0。
上下文的第二部分httpd_t
是类型。类型定义进程的域以及文件的类型。在本例中,httpd进程在 httpd
_t
域中运行。
httpd_t
)内运行的进程如何与文件、其他进程和系统交互。文件必须正确标记,以允许 httpd
访问这些文件。例如,httpd 可以
读取使用 httpd_sys_content_t
类型标记的文件,但无法写入这些文件,即使 Linux(DAC)权限允许写入访问。必须启用布尔值以允许某些行为,例如允许脚本网络访问、允许 httpd
访问 NFS 和 CIFS 卷,以及允许 httpd
执行通用网关接口(CGI)脚本。
/etc/httpd/conf/httpd.conf
文件后,httpd 侦听
TCP 端口 80、443、488、8008、8009 或 8443 以外的端口,必须使用 semanage port 命令将新端口号添加到 SELinux 策略配置。以下示例演示了将 httpd
配置为侦听 httpd 的 SELinux 策略配置中尚未定义的端口 ,
因此 httpd
无法启动。本例还演示如何配置 SELinux 系统,以允许 httpd
成功侦听策略中尚未定义的非标准端口。本例假定已安装了 httpd 软件包。以 root 用户身份运行示例中的每个命令:
- 输入以下命令确认
httpd
没有运行:~]# systemctl status httpd.service httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled) Active: inactive (dead)
如果输出不同,请停止该进程:~]# systemctl stop httpd.service
- 使用
semanage
工具查看 SELinux 允许httpd
侦听的端口:~]# semanage port -l | grep -w http_port_t http_port_t tcp 80, 443, 488, 8008, 8009, 8443
- 以 root 用户身份编辑
/etc/httpd/conf/httpd.conf
文件。配置Listen
选项,使它列出httpd
的 SELinux 策略配置中未配置的端口。在本例中,httpd被配置为侦听端口 12345:
# 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 127.0.0.1:12345
- 输入以下命令启动
httpd
:~]# systemctl start httpd.service Job for httpd.service failed. See 'systemctl status httpd.service' and 'journalctl -xn' for details.
记录类似如下的 SELinux 拒绝信息:setroubleshoot: SELinux is preventing the httpd (httpd_t) from binding to port 12345. For complete SELinux messages. run sealert -l f18bca99-db64-4c16-9719-1db89f0d8c77
- 为了使 SELinux 允许
httpd
侦听端口 12345,如本例中使用的那样,需要使用以下命令:~]# semanage port -a -t http_port_t -p tcp 12345
- 再次启动
httpd
并使它监听新端口:~]# systemctl start httpd.service
- 现在 SELinux 已配置为允许
httpd
侦听非标准端口(本示例中为 TCP 12345),httpd 在此端口上成功启动
。 - 要证明
httpd
正在 TCP 端口 12345 上侦听和通信,请打开到指定端口的 telnet 连接并发出 HTTP GET 命令,如下所示:~]# telnet localhost 12345 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. GET / HTTP/1.0 HTTP/1.1 200 OK Date: Wed, 02 Dec 2009 14:36:34 GMT Server: Apache/2.2.13 (Red Hat) Accept-Ranges: bytes Content-Length: 3985 Content-Type: text/html; charset=UTF-8 [...continues...]
13.2. 类型
/var/www/html/
目录中创建一个新文件,并显示了从父目录(/var/www/html/
)继承 httpd_sys_content_t
类型的文件:
- 输入以下命令查看
/var/www/html/ 的
SELinux 上下文:~]$ ls -dZ /var/www/html drwxr-xr-x root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html
这表明/var/www/html/
已使用httpd_sys_content_t
类型进行标记。 - 以 root 用户身份使用
touch
工具创建新文件:~]# touch /var/www/html/file1
- 输入以下命令查看 SELinux 上下文:
~]$ ls -Z /var/www/html/file1 -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/file1
httpd_sys_content_t
类型 的文件1
。SELinux 允许 httpd
读取使用此类型标记的文件,但不允许写入它们,即使 Linux 权限允许写入访问。SELinux 策略定义 httpd_t
域中运行的进程类型(httpd 运行
位置)可以读取和写入到哪些类型。这有助于防止进程访问由另一个进程使用的文件。
httpd
可以访问使用 httpd_sys_content_t
类型(通常用于 Apache HTTP 服务器)标记的文件,但默认情况下无法访问使用 samba_share_t
类型标记的文件(适用于 Samba)。此外,用户主目录中的文件标有 user_home_t
类型: 默认情况下,这可防止 httpd
读取或写入用户主目录中的文件。
httpd
的一些类型。不同的类型允许您配置灵活的访问:
httpd_sys_content_t
- 将此类型用于静态 Web 内容,如静态网站使用的
.html
文件。使用此类型的标记的文件可以访问httpd 和 httpd
执行脚本(仅读取)。
默认情况下,httpd
或其他进程无法将标有此类型的文件和目录写入或修改。请注意,默认情况下,在 中创建或复制到/var/www/html/
目录中的文件使用httpd_sys_content_t
类型进行标记。 httpd_sys_script_exec_t
- 将此类型用于您希望
httpd
执行的脚本。此类型通常用于/var/www/cgi-bin/
目录中的通用网关接口(CGI)脚本。默认情况下,SELinux 策略阻止httpd
执行 CGI 脚本。要允许这种情况,请使用httpd_sys_script_exec_t
类型标记脚本并启用httpd_enable_cgi
布尔值。由httpd 执行时,标有 httpd_sys_script_exec
域中运行_t
的脚本在 httpd_sys_script_t。
httpd_sys_script_t
域可以访问其他系统域,如postgresql_t
和mysqld_t
。 httpd_sys_rw_content_t
- 使用此类型标记的文件可以通过使用
httpd_sys_script_exec_t
类型标记的脚本写入到 中,但无法通过标记任何其他类型的脚本进行修改。您必须使用httpd_sys_rw_content_t
类型标记要从 并通过httpd_sys_script_exec_t
类型的脚本读取并写入的文件。 httpd_sys_ra_content_t
- 使用此类型标记的文件可以通过使用
httpd_sys_script_exec_t
类型标记的脚本附加到,但无法通过标记任何其他类型的脚本进行修改。您必须使用httpd_sys_ra_content_t 类型来
标记要从中读取的文件,并通过标有httpd_sys_script_exec_t
类型的脚本将其附加到。 httpd_unconfined_script_exec_t
- 带有此类型标记的脚本在未受到 SELinux 保护的情况下运行。耗尽所有其他选项后,仅将此类型用于复杂的脚本。最好使用这种类型,而不是对
httpd
或整个系统禁用 SELinux 保护。
~]$ grep httpd /etc/selinux/targeted/contexts/files/file_contexts
过程 13.1. 更改 SELinux 上下文
httpd
使用的 index.html
文件,并标记该文件和目录以允许 httpd
访问它们:
- 以 root 用户身份使用
mkdir
实用程序创建顶级目录结构以存储供httpd
使用的文件:~]# mkdir -p /my/website
- 在 file-context 配置中与 模式不匹配的文件和目录可能会使用
default_t
类型进行标记。受限制的服务无法访问此类型:~]$ ls -dZ /my drwxr-xr-x root root unconfined_u:object_r:default_t:s0 /my
- 以 root 身份输入以下命令,将
my/
目录和子目录的类型更改为httpd
可访问的类型:现在,在/my/website/
下创建的文件会继承httpd_sys_content_t
类型,而不是default_t
类型,因此 httpd 可以访问:~]# chcon -R -t httpd_sys_content_t /my/ ~]# touch /my/website/index.html ~]# ls -Z /my/website/index.html -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 /my/website/index.html
httpd
使用的 index.html
文件,并永久更改该目录和文件的标签以允许 httpd
访问它们:
- 以 root 用户身份使用
mkdir
实用程序创建顶级目录结构以存储供httpd
使用的文件:~]# mkdir -p /my/website
- 以 root 用户身份输入以下命令,将标签更改添加到 file-context 配置中:
~]# semanage fcontext -a -t httpd_sys_content_t "/my(/.*)?"
"/my(/.*)?"
表达式表示标签更改适用于my/
目录及其下的所有文件和目录。 - 以 root 用户身份使用
touch
工具创建新文件:~]# touch /my/website/index.html
- 以 root 身份输入以下命令来应用标签更改(restorecon 读取 file-context 配置,这由 semanage 命令在第 2 步中修改):
~]# restorecon -R -v /my/ restorecon reset /my context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0 restorecon reset /my/website context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0 restorecon reset /my/website/index.html context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0
13.3. 布尔值
httpd_anon_write
布尔值,以 root 用户身份输入以下命令:
~]# setsebool -P httpd_anon_write on
~]# setsebool -P httpd_anon_write off
-P
选项。
httpd
的运行方式:
httpd_anon_write
- 禁用后,此布尔值仅允许
httpd
对标记为public_content_rw_t
类型的文件具有读取访问权限。启用此布尔值可允许httpd
写入标有public_content_rw_t
类型的文件,例如包含公共文件传输服务文件的公共目录。 httpd_mod_auth_ntlm_winbind
- 启用此布尔值允许使用
httpd
中的mod_auth_ntlm_winbind 模块访问 NTLM 和 Winbind
身份验证机制。 httpd_mod_auth_pam
- 启用此布尔值允许使用
httpd
中的mod_auth_pam
模块访问 PAM 身份验证机制。 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
- 禁用后,此布尔值拒绝
httpd
通过D-Bus
访问avahi
服务。启用此布尔值以允许此访问。 httpd_enable_cgi
- 禁用后,此布尔值会阻止
httpd
执行 CGI 脚本。启用此布尔值以允许httpd
执行 CGI 脚本(CGI 脚本必须使用httpd_sys_script_exec_t
类型标记)。 httpd_enable_ftp_server
- 启用此布尔值允许
httpd
侦听 FTP 端口并充当 FTP 服务器。 httpd_enable_homedirs
- 禁用后,此布尔值阻止
httpd
访问用户主目录。启用此布尔值以允许httpd
访问用户主目录;例如,/home/*/ 中的内容
。 httpd_execmem
- 启用后,此布尔值允许
httpd
执行需要内存地址可执行和可写入的程序。不建议从安全角度启用此布尔值,因为它可减少对缓冲区溢出的保护,但某些模块和应用程序(如 Java 和 Mono 应用)需要此特权。 httpd_ssi_exec
- 此布尔值定义服务器端是否可以在网页中包含(SSI)元素。
httpd_tty_comm
- 此布尔值定义是否允许
httpd
访问控制终端。通常不需要这种访问,但在配置 SSL 证书文件等情形中,需要进行终端访问来显示和处理密码提示符。 httpd_unified
- 启用后,此布尔值允许
httpd_t
完全访问所有httpd
类型(即执行、读取或写入 sys_content_t)。禁用后,将区分只读、可写入或可执行的 Web 内容。禁用此布尔值可确保额外的安全级别,但增加了管理开销,即必须根据每个布尔值应具有的文件访问权限单独标记脚本和其他 Web 内容。 httpd_use_cifs
- 启用此布尔值,以允许
httpd
访问使用thecifs_t
类型标记的 CIFS 卷上的文件,例如使用 Samba 挂载的文件系统。 httpd_use_nfs
- 启用此布尔值,以允许
httpd
访问使用nfs_t
类型标记的 NFS 卷上的文件,例如使用 NFS 挂载的文件系统。
~]$ getsebool -a | grep service_name
输入以下命令查看特定布尔值的描述:
~]$ sepolicy booleans -b boolean_name
请注意,需要额外的 policycoreutils-devel 软件包来提供 sepolicy
实用程序,这个命令才能正常工作。
13.4. 配置示例
13.4.1. 运行静态站点
httpd_sys_content_t
类型标记该网站的 .html
文件。默认情况下,Apache HTTP 服务器无法写入标记为 httpd_sys_content_t
类型的文件。以下示例为只读网站创建一个新目录来存储文件:
- 以 root 用户身份使用
mkdir
实用程序创建顶级目录:~]# mkdir /mywebsite
- 以 root 用户身份,创建
/mywebsite/index.html
文件。将以下内容复制并粘贴到/mywebsite/index.html
中:<html> <h2>index.html from /mywebsite/</h2> </html>
- 要允许 Apache HTTP 服务器只读访问
/mywebsite/
以及它下的文件和子目录,请将 目录标记为httpd_sys_content_t
类型。以 root 用户身份输入以下命令,将标签更改添加到 file-context 配置中:~]# semanage fcontext -a -t httpd_sys_content_t "/mywebsite(/.*)?"
- 以 root
用户身份使用 restorecon
工具进行标签更改:~]# restorecon -R -v /mywebsite restorecon reset /mywebsite context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0 restorecon reset /mywebsite/index.html context unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0
- 在本例中,以 root 用户身份编辑
/etc/httpd/conf/httpd.conf
文件。注释掉现有的DocumentRoot
选项。添加DocumentRoot "/mywebsite"
选项。编辑后,这些选项应如下所示:#DocumentRoot "/var/www/html" DocumentRoot "/mywebsite"
- 以 root 身份输入以下命令,查看 Apache HTTP 服务器的状态。如果服务器停止,启动它:
~]# systemctl status httpd.service httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled) Active: inactive (dead)
~]# systemctl start httpd.service
如果服务器正在运行,请以 root 身份执行以下命令来重新启动服务(这也会应用对httpd.conf
所做的任何更改):~]# systemctl status httpd.service httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled) Active: active (running) since Wed 2014-02-05 13:16:46 CET; 2s ago
~]# systemctl restart httpd.service
- 使用 Web 浏览器导航到
此时会显示以下内容:
index.html from /mywebsite/
13.4.2. 共享 NFS 和 CIFS 卷
nfs_t
类型。此外,默认情况下,挂载在客户端上的 Samba 共享使用策略定义的默认上下文标记。在常见策略中,此默认上下文使用 thecifs_t
类型。
nfs_t or cifs_t
类型标记的文件。这可能会导致标记为这些类型的文件系统被挂载,然后被其他服务读取或导出。可以启用或禁用布尔值,以控制哪些服务可以访问 nfs_t
和 cifs_t
类型。
httpd_use_nfs
布尔值,以允许 httpd
访问和共享 NFS 卷(使用 nfs_t
类型标记):
~]# setsebool -P httpd_use_nfs on
httpd_use_cifs
布尔值,以允许 httpd
访问和共享 CIFS 卷(使用 cifs_t
类型标记):
~]# setsebool -P httpd_use_cifs on
-P
选项。
13.4.3. 在服务间共享文件
httpd_sys_content_t
类型标记的文件,这些文件旨在供 Apache HTTP 服务器使用。如果所需的文件标有 public_content_t 或 public_content_ rw_t
类型,则可以在 Apache HTTP 服务器、FTP、rsync
和 Samba 之间共享文件。
- 以 root 用户身份使用
mkdir
工具创建新的顶级目录,以在多个服务间共享文件:~]# mkdir /shares
- 在 file-context 配置中与 模式不匹配的文件和目录可能会使用
default_t
类型进行标记。受限制的服务无法访问此类型:~]$ ls -dZ /shares drwxr-xr-x root root unconfined_u:object_r:default_t:s0 /shares
- 以 root 用户身份,创建
/shares/index.html
文件。将以下内容复制并粘贴到/shares/index.html
中:<html> <body> <p>Hello</p> </body> </html>
- 使用
public_content_t
类型标记/shares/
允许 Apache HTTP 服务器、FTP、rsync 和 Samba 的只读访问。以 root 用户身份输入以下命令,将标签更改添加到 file-context 配置中:~]# semanage fcontext -a -t public_content_t "/shares(/.*)?"
- 以 root
用户身份使用 restorecon
工具应用标签更改:~]# restorecon -R -v /shares/ restorecon reset /shares context unconfined_u:object_r:default_t:s0->system_u:object_r:public_content_t:s0 restorecon reset /shares/index.html context unconfined_u:object_r:default_t:s0->system_u:object_r:public_content_t:s0
/shares/
:
- 确认已安装了 samba 、samba-common 和 samba-client 软件包(版本号可能有所不同):
~]$ rpm -q samba samba-common samba-client samba-3.4.0-0.41.el6.3.i686 samba-common-3.4.0-0.41.el6.3.i686 samba-client-3.4.0-0.41.el6.3.i686
如果没有安装任何这些软件包,请以 root 用户身份运行以下命令安装它们:~]# yum install package-name
- 以 root 用户身份编辑
/etc/samba/smb.conf
文件。在该文件的底部添加以下条目,以通过 Samba 共享/shares/
目录:[shares] comment = Documents for Apache HTTP Server, FTP, rsync, and Samba path = /shares public = yes writable = no
- 需要 Samba 帐户来挂载 Samba 文件系统。以 root 身份输入以下命令来创建 Samba 帐户,其中 username 是现有 Linux 用户。例如,smbpasswd -a testuser 为 Linux
testuser
用户创建一个 Samba 帐户:~]# smbpasswd -a testuser New SMB password: Enter a password Retype new SMB password: Enter the same password again Added user testuser.
如果您运行上述命令,指定系统上不存在的帐户的用户名,这会导致Cannot locate Unix 帐户出现 'username'!
错误。 - 启动 Samba 服务:
~]# systemctl start smb.service
- 输入以下命令列出可用的共享,其中 username 是第 3 步中添加的 Samba 帐户。提示输入密码时,在第 3 步中输入分配给 Samba 帐户的密码(版本号可能有所不同):
~]$ smbclient -U username -L localhost Enter username's password: Domain=[HOSTNAME] OS=[Unix] Server=[Samba 3.4.0-0.41.el6] Sharename Type Comment --------- ---- ------- shares Disk Documents for Apache HTTP Server, FTP, rsync, and Samba IPC$ IPC IPC Service (Samba Server Version 3.4.0-0.41.el6) username Disk Home Directories Domain=[HOSTNAME] OS=[Unix] Server=[Samba 3.4.0-0.41.el6] Server Comment --------- ------- Workgroup Master --------- -------
- 用户
mkdir
实用程序来创建新目录。该目录将用于挂载共享
Samba 共享:~]# mkdir /test/
- 以 root 身份输入以下命令将
共享 Samba 共享
挂载到/test/
,将 username 替换为第 3 步中的用户名:~]# mount //localhost/shares /test/ -o user=username
输入 username 的密码,这是在第 3 步中配置的。 - 查看通过 Samba 共享的 文件的内容:
~]$ cat /test/index.html <html> <body> <p>Hello</p> </body> </html>
/shares/
:
- 确认已安装 httpd 软件包(版本号可能有所不同):
~]$ rpm -q httpd httpd-2.2.11-6.i386
如果没有安装这个软件包,以 root用户身份使用 yum
工具安装它:~]# yum install httpd
- 更改到
/var/www/html/
目录。以 root 用户身份输入以下命令来创建/shares/
目录的链接(名为共享
):html]# ln -s /shares/ shares
- 启动 Apache HTTP 服务器:
~]# systemctl start httpd.service
- 使用 Web 浏览器导航到
显示
/shares/index.html
文件。
index.html
文件(如果存在)。如果 /shares/
没有 index.html
,且有 file1
、file2
和 file3
,则访问 http://localhost/shares
时会出现目录列表:
- 删除
index.html
文件:~]# rm -i /shares/index.html
- 以 root
用户身份使用 touch
实用程序在/shares/
中创建三个文件:~]# touch /shares/file{1,2,3} ~]# ls -Z /shares/ -rw-r--r-- root root system_u:object_r:public_content_t:s0 file1 -rw-r--r-- root root unconfined_u:object_r:public_content_t:s0 file2 -rw-r--r-- root root unconfined_u:object_r:public_content_t:s0 file3
- 以 root 用户身份输入以下命令查看 Apache HTTP 服务器的状态:
~]# systemctl status httpd.service httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled) Active: inactive (dead)
如果服务器停止,启动它:~]# systemctl start httpd.service
- 使用 Web 浏览器导航到
此时会显示目录列表:
13.4.4. 更改端口号
semanage
工具列出 SELinux 允许 httpd
侦听的端口:
~]# semanage port -l | grep -w http_port_t
http_port_t tcp 80, 443, 488, 8008, 8009, 8443
httpd
侦听 TCP 端口 80、443、488、8008、8009 或 8443。如果配置了 /etc/httpd/conf/httpd.conf
,以便 httpd
侦听未列出的 http_port_t
端口,httpd无法启动
。
httpd
配置为在 TCP 端口 80、443、488、8008、8009 或 8443 以外的端口中运行:
- 以 root 用户身份编辑
/etc/httpd/conf/httpd.conf
文件,以便Listen
选项列出httpd
的 SELinux 策略中未配置的端口。以下示例将httpd
配置为侦听 10.0.0.1 IP 地址和 TCP 端口 12345:# 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
- 以 root 用户身份输入以下命令,将端口添加到 SELinux 策略配置中:
~]# 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
httpd
,请以 root 用户身份使用 semanage
工具从策略配置中删除端口:
~]# semanage port -d -t http_port_t -p tcp 12345
第 14 章 Samba
~]$ rpm -q samba
package samba is not installed
yum
工具来安装它:
~]# yum install samba
14.1. Samba 和 SELinux
smbd
)默认运行限制。受限制的服务在自己的域中运行,与其他受限服务分离。以下示例演示了在自己的域中运行的 smbd
进程。本例假设安装了 samba 软件包:
- 运行 getenforce 命令确认 SELinux 是否以强制模式运行:
~]$ getenforce Enforcing
当 SELinux 以强制模式运行时,该命令将返回强制
。 - 以 root 用户身份输入以下命令启动
smbd
:~]# systemctl start smb.service
确认 服务正在运行。输出中应包括以下信息(只有时间戳有所不同):~]# systemctl status smb.service smb.service - Samba SMB Daemon Loaded: loaded (/usr/lib/systemd/system/smb.service; disabled) Active: active (running) since Mon 2013-08-05 12:17:26 CEST; 2h 22min ago
- 要查看
smbd
进程,请执行以下命令:~]$ ps -eZ | grep smb system_u:system_r:smbd_t:s0 9653 ? 00:00:00 smbd system_u:system_r:smbd_t:s0 9654? 00:00:00 smbd
与smbd
进程关联的 SELinux 上下文为system_u:system_r:smbd_t:s0。
上下文的第二部分smbd_t
是类型。类型定义进程的域以及文件的类型。在本例中,smbd 进程
在smbd_t
域中运行。
smbd
访问和共享这些文件。例如,smbd
可以读取和写入标有 samba_share_t
类型的文件,但默认情况下,无法访问使用 Apache HTTP 服务器使用 httpd_sys_content_t
类型的文件。必须启用布尔值以允许某些行为,例如允许通过 Samba 导出主目录和 NFS 卷,以及允许 Samba 充当域控制器。
14.2. 类型
samba_share_t
类型标记文件,以允许 Samba 共享它们。仅标记您创建的文件,且不要使用 samba_share_t
类型重新标记系统文件:可以启用布尔值以共享此类文件和目录。只要相应地设置了 /etc/samba/smb.conf
文件,SELinux 允许 Samba 写入使用 samba_share_t
类型标记的文件。
samba_etc_t
类型用于 /etc/samba/
目录中的某些文件,如 smb.conf
。不要使用 samba_etc_t
类型手动标记文件。如果此目录中的文件没有正确标记,请以 root 用户身份输入 restorecon -R -v /etc/samba 命令,将这些文件恢复到其默认上下文。如果 /etc/samba/smb.conf
没有使用 samba_etc_t
类型标记,启动 Samba 服务可能会失败,并且可能会记录 SELinux 拒绝消息。以下是 /etc/samba/smb.conf
使用 httpd_sys_content_t
类型标记时的拒绝信息示例:
setroubleshoot: SELinux is preventing smbd (smbd_t) "read" to ./smb.conf (httpd_sys_content_t). For complete SELinux messages. run sealert -l deb33473-1069-482b-bb50-e4cd05ab18af
14.3. 布尔值
smbd_anon_write
- 启用此布尔值后,smb
d
便可写入公共目录,例如为其他情况下没有特殊访问限制的常用文件保留的区域。 samba_create_home_dirs
- 启用此布尔值后,Samba 便可独立创建新的主目录。这通常通过 PAM 等机制执行。
samba_domain_controller
- 启用后,此布尔值允许 Samba 充当域控制器,并授予其执行 useradd、groupadd 和 passwd 等相关命令的权限。
samba_enable_home_dirs
- 启用此布尔值可让 Samba 共享用户的主目录。
samba_export_all_ro
- 导出任何文件或目录,允许只读权限。这样,未使用
samba_share_t
类型标记的文件和目录可以通过 Samba 共享。当启用了samba_export_all_ro
布尔值,但samba_export_all_rw
布尔值被禁用时,对 Samba 共享的写入访问将被拒绝,即使在/etc/samba/smb.conf
中配置了写入访问权限,也允许写入访问权限。 samba_export_all_rw
- 导出任何文件或目录,允许读取和写入权限。这允许通过 Samba 导出没有使用
samba_share_t
类型标记的文件和目录。必须将/etc/samba/smb.conf
中的权限和 Linux 权限配置为允许写入访问。 samba_run_unconfined
- 启用此布尔值后,Samba 就可以运行
/var/lib/samba/scripts/
目录中未限制的脚本。 samba_share_fusefs
- 必须启用此布尔值,以便 Samba 共享 fusefs 文件系统。
samba_share_nfs
- 禁用此布尔值可防止
smbd
通过 Samba 对 NFS 共享具有完全访问权限。启用此布尔值将允许 Samba 共享 NFS 卷。 use_samba_home_dirs
- 启用此布尔值,将远程服务器用于 Samba 主目录。
virt_use_samba
- 允许虚拟机访问 CIFS 文件.
~]$ getsebool -a | grep service_name
输入以下命令查看特定布尔值的描述:
~]$ sepolicy booleans -b boolean_name
请注意,需要额外的 policycoreutils-devel 软件包来提供 sepolicy
实用程序,这个命令才能正常工作。
14.4. 配置示例
14.4.1. 共享您创建的目录
- 确认已安装 samba 、samba-common 和 samba-client 软件包:
~]$ rpm -q samba samba-common samba-client package samba is not installed package samba-common is not installed package samba-client is not installed
如果没有安装这些软件包,以 root 用户身份使用yum
工具安装它们:~]# yum install package-name
- 以 root 用户身份使用
mkdir
实用程序创建一个新的顶级目录,以通过 Samba 共享文件:~]# mkdir /myshare
- 使用
touch
实用程序 root 创建空文件。此文件稍后用于验证 Samba 共享正确挂载:~]# touch /myshare/file1
- 只要相应地设置了
/etc/samba/smb.conf
文件,SELinux 允许 Samba 读取和写入标记有samba_share_t
类型的文件。以 root 用户身份输入以下命令,将标签更改添加到 file-context 配置中:~]# semanage fcontext -a -t samba_share_t "/myshare(/.*)?"
- 以 root
用户身份使用 restorecon
工具应用标签更改:~]# restorecon -R -v /myshare restorecon reset /myshare context unconfined_u:object_r:default_t:s0->system_u:object_r:samba_share_t:s0 restorecon reset /myshare/file1 context unconfined_u:object_r:default_t:s0->system_u:object_r:samba_share_t:s0
- 以 root 用户身份编辑
/etc/samba/smb.conf
。在该文件的底部添加以下内容,以通过 Samba 共享/myshare/
目录:[myshare] comment = My share path = /myshare public = yes writable = no
- 需要 Samba 帐户来挂载 Samba 文件系统。以 root 身份输入以下命令来创建 Samba 帐户,其中 username 是现有 Linux 用户。例如,smbpasswd -a testuser 为 Linux
testuser
用户创建一个 Samba 帐户:~]# smbpasswd -a testuser New SMB password: Enter a password Retype new SMB password: Enter the same password again Added user testuser.
如果您输入以上命令并指定系统中不存在的帐户的用户名,这会导致Cannot locate Unix 帐户出现 'username'!
错误。 - 启动 Samba 服务:
~]# systemctl start smb.service
- 输入以下命令列出可用的共享,其中 username 是第 7 步中添加的 Samba 帐户。提示输入密码时,在第 7 步中输入分配给 Samba 帐户的密码(版本号可能有所不同):
~]$ smbclient -U username -L localhost Enter username's password: Domain=[HOSTNAME] OS=[Unix] Server=[Samba 3.4.0-0.41.el6] Sharename Type Comment --------- ---- ------- myshare Disk My share IPC$ IPC IPC Service (Samba Server Version 3.4.0-0.41.el6) username Disk Home Directories Domain=[HOSTNAME] OS=[Unix] Server=[Samba 3.4.0-0.41.el6] Server Comment --------- ------- Workgroup Master --------- -------
- 以 root 用户身份使用
mkdir
实用程序来创建新目录。该目录将用于挂载myshare
Samba 共享:~]# mkdir /test/
- 以 root 身份输入以下命令将
myshare
Samba 共享挂载到/test/
,将 username 替换为第 7 步中的用户名:~]# mount //localhost/myshare /test/ -o user=username
输入 username 的密码,该密码在第 7 步中配置。 - 输入以下命令查看在第 3 步中创建的
file1
文件:~]$ ls /test/ file1
14.4.2. 共享网站
samba_share_t
类型标记文件,例如,当想要在 /var/www/html/
目录中共享网站时。对于这样的情形,请使用 samba_export_all_ro
布尔值共享任何文件或目录(不考虑当前标签)、允许只读权限,或者使用 samba_export_all_rw
布尔值共享任何文件或目录(无当前标签除外),允许读取和写入权限。
/var/www/html/
中为网站创建一个文件,然后通过 Samba 共享该文件,允许读取和写入权限。本例假定安装了 httpd、samba、samba-common、samba-client 和 wget 软件包:
- 以 root 用户身份,创建
/var/www/html/file1.html
文件。将以下内容复制并粘贴到该文件中:<html> <h2>File being shared through the Apache HTTP Server and Samba.</h2> </html>
- 输入以下命令查看
file1.html
的 SELinux 上下文:~]$ ls -Z /var/www/html/file1.html -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/file1.html
该文件标有httpd_sys_content_t
标签。默认情况下,Apache HTTP 服务器可以访问此类型,但 Samba 不能。 - 启动 Apache HTTP 服务器:
~]# systemctl start httpd.service
- 更改到用户具有写入权限的目录,并输入以下命令。除非对默认配置进行了更改,否则这个命令会成功:
~]$ wget http://localhost/file1.html Resolving localhost... 127.0.0.1 Connecting to localhost|127.0.0.1|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 84 [text/html] Saving to: `file1.html.1' 100%[=======================>] 84 --.-K/s in 0s `file1.html.1' saved [84/84]
- 以 root 用户身份编辑
/etc/samba/smb.conf
。在该文件的底部添加以下内容,通过 Samba 共享/var/www/html/
目录:[website] comment = Sharing a website path = /var/www/html/ public = no writable = no
/var/www/html/
目录标有httpd_sys_content_t
类型。默认情况下,Samba 无法访问使用此类型标记的文件和目录,即使 Linux 权限允许这样做。要允许 Samba 访问,请启用samba_export_all_ro
布尔值:~]# setsebool -P samba_export_all_ro on
如果您不希望更改在重新引导后保留,则不要使用-P
选项。请注意,启用samba_export_all_ro
布尔值可允许 Samba 访问任何类型。- 启动 Samba 服务:
~]# systemctl start smb.service
第 15 章 文件传输协议
vsftpd
)设计为快速、稳定且最重要的是安全。它能够高效且安全地处理大量连接,因此 vsftpd
是唯一随 Red Hat Enterprise Linux 分发的独立 FTP 的原因。
~]$ rpm -q vsftpd
package vsftpd is not installed
yum
工具安装它:
~]# yum install vsftpd
15.1. 类型
/var/ftp/
目录中的文件具有读取访问权限。此目录标有 public_content_t
类型,仅允许读取访问权限,即使 /etc/vsftpd/vsftpd.conf
中配置了写入访问权限。public_content_t
类型可供其他服务访问,如 Apache HTTP 服务器、Samba 和 NFS。
public_content_t
- 使用
public_content_t
类型标记您创建的文件和目录,以便通过vsftpd
以只读方式共享它们。其他服务(如 Apache HTTP 服务器、Samba 和 NFS)也有权访问使用此类型标记的文件。标签有public_content_t
类型的文件无法写入,即使 Linux 权限允许写入访问。如果需要写入访问权限,请使用public_content_rw_t
类型。 public_content_rw_t
- 使用
public_content_rw_t
类型标记您创建的文件和目录,以通过vsftpd
使用读写权限共享它们。其他服务(如 Apache HTTP 服务器、Samba 和 NFS)也有权访问使用此类型标记的文件。请记住,必须为每个服务启用布尔值,然后才能写入标有此类型的文件。
15.2. 布尔值
ftpd_anon_write
- 禁用后,此布尔值可防止
vsftpd
写入标有public_content_rw_t
类型的文件和目录。启用此布尔值,以允许用户使用 FTP 上传文件。将文件上传到 的目录必须使用public_content_rw_t
类型进行标记,并且必须相应地设置 Linux 权限。 ftpd_full_access
- 启用此布尔值后,只有 Linux(DAC)权限用于控制访问权限,经过身份验证的用户也可以读取和写入没有使用 public_content_t
或 public_content_
rw_t
类型标记的文件。 ftpd_use_cifs
- 启用此布尔值后,
vsftpd
可以访问标有thecifs_t
类型的文件和目录;因此,启用此布尔值后,您可以共享通过vsftpd
使用 Samba 挂载的文件系统。 ftpd_use_nfs
- 启用此布尔值后,
vsftpd
可以访问标有nfs_t
类型的文件和目录;因此,这个布尔值允许您共享通过vsftpd
使用 NFS 挂载的文件系统。 ftpd_connect_db
- 允许 FTP 后台程序启动与数据库的连接.
httpd_enable_ftp_server
- 允许
httpd
守护进程侦听 FTP 端口并充当 FTP 服务器。 tftp_anon_write
- 启用此布尔值后,TFTP 可以访问公共目录,例如为其他情况下没有特殊访问限制的常用文件保留区域。
ftp_home_dir
布尔值。如需更多信息,请参阅 Red Hat Enterprise Linux 7.3 发行注记 文档。
~]$ getsebool -a | grep service_name
输入以下命令查看特定布尔值的描述:
~]$ sepolicy booleans -b boolean_name
请注意,需要额外的 policycoreutils-devel 软件包来提供 sepolicy
实用程序,这个命令才能正常工作。
第 16 章 网络文件系统
~]$ rpm -q nfs-utils
package nfs-utils is not installed
yum
工具作为 root 来安装它:
~]# yum install nfs-utils
16.1. NFS 和 SELinux
nfsd
进程除外,该进程使用 unconfined kernel_t
域类型进行标记。默认情况下,SELinux 策略允许 NFS 共享文件。此外,还支持在客户端和服务器之间传递 SELinux 标签,这可以为访问 NFS 卷的受限制域提供更好的安全控制。例如,在 NFS 卷上设置主目录时,可以指定只能访问主目录而非卷中其他目录的受限制域。同样,安全虚拟化等应用可以在 NFS 卷上设置镜像文件的标签,从而提高虚拟机的隔离级别。
16.2. 类型
nfs_t
类型。root 用户可以使用 mount -context
选项覆盖默认类型。以下类型用于 NFS:不同的类型允许您配置灵活的访问:
var_lib_nfs_t
- 此类型用于复制到
/var/lib/nfs/
目录中的现有文件和新文件。在正常操作中不需要更改此类型。要恢复对默认设置的更改,以 root 用户身份运行 restorecon -R -v /var/lib/nfs 命令。 nfsd_exec_t
/usr/sbin/rpc.nfsd
文件标有nfsd_exec_t
标签,以及其他系统可执行文件和与 NFS 相关的库也是如此。用户不应为此类型标记任何文件。nfsd_exec_t
将过渡到nfsd_t
。
16.3. 布尔值
ftpd_use_nfs
- 启用后,此布尔值允许
ftpd
守护进程访问 NFS 卷。 cobbler_use_nfs
- 启用后,此布尔值允许
cobblerd
守护进程访问 NFS 卷。 git_system_use_nfs
- 启用后,此布尔值允许 Git 系统守护进程读取 NFS 卷上的系统共享存储库。
httpd_use_nfs
- 启用后,此布尔值允许
httpd
守护进程访问 NFS 卷中存储的文件。 samba_share_nfs
- 启用后,此布尔值允许
smbd
守护进程共享 NFS 卷。禁用后,此布尔值可防止smbd
使用 Samba 对 NFS 共享具有完全访问权限。 sanlock_use_nfs
- 启用后,这个布尔值允许
sanlock
守护进程管理 NFS 卷。 sge_use_nfs
- 启用后,此布尔值允许
sge
调度程序访问 NFS 卷。 use_nfs_home_dirs
- 启用后,这个布尔值添加了对 NFS 主目录的支持。
virt_use_nfs
- 启用后,此布尔值允许自信虚拟客户机管理 NFS 卷上的文件。
xen_use_nfs
- 启用后,此布尔值允许
Xen
管理 NFS 卷上的文件。 git_cgi_use_nfs
- 启用后,此布尔值允许 Git 通用网关接口(CGI)访问 NFS 卷。
~]$ getsebool -a | grep service_name
输入以下命令查看特定布尔值的描述:
~]$ sepolicy booleans -b boolean_name
请注意,需要额外的 policycoreutils-devel 软件包来提供 sepolicy
实用程序,这个命令才能正常工作。
16.4. 配置示例
16.4.1. 启用 SELinux 标记的 NFS 支持
nfs-srv
上执行第 1-3 步。
- 如果 NFS 服务器正在运行,请停止它:
[nfs-srv]# systemctl stop nfs
确认服务器已停止:[nfs-srv]# systemctl status nfs nfs-server.service - NFS Server Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; disabled) Active: inactive (dead)
- 编辑
/etc/sysconfig/nfs
文件,将RPCNFSDARGS
标志设置为"-V 4.2:
# Optional arguments passed to rpc.nfsd. See rpc.nfsd(8) RPCNFSDARGS="-V 4.2"
- 再次启动服务器,并确认它正在运行。输出将包含以下信息,只有时间戳会有所不同:
[nfs-srv]# systemctl start nfs
[nfs-srv]# systemctl status nfs nfs-server.service - NFS Server Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; disabled) Active: active (exited) since Wed 2013-08-28 14:07:11 CEST; 4s ago
- 在客户端中挂载 NFS 服务器:
[nfs-client]# mount -o v4.2 server:mntpoint localmountpoint
- 现在,所有 SELinux 标签都从服务器成功传递给客户端:
[nfs-srv]$ ls -Z file -rw-rw-r--. user user unconfined_u:object_r:svirt_image_t:s0 file [nfs-client]$ ls -Z file -rw-rw-r--. user user unconfined_u:object_r:svirt_image_t:s0 file
第 17 章 Berkeley Internet 名称域
指定的
守护进程执行名称解析服务。BIND 允许用户按名称而非数字地址查找计算机资源和服务。
~]$ rpm -q bind
package bind is not installed
yum
工具安装它:
~]# yum install bind
17.1. BIND 和 SELinux
/var/named/slaves/、/
var/named/dynamic/
和 /var/named/data/
目录的默认权限允许使用区域传送和动态 DNS 更新来更新区域文件。/var/named/
中的文件使用 named_zone_t
类型标记,该类型用于主区域文件。
/etc/named.conf
文件配置为将从属区域放置在 /var/named/slaves/
中。以下是在 /var/named/slaves/
中存储 testdomain.com
的区域文件的从属
DNS 服务器中的域条目示例:
zone "testdomain.com" { type slave; masters { IP-address; }; file "/var/named/slaves/db.testdomain.com"; };
named_zone_t
,则必须启用 named_write_master_zones
布尔值,以允许区域传送和动态 DNS 更新区域文件。此外,必须更改父目录的模式,以允许 指定用户
或组具有读取、写入和执行访问权限。
/var/named/
中的区域文件标有 named_cache_t
类型,则文件系统重新标记或运行 restorecon -R /var/ 将将其类型更改为 named_zone_t
。
17.2. 类型
named_zone_t
- 用于主区域文件.其他服务无法修改此类型的文件。只有启用了
named
_write_master_zones
布尔值时,指定守护进程才能修改此类型的文件。 named_cache_t
- 默认情况下,
named
可以写入使用此类型标记的文件,而不设置额外的布尔值。在/var/named/slaves/、/
复制或创建的文件会自动标记为var/
named/dynamic/ 和/var/
named/data/ 目录中named_cache_t
类型。 named_var_run_t
- 在
/var/run/bind/、/
复制或创建的文件会自动标记为var/
run/named/ 和/var/
run/unbound/ 目录中named_var_run_t
类型。 named_conf_t
- 与 BIND 相关的配置文件通常存储在
/etc
目录中,使用named_conf_t
类型自动标记。 named_exec_t
- 与 BIND 相关的可执行文件通常存储在
/usr/sbin/
目录中,使用named_exec_t
类型自动标记。 named_log_t
- 与 BIND 相关的日志文件通常存储在
/var/log/
目录中,使用named_log_t
类型自动标记。 named_unit_file_t
/usr/lib/systemd/system/
目录中的可执行 BIND 相关文件会自动使用named_unit_file_t
类型进行标记。
17.3. 布尔值
named_write_master_zones
- 禁用后,此布尔值可防止
named
写入标记为named_zone_t
类型的区域文件或目录。守护进程通常不需要写入区域文件;但是,如果需要,或者次要服务器需要写入区域文件,请启用此布尔值以允许执行此操作。 named_tcp_bind_http_port
- 启用后,此布尔值允许 BIND 绑定 Apache 端口。
~]$ getsebool -a | grep service_name
输入以下命令查看特定布尔值的描述:
~]$ sepolicy booleans -b boolean_name
请注意,需要额外的 policycoreutils-devel 软件包来提供 sepolicy
实用程序,这个命令才能正常工作。
17.4. 配置示例
17.4.1. 动态 DNS
/var/named/dynamic/
目录。在 中创建或复制到此目录中创建的文件将继承 Linux 权限,允许 named
写入它们。由于这些文件使用 named_cache_t
类型标记,SELinux 允许 named
向它们写入。
/var/named/dynamic/
中的区域文件标有 named_zone_t
类型,则动态 DNS 更新可能在特定时间段内不成功,因为更新需要在合并之前首先写入到日志中。如果在日志尝试合并时使用 named_zone_t
类型标记区域文件,则会记录如下错误:
named[PID]: dumping master file: rename: /var/named/dynamic/zone-name: permission denied
setroubleshoot: SELinux is preventing named (named_t) "unlink" to zone-name (named_zone_t)
restorecon
工具:
~]# restorecon -R -v /var/named/dynamic
第 18 章 并发版本系统
~]$ rpm -q cvs
package cvs is not installed
用户身份使用 yum
工具来安装它:
~]# yum install cvs
18.1. CVS 和 SELinux
cvs
守护进程使用 cvs_t
类型运行。默认情况下,在 Red Hat Enterprise Linux 中,CVS 只允许读取和写入某些目录。标签 cvs_data_t
定义 cvs
对哪些区域具有读取和写入访问权限。将 CVS 与 SELinux 搭配使用时,必须分配正确的标签,以便客户端能够完全访问为 CVS 数据保留的区域。
18.2. 类型
cvs_data_t
- 此类型用于 CVS 存储库中的数据。CVS 只有当数据具有此类型时,才可获得对数据的完整访问权限。
cvs_exec_t
- 此类型用于
/usr/bin/cvs
二进制文件。
18.3. 布尔值
cvs_read_shadow
- 此布尔值允许
cvs
守护进程访问/etc/shadow
文件以进行用户身份验证。
~]$ getsebool -a | grep service_name
输入以下命令查看特定布尔值的描述:
~]$ sepolicy booleans -b boolean_name
请注意,需要额外的 policycoreutils-devel 软件包来提供 sepolicy
实用程序,这个命令才能正常工作。
18.4. 配置示例
18.4.1. 设置 CVS
cvs-srv
的 CVS 服务器,IP 地址为 192.168.1.1
,主机名为 cvs-client
的客户端,以及 IP 地址 192.168.1.100
。两个主机在同一子网(192.168.1.0/24)中。这只是一个示例,假设已安装了 cvs 和 xinetd 软件包,使用了 SELinux targeted 策略,并且 SELinux 正以强制模式运行。
vs-srv.
- 这个示例需要 cvs 和 xinetd 软件包。确认已安装了软件包:
[cvs-srv]$ rpm -q cvs xinetd package cvs is not installed package xinetd is not installed
如果没有安装,以 root用户身份使用 yum
工具安装它:[cvs-srv]# yum install cvs xinetd
- 以 root 用户身份输入以下命令,创建一个名为
CVS
的组:[cvs-srv]# groupadd CVS
这也可通过使用system-config-users
实用程序来完成。 - 创建一个用户名为
cvsuser 的用户
,并使该用户成为 CVS 组的成员。这可以通过system-config-users
完成。 - 编辑
/etc/services
文件,并确保 CVS 服务器具有类似如下的未注释条目:cvspserver 2401/tcp # CVS client/server operations cvspserver 2401/udp # CVS client/server operations
- 在文件系统的根区域创建 CVS 存储库。在使用 SELinux 时,最好在 root 文件系统中包含 存储库,以便为它指定递归标签,而不影响任何其他子目录。例如,以 root 用户身份创建一个
/cvs/
目录来存放存储库:[root@cvs-srv]# mkdir /cvs
- 为所有用户授予
/cvs/
目录的完整权限:[root@cvs-srv]# chmod -R 777 /cvs
警告这只是一个示例,不应在生产系统中使用这些权限。 - 编辑
/etc/xinetd.d/cvs
文件,并确保 CVS 部分未注释并配置为使用/cvs/
目录。该文件应类似于:service cvspserver { disable = no port = 2401 socket_type = stream protocol = tcp wait = no user = root passenv = PATH server = /usr/bin/cvs env = HOME=/cvs server_args = -f --allow-root=/cvs pserver # bind = 127.0.0.1
- 启动
xinetd
守护进程:[cvs-srv]# systemctl start xinetd.service
- 添加一条规则,允许使用
system-config-firewall
实用程序通过端口 2401 上的 TCP 进行入站连接。 - 在客户端中,以
cvsuser
用户身份输入以下命令:[cvsuser@cvs-client]$ cvs -d /cvs init
- 此时,CVS 已配置好,但 SELinux 仍会拒绝登录和文件访问。要演示这一点,请在
cvs-client
上设置$CVSROOT
变量并尝试远程登录。以下步骤应该在cvs-client
上执行:[cvsuser@cvs-client]$ export CVSROOT=:pserver:cvsuser@192.168.1.1:/cvs [cvsuser@cvs-client]$ [cvsuser@cvs-client]$ cvs login Logging in to :pserver:cvsuser@192.168.1.1:2401/cvs CVS password: ******** cvs [login aborted]: unrecognized auth response from 192.168.100.1: cvs pserver: cannot open /cvs/CVSROOT/config: Permission denied
SELinux 已阻止访问。为了让 SELinux 允许此访问,应该在cvs-srv
上执行以下步骤: - 更改
/cvs/
目录的上下文,以便以递归方式标记/cvs/
目录中的任何现有和新数据,为其提供cvs_data_t
类型:[root@cvs-srv]# semanage fcontext -a -t cvs_data_t '/cvs(/.*)?' [root@cvs-srv]# restorecon -R -v /cvs
- 客户端
cvs-client
现在能够登录并访问这个仓库中的所有 CVS 资源:[cvsuser@cvs-client]$ export CVSROOT=:pserver:cvsuser@192.168.1.1:/cvs [cvsuser@cvs-client]$ [cvsuser@cvs-client]$ cvs login Logging in to :pserver:cvsuser@192.168.1.1:2401/cvs CVS password: ******** [cvsuser@cvs-client]$
第 19 章 Squid 缓存代理
~]$ rpm -q squid
package squid is not installed
用户身份使用 yum
工具来安装它:
~]# yum install squid
19.1. Squid 缓存代理和 SELinux
- 运行 getenforce 命令确认 SELinux 是否以强制模式运行:
~]$ getenforce Enforcing
当 SELinux 以强制模式运行时,该命令将返回强制
。 - 以 root 用户身份输入以下命令启动
squid
守护进程:~]# systemctl start squid.service
确认 服务正在运行。输出中应包括以下信息(只有时间戳有所不同):~]# systemctl status squid.service squid.service - Squid caching proxy Loaded: loaded (/usr/lib/systemd/system/squid.service; disabled) Active: active (running) since Mon 2013-08-05 14:45:53 CEST; 2s ago
- 输入以下命令查看
squid 进程
:~]$ ps -eZ | grep squid system_u:system_r:squid_t:s0 27018 ? 00:00:00 squid system_u:system_r:squid_t:s0 27020 ? 00:00:00 log_file_daemon
与squid
进程关联的 SELinux 上下文为system_u:system_r:squid_t:s0。
上下文的第二部分squid_t
是类型。类型定义进程的域以及文件的类型。在本例中,Squid 进程在squid_t
域中运行。
squid_t
,它们通常与文件、其他进程和系统交互。文件必须正确标记,以允许对文件进行 squid 访问。
/etc/squid/squid.conf
文件被配置为 squid
侦听默认 TCP 端口 3128、3401 或 4827 以外的端口时,必须使用 semanage port 命令将所需的端口号添加到 SELinux 策略配置中。以下示例演示了将 squid
配置为侦听 SELinux 策略配置中最初未为其定义的端口,因此,服务器无法启动。本例还演示如何配置 SELinux 系统,以允许 守护进程成功侦听策略中尚未定义的非标准端口。本例假定已安装了 squid 软件包。以 root 用户身份运行示例中的每个命令:
- 确认
squid
守护进程没有运行:~]# systemctl status squid.service squid.service - Squid caching proxy Loaded: loaded (/usr/lib/systemd/system/squid.service; disabled) Active: inactive (dead)
如果输出不同,请停止该进程:~]# systemctl stop squid.service
- 输入以下命令查看 SELinux 允许
squid
侦听的端口:~]# semanage port -l | grep -w -i squid_port_t squid_port_t tcp 3401, 4827 squid_port_t udp 3401, 4827
- 以 root 用户身份编辑
/etc/squid/squid.conf
。配置http_port
选项,使其列出squid
的 SELinux 策略配置中未配置的端口。在这个示例中,守护进程被配置为侦听端口 10000:# Squid normally listens to port 3128 http_port 10000
- 运行 setsebool 命令,确保
squid_connect_any
布尔值设置为 off。这样可保证squid
只允许在特定端口上操作:~]# setsebool -P squid_connect_any 0
- 启动
squid
守护进程:~]# systemctl start squid.service Job for squid.service failed. See 'systemctl status squid.service' and 'journalctl -xn' for details.
记录类似如下的 SELinux 拒绝信息:localhost setroubleshoot: SELinux is preventing the squid (squid_t) from binding to port 10000. For complete SELinux messages. run sealert -l 97136444-4497-4fff-a7a7-c4d8442db982
- 为了使 SELinux 允许
squid
侦听端口 10000,如本例中使用的那样,需要使用以下命令:~]# semanage port -a -t squid_port_t -p tcp 10000
- 再次启动
squid
并使其监听新端口:~]# systemctl start squid.service
- 现在 SELinux 已配置为允许 Squid 侦听非标准端口(本示例中为 TCP 10000),它在此端口上成功启动。
19.2. 类型
httpd_squid_script_exec_t
- 此类型用于诸如
cachemgr.cgi
等实用程序,它提供有关 Squid 及其配置的各种统计信息。 squid_cache_t
- 将此类型用于由 Squid 缓存的数据,如
/etc/squid/squid.conf
中的cache_dir
指令所定义。默认情况下,在 中创建或复制到/var/cache/squid/ 和
目录中的文件使用/var/
spool/squid/squid_cache_t
类型进行标记。用于在 中创建或复制到/var/squid Guard / 目录的
URL 重定向器插件的文件也使用squid
Guardsquid_cache_t
类型标记。Squid 只能将标记为此类型的文件和目录用于其缓存的数据。 squid_conf_t
- 此类型用于 Squid 配置的目录和文件。现有文件或者在 中创建或复制到
/etc/squid/ 和
目录的文件均使用此类型进行标记,包括错误消息和图标。/usr/
share/squid/ squid_exec_t
- 此类型用于
squid
二进制文件/usr/sbin/squid
。 squid_log_t
- 此类型用于日志。现有文件或者在 中创建或复制到
/var/log/squid/ 或
必须使用此类型进行标记。/var/
log/squidGuard/ 的文件 squid_initrc_exec_t
- 此类型用于启动
squid
(位于/etc/rc.d/init.d/squid
)所需的初始化文件。 squid_var_run_t
- 此类型供
/var/run/
目录中的文件使用,特别是名为/var/run/squid.pid
的进程 ID(PID),该进程在运行时由 Squid 创建。
19.3. 布尔值
squid_connect_any
- 启用后,此布尔值允许 Squid 发起与任何端口上的远程主机的连接。
squid_use_tproxy
- 启用后,此布尔值允许 Squid 作为透明代理运行。
~]$ getsebool -a | grep service_name
输入以下命令查看特定布尔值的描述:
~]$ sepolicy booleans -b boolean_name
请注意,需要额外的 policycoreutils-devel 软件包来提供 sepolicy
实用程序,这个命令才能正常工作。
19.4. 配置示例
19.4.1. Squid 连接到非标准端口
- 确认已安装了 squid :
~]$ rpm -q squid package squid is not installed
如果没有安装该软件包,以 root用户身份使用 yum
工具安装它:~]# yum install squid
- 编辑主配置文件
/etc/squid/squid.conf
,并确认cache_dir
指令没有被注释,如下所示:cache_dir ufs /var/spool/squid 100 16 256
此行指定要在本示例中使用的cache_dir
指令的默认设置;它由 Squid 存储格式(ufs
)、缓存所在系统上的目录(/var/spool/squid
)组成,以兆字节为单位的磁盘空间大小(分别为16
和256
)
,最后包含 Squid 存储格式(ufs)。 - 在同一配置文件中,确保
http_access allow localnet
指令已被取消注释。这允许来自localnet
ACL 的流量(在 Red Hat Enterprise Linux 上的 Squid 默认安装中自动配置)。它将允许任何现有 RFC1918 网络上的客户端计算机通过代理进行访问,这足以满足这个简单示例。 - 在同一配置文件中,确保 see
_hostname
指令未注释,并且已配置为计算机的主机名。该值应该是主机的完全限定域名(FQDN):visible_hostname squid.example.com
- 以 root 身份,输入以下命令启动
squid
守护进程。由于这是squid
首次启动时,这个命令会按照cache_dir
指令上方指定的缓存目录初始化,然后启动守护进程:~]# systemctl start squid.service
确保squid
启动成功。输出将包括以下信息,只有时间戳会有所不同:~]# systemctl status squid.service squid.service - Squid caching proxy Loaded: loaded (/usr/lib/systemd/system/squid.service; disabled) Active: active (running) since Thu 2014-02-06 15:00:24 CET; 6s ago
- 确认
squid
进程 ID(PID)已作为受限服务启动,如squid_var_run_t
值所示:~]# ls -lZ /var/run/squid.pid -rw-r--r--. root squid unconfined_u:object_r:squid_var_run_t:s0 /var/run/squid.pid
- 此时,连接到先前配置的
localnet
ACL 的客户端计算机能够将此主机的内部接口用作其代理。这可以在适用于所有常见 Web 浏览器或系统范围的设置中配置。Squid 现在侦听目标计算机的默认端口(TCP 3128),但目标计算机将仅允许通过通用端口与 Internet 上的其他服务的传出连接。这是由 SELinux 本身定义的策略。SELinux 将拒绝对非标准端口的访问,如下一步中所示: - 当客户端通过 Squid 代理(如侦听 TCP 端口 10000 的网站)使用非标准端口发出请求时,会记录类似如下的拒绝:
SELinux is preventing the squid daemon from connecting to network port 10000
- 要允许此访问,必须修改
squid_connect_any
布尔值,因为它默认是禁用的:~]# setsebool -P squid_connect_any on
注意如果您不希望 setsebool 更改在重新引导后保留,则不要使用-P
选项。 - 现在,客户端可以访问 Internet 上的非标准端口,因为现在允许 Squid 代表其客户端发起到任何端口的连接。
第 20 章 MariaDB(MariaDB 的替代)
mysqld)
和许多客户端程序和库组成。[18]
~]$ rpm -q mariadb-server
package mariadb-server is not installed
用户身份使用 yum
工具安装它:
~]# yum install mariadb-server
20.1. MariaDB and SELinux
- 运行 getenforce 命令确认 SELinux 是否以强制模式运行:
~]$ getenforce Enforcing
当 SELinux 以强制模式运行时,该命令将返回强制
。 - 以 root 用户身份输入以下命令启动
mariadb
:~]# systemctl start mariadb.service
确认 服务正在运行。输出中应包括以下信息(只有时间戳有所不同):~]# systemctl status mariadb.service mariadb.service - MariaDB database server Loaded: loaded (/usr/lib/systemd/system/mariadb.service; disabled) Active: active (running) since Mon 2013-08-05 11:20:11 CEST; 3h 28min ago
- 输入以下命令查看
mysqld 进程
:~]$ ps -eZ | grep mysqld system_u:system_r:mysqld_safe_t:s0 12831 ? 00:00:00 mysqld_safe system_u:system_r:mysqld_t:s0 13014 ? 00:00:00 mysqld
与mysqld
进程关联的 SELinux 上下文为system_u:system_r:mysqld_t:s0。
上下文的第二部分mysqld_t
是类型。类型定义进程的域以及文件的类型。在本例中,mysqld 进程
在mysqld_t
域中运行。
20.2. 类型
mysqld
:不同的类型允许您配置灵活的访问:
mysqld_db_t
- 此类型用于 MariaDB 数据库的位置。在 Red Hat Enterprise Linux 中,数据库的默认位置是
/var/lib/mysql/
目录,但可以更改此目录。如果 MariaDB 数据库的位置发生更改,则必须使用此类型标记新位置。有关如何更改默认数据库位置以及如何相应地标记新部分的说明,请参阅 第 20.4.1 节 “MariaDB 更改数据库位置” 中的示例。 mysqld_etc_t
- 此类型用于 MariaDB 主配置文件
/etc/my.cnf
,以及/etc/mysql/
目录中的任何其他配置文件。 mysqld_exec_t
- 此类型用于位于
/usr/libexec/mysqld 的
,这是红帽企业 Linux 上 MariaDB 二进制文件的默认位置。其他系统可能会在mysqld
二进制文件/usr/sbin/mysqld
找到此二进制文件,该二进制文件也应使用此类型进行标记。 mysqld_unit_file_t
- 默认情况下,此类型用于 Red Hat Enterprise Linux 中的
/usr/lib/systemd/system/
目录中的可执行 MariaDB 相关文件。 mysqld_log_t
- MariaDB 的日志需要使用此类型进行标记才能正常运行。与
mysql.*
通配符匹配的/var/log/
目录中所有日志文件都必须使用此类型进行标记。 mysqld_var_run_t
- 此类型供
/var/run/mariadb/
目录中的文件使用,特别是名为/var/run/mariadb/mariadb.pid
的进程 ID(PID),该进程在运行时由mysqld
守护进程创建。此类型也用于相关的套接字文件,如/var/lib/mysql/mysql.sock
。此类文件必须正确标记,才能作为受限制的服务进行正常操作。
20.3. 布尔值
selinuxuser_mysql_connect_enabled
- 启用后,此布尔值允许用户连接到本地 MariaDB 服务器。
exim_can_connect_db
- 启用后,此布尔值允许
exim
邮件发送程序发起与数据库服务器的连接。 ftpd_connect_db
- 启用后,此布尔值允许
ftp
守护进程启动与数据库服务器的连接。 httpd_can_network_connect_db
- Web 服务器需要启用此布尔值,才能与数据库服务器通信。
~]$ getsebool -a | grep service_name
输入以下命令查看特定布尔值的描述:
~]$ sepolicy booleans -b boolean_name
请注意,需要额外的 policycoreutils-devel 软件包来提供 sepolicy
实用程序,这个命令才能正常工作。
20.4. 配置示例
20.4.1. MariaDB 更改数据库位置
/var/lib/mysql/
。这是 SELinux 默认预期的位置,因此已使用 mysqld_db_t
类型正确标记了此区域。
auditd
服务正在运行,并且 /var/lib/mysql/
的默认位置有一个有效的数据库。
- 查看
mysql
的默认数据库位置的 SELinux 上下文:~]# ls -lZ /var/lib/mysql drwx------. mysql mysql system_u:object_r:mysqld_db_t:s0 mysql
这将显示mysqld_db_t
,它是数据库文件的位置的默认上下文元素。此上下文必须手动应用到本示例中将使用的新数据库位置,才能正常工作。 - 输入以下命令并输入
mysqld
root 密码以显示可用的数据库:~]# mysqlshow -u root -p Enter password: ******* +--------------------+ | Databases | +--------------------+ | information_schema | | mysql | | test | | wikidb | +--------------------+
- 停止
mysqld
守护进程:~]# systemctl stop mariadb.service
- 为数据库的新位置创建一个新目录。本例中使用了
/mysql/
:~]# mkdir -p /mysql
- 将数据库文件复制到新位置:
~]# cp -R /var/lib/mysql/* /mysql/
- 更改此位置的所有权,以允许 mysql 用户和组访问。这会设置 SELinux 仍然会观察到的传统 Unix 权限:
~]# chown -R mysql:mysql /mysql
- 输入以下命令查看新目录的初始上下文:
~]# ls -lZ /mysql drwxr-xr-x. mysql mysql unconfined_u:object_r:usr_t:s0 mysql
此新创建的目录的 contextusr_t
目前不适用于 SELinux,作为 MariaDB 数据库文件的位置。上下文更改后,MariaDB 将能够在此领域正常工作。 - 使用文本编辑器打开主 MariaDB 配置文件
/etc/my.cnf
,再修改datadir
选项,使其引用新位置。在本例中,应输入的值为/mysql
:[mysqld] datadir=/mysql
保存此文件并退出。 - 启动
mysqld
。该服务应该无法启动,拒绝信息会记录到/var/log/messages
文件中:~]# systemctl start mariadb.service Job for mariadb.service failed. See 'systemctl status postgresql.service' and 'journalctl -xn' for details.
但是,如果audit
守护进程与setroubleshoot
服务一起运行,拒绝将记录到/var/log/audit/audit.log
文件中:SELinux is preventing /usr/libexec/mysqld "write" access on /mysql. For complete SELinux messages. run sealert -l b3f01aff-7fa6-4ebe-ad46-abaef6f8ad71
此拒绝的原因是 MariaDB 数据文件未正确标记/mysql/
。SELinux 正在阻止 MariaDB 访问标记为usr_t 的内容
。执行以下步骤解决这个问题: - 输入以下命令为
/mysql/
添加上下文映射:请注意,默认情况下不会安装semanage
工具。如果您的系统中没有它,请安装 policycoreutils-python 软件包。~]# semanage fcontext -a -t mysqld_db_t "/mysql(/.*)?"
- 这个映射被写入到
/etc/selinux/targeted/contexts/files/file_contexts.local
文件中:~]# grep -i mysql /etc/selinux/targeted/contexts/files/file_contexts.local /mysql(/.*)? system_u:object_r:mysqld_db_t:s0
- 现在,使用
restorecon
工具将这个上下文映射到正在运行的系统:~]# restorecon -R -v /mysql
- 现在,
/mysql/
位置已标记为 MariaDB 的正确上下文,mysqld
启动:~]# systemctl start mariadb.service
- 确认
/mysql/
的上下文已更改:~]$ ls -lZ /mysql drwxr-xr-x. mysql mysql system_u:object_r:mysqld_db_t:s0 mysql
- 该位置已被更改并标记,
mysqld
已成功启动。此时,应测试所有正在运行的服务,以确认正常运行。
第 21 章 PostgreSQL
~]# rpm -q postgresql-server
用户身份使用 yum
工具安装它:
~]# yum install postgresql-server
21.1. PostgreSQL 和 SELinux
- 运行 getenforce 命令确认 SELinux 是否以强制模式运行:
~]$ getenforce Enforcing
当 SELinux 以强制模式运行时,该命令将返回强制
。 - 以 root 用户身份输入以下命令启动
postgresql
:~]# systemctl start postgresql.service
确认 服务正在运行。输出中应包括以下信息(只有时间戳有所不同):~]# systemctl start postgresql.service postgresql.service - PostgreSQL database server Loaded: loaded (/usr/lib/systemd/system/postgresql.service; disabled) Active: active (running) since Mon 2013-08-05 14:57:49 CEST; 12s
- 输入以下命令查看
postgresql 进程
:~]$ ps -eZ | grep postgres system_u:system_r:postgresql_t:s0 395 ? 00:00:00 postmaster system_u:system_r:postgresql_t:s0 397 ? 00:00:00 postmaster system_u:system_r:postgresql_t:s0 399 ? 00:00:00 postmaster system_u:system_r:postgresql_t:s0 400 ? 00:00:00 postmaster system_u:system_r:postgresql_t:s0 401 ? 00:00:00 postmaster system_u:system_r:postgresql_t:s0 402 ? 00:00:00 postmaster
与postgresql
进程关联的 SELinux 上下文为system_u:system_r:postgresql_t:s0。
上下文的第二部分postgresql_t
是类型。类型定义进程的域以及文件的类型。在本例中,postgresql进程在 postgresql
_t
域中运行。
21.2. 类型
postgresql
:不同的类型允许您配置灵活的访问。请注意,在下面的列表中,使用多个正则表达式来匹配所有可能的位置:
postgresql_db_t
- 此类型用于多个位置。使用这个类型的标记位置用于 PostgreSQL 的数据文件:
/usr/lib/pgsql/test/regres
/usr/share/jonas/pgsql
/var/lib/pgsql/data
/var/lib/postgres(ql)?
postgresql_etc_t
- 此类型用于
/etc/postgresql/
目录中的配置文件。 postgresql_exec_t
- 此类型用于多个位置。使用这个类型标记的位置用于 PostgreSQL 的二进制文件:
/usr/bin/initdb(.sepgsql)?
/usr/bin/(se)?postgres
/usr/lib(64)?/postgresql/bin/.*
/usr/lib(64)?/pgsql/test/regress/pg_regress
systemd_unit_file_t
- 此类型用于
/usr/lib/systemd/system/
目录中的可执行 PostgreSQL 相关文件。 postgresql_log_t
- 此类型用于多个位置。使用这个类型标记的位置用于日志文件:
/var/lib/pgsql/logfile
/var/lib/pgsql/pgstartup.log
/var/lib/sepgsql/pgstartup.log
/var/log/postgresql
/var/log/postgres.log.*
/var/log/rhdb/rhdb
/var/log/sepostgresql.log.*
postgresql_var_run_t
- 此类型用于 PostgreSQL 的运行时文件,如
/var/run/postgresql/
目录中的进程 ID(PID)。
21.3. 布尔值
selinuxuser_postgresql_connect_enabled
- 启用此布尔值后,任何用户域(如 PostgreSQL 定义)都允许与数据库服务器建立连接。
~]$ getsebool -a | grep service_name
输入以下命令查看特定布尔值的描述:
~]$ sepolicy booleans -b boolean_name
请注意,需要额外的 policycoreutils-devel 软件包来提供 sepolicy
实用程序,这个命令才能正常工作。
21.4. 配置示例
21.4.1. PostgreSQL 更改数据库位置
/var/lib/pgsql/data/
。这是 SELinux 默认预期的位置,因此已使用 postgresql_db_t
类型正确标记了此区域。
- 查看
postgresql
默认数据库位置的 SELinux 上下文:~]# ls -lZ /var/lib/pgsql drwx------. postgres postgres system_u:object_r:postgresql_db_t:s0 data
这将显示postgresql_db_t
,它是数据库文件位置的默认上下文元素。此上下文必须手动应用到本示例中将使用的新数据库位置,才能正常工作。 - 为数据库的新位置创建一个新目录。本例中使用了
/opt/postgresql/data/
。如果您使用不同的位置,请将以下步骤中的文本替换为您的位置:~]# mkdir -p /opt/postgresql/data
- 执行新位置的目录列表。请注意,新目录的初始上下文是
usr_t
。该上下文不足以让 SELinux 为 PostgreSQL 提供保护机制。当上下文改变后,它将能够在新领域正常工作。~]# ls -lZ /opt/postgresql/ drwxr-xr-x. root root unconfined_u:object_r:usr_t:s0 data
- 更改新位置的所有权,以允许 postgres 用户和组访问。这会设置 SELinux 仍然会观察到的传统 Unix 权限。
~]# chown -R postgres:postgres /opt/postgresql
- 使用文本编辑器打开
/etc/systemd/system/postgresql.service
文件,并修改PGDATA
和PGLOG
变量以指向新位置:~]# vi /etc/systemd/system/postgresql.service PGDATA=/opt/postgresql/data PGLOG=/opt/postgresql/data/pgstartup.log
保存此文件并退出文本编辑器。如果/etc/systemd/system/postgresql.service
文件不存在,请创建该文件并插入以下内容:.include /lib/systemd/system/postgresql.service [Service] # Location of database directory Environment=PGDATA=/opt/postgresql/data Environment=PGLOG=/opt/postgresql/data/pgstartup.log
- 在新位置初始化数据库:
~]$ su - postgres -c "initdb -D /opt/postgresql/data"
- 更改数据库位置后,启动服务此时将失败:
~]# systemctl start postgresql.service Job for postgresql.service failed. See 'systemctl status postgresql.service' and 'journalctl -xn' for details.
SELinux 导致服务无法启动。这是因为新位置没有正确标记。以下步骤解释了如何标记新位置(/opt/postgresql/
)并正确启动 postgresql 服务: - 使用
semanage
工具为/opt/postgresql/ 以及
其中的任何其他目录/文件添加上下文映射:~]# semanage fcontext -a -t postgresql_db_t "/opt/postgresql(/.*)?"
- 这个映射被写入到
/etc/selinux/targeted/contexts/files/file_contexts.local
文件中:~]# grep -i postgresql /etc/selinux/targeted/contexts/files/file_contexts.local /opt/postgresql(/.*)? system_u:object_r:postgresql_db_t:s0
- 现在,使用
restorecon
工具将这个上下文映射到正在运行的系统:~]# restorecon -R -v /opt/postgresql
- 现在,
/opt/postgresql/
位置已标记为 PostgreSQL 的正确上下文,postgresql服务
将成功启动:~]# systemctl start postgresql.service
- 确认
/opt/postgresql/
的上下文正确:~]$ ls -lZ /opt drwxr-xr-x. root root system_u:object_r:postgresql_db_t:s0 postgresql
- 使用 ps 命令检查
postgresql 进程是否
显示新位置:~]# ps aux | grep -i postmaster postgres 21564 0.3 0.3 42308 4032 ? S 10:13 0:00 /usr/bin/postmaster -p 5432 -D /opt/postgresql/data/
- 该位置已被更改并标记,
postgresql
已成功启动。此时,应测试所有正在运行的服务,以确认正常运行。
第 22 章 rsync
rsync
实用程序执行快速文件传输,用于在系统间同步数据。[20]
~]$ rpm -q rsync
package rsync is not installed
用户身份使用 yum
工具安装它:
~]# yum install rsync
22.1. rsync and SELinux
rsync
守护进程共享文件,您必须使用 public_content_t
类型标记文件和目录。与大多数服务一样,SELinux 需要正确的标记才能通过 rsync
执行其保护机制。[21]
22.2. 类型
rsync
一起使用:要配置灵活访问的所有类型:
public_content_t
- 这是一种通用类型,用于通过
rsync
共享的文件的位置(以及实际文件)。如果创建了一个特殊目录来存放要与rsync
共享的文件,则该目录及其内容需要应用此标签。 rsync_exec_t
- 此类型用于
/usr/bin/rsync
系统二进制文件。 rsync_log_t
- 默认情况下,此类型用于位于
/var/log/rsync.log
的rsync
日志文件。要将文件 rsync 日志的位置更改为,可在运行时对 rsync 命令使用--log-file=FILE
选项。 rsync_var_run_t
- 此类型用于
rsyncd
锁定文件,该文件位于/var/run/rsyncd.lock
。此锁定文件供rsync
服务器用于管理连接限制。 rsync_data_t
- 此类型用于您要用作 rsync 域的文件和目录,并将它们与其他服务的访问范围隔离开来。此外,
public_content_t
是一种常规 SELinux 上下文类型,当文件或目录与多个服务(例如,FTP 和 NFS 目录作为 rsync 域)交互时,可以使用它。 rsync_etc_t
- 此类型用于
/etc
目录中与 rsync 相关的文件。
22.3. 布尔值
rsync_anon_write
- 启用此布尔值后,r
sync
可以在rsync_t
域中管理类型为public_content_rw_t
的文件、链接和目录。这些通常是用于公共文件传输服务的公共文件。必须对此类型进行标记。 rsync_client
- 启用此布尔值后,
r
sync 可以启动到定义为rsync_port_t
的端口的连接,并允许守护进程管理类型为rsync_data_t
的文件、链接和目录。请注意,rsync 必须
位于 rsync_t
域中,以便 SELinux 能够对它进行控制。本章中的配置示例演示了在rsync
_t 域中运行的 rsync
。 rsync_export_all_ro
- 启用此布尔值后,r
sync
域中的 rsync
可以导出对客户端具有只读访问权限的 NFS 和 CIFS 卷。
~]$ getsebool -a | grep service_name
输入以下命令查看特定布尔值的描述:
~]$ sepolicy booleans -b boolean_name
请注意,需要额外的 policycoreutils-devel 软件包来提供 sepolicy
实用程序,这个命令才能正常工作。
22.4. 配置示例
22.4.1. rsync 作为守护进程
rsync
守护进程在非标准端口上正常运行。
过程 22.1. 获取 rsync 作为 rsync_t 启动
- 运行 getenforce 命令确认 SELinux 是否以强制模式运行:
~]$ getenforce Enforcing
当 SELinux 以强制模式运行时,该命令将返回强制
。 - 运行 这个命令 确认 rsync 二进制文件位于系统路径中:
~]$ which rsync /usr/bin/rsync
- 当将 rsync 作为守护进程运行时,配置文件应使用并保存为
/etc/rsyncd.conf
。请注意,本例中使用的以下配置文件非常简单,并不表示所有可用的选项,而是足以演示rsync
守护进程:log file = /var/log/rsync.log pid file = /var/run/rsyncd.pid lock file = /var/run/rsync.lock [files] path = /srv/rsync comment = file area read only = false timeout = 300
- 现在,rsync 有一个简单的配置文件可在守护进程模式下运行,您可以运行以下命令来启动该文件:
~]# systemctl start rsyncd.service
确保rsyncd
已成功启动(输出应当类似于下方所示),只有时间戳会有所不同:~]# systemctl status rsyncd.service rsyncd.service - fast remote file copy program daemon Loaded: loaded (/usr/lib/systemd/system/rsyncd.service; disabled) Active: active (running) since Thu 2014-02-27 09:46:24 CET; 2s ago Main PID: 3220 (rsync) CGroup: /system.slice/rsyncd.service └─3220 /usr/bin/rsync --daemon --no-detach
SELinux 现在可以在rsync
守护进程上强制实施保护机制,因为它现在在rsync_t
域中运行:~]$ ps -eZ | grep rsync system_u:system_r:rsync_t:s0 3220 ? 00:00:00 rsync
rsync _t 域中运行 rsync
d
。rsync 也可以作为套接字激活的服务运行。在这种情况下,只有客户端尝试连接服务后才会执行 rsyncd
。要启用 rsyncd
作为套接字激活的服务运行,请按照上述步骤操作。要将 rsyncd
作为套接字激活的服务启动,以 root 用户身份输入以下命令:
~]# systemctl start rsyncd.socket
过程 22.2. 在非默认端口上运行 rsync 守护进程
- 修改
/etc/rsyncd.conf
文件,并在全局配置区域(即定义任何文件区域之前)的 文件顶部添加port = 10000
行。新配置文件将如下所示:log file = /var/log/rsyncd.log pid file = /var/run/rsyncd.pid lock file = /var/run/rsync.lock port = 10000 [files] path = /srv/rsync comment = file area read only = false timeout = 300
- 使用这个新设置启动
rsync
守护进程后,SELinux 会记录类似如下的拒绝信息:Jul 22 10:46:59 localhost setroubleshoot: SELinux is preventing the rsync (rsync_t) from binding to port 10000. For complete SELinux messages, run sealert -l c371ab34-639e-45ae-9e42-18855b5c2de8
- 使用
semanage
工具将 TCP 端口 10000 添加到rsync_port_t
中的 SELinux 策略中:~]# semanage port -a -t rsync_port_t -p tcp 10000
- 现在,对于
rsync_port_t
的 TCP 端口 10000 已添加到 SELinux 策略中,rsyncd
将在此端口上启动并正常运行:~]# systemctl start rsyncd.service
~]# netstat -lnp | grep 10000 tcp 0 0 0.0.0.0:10000 0.0.0.0:* LISTEN 9910/rsync
rsyncd 在
TCP 端口 10000 上运行。
第 23 章 postfix
~]$ rpm -q postfix
package postfix is not installed
yum
工具 root 安装它:
~]# yum install postfix
23.1. Postfix 和 SELinux
- 运行 getenforce 命令确认 SELinux 是否以强制模式运行:
~]$ getenforce Enforcing
当 SELinux 以强制模式运行时,该命令将返回强制
。 - 以 root 用户身份输入以下命令启动
postfix
:~]# systemctl start postfix.service
确认 服务正在运行。输出中应包括以下信息(只有时间戳有所不同):~]# systemctl status postfix.service postfix.service - Postfix Mail Transport Agent Loaded: loaded (/usr/lib/systemd/system/postfix.service; disabled) Active: active (running) since Mon 2013-08-05 11:38:48 CEST; 3h 25min ago
- 运行以下命令来查看
postfix 进程
:~]$ ps -eZ | grep postfix system_u:system_r:postfix_master_t:s0 1651 ? 00:00:00 master system_u:system_r:postfix_pickup_t:s0 1662 ? 00:00:00 pickup system_u:system_r:postfix_qmgr_t:s0 1663 ? 00:00:00 qmgr
在上面的输出中,与 Postfix主
进程关联的 SELinux 上下文是system_u:system_r:postfix_master_t:s0。
上下文的第二部分postfix_master_t
是此进程的类型。类型定义进程的域以及文件的类型。在本例中,master
进程在postfix_master_t
域中运行。
23.2. 类型
postfix_etc_t
- 此类型用于
/etc/postfix/
目录中 Postfix 的配置文件。 postfix_data_t
- 此类型用于
/var/lib/postfix/
目录中的 Postfix 数据文件。 postfix_var_run_t
- 此类型用于存储在
/run/
目录中的 Postfix 文件。 postfix_initrc_exec_t
- Postfix 可执行文件使用
postfix_initrc_exec_t
类型进行标记。执行时,它们过渡到postfix_initrc_t
域。 postfix_spool_t
- 此类型用于存储在
/var/spool/
目录中的 Postfix 文件。
~]$ grep postfix /etc/selinux/targeted/contexts/files/file_contexts
23.3. 布尔值
postfix_local_write_mail_spool
- 启用此布尔值后,Postfix 可以写入系统上的本地邮件假脱机。使用本地假脱机时,Postfix 要求启用此布尔值以进行正常操作。
~]$ getsebool -a | grep service_name
输入以下命令查看特定布尔值的描述:
~]$ sepolicy booleans -b boolean_name
请注意,需要额外的 policycoreutils-devel 软件包来提供 sepolicy
实用程序,这个命令才能正常工作。
23.4. 配置示例
23.4.1. SpamAssassin 和 Postfix
~]$ rpm -q spamassassin
package spamassassin is not installed
用户身份使用 yum
工具安装它:
~]# yum install spamassassin
过程 23.1. 在非默认端口上运行 SpamAssassin
- 以 root 用户身份使用
semanage
工具显示 SELinux 允许spamd
守护进程默认侦听的端口:~]# semanage port -l | grep spamd spamd_port_t tcp 783
此输出显示在spamd_port_t
中定义了 TCP/783,作为要操作的 SpamAssassin 的端口。 - 编辑
/etc/sysconfig/spamassin
配置文件并进行修改,使其在示例端口 TCP/10000 上启动 SpamAssassin:# Options to spamd SPAMDOPTIONS="-d -p 10000 -c m5 -H"
此行现在指定 SpamAssassin 在端口 10000 上运行。本例的其余部分将显示如何修改 SELinux 策略以允许打开此套接字。 - 启动 SpamAssassin,并显示类似如下的错误消息:
~]# systemctl start spamassassin.service Job for spamassassin.service failed. See 'systemctl status spamassassin.service' and 'journalctl -xn' for details.
此输出意味着 SELinux 已阻止对此端口的访问。 - SELinux 会记录类似如下的拒绝信息:
SELinux is preventing the spamd (spamd_t) from binding to port 10000.
- 以 root 用户身份运行
semanage
以修改 SELinux 策略,以允许 SpamAssassin 在示例端口(TCP/10000)上运行:~]# semanage port -a -t spamd_port_t -p tcp 10000
- 确认 SpamAssassin 现在将启动并在 TCP 端口 10000 上运行:
~]# systemctl start spamassassin.service ~]# netstat -lnp | grep 10000 tcp 0 0 127.0.0.1:10000 0.0.0.0:* LISTEN 2224/spamd.pid
- 此时,
垃圾邮件在 TCP 端口 10000 上正确
运行,因为 SELinux 策略允许访问该端口。
第 24 章 DHCP
dhcpd
守护进程在 Red Hat Enterprise Linux 中用于动态提供和配置客户端的第 3 层 TCP/IP 详细信息。
dhcpd
守护进程。输入以下命令查看是否安装了 dhcp 软件包:
~]# rpm -q dhcp
package dhcp is not installed
用户身份使用 yum
工具安装它:
~]# yum install dhcp
24.1. DHCP 和 SELinux
dhcpd
时,它将默认限制。受限制的进程在其自己的域中运行,并且与其他受限制的进程隔开。如果一个受攻击者限制的进程受到 SELinux 策略配置的影响,攻击者对资源的访问权限和可能受到的破坏会受到限制。以下示例演示了在自己的域中运行的 dhcpd
和相关进程。本例假设已安装了 dhcp 软件包,并且 dhcpd
服务已经启动:
- 运行 getenforce 命令确认 SELinux 是否以强制模式运行:
~]$ getenforce Enforcing
当 SELinux 以强制模式运行时,该命令将返回强制
。 - 以 root 用户身份输入以下命令启动
dhcpd
:~]# systemctl start dhcpd.service
确认 服务正在运行。输出中应包括以下信息(只有时间戳有所不同):~]# systemctl status dhcpd.service dhcpd.service - DHCPv4 Server Daemon Loaded: loaded (/usr/lib/systemd/system/dhcpd.service; disabled) Active: active (running) since Mon 2013-08-05 11:49:07 CEST; 3h 20min ago
- 运行以下命令来查看
dhcpd 进程
:~]$ ps -eZ | grep dhcpd system_u:system_r:dhcpd_t:s0 5483 ? 00:00:00 dhcpd
与 dhcpd 进程关联的 SELinux 上下文是system_u:system_r:dhcpd_t:s0。
24.2. 类型
dhcp_etc_t
- 此类型主要用于
/etc
目录中的文件,包括配置文件。 dhcpd_var_run_t
- 此类型用于
/var/run/
目录中dhcpd
的 PID 文件。 dhcpd_exec_t
- 这种类型用于将 DHCP 可执行文件转换到
dhcpd_t
域。 dhcpd_initrc_exec_t
- 此类型用于将 DHCP 可执行文件转换到
dhcpd_initrc_t
域。
dhcpd
的文件及其类型的完整列表,请输入以下命令:
~]$ grep dhcp /etc/selinux/targeted/contexts/files/file_contexts
第 25 章 OpenShift by Red Hat
~]$
rpm -q openshift-clients
package openshift-clients is not installed
25.1. OpenShift and SELinux
25.2. 类型
进程类型
openshift_t
- OpenShift 进程与
openshift_t
SELinux 类型关联。
可执行文件上的类型
openshift_cgroup_read_exec_t
- SELinux 允许这种类型的文件将可执行文件转换到
openshift_cgroup_read_t
域。 openshift_cron_exec_t
- SELinux 允许这种类型的文件将可执行文件转换到
openshift_cron_t
域。 openshift_initrc_exec_t
- SELinux 允许这种类型的文件将可执行文件转换到
openshift_initrc_t
域。
可写入类型
openshift_cgroup_read_tmp_t
- 这种类型允许 OpenShift 控制组(cgroup)在
/tmp
目录中读取和访问临时文件。 openshift_cron_tmp_t
- 此类型允许将 OpenShift cron 作业临时文件存储在
/tmp
中。 openshift_initrc_tmp_t
- 此类型允许将 OpenShift
initrc
临时文件存储在/tmp
中。 openshift_log_t
- 使用此类型的文件被视为 OpenShift 日志数据,通常存储在
/var/log/
目录下。 openshift_rw_file_t
- OpenShift 有权读取并写入使用此类型标记的文件。
openshift_tmp_t
- 此类型用于将 OpenShift 临时文件存储到
/tmp
中。 openshift_tmpfs_t
- 这种类型允许将 OpenShift 数据存储在 tmpfs 文件系统上。
openshift_var_lib_t
- 此类型允许将 OpenShift 文件存储在
/var/lib/
目录中。 openshift_var_run_t
- 此类型允许将 OpenShift 文件存储在
/run/ 或
/var/run/
目录中。
25.3. 布尔值
openshift_use_nfs
- 启用此布尔值后,可以在 NFS 共享上安装 OpenShift。
~]$ getsebool -a | grep service_name
输入以下命令查看特定布尔值的描述:
~]$ sepolicy booleans -b boolean_name
请注意,需要额外的 policycoreutils-devel 软件包来提供 sepolicy
实用程序,这个命令才能正常工作。
25.4. 配置示例
25.4.1. 更改默认的 OpenShift 目录
/var/lib/openshift/
目录中,该目录标有 openshift_var_lib_t
SELinux 类型。要允许 OpenShift 将数据存储到其他目录中,请使用适当的 SELinux 上下文标记新目录。
/srv/openshift/
:
过程 25.1. 更改存储数据的默认 OpenShift 目录
- 以 root 用户身份,在
/srv
目录中创建一个新的openshift/
目录。新目录使用var_t
类型标记:~]#
mkdir /srv/openshift~]$
ls -Zd /srv/openshift drwxr-xr-x. root root unconfined_u:object_r:var_t:s0 openshift/ - 以 root 用户身份,使用
semanage
实用程序将/srv/openshift/
映射到正确的 SELinux 上下文:~]#
semanage fcontext -a -e /var/lib/openshift /srv/openshift - 然后,以 root
用户身份使用 restorecon
工具应用更改:~]#
restorecon -R -v /srv/openshift /srv/openshift/
目录现在使用正确的openshift_var_lib_t
类型标记:~]$
ls -Zd /srv/openshift drwxr-xr-x. root root unconfined_u:object_r:openshift_var_lib_t:s0 openshift/
第 26 章 Identity Management
~]$ rpm -q ipa-server
package ipa-server is not installed
如果没有安装,以 root 用户身份输入以下命令安装它:
~]# yum install ipa-server
26.1. Identity Management 和 SELinux
SSSD
)查询为特定 IdM 用户定义的访问权限。然后,pam_selinux
模块会向内核发送一个请求,以根据 IdM 访问权限使用正确的 SELinux 上下文启动用户进程,如 guest_u:guest_r:guest_t:s0。
26.1.1. 对 Active Directory 域的信任
WinSync
工具来允许 Active Directory(AD)域中的用户访问 IdM 域中存储的数据。为此,WinSync
必须将 AD 服务器中的用户和组数据复制到本地服务器,并保持数据同步。
SSD
守护进程已被改进来使用 AD,用户可以在 IdM 和 AD 域之间创建信任的关系。用户和组数据直接从 AD 服务器读取。另外,提供 Kerberos 跨域信任,允许 AD 和 IdM 域间的单点登录(SSO)身份验证。如果设置了 SSO,来自 AD 域的用户可以访问存储在 IdM 域中无需密码的 Kerberos 保护的数据。
26.2. 配置示例
26.2.1. 将 SELinux 用户映射到 IdM 用户
过程 26.1. 如何将用户添加到 SELinux 映射
- 要创建新的 SELinux 映射,输入以下命令,其中
SELinux_mapping
是新 SELinux 映射的名称,--selinuxuser
选项指定特定的 SELinux 用户:~]$ ipa selinuxusermap-add SELinux_mapping --selinuxuser=staff_u:s0-s0:c0.c1023
- 输入以下命令将
tuser
用户名的 IdM 用户添加到 SELinux 映射中:~]$ ipa selinuxusermap-add-user --users=tuser SELinux_mapping
- 要在 SELinux 映射中添加名为
ipaclient.example.com
的新主机,请输入以下命令:~]$ ipa selinuxusermap-add-host --hosts=ipaclient.example.com SELinux_mapping
- 当登录到 ipaclient.example.com 主机时
,
标签:tuser
用户会获得 staff_u:s0:c0.c1023[tuser@ipa-client]$ id -Z staff_u:staff_r:staff_t:s0-s0:c0.c1023
第 27 章 Red Hat Gluster Storage
27.1. Red Hat Gluster Storage 和 SELinux
glusterd
(GlusterFS 管理服务)和 glusterfsd
(NFS 服务器)进程提供灵活的强制访问控制,作为红帽 Gluster 存储的一部分。这些进程具有高级进程隔离,未绑定 glusterd_t
SELinux 类型。
27.2. 类型
进程类型
glusterd_t
- Gluster 进程与
glusterd_t
SELinux 类型关联。
可执行文件上的类型
glusterd_initrc_exec_t
- 适用于 Gluster 初始化脚本文件的 SELinux 特定脚本类型上下文。
glusterd_exec_t
- Gluster 可执行文件的特定于 SELinux 的可执行文件上下文。
端口类型
gluster_port_t
- 为
glusterd
定义此类型。默认情况下,gluster
d 使用 204007-24027 和 38465-38469 TCP 端口。
文件上下文
glusterd_brick_t
- 此类型用于威胁为
glusterd brick 数据
的文件。 glusterd_conf_t
- 此类型与
glusterd
配置数据关联,通常存储在/etc
目录中。 glusterd_log_t
- 具有此类型的文件被视为
glusterd
日志数据,通常存储在/var/log/
目录下。 glusterd_tmp_t
- 此类型用于存储
/tmp
目录中的glusterd
临时文件。 glusterd_var_lib_t
- 此类型允许将
glusterd
文件存储在/var/lib/
目录中。 glusterd_var_run_t
- 此类型允许将
glusterd
文件存储在/run/ 或
/var/run/
目录中。
27.3. 布尔值
gluster_export_all_ro
- 启用此布尔值后,glu
sterfsd
即可以只读方式共享文件和目录。此布尔值默认为禁用。 gluster_export_all_rw
- 启用此布尔值后,glu
sterfsd 将允许 glusterfsd
共享具有读写访问权限的文件和目录。此布尔值默认为启用。 gluster_anon_write
- 启用此布尔值后,glu
sterfsd
可以修改标有public_content_rw_t
SELinux 类型的公共文件。
~]$ getsebool -a | grep service_name
输入以下命令查看特定布尔值的描述:
~]$ sepolicy booleans -b boolean_name
请注意,需要额外的 policycoreutils-devel 软件包来提供 sepolicy
实用程序,这个命令才能正常工作。
27.4. 配置示例
27.4.1. 标记 Gluster Bricks
glusterd_brick_t
,SELinux 会拒绝某些文件访问操作并生成各种 AVC 消息。
/dev/rhgs/gluster
,以用作 Gluster brick。
过程 27.1. 如何标记 Gluster Brick
- 创建目录以挂载之前格式化的逻辑卷。例如:
~]# mkdir /mnt/brick1
- 在这种情况下,将逻辑卷
/dev/vg-group/gluster
挂载到上一步中创建的/mnt/brick1/
目录。~]# mount /dev/vg-group/gluster /mnt/brick1/
请注意,mount 命令仅临时挂载设备。要永久挂载该设备,请在/etc/fstab
文件中添加类似如下的条目:/dev/vg-group/gluster /mnt/brick1 xfs rw,inode64,noatime,nouuid 1 2
如需更多信息,请参阅 fstab(5) 手册页。 - 检查
/mnt/brick1/
的 SELinux 上下文:~]$ ls -lZd /mnt/brick1/ drwxr-xr-x. root root system_u:object_r:unlabeled_t:s0 /mnt/brick1/
目录标有unlabeled_t
SELinux 类型。 - 将 SELinux 类型
/mnt/brick1/
更改为glusterd_brick_t
SELinux 类型:~]# semanage fcontext -a -t glusterd_brick_t "/mnt/brick1(/.*)?"
- 使用
restorecon
程序应用更改:~]# restorecon -Rv /mnt/brick1
- 最后,验证上下文是否已成功更改:
~]$ ls -lZd /mnt/brick1 drwxr-xr-x. root root system_u:object_r:glusterd_brick_t:s0 /mnt/brick1/
第 28 章 参考
books
- SELinux 按示例
- Mayer、MacMillan 和 Caplan2007 年 Prentice 酒店.
- SELinux:NSA 的开源安全增强型 Linux
- Bill McCartyO'Reilly Media Inc., 2004
教程和帮助
- Russell Coker 的教程和对话
- Dan Walsh 杂志
- 红帽知识库
常规信息
- NSA SELinux 主网站
- NSA SELinux FAQ
邮件列表
- NSA SELinux 邮件列表
- Fedora SELinux 邮件列表
社区
- SELinux Project Wiki
- SELinux 社区页面
- IRC
- IRC.freenode.net, #selinux
附录 A. 修订历史记录
修订历史 | |||
---|---|---|---|
修订 0.3-06 | Fri Aug 9 2019 | Mirek Jahoda | |
| |||
修订 0.3-05 | Sat Oct 20 2018 | Mirek Jahoda | |
| |||
修订 0.3-03 | Tue Apr 3 2018 | Mirek Jahoda | |
| |||
修订 0.3-01 | Thu Jul 13 2017 | Mirek Jahoda | |
| |||
修订 0.2-18 | Wed Nov 2 2016 | Mirek Jahoda | |
| |||
修订 0.2-11 | Sun Jun 26 2016 | Mirek Jahoda | |
| |||
修订 0.2-10 | Sun Feb 14 2016 | Robert Krátký | |
| |||
修订 0.2-9 | Thu Dec 10 2015 | Barbora Ančincová | |
| |||
修订 0.2-8 | Thu Nov 11 2015 | Barbora Ančincová | |
| |||
修订 0.2-7 | Thu Aug 13 2015 | Barbora Ančincová | |
| |||
修订 0.2-6 | Wed Feb 18 2015 | Barbora Ančincová | |
| |||
修订 0.2-5 | Fri Dec 05 2014 | Barbora Ančincová | |
| |||
修订 0.2-4 | Thu Dec 04 2014 | Barbora Ančincová | |
| |||
修订 0.1-41 | Tue May 20 2014 | Tomáš Čapek | |
| |||
修订 0.1-1 | Tue Jan 17 2013 | Tomáš Čapek | |
|