Linux

為什麼我的 unix 套接字使用與其他文件不同的 ACL 遮罩創建?

  • June 26, 2018

我正在部署一個 Nodejs Express 應用程序。它將與 Nginx 伺服器在同一個機器上執行,它將通過 unix 套接字代理對它的請求。然而,這個問題並不特定於 Nodejs。

express 應用程序以 user 身份nodejs執行,nginx 以nginx.

我的計劃是創建一個Express/sockets擁有的目錄nodejs來放入套接字,並通過目錄上的預設 ACL 授予nginx對這些套接字的訪問權限。如果這是一個愚蠢的想法,請隨時告訴我,但請記住,這不是我的核心問題。

我通過以 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

如果以 as 執行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--

偉大的!

但是,如果 Node 通過呼叫listen()此目錄中的路徑來創建套接字,則會使用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

/sockets如果我在(例如 by )中使用 Nodejs 創建一個普通文件,fs.writeFile它的創建權限與我在上面執行時的權限相同touch /sockets/testFile,所以我認為這不是 Node 的問題umask

同樣,如果我執行等效程式碼來綁定到 in 中的套接字python,結果是相同的,所以我認為這不是 Node 本身的問題。

顯然,這會阻止 Nginx 與我的 Express 應用程序對話。誰能弄清楚為什麼?:/ 伺服器正在執行 CentOS 7。

答案是 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

引用自:https://serverfault.com/questions/833349