У меня есть установка Unix, которая должна использоваться как chroot и как автономная система. Если он работает как chroot, я не хочу запускать какие-либо службы (cron, inetd и т. Д.), Потому что они будут конфликтовать с хост-системой или будут избыточными.
Как мне написать скрипт оболочки, который ведет себя по-разному в зависимости от того, работает ли он в chroot? Моя непосредственная потребность в современной системе Linux, с /procмонтированной в chroot, и скрипт запускается как root, но приветствуются и более переносимые ответы. (См. Как мне сказать, что я работаю в chroot, если / proc не смонтирован? Для Linux без /proc.)
В целом, предложения, которые работают для других методов сдерживания, были бы интересны. Практический вопрос заключается в том, должна ли эта система запускать какие-либо службы? (Ответ - нет в chroot и да в полноценных виртуальных машинах; я не знаю о промежуточных случаях, таких как тюрьмы или контейнеры.)
Здесь я проверил, initсовпадает ли корень процесса (PID 1) с корнем текущего процесса. Хотя /proc/1/rootэто всегда ссылка на /(если только она initне является chroot, но это не тот случай, который меня волнует), следование по ней ведет к корневому каталогу «master». Этот метод используется в нескольких сценариях обслуживания в Debian, например, для пропуска запуска udev после установки в chroot.
if [ "$(stat -c %d:%i /)" != "$(stat -c %d:%i /proc/1/root/.)" ]; then
echo "We are chrooted!"
else
echo "Business as usual"
fi
(Кстати, это еще один пример того, почему chrootбесполезно для безопасности, если у корневого процесса есть root-доступ. Процессы без полномочий root не могут читать /proc/1/root, но они могут следовать, /proc/1234/rootесли есть запущенный процесс с PID 1234, работающим так же пользователь.)
Если у вас нет прав доступа root, вы можете посмотреть /proc/1/mountinfoи /proc/$$/mountinfo(кратко описано в документации filesystems/proc.txtядра Linux ). Этот файл доступен для чтения всем и содержит много информации о каждой точке монтирования в представлении процесса файловой системы. Пути в этом файле ограничены тем, что chroot влияет на процесс чтения, если таковой имеется. Если чтение процесса /proc/1/mountinfoпривязано к файловой системе, отличной от глобального корня (при условии, что корень pid 1 является глобальным корнем), тогда запись для не /появляется /proc/1/mountinfo. Если чтение процесса /proc/1/mountinfoявляется изолированным в каталог на глобальной корневой файловой системе, то запись для /появляюсь в /proc/1/mountinfo, но с другим идентификатором монтирование. Кстати, корневое поле ($4) указывает, где находится chroot в основной файловой системе.
Это чисто решение Linux. Это может быть обобщено на другие варианты Unix с достаточно похожим /proc(у Solaris есть подобное /proc/1/root, я думаю, но нет mountinfo).
Это не будет работать в OpenBSD, потому что он имеет случайные PID ; корневой процесс в основном никогда не PID 1. Теперь вы знаете, почему!
Адам Кац
@AdamKatz "... с несколькими очевидными исключениями, например, init (8)." Так что это?
Муру
@muru: ау, ебет Вы сбили меня. Я не уверен, почему init(8)абсолютно необходимо иметь слот № 1, если нет какой-то жестко запрограммированной природы, которая требует этого (в которой я все еще не уверен, почему ). Конечно, в BSD гораздо более продвинутые тюрьмы, чем просто в chroot, поэтому я даже не уверен, насколько это проблематично.
Адам Кац
4
@AdamKatz Все наоборот: pid 1 играет особую роль (он должен пожинать зомби, и он неуязвим для SIGKILL). Программа init является реализацией этой роли. Причина, по которой мой ответ не работает в OpenBSD, не имеет к этому никакого отношения: причина в том, что в OpenBSD нет ничего похожего на Solaris / Linux /proc. В любом случае, мой ответ не предназначался ни для чего, кроме Linux.
Жиль "ТАК - перестань быть злым"
@ Жиль Я полагал, что OpenBSD так или иначе победит это. Тем не менее, я удивлен, что все эти особые элементы роли не могут быть применены к произвольному PID (без последствий), что я и имел в виду в своем выделенном курсивом «почему» ранее.
Номер инода, отличный от 2, указывает на то, что видимый корень не является фактическим корнем файловой системы. Это не будет обнаруживать chroot, которые оказались корневыми в точке монтирования или в операционных системах со случайными номерами корневых узлов .
На каких файловых системах работает эта эвристика?
Жиль "ТАК - перестань быть злым"
Проверено на ext3 и hfs.
10
Так что я дурачился и думаю, что нашел более надежный метод, который не требует прав root (только для Linux). Я все еще открыт для контрпримеров или более переносимых методов.
Жиль "ТАК - перестань быть злым"
6
Это верно для ext [234], но не для всех файловых систем. Он также только проверяет, что ваш корень является корнем файловой системы, которая не может быть смонтирована как настоящий корень. Другими словами, если вы смонтируете другой раздел в / jail и chroot /jail, тогда он будет выглядеть как настоящий корень этого теста.
psusi
1
@ AdamKatz Видимо нет. Протестировано в openbsd 6.0-stable, номер инода по-прежнему равен 2 для фактического корневого пути, в то время как это случайное число для chroot.
Дмитрий Д.Б.
5
Хотя это явно не так переносимо, как многие другие опции, перечисленные здесь, попробуйте сделать это, если вы используете систему на основе Debian ischroot.
Чтобы получить статус в консоли напрямую, используя ischroot:
ischroot;echo $?
Коды выхода:
0 if currently running in a chroot
1 if currently not running in a chroot
2 if the detection is not possible (On GNU/Linux this happens if the script is not run as root).
init(8)
абсолютно необходимо иметь слот № 1, если нет какой-то жестко запрограммированной природы, которая требует этого (в которой я все еще не уверен, почему ). Конечно, в BSD гораздо более продвинутые тюрьмы, чем просто в chroot, поэтому я даже не уверен, насколько это проблематично./proc
. В любом случае, мой ответ не предназначался ни для чего, кроме Linux.Как уже упоминались в портативном способе найти номер индексного дескриптора и обнаружение CHROOT тюрьмы изнутри , вы можете проверить , является ли индексный дескриптором
/
является2
:Номер инода, отличный от 2, указывает на то, что видимый корень не является фактическим корнем файловой системы. Это не будет обнаруживать chroot, которые оказались корневыми в точке монтирования или в операционных системах со случайными номерами корневых узлов .
источник
chroot /jail
, тогда он будет выглядеть как настоящий корень этого теста.Хотя это явно не так переносимо, как многие другие опции, перечисленные здесь, попробуйте сделать это, если вы используете систему на основе Debian
ischroot
.См .: https://manpages.debian.org/jessie/debianutils/ischroot.1.en.html.
Чтобы получить статус в консоли напрямую, используя ischroot:
ischroot;echo $?
Коды выхода:
источник