Я ищу безопасное место для размещения доменных сокетов Unix, которые будут использоваться для управления REPL.
В Linux я бы использовал /run/user/$UID
, который соответствует всем требованиям, кроме переносимости. Мне нужно, чтобы программа, которая ими управляет, была переносимой.
Одним из вариантов является использование каталога, находящегося ниже, ~
но это приводит к другой проблеме: домашний каталог пользователя может находиться в каталоге, который слишком глубок для привязки к нему сокета домена Unix из-за ограничения длины пути.
Размещение сокета в каталоге в /tmp
является переносимым, но я беспокоюсь о состоянии гонки при удалении каталога. Я также беспокоюсь о том, /tmp
можно ли положиться на то, что бит sticky установлен на всех платформах (то есть, чтобы пользователи не могли удалять или переименовывать временные файлы других пользователей). Я предполагаю, что /tmp
это липкий бит, однако, поскольку в противном случае многие, многие приложения (каждый скрипт, который использует mkstemp
) небезопасны.
Мой текущий план заключается в том, чтобы сервер создал временный каталог в /tmp
, а клиенты проверяли владельца содержащего его каталога перед использованием сокета. Достаточно ли этого для безопасности?
решение1
Theде-юрестандартныйРасположение временных файлов указывается в переменной окружения TMPDIR
.
Эта переменная должна представлять собой путь к каталогу, доступному для программ, которым требуется место для создания временных файлов.
На самом деле, многие системы не определяют TMPDIR
.де-фактоСтандартное расположение временных файлов — /tmp
. Поэтому проверьте TMPDIR
, и если он не установлен, используйте /tmp
. В скрипте оболочки вы можете использовать ${TMPDIR:-/tmp}
, или, если вам так удобнее,
if [ -z "$TMPDIR" ]; then TMPDIR=/tmp; fi
или справиться сset -u
: "${TMPDIR:=/tmp}"
Можно предположить, что это местоположение доступно для записи, но оно может быть доступно для чтения и записи всем, поэтому:
- Когда вы создаете обычный файл, всегда проверяйте, что вы не перезаписываете существующий файл, который может вам не принадлежать. Не используйте для этого перенаправление оболочки. Отдельно проверять владельца небезопасно, поскольку злоумышленник может перемещать символические ссылки во время работы вашей программы, чтобы обмануть проверки. Кроме того, вы не можете полагаться на то, что определенное имя не существует; чтобы предотвратить создание параллельной программой отказа в обслуживании путем создания файла с тем же именем непосредственно перед вами, используйте случайное имя. Вы можете использовать утилиту
mktemp
(широко распространенную, присутствует в GNU, BusyBox, BSD, но не POSIX) илиmkstemp
функцию библиотеки C. Под капотомopen
илиcreat
должны вызываться сO_EXCL
флагом. - Вы можете создать каталог с помощью
mkdir
. Это надежно от кражи прав собственности, поскольку не будет повторно использоваться существующий файл, но он подвержен тому же отказу в обслуживании, что и обычные файлы, поэтому вам следует использовать случайное имя.mktemp -d
— хороший способ сделать это. - Вы можете создать сокет (для этого нет стандартной утилиты оболочки). Как и в случае с каталогом, он защищен от подмены владельца, но не от отказа в обслуживании.
Linux учитывает разрешения на именованные сокеты, но есть варианты Unix, которые этого не делают. Вот почему сокеты/tmp
обычно создаются в подкаталогах.
Программы, которые создают подкаталог /tmp
(или $TMPDIR
если задано) и создают там именованный сокет, включают серверы X11, ssh-agent, gpg-agent, KDE, emacs, … (это только те, которые существуют на машине, где я это публикую). Как видите, вы будете в хорошей компании.