Сокеты домена Unix для пользователя без прав root

Сокеты домена Unix для пользователя без прав root

Я работаю над приложением, которое использует сокет домена Unix для IPC. Насколько я знаю, распространенный способ — поместить файл сокета внутрь /var/run. Я работаю с Ubuntu 18.04 и вижу, что var/runэто символическая ссылка для /run. К сожалению, папка доступна rootтолько для:

  ls -Al /
  drwxr-xr-x  27 root root        800 Apr 12 17:39 run

Таким образом, доступ на запись в эту папку есть только у пользователя root, что делает невозможным использование доменных сокетов Unix для обычных пользователей.

Во-первых, я не могу понять, почему? И как использовать сокеты домена Unix для не-root пользователей? Я могу использовать домашнюю папку, конечно, но я предпочитаю использовать какой-то правильный и общепринятый метод.

решение1

Нет ничего плохого в создании сокета в dotfile или dotdir в домашнем каталоге пользователя, если пользователь не является каким-то особым системным пользователем. Единственная проблема будет в домашнем каталоге, общем для нескольких машин через nfs, но это можно легко обойти, включив имя хоста в имя сокета.


В Linux/Ubuntu вы также можете использовать"абстрактный"Сокеты домена Unix, которые не используют никаких путей или инодов в файловой системе. Абстрактные сокеты Unix — это те, адрес/путь которых начинается с байта NUL:

абстрактный: абстрактный адрес сокета отличается (от имени пути сокета) тем, что sun_path[0]представляет собой нулевой байт ( \0).

Адрес сокета в этом пространстве имен задается дополнительными байтами, sun_pathкоторые покрываются указанной длиной структуры адреса. (Нулевые байты в имени не имеют особого значения.) Имя не связано с путями файловой системы. Когда возвращается адрес абстрактного сокета, возвращаемое addrlen больше sizeof(sa_family_t)(т. е. больше 2), а имя сокета содержится в первых (addrlen - sizeof(sa_family_t))байтах sun_path.

При отображении или вводе пользователем байты NUL в абстрактном адресе сокета Unix обычно заменяются на s. Многие программы делают это ужасно неправильно, поскольку они никак @не экранируют обычные s и/или предполагают, что только первый байт может быть NUL.@

В отличие от обычных путей сокетов Unix, абстрактные имена сокетов Unix имеют другую семантику, поскольку к ним может привязаться кто угодно (если имя еще не занято), и к ним может подключиться кто угодно.

Вместо того чтобы полагаться на разрешение файла/каталога для ограничения того, кто может подключаться к вашему сокету, и предполагать, что, например, только пользователь root может создавать сокеты внутри некоторого каталога, вам следует проверить учетные данные однорангового узла getsockopt(SO_PEERCRED)(чтобы получить uid/pid того, кто подключился или связал одноранговый узел) или SCM_CREDENTIALSвспомогательное сообщение (чтобы получить uid/pid того, кто отправил сообщение через сокет).

Это (замена обычных проверок прав доступа к файлам) также является единственным разумным использованием SO_PEERCRED/ SCM_CREDENTIALSIMHO.

решение2

Ваш сокет домена unix не должен напрямую входить в /run, вам нужно создать папку внутри /run, например, /run/my-ipcс соответствующими правами для вашего пользователя, а затем писать в эту папку.

Папка должна быть пересозданной при загрузке. Принятый ответ дляэтот вопрособъясняет несколько альтернатив.

Связанный контент