介绍
Web 应用程序有两个通用文件夹,这是很常见的情况。一个文件夹内包含由应用服务器执行的代码,例如 uwsgi;另一个文件夹内包含由 Web 服务器直接提供的静态内容,例如 nginx。
在 Debian 服务器上,Web 服务器的用户帐户是 www-data,而应用服务器通常每个应用程序都是唯一的。这意味着在代码文件中可以有以下 acl:
# file: code/main.py
# owner: user
# group: user
user::rwx
group::rwx
group:app-server:rwx
other::---
而静态文件可以具有以下 ACL:
# file: static/bootstrap.css
# owner: user
# group: user
user::rwx
group::rwx
group:app-server:rwx
group:www-data:r--
other::---
实际问题
具有这些权限的文件怎么可能:
$ sudo getfacl /srv/domain/django/static_files/bootstrap/css/bootstrap.css
getfacl: Removing leading '/' from absolute path names
# file: srv/domain/django/static_files/bootstrap/css/bootstrap.css
# owner: user
# group: user
user::rwx
group::rwx
group:www-data:r--
group:app-server:rwx
group:user-organization:rwx
mask::rwx
other::---
www-data 无法读取:
$ sudo -u www-data cat /srv/domain/django/static_files/bootstrap/css/bootstrap.css
cat: /srv/domain/django/static_files/bootstrap/css/bootstrap.css: Permission denied
当用户www-data明显是同名组的成员时:
$ id www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)
事实上,放弃所有控制权并允许任何人阅读对情况没有任何帮助:
$ sudo chmod 774 /srv/domain/django/static_files/bootstrap/css/bootstrap.css
$ sudo getfacl /srv/domain/django/static_files/bootstrap/css/bootstrap.css
getfacl: Removing leading '/' from absolute path names
# file: srv/domain/django/static_files/bootstrap/css/bootstrap.css
# owner: user
# group: user
user::rwx
group::rwx
group:www-data:r--
group:app-server:rwx
group:user-organization:rwx
mask::rwx
other::r--
$ cat /srv/domain/django/static_files/bootstrap/css/bootstrap.css
cat: /srv/domain/django/static_files/bootstrap/css/bootstrap.css: Permission denied
使用 chown 和 chgrp 将文件的所有权和组更改为 www-data 不会改变结果。我在 dmesg、messages 或 auth.log 中找不到任何有趣的内容。
所以有些事情正在发生,但我却没有任何主意。
答案1
答案在于,用户组必须具有列出或执行权限每一个文件夹,指向包含该文件的文件夹。
换句话说,解决方案如下:
$ sudo setfacl -m g:www-data:X /srv/domain
$ sudo setfacl -m g:www-data:X /srv/domain/django
$ sudo setfacl -R -m g:www-data:rX /srv/domain/django/static_files