LINUX.ORG.RU

Запускалка программ через unix socket. Нужно или не нужно?

 , ,


0

1

Примеры применений:

* Простой запуск программ внутри LXC или unshare.

* Типа sudo, только простое и не нужен setuid-bit.

* Позволить пользоватеям chroot в определённую директорию.

https://github.com/vi/dive


Изначально подумалось: uber cool. А потом подумалось, что ведь это по сути такой light-weight sshd на юникс сокете?.. Ну, наверное, все равно нужно. Есть какие-нибудь области применения помимо poor's man sudo?

А еще изначально подумал, что демон принимает fd программы, а потом её экзекутит в своем unshare окружении через fexecve. Вот это было бы убер кул (правда тогда куча вопросов было бы с so-либами, плюс сам fexecve это еще тот костыль).

Но по коду, вроде бы, понял, что передается path, argv, env + in/out/err? То есть, в чистом виде rsh, но очень-очень легкий.

hexdump01010101 ()
Ответ на: комментарий от hexdump01010101

Есть какие-нибудь области применения помимо poor's man sudo?

Изначальный use case - это простой запуск программ в других пространствах имён (сетевом, файловосистемном) извне.

Без этого, например, можно так:

root(host)          # unshare -n bash
root(inside unshare)# tmux
root(tmux)          # (настроить сеть, запустить проги)

root(host)          # tmux a
root(tmux)          # (запустить ещё проги)

При помощи dived это можно делать прямо и легковесно.

vi0 ()
Ответ на: комментарий от hexdump01010101

А еще изначально подумал, что демон принимает fd программы,
а потом её экзекутит в своем unshare окружении через fexecve.

Можно и так сделать. Не знал про fexecve. Но, похоже, в неинтересных случаях можно обойтись и без fexecve, а в интересных он не сработает как надо.

Вот это было бы убер кул
(правда тогда куча вопросов было бы с so-либами,
плюс сам fexecve это еще тот костыль).

Сейчас туда передаётся текущая директория в виде дескриптора (если dived не запущено с --no-chdir). Поэтому программу с библиотеками запустить, думаю, можно запустить типа как

dive /var/run/dove ../lib/ld-linux.so.2 --library-path ../lib:../usr/lib:../lib/i386-linux-gnu/:../usr/lib/i386-linux-gnu/ ../bin/zsh4
(проверил через «dived /var/run/dove --chroot /tmp» что оно работает)

vi0 ()
Ответ на: комментарий от vi0

Это понятно. Но я имел ввиду применения в смысле решения задач. Программы ведь не запускают ради того, чтобы просто запустить.

Область применения LXC, скажем, это VPS-хостинг, но там небось будут свои «панели управления», и такой вот мультиплексор/прокси там будет свой.

ОК, я переформулирую вопрос: зачем вам этот простой запуск программ в других пространствах имен? Вопрос без подвоха, мне самому интересно найти ответ на ваш же вопрос «нужно или не нужно». :) Может какие-нибудь примеры из повседневных задач, решаемых таким вот способом?..

hexdump01010101 ()
Ответ на: комментарий от hexdump01010101

зачем вам этот простой запуск программ в других пространствах имен?

Для себя в первую очередь. У меня некоторые проги работают и изолированном пространстве имён, чтобы, например, рабочая локалка была видна только для программ, связанных с работой. А остальные программы видят только интернет (через прокси). (Вообще у меня всё хитро настроено, используется много учётных записей, много правил iptables, всякие шифрования, пару chroot'ов и unshare).

Ещё чтобы можно было легко и быстро (без iptables, без отдельной учётки) запустить прогу без сети («Multi-user example» в README).

Ещё чтобы иметь аналог sudo для себя, который будет работать если все файловые системы примонтированы с nosuid и который я на 100% помимаю как работает.

Ещё чтобы можно было легко из-под пользователя запускать проги под chroot'ом (но чтобы было безопасно).

Я хочу чтобы dived был как по духу как socat: маленькое, многофункциональное, полезное.

vi0 ()
Ответ на: комментарий от vi0

Можно и так сделать. Не знал про fexecve.

К сожалению, на этапе подгрузки библиотек, файлы этих самых библиотек будут открываться уже из нового namespace. А смысл передачи «executable as fd», я видел именно как некий бэкдор из одного namespace обратно в другой. :)

Ну скажем, программа в unshare/lxc не видит /bin/ls, но мы ей передаем уже открытый fd, который программа уже может читать/загружать. Все бы хорошо, но сам fexecve работает через /proc (согласно ману), что наводит на мысль, что работать оно не будет. Даже если исключить so библиотеки и сопутствующие проблемы...

Так что, в данном случае передача по пути будет правильнее, хоть это и менее интересно.

hexdump01010101 ()
Ответ на: комментарий от hexdump01010101

как некий бэкдор из одного namespace обратно в другой
, хоть это и менее интересно.

Вы дочитали позапредыдущее сообщение? «Бэкдор» есть в виде текущей директории. Через неё и можно запустить прогу. Я даже пример привёл. (только вот bash что-то не хочет, говорит «bash: xmalloc: ../bash/shell.c:1655: cannot allocate 2 bytes (4096 bytes allocated». Он даже не хочет запускаться через просто «/lib/ld-linux.so.2 /bin/bash»).

vi0 ()
Ответ на: комментарий от vi0

Вы дочитали позапредыдущее сообщение?

Неа :) Теперь дочитал...

Кстати, я в коде вижу fchdir() - ок, мы установили ".". Но ведь полного пути у этой директории (в контексте нового контейнера) может и не быть? Или не может?

hexdump01010101 ()
Ответ на: комментарий от hexdump01010101

Полного пути нет. Bash пишет в этом случае "(unreachable)/mnt/home/vi/$ ". Но относительный есть, по которому мы и запускаем наши программы.

vi0 ()
Ответ на: комментарий от hexdump01010101

Добавил только что ещё опцию "-r" - устанавливать корневой директорией ту же, что и у клиента. Запускать программы с хоста с этой опцией будет удобно. Если ещё указать -H и -W, то текущей директорией становится бывшая корневая, и пользователь может «проинспектировать» ФС контейнера утилитами с хоста.

vi0 ()

Ещё добавил некоторое количество возможностей (с сохранением простоты).

vi0 ()
Ответ на: комментарий от hexdump01010101

Но по коду, вроде бы, понял, что передается
path, argv, env + in/out/err?

Не только in/out/err, а вообще все дескрипторы. Ещё current and root directories (тоже в виде дескриптора), controlling terminal (в виде дескриптора, сейчас оно просто берёт stdin), umask.

«path» не передаётся, передаётся чисто массив строк. Если сервер запущен с "-- /path/to/prog", то оно будет запускать /path/to/prog с переданными пользователем пареметрами.

То есть, в чистом виде rsh, но очень-очень легкий.

Может быть. Оно после подключения настраивает программу, а dived продолжает висеть только чтобы вернуть правильный код возврата вызывающему в dive, который вернёт его приложению.

vi0 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.