我们公司有一个 CentOS 7 的网络服务器,我们的客户通过 FTP(vsftpd)管理他们的网站。SELinux 处于强制模式。
问题是通过 VSFTPD 创建/上传的数据没有继承适当的 SELinux 上下文。让我解释一下。
例如,对于 WordPress 网站,服务器已经具有一些可以使用的规则semanage fcontext -l |grep '/var/www'
,它们是:
/var/www/html(/.*)?/uploads(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0
/var/www/html(/.*)?/wp-content(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0
因此,当我通过 SSH 将 WordPress 网站从另一台服务器复制到目录中时/var/www/html/
,文件夹wp-content/
和wp-content/uploads/
具有适当的httpd_sys_rw_content_t
安全上下文。但是,当这些文件夹是通过 FTP 创建时,它们获得的上下文是httpd_sys_content_t
(没有读写)。这意味着即使我们客户向 apache 用户/组授予写入权限,他们上传到服务器的网站也无法写入这些目录,因此 WordPress 管理员无法工作。因此,当他们上传网站时,他们必须请求我们的支持来解决这个问题,这对所有相关人员来说都是浪费时间。
假设客户将他们的网站上传到httpdocs
,如果我通过 SSH 执行mv httpdocs/ httpdocs.2/ && cp -pr httpdocs.2/ httpdocs/ && rm httpdocs.2/ -fr
此操作,问题就解决了,所以数据没有问题。
我也可以做些什么restorecon -Rv httpdocs/
来解决这个问题。
所以,问题是:如何让通过 VSFTPD 创建/上传的目录继承适当的 SELinux 上下文,就像通过 SSH 创建/上传目录时继承一样?
答案1
运行时发生的默认标记与服务器上应用的基于正则表达式的后标记策略之间存在差异。
您在这里注意到的是:
/var/www/html(/.*)?/uploads(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0
/var/www/html(/.*)?/wp-content(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0
是岗位标签政策。
您在问题中讨论的内容实际上与运行时策略有关。
当使用 SELinux 在目录中创建条目时,控制文件或目录最终被标记为什么的规则不是由您引用的正则表达式决定的,而是由以下其他规则决定的(我相信这是正确的顺序,但可能遗漏了一些东西)。
- 有一个明确的命名
type_transition
规则。 - 有一个明确的未命名
type_transition
规则。 - 继承与父目录相同的上下文。
- 应用
default_context
。
因此,当我通过 SSH 将 WordPress 网站从另一台服务器复制到 /var/www/html/ 中的目录中时,文件夹 wp-content/ 和 wp-content/uploads/ 具有正确的 httpd_sys_rw_content_t 安全上下文。
所以,是的,它确实会这样做,但原因并非你所想的那样。当然不是因为帖子标签政策。
type_transition
发生这种情况是因为存在提供此行为的特定命名规则。
$ sesearch -C -T -s unconfined_t -t httpd_sys_content_t -c dir
Found 4 named file transition filename_trans:
type_transition unconfined_t httpd_sys_content_t : dir httpd_sys_rw_content_t "wp-content";
type_transition unconfined_t httpd_sys_content_t : dir httpd_sys_rw_content_t "smarty";
type_transition unconfined_t httpd_sys_content_t : dir httpd_sys_rw_content_t "uploads";
type_transition unconfined_t httpd_sys_content_t : dir httpd_sys_rw_content_t "upgrade";
这基本上就是说。
- 如果你是
unconfined_t
和 - 如果你正在目标类型中执行操作
httpd_sys_content_t
和 - 如果新条目的类是目录和
- 如果新条目的名称是“uploads”然后
- 新类型是
httpd_sys_rw_content_t
这对 SSHD 有效的原因在于,在您登录后,您将获得unconfined_t
适用此规则的源上下文。
这对 FTP 服务不起作用,因为此服务的源上下文很可能ftpd_t
没有匹配规则。
因此,您需要修改策略来改变 SELinux 的行为,以便也遵守您在其他 FTP 条目中看到的命名文件裁决。
至少在 Fedora 23 中,存在一个允许这样做的接口,像这样的策略模块可以做到这一点。
policy_module(local_ftpd, 7.2.0)
require {
type ftpd_t;
}
apache_filetrans_named_content(ftpd_t)
您可以通过确保selinux-policy-devel
包已安装并正在运行来加载它make -f /usr/share/selinux/devel/Makefile load
。