4.10. 维护 SELinux 标签
这些小节描述了复制、移动和存档文件和目录时 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
将作为新文件创建。如上例所示,/etc/file1
根据 default-labeling 规则,使用 etc_t
类型进行标记。
在现有文件中复制文件时,会保留现有文件的上下文,除非用户指定的 cp 选项保留原始文件的上下文,如--
preserve=context
。SELinux 策略可能会阻止在复制期间保留上下文。
过程 4.11. 在不保留 SELinux 上下文的情况下复制
此流程显示,当使用 cp 命令复制文件时,如果没有提供选项,则类型将从目标父目录继承。
- 在用户的主目录中创建文件。该文件使用
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/
中时,file1
的user_home_t
类型会被保留:~]#
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 - without-
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 - 使用
file2
覆盖file1
:~]#
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
重要
复制文件和目录,而不是移动它们。这有助于确保它们标记为正确的 SELinux 上下文。不正确的 SELinux 上下文可能会阻止进程访问此类文件和目录。
4.10.2. 移动文件和目录
文件和目录在移动时保留其当前 SELinux 上下文。在很多情况下,这对他们移动到的位置来说不正确。以下示例演示了将文件从用户的主目录移到
/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
默认情况下,Apache HTTP 服务器无法读取标记为
user_home_t
类型的文件。如果组成 web 页面的所有文件都标有 user_home_t
类型,或者 Apache HTTP 服务器无法读取的另一种类型,则在尝试使用 Web 浏览器访问它们时(如 Mozilla Firefox )将拒绝权限。
重要
使用 mv 命令移动文件和目录可能会导致 SELinux 上下文不正确,从而防止进程(如 Apache HTTP 服务器和 Samba)访问这些文件和目录。
4.10.3. 检查默认 SELinux 上下文
使用
matchpathcon
工具检查文件和目录是否具有正确的 SELinux 上下文。这个工具查询 系统策略
,然后提供与文件路径关联的默认安全上下文。[6] 以下示例演示了如何使用 matchpathcon 来验证 /var/www/html/
目录中的文件是否已正确标记:
过程 4.16. 使用 matchpathcon
检查默认 SELinux Conxtext
- 以 root 用户身份,在
/var/www/html/
目录中创建三个文件(file
1、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.
matchpathcon 命令的输出解释了
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
要解决标签问题,并允许 Apache HTTP 服务器以 root 身份访问
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 -
请注意,根据目录,您可能需要是 root 用户才能运行
restorecon
。
以下示例演示了创建一个保留 SELinux 上下文的
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/
中创建三个文件(file
1、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. 使用 星级归档文件
star
工具默认不保留扩展属性。由于 SELinux 上下文存储在扩展属性中,因此存档文件时可能会丢失上下文。使用 star -xattr -H=exustar 命令创建保留上下文的存档。默认情况下不安装 星级 软件包。要安装 星 级,请以 root 用户身份运行 yum install star 命令。
以下示例演示了创建一个保留 SELinux 上下文的
star
归档:
过程 4.18. 创建 星级
归档
- 以 root 用户身份,在
/var/www/html/
中创建三个文件(file
1、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/
。在这个目录中,输入以下命令提取star
归档:~]$
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
,这发生了-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) 手册页。