我正在部署一个 Nodejs Express 应用程序。它将与 Nginx 服务器在同一台机器上运行,后者将通过 unix 套接字将请求代理到它。然而,这个问题并不特定于 Nodejs。
express 应用程序以用户身份运行nodejs
,nginx 以身份运行nginx
。
我的计划是创建一个Express/sockets
拥有的目录nodejs
来放置套接字,并nginx
通过目录上的默认 ACL 授予对这些套接字的访问权限。如果这个想法很愚蠢,请随时告诉我,但请记住这不是我的核心问题。
我以 root 身份运行以下命令在目录上创建 ACL:
setfacl -Rd --mask -m nginx:rw /sockets
setfacl -R --mask -m nginx:rwX /sockets
然后,该目录具有以下 ACL:(为了问题的易读性,我将其制成表格)
# file: /sockets
# owner: nodejs
# group: root
user: : rwx
user: nginx: rwx
group: : r-x
mask: : rwx
other: : r-x
default: user: :rwx
default: user:nginx:rw-
default:group: :r-x
default: mask: :rwx
default:other: :r-x
如果以 身份运行nodejs
并写入文件,则会正确创建该文件:
sudo -su nodejs
touch /sockets/testFile
getfacl /sockets/testFile
# file: /sockets/testFile
# owner: nodejs
# group: nodejs
user: :rw-
user:nginx:rw-
group: :r-x #effective:r--
mask: :rw-
other: :r--
伟大的!
listen()
但是,如果 Node 通过调用此目录中的路径创建套接字,则会使用mask
阻止nginx
访问的 ACL 创建套接字。
const e = require('express')()
e.listen('/sockets/testSocket', (e) => console.error(e))
getfacl /sockets/testSocket
# file: /sockets/testSocket
# owner: nodejs
# group: nodejs
user: :rwx
user:nginx:rw- #effective:r--
group: :r-x
mask: :r-x
other: :r-x
如果我使用 Nodejs 创建一个普通文件/sockets
(例如通过fs.writeFile
),它将使用与我上面运行时相同的权限创建touch /sockets/testFile
,所以我不认为这是 Node 的问题umask
。
同样,如果我运行等效代码来绑定到中的套接字python
,结果是相同的,所以我不认为这是 Node 本身的问题。
显然,这阻止了 Nginx 与我的 Express 应用程序通信。有人能找出原因吗? :/ 服务器正在运行 CentOS 7。
答案1
答案是 socket() 是一个 libc 函数,它没有实现 100% 记录的 ACL 策略。
通过实验我发现你必须为调用进程设置 umask,根据 ACL 规则应该不是创建文件时很重要,并且为了按照您想要的方式成功创建套接字,您必须:
umask 0002
setfacl -d -m user:nginx:rwx /sockets
setfacl -d -m group::rwx /sockets
setfacl -d -m mask::rwx /sockets