介绍
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 没有任何兴趣。
所以有些事情正在发生,但我完全没有想法。
答案在于用户组必须对通向包含该文件的文件夹的每个文件夹具有列出或执行权限。
换句话说,解决方案如下: