SELinux 安全访问控制
SELinux 介绍
SELinux
(Security Enhanced Linux)是在进行程序、文件等权限设置依据的一个内核模块。
传统的权限管理方式称为自主访问控制,SELinux
使用的是委托访问控制:
-
自主访问控制:
自主访问控制(
DAC
,Discretionary Access Control)是依据进程的所有者与文件资源的rwx
权限来决定文件的访问能力。DAC
访问控制的缺陷:root
具有最高权限;- 用户可以取得进程来更改文件资源的访问权限。
-
强制访问控制:
SELinux
导入了强制访问控制(MAC
,Mandatory Access Control)的方法。MAC
可以针对特定的进程与特定的文件资源来进行权限控制,控制的主体变成了进程而不是用户。此外这个主体进程也不能任意使用系统文件资源,因为每个文件资源也有针对该主体进程设置可取用的权限。
这样,可以控制的项目和策略组合非常多,因此
SELinux
也提供一些默认的策略,并在该策略内提供多个规则,以便用户可以选择是否启用该控制规则。
SELinux 名词
-
主体(Subject)
SELinux 主要管理的就是进程。
-
目标(Object)
主体进程能否访问的目标资源一般就是文件系统。
-
策略(Policy)
由于进程与文件数量庞大,因此 SELinux 会依据某些服务来制订基本的访问安全性策略。目前提供三个主要的策略,分别是:
- targeted:针对网络服务限制较多,针对本机限制较少,是默认的策略。
- minimum:由 targeted 修订而来,仅针对选择的程序来保护。
- mls(strict):完整的 SELinux 限制,限制方面较为严格。
-
安全上下文(Security Context)
主体能不能访问目标除了策略指定之外,主体与目标的安全上下文必须一致才能够顺利访问。安全上下文有点类似文件系统的 rwx。安全上下文的内容与设置非常重要,如果设置错误某些服务就无法访问文件系统,出现权限不符的错误信息。
文件的安全上下文记录放置到文件的 inode 内。
使用
ls -Z
命令可以查看安全上下文:[root@101c7 bin]$ ll -Z -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 error.log -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 nomarl.log
安全上下文主要用冒号分为四个字段:身份识别,角色,类型,灵敏度。
-
身份标识(Identify)
相当于账号方面的身份标识,常见的有:
- unconfined_u:表示不受 SELinux 限制的用户,也就是说该文件来自不受限的程序产生。
- system_u:表示系统程序方面的标识,通常是系统自己产生的文件。
系统或网络服务产生的大部分数据是 system_u,用户通过 bash 创建的文件,大多是不受限的 unconfined_u 身份。
-
角色(Role)
通过角色字段,我们可以知道这个数据是属于程序,文件资源还是代表用户,常见的有:
- object_r:代表文件或目录;
- system_r:代表进程,一般用户也会被指定为 system_r。
角色字段最后面使用 _r 来结尾。
-
类型(Type)
在默认 targeted 策略中最重要的是类型字段,一个主体进程能不能读取到这个文件资源与类型字段有关。类型字段与文件与进程的定义不太相同,分别是:
-
type:在文件资源(Object)上面称为类型(Type);
-
domain:在主体程序(Subject)中则称为域(domain);
domain 需要与 type 搭配,程序才能够顺利读取文件资源。
-
类型 domain 与 type
以 cron 程序举例看程序的域和文件的类型之间的关系.
先查询 cron 进程的安全上下文内容:
[root@101c7 thin1]$ ps -eZ | grep cron
system_u:system_r:crond_t:s0-s0:c0.c1023 885 ? 00:00:02 crond
system_u:system_r:crond_t:s0-s0:c0.c1023 27679 ? 00:00:00 atd
cron 关联进程有两个,但它们的安全上下文一样:
-
身份标识:角色为 system_u:system_r,说明 crond 和 atd 为系统进程.
-
最重要的安全上下文类型为 crond_t 域.
再查询可执行文件 crond,crontab 和配置文件目录/etc/cron.d 的安全上下文:
[root@101c7 thin1]$ ll -Zd /usr/sbin/crond /etc/crontab /etc/cron.d
-rwxr-xr-x. root root system_u:object_r:crond_exec_t:s0 /usr/sbin/crond
-rw-r--r--. root root system_u:object_r:system_cron_spool_t:s0 /etc/crontab
drwxr-xr-x. root root system_u:object_r:system_cron_spool_t:s0 /etc/cron.d
安全上下文详情如下:
-
身份标识都是系统进程
-
配置目录/etc/cron.d 的类型为 system_cron_spool_t,
-
可执行文件 crond 的类型为 crond_exec_t,
-
可执行文件 crontab 的类型为 system_cron_spool_t.
分析可得以下结论:
-
当执行类型为 crond_exec_t 的二进制文件/usr/sbin/crond 后,这个程序产生类型为 crond_t 域的进程 crond.
-
而 crond_t 域类型进程能读取 system_cron_spool_t 类型的资源文件.
-
域与类型对应关系已经被定义好,所以如果类型设置错误,即使文件 rwx 权限全开程序也读不了目标资源.
-
最终能不能读取到正确数据,还要看 rwx 是否符合 Linux 权限的规范.
SELinux 启动管理
目前 SELinux 支持三种模式,分别是:
- enforcing:强制模式,代表 SELinux 正在运行中,且已经正确开始限制 domain/type 了。
- permissive:宽容模式,代表 SELinux 正在运行中,不过仅有警告日志记录,并没有实际限制。这种模式可作调试用。
- disabled:关闭。
查询 SELinux 模式通过命令 getenforce
:
[root@101c7 bin]$ getenforce
Enforcing
查询 SELinux 的策略使用 sestatus
来查看,支持参数为:
参数 | 说明 |
---|---|
-v | 检查列于 /etc/sestatus.conf 内的文件与程序的安全上下文内容 |
-b | 将目前策略的规则布尔值列出,即某些规则是否启动 |
列出目前的 SELinux 使用策略:
[root@101c7 thin1]$ 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: 31
SELinux 的配置文件是 /etc/selinux/config
:
[root@101c7 bin]$ cat /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of three two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
里面设置了 SELinux 的模式与策略。如果改变策略或模式开关需要重启系统。
由 enforcing 变为 permissive 模式可以在系统运行时切换。
切换 SELinux 模式使用 setenforce
命令,0 为宽容模式,1 为强制模式:
[root@101c7 bin]$ setenforce 0
[root@101c7 bin]$ getenforce
Permissive
有时从 disabled 切换成 enforcing 模式后,系统必须针对文件写入安全标签(SELinux Label),会有一堆服务无法启动,提示权限错误。可以在 Permissive 状态下使用 restorecon -Rv /
来重新还原 SELinux 的类型。
SELinux 规则统计
查询规则启动状态可以使用 sestatus -b
或 getsebool -a
命令:
[root@101c7 thin1]$ sestatus -b
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: 31
Policy booleans:
abrt_anon_write off
abrt_handle_event off
abrt_upload_watch_anon_write on
antivirus_can_scan_system off
...
[root@101c7 thin1]$ getsebool -a
abrt_anon_write --> off
abrt_handle_event --> off
abrt_upload_watch_anon_write --> on
antivirus_can_scan_system --> off
...
要查询规则具体内容,需要安装 setools
工具套件:
[root@101c7 thin1]$ yum install -y setools-console-*
使用 seinfo
工具查询规则统计信息:
[root@101c7 thin1]$ seinfo
Statistics for policy file: /sys/fs/selinux/policy
Policy Version & Type: v.31 (binary, mls)
Classes: 130 Permissions: 272
Sensitivities: 1 Categories: 1024
Types: 4793 Attributes: 253
Users: 8 Roles: 14
Booleans: 316 Cond. Expr.: 362
Allow: 107834 Neverallow: 0
Auditallow: 158 Dontaudit: 10022
Type_trans: 18153 Type_change: 74
Type_member: 35 Role allow: 37
Role_trans: 414 Range_trans: 5899
Constraints: 143 Validatetrans: 0
Initial SIDs: 27 Fs_use: 32
Genfscon: 103 Portcon: 614
Netifcon: 0 Nodecon: 0
Permissives: 0 Polcap: 5
可以看到当前 v31 版本的规则(Booleans)总共有 316 条。此外 seinfo
加参数还可以查询其他种类信息:
参数 | 说明 |
---|---|
–all | 列出所有信息 |
-u | 列出所有身份标识种类 |
-r | 列出所有角色种类 |
-t | 列出所有类别种类 |
-b | 列出所有规则种类 |
SELinux 规则查询
使用 sesearch
命令可以用来搜索规则。命令语法:sesearch [-A] [-s 主体程序类型] [-t 目标类别] [-b 规则]
主要参数:
参数 | 说明 |
---|---|
-A | 列出后面的数据中,允许"读取或放行"的相关数据 |
-s | 后面接域类型,例如 -s httpd_t |
-t | 后面接类别,例如 -t user_home_dir_t |
-b | 后面接 SELinux 规则,如 -b httpd_enable_ftp_server |
例如找出 crond_t
这个域类型的进程能够读取的文件类型:
[root@101c7 thin1]$ sesearch -A -s crond_t | grep spool
allow crond_t system_cron_spool_t : dir { ioctl read getattr lock search open } ;
allow crond_t var_spool_t : file { ioctl read getattr lock open } ;
allow daemon user_cron_spool_t : file { ioctl read write getattr lock append } ;
allow
后面接进程域类型和文件类型,冒号后表明资源类型,大括号 {} 内为允许的动作。
例如第一条表示允许 crond_t
域类型进程对 system_cron_spool_t
类型的文件夹读取,打开,查看属性等操作。
再使用 semanage
查一下 httpd_enable_homedirs
这条规则的含义:
[root@101c7 thin1]$ semanage boolean -l | grep httpd_enable_homedirs
SELinux boolean State Default Description
httpd_enable_homedirs (off , off) Allow httpd to enable homedirs
在 description 一列介绍了规则内容是允许 httpd 程序去读取使用者主文件夹。
再使用 sesearch
来搜索 httpd_enable_homedirs
规则里面具体规定:
[root@101c7 thin1]$ sesearch -A -b httpd_enable_homedirs
Found 77 semantic av rules:
allow httpd_t user_home_dir_t : lnk_file { read getattr } ;
allow httpd_suexec_t user_home_dir_t : dir { getattr search open } ;
allow httpd_t nfs_t : lnk_file { read getattr } ;
allow httpd_sys_script_t nfs_t : file { ioctl read geta
共有 77 条相关规定,如果规则没有启用,httpd_t
域类型进程就无法读取使用者主文件夹。这是由 sestatus
查到的 Policy deny_unknown status 设置规定默认抵挡未知的主题程序。
SELinux 规则开闭
当确认要关闭或开启某条规则可以使用 setsebool
来管理。例如启动 httpd_enable_homedirs
规则:
[root@101c7 thin1]$ getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off
[root@101c7 thin1]$ setsebool -P httpd_enable_homedirs 1
[root@101c7 thin1]$ getsebool httpd_enable_homedirs
httpd_enable_homedirs --> on
安全上下文修改
修改文件的安全上下文可以使用 chcon
命令。命令格式:chcon [-R] [-t type] [-u user] [-r role] 文件
参数说明如下:
参数 | 说明 |
---|---|
-R | 递归修改目录 |
-t | 接安全上下文的类型字段,如 thhpd_sys_content_t |
-u | 接身份识别 |
-r | 接角色 |
-v | 显示详细结果 |
–reference=参考文件 | 用参考文件作为范例修改目标文件的安全上下文 |
例如修改 1.txt
文件的安全上下文类型为 net_conf_t
:
[root@101c7 thin1]$ chcon -v -t net_conf_t 1.txt
changing security context of ‘1.txt’
[root@101c7 thin1]$ ll -Z 1.txt
-rw-r--r--. root root unconfined_u:object_r:net_conf_t:s0 1.txt
另一种修改方式,例如将 /etc/shadow
的安全上下文套用到 1.txt
文件上:
[root@101c7 thin1]$ chcon -v --reference=/etc/shadow 1.txt
changing security context of ‘1.txt’
[root@101c7 thin1]$ ll -Z /etc/shadow 1.txt
-rw-r--r--. root root system_u:object_r:shadow_t:s0 1.txt
----------. root root system_u:object_r:shadow_t:s0 /etc/shadow
安全上下文恢复
如果想要将目录的安全上下文类型错误恢复到默认值,可以使用 restorecon
命令。
restorecon
命令可用 -R
来递归修改目录,例如恢复 /etc/cron.d/
下面的文件安全上下文类型为默认值:
[root@101c7 thin1]$ mv 1.txt /etc/cron.d/ ; ll -Z /etc/cron.d/
-rw-r--r--. root root system_u:object_r:system_cron_spool_t:s0 0hourly
-rw-r--r--. root root system_u:object_r:shadow_t:s0 1.txt
-rw-r--r--. root root system_u:object_r:system_cron_spool_t:s0 raid-check
[root@101c7 thin1]$ restorecon -Rv /etc/cron.d ; ll -Z /etc/cron.d/
restorecon reset /etc/cron.d/1.txt context system_u:object_r:shadow_t:s0->system_u:object_r:system_cron_spool_t:s0
-rw-r--r--. root root system_u:object_r:system_cron_spool_t:s0 0hourly
-rw-r--r--. root root system_u:object_r:system_cron_spool_t:s0 1.txt
-rw-r--r--. root root system_u:object_r:system_cron_spool_t:s0 raid-check
可以看到移动到/etc/cron.d/
的文件 1.txt
安全上下文类型从 shadow_t
恢复成了 system_cron_spool_t
。
安全上下文默认值修改
之所以用 restorecon
命令可以恢复目录内的文件安全上下文类型,是因为目录和文件有个安全上下文默认值设定。
可以通过 semanage
命令来查询与修改安全上下文类型默认值。
常用参数:
参数 | 说明 |
---|---|
fcontext | 用在安全性上下文标签(默认值)方面的用途,-l 查询 |
-a | 增加,可以增加一些目录的默认安全上下文类型设置 |
-m | 修改 |
-d | 删除 |
例如查询 /etc/cron.d
目录的默认值:
[root@101c7 thin1]$ semanage fcontext -l | grep -E "/etc/cron\\\.d\("
/etc/cron\.d(/.*)? all files system_u:object_r:system_cron_spool_t:s0
修改 ftp_port_t
端口策略,增加一个端口 955
作为 FTP 端口:
[root@101c7 home]$ semanage port -a -t ftp_port_t -p tcp 955; semanage port -l | grep 955
ftp_port_t tcp 955, 21, 989, 990
修改目录 /root/myps
的安全上下文类型为 system_cron_spool_t
:
[root@101c7 ~]$ ll -dZ /root/myps/* /root/myps /root
dr-xr-x---. root root system_u:object_r:admin_home_t:s0 /root
drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 /root/myps
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 /root/myps/ip.txt
[root@101c7 ~]$ semanage fcontext -a -t system_cron_spool_t "/root/myps(/.*)?"
[root@101c7 ~]$ ll -dZ /root/myps/* /root/myps /root
dr-xr-x---. root root system_u:object_r:admin_home_t:s0 /root
drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 /root/myps
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 /root/myps/ip.txt
[root@101c7 ~]$ semanage fcontext -l | grep -E "/root/myps\("
/root/myps(/.*)? all files system_u:object_r:system_cron_spool_t:s0
[root@101c7 ~]$ restorecon -Rv /root/myps
restorecon reset /root/myps context unconfined_u:object_r:admin_home_t:s0->unconfined_u:object_r:system_cron_spool_t:s0
restorecon reset /root/myps/ip.txt context unconfined_u:object_r:admin_home_t:s0->unconfined_u:object_r:system_cron_spool_t:s0
[root@101c7 ~]$ ll -dZ /root/myps/* /root/myps
drwxr-xr-x. root root unconfined_u:object_r:system_cron_spool_t:s0 /root/myps
-rw-r--r--. root root unconfined_u:object_r:system_cron_spool_t:s0 /root/myps/ip.txt
修改了以后再用 restorecon
命令还原默认值,所有其目录和文件的安全上下文类型变成了新设置的值。
SELinux 日志查询
首先检查用于 SE 日志记录的服务 auditd
(setroubleshoot)是否启动中:
[root@101c7 ~]$ systemctl status auditd
â— auditd.service - Security Auditing Service
Loaded: loaded (/usr/lib/systemd/system/auditd.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2021-09-09 15:08:51 EDT; 1 weeks 1 days ago
默认情况下系统会自动启动。这里使用 httpd
服务来测试:
[root@101c7 bin]$ ps aux -Z | grep http
system_u:system_r:httpd_t:s0 root 60730 0.0 0.1 230444 5204 ? Ss 10:30 0:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0 apache 60731 0.0 0.0 230576 3732 ? S 10:30 0:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0 apache 60732 0.0 0.0 230576 3736 ? S 10:30 0:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0 apache 60733 0.0 0.0 230576 3736 ? S 10:30 0:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0 apache 60734 0.0 0.0 230576 3720 ? S 10:30 0:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0 apache 60735 0.0 0.0 230576 3732 ? S 10:30 0:00 /usr/sbin/httpd -DFOREGROUND
查询得知 httpd
的进程安全上下文类型为 httpd_t
域。增加首页内容:
[root@101c7 bin]$ echo "Today is 9.14" > /var/www/html/index.html
通过浏览器访问服务器的 IP 地址可看到刚建页面。此时浏览器会通过 httpd
这个进程去读取 /var/www/html/index.html
文件。
查询一下 index.html
文件的安全上下文:
[root@101c7 bin]$ ll -Z /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html
看到文件安全上下文类型为 httpd_sys_content_t
,查询一下 httpd_t
域类型与它的关系:
[root@101c7 ~]$ sesearch -A -s httpd_t | grep httpd_sys_content_t
allow httpd_t httpd_sys_content_t : lnk_file { read getattr } ;
allow httpd_t httpd_sys_content_t : dir { ioctl read getattr lock search open } ;
allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock map open } ;
allow daemon httpd_sys_content_t : dir { getattr search open } ;
allow httpd_t httpd_sys_content_t : dir { ioctl read write getattr lock add_name remove_name search open } ;
接着测试一下错误的安全上下文类型,可以将网页数据在 /root
文件夹下面生成,再移动到 /var/www/html/
:
[root@101c7 bin]$ echo "Now is 22:41" > index.html
[root@101c7 bin]$ mv index.html /var/www/html/
mv: overwrite a€?/var/www/html/index.htmla€?? y
再次访问 index.html
,结果变成了 Forbidden
拒绝访问:
[root@101c7 home]$ curl 127.0.0.1/index.html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /index.html
on this server.</p>
</body></html>
把 Selinux 转换工作模式再访问试试:
[root@101c7 home]$ setenforce 0
[root@101c7 home]$ curl 127.0.0.1/index.html
Now is 23:41
[root@101c7 home]$ setenforce 1
切换 SELinux 到警告模式后访问 index.html
正常,可以确定是 SELinux 的问题。看下 index.html
的安全上下文:
[root@101c7 bin]$ ll -Z /var/www/html/index.html
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 /var/www/html/index.html
安全上下文类型为 admin_home_t
,查询一下与 httpd_t
的关系:
[root@101c7 ~]$ sesearch -A -s httpd_t | grep admin_home_t
allow domain admin_home_t : dir { getattr search open } ;
allow domain admin_home_t : lnk_file { read getattr } ;
结果显示没有结果,也就默认会被拒绝掉。到 /var/log/messages
下面查看下日志,果然有记录:
[root@101c7 ~]$ tail -f /var/log/messages
Sep 18 08:40:32 101c7 setroubleshoot: failed to retrieve rpm info for /var/www/html/index.html
Sep 18 08:40:32 101c7 setroubleshoot: SELinux is preventing httpd from getattr access on the file /var/www/html/index.html. For complete SELinux messages run: sealert -l c7d023db-6ae4-4397-9a6b-5b1061f5a9fa
来自 setroubleshoot
的报告指出 SELinux 拒绝了 httpd
读取 /var/www/html/index.html
的请求,运行 sealert -l
命令来查看报告。看看 sealert
给出的报告:
[root@101c7 ~]$ sealert -l c7d023db-6ae4-4397-9a6b-5b1061f5a9fa
SELinux is preventing httpd from getattr access on the file /var/www/html/index.html.
***** Plugin restorecon (99.5 confidence) suggests ************************
If you want to fix the label.
/var/www/html/index.html default label should be httpd_sys_content_t.
Then you can run restorecon. The access attempt may have been stopped due to insufficient permissions to access a parent directory in which case try to change the following command accordingly.
Do
# /sbin/restorecon -v /var/www/html/index.html
***** Plugin catchall (1.49 confidence) suggests **************************
If you believe that httpd should be allowed getattr access on the index.html 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:admin_home_t:s0
Target Objects /var/www/html/index.html [ file ]
Source httpd
Source Path httpd
Port <Unknown>
Host 101c7
Source RPM Packages
Target RPM Packages
Policy RPM selinux-policy-3.13.1-268.el7_9.2.noarch
Selinux Enabled True
Policy Type targeted
Enforcing Mode Enforcing
Host Name 101c7
Platform Linux 101c7 3.10.0-1160.41.1.el7.x86_64 #1 SMP Tue
Aug 31 14:52:47 UTC 2021 x86_64 x86_64
Alert Count 6
First Seen 2021-09-18 08:39:24 EDT
Last Seen 2021-09-18 08:52:01 EDT
Local ID c7d023db-6ae4-4397-9a6b-5b1061f5a9fa
Raw Audit Messages
type=AVC msg=audit(1631969521.111:5038): avc: denied { getattr } for pid=60731 comm="httpd" path="/var/www/html/index.html" dev="dm-0" ino=33829126 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0
Hash: httpd,httpd_t,admin_home_t,file,getattr
报告指出报错原因 99.5% 是因为:index.html
文件的默认 label 应该为 httpd_sys_content_t
,这是我们已经知道的错误原因,并且下面给出了解决办法,运行命令 /sbin/restorecon -v /var/www/html/index.html
来修复这一错误。
接着报告提示 1.49% 的可能原因是遇到了 bug,可以运行命令 ausearch -c 'httpd' --raw | audit2allow -M my-httpd
和 semodule -i my-httpd.pp
来报告错误。
先试下后面这条命令:
[root@101c7 ~]$ ausearch -c 'httpd' --raw | audit2allow -M my-httpd
******************** IMPORTANT ***********************
To make this policy package active, execute:
semodule -i my-httpd.pp
[root@101c7 ~]$ semodule -i my-httpd.pp
然后在浏览器访问 http 服务器,惊讶地发现可以访问了,日志 /var/log/messages
里面没有报错,显然最后一条命令起了作用。现在通过在 /root
下面新建 index.html
再转移到 /var/www/html/
的方式也不会拒绝访问了。
查询一下 httpd_t
与 admin_home_t
的关系:
[root@101c7 home]$ sesearch -A -s httpd_t | grep admin_home_t
allow domain admin_home_t : dir { getattr search open } ;
allow domain admin_home_t : lnk_file { read getattr } ;
allow httpd_t admin_home_t : file { read getattr open } ;
果然系统给我们新建了一条策略来解决这一问题。由此可见,只要知道分析错误日志,SELinux 的 targeted 模式还是很灵活的,不必急着装好系统后就把 SELinux 关掉。
另外 /var/log/audit
下面也有日志,不过有用的信息并不多:
[root@101c7 home]$ audit2why < /var/log/audit/audit.log
type=AVC msg=audit(1631972305.031:5057): avc: denied { open } for pid=60735 comm="httpd" path="/var/www/html/index.html" dev="dm-0" ino=50435189 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:home_root_t:s0 tclass=file permissive=1
Was caused by:
Missing type enforcement (TE) allow rule.
You can use audit2allow to generate a loadable module to allow this access.