Назад | Перейти на главную страницу

Почему мой сокет unix создан с маской ACL, отличной от маски других файлов?

Я развертываю приложение Nodejs Express. Он будет работать как на том же компьютере, что и сервер Nginx, который будет передавать ему запросы через сокет unix. Однако вопрос не относится к Nodejs.

Экспресс-приложение запускается как пользователь nodejs, а nginx работает как nginx.

Мой план - создать /sockets каталог, принадлежащий nodejs для Express, чтобы вставить розетки и предоставить nginx доступ к этим сокетам через ACL по умолчанию в каталоге. Не стесняйтесь сказать мне, если это глупая идея, но имейте в виду, что это не мой основной вопрос.

Я создаю ACL в каталоге, запустив от имени пользователя root

setfacl -Rd --mask -m nginx:rw  /sockets
setfacl -R  --mask -m nginx:rwX /sockets

В этом случае в каталоге есть следующие списки управления доступом: (таблица, сделанная мной для наглядности в вопросе)

# 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--

Большой!

Однако, если Node создает сокет, вызывая listen() на пути в этом каталоге он создается с помощью ACL mask что мешает nginx от доступа к нему.

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's umask.

Аналогичным образом, если я запустил эквивалентный код для привязки к сокету в python, результаты те же, поэтому я не думаю, что проблема связана с самим Node.

Очевидно, это мешает Nginx взаимодействовать с моим приложением Express. Кто-нибудь может понять, почему? : / На сервере работает CentOS 7.

Ответ заключается в том, что socket () - это функция libc, которая не реализует политики ACL, которые задокументированы на 100%.

Путем экспериментов я обнаружил, что вы должны установить umask для вызывающего процесса, который согласно правилам ACL должен не важно при создании файлов, и для успешного создания сокетов так, как вы хотите, вы должны:

umask 0002
setfacl -d -m user:nginx:rwx /sockets
setfacl -d -m group::rwx /sockets
setfacl -d -m mask::rwx /sockets