Не полагайтесь на серверы, не находящиеся под вашим контролем, для воспроизведения определенного состояния системы. Даже если серверы Debian довольно надежны, никогда не знаешь, что может случиться в будущем. Это особенно актуально для других репозиториев, которые вы можете использовать.
Вам следует поддерживать собственное зеркало, чтобы получить воспроизводимые состояния системы. Таким образом, у вас может быть даже рабочее состояние для ваших обычных систем и несколько тестовых состояний для новых конфигураций.
Средство управления репозиторием aptly может создавать зеркала репозиториев. Вы можете выбирать пакеты для зеркалирования, создавать моментальные снимки содержимого репозитория в определенные моменты времени и объединять несколько зеркал или моментальных снимков в один репозиторий. Таким образом, вы можете полностью воспроизвести состояния системы.
Чтобы ответить на ваш вопрос напрямую:
how to properly execute a service with external dependencies outside of the chroot using RootDirectory.
Вы не можете. Если что-то находится в chroot-тюрьме, оно не может получить доступ ни к чему снаружи, включая двоичные файлы и библиотеки. Но у вас все еще есть способы защитить вашу систему.
Takes a directory path relative to the host's root directory (i.e. the root of the system running the service manager). Sets the root directory for executed processes, with the chroot(2) system call. If this is used, it must be ensured that the process binary and all its auxiliary files are available in the chroot() jail.
Если вы установите RootDirectory=/srv/http
, то при вызове /server.py
он попытается выполнить /usr/bin/python
, но потерпит неудачу, потому что не может найти этот путь. Даже если бы вы могли сделать что-то вроде ExecStartPre=/bin/cp /usr/bin/python /src/http/usr/bin/python
, у вас все равно возникнут проблемы при попытке import flask
или import pyramid
, так как эти библиотеки не установлены в вашем chroot. Я провел тест с настройкой, подобной вашей, и без хорошего шебанга получил ту же ошибку, что и вы.
Вот три варианта:
Дайте вашему chroot все, что ему нужно. Если вы работаете в системе, основанной на Debian -, тоdebootstrap
— отличный инструмент для настройки, deboostrap buster /srv/http
должен работать. Он установит базовую систему, после чего вы сможете sudo chroot && apt install python python-flask
или что-то еще, что вам нравится внутри.
Используйте встроенные параметры -для песочницы вашего сервиса вместо его chroot. В частности:
RemoveIPC=true
и PrivateTmp=true
. Это гарантирует, что время жизни объектов IPC и временных файлов, созданных исполняемым процессом, привязано к времени выполнения службы. Поскольку /tmp
и /var/tmp
обычно являются единственными мировыми -доступными для записи каталогами в системе, это гарантирует, что устройство не сможет оставить файлы после завершения работы. NoNewPrivileges=true
и RestrictSUIDSGID=true
.Это гарантирует, что запущенные процессы не смогут воспользоваться преимуществами или создать файлы или каталоги SUID/SGID. ProtectSystem=strict
и ProtectHome=read-only
запрещают службе запись в любое место в вашей файловой системе (исключениями являются/dev/
/proc/
и /sys/
. Чтобы разрешить службе запись в определенные каталоги, они должны быть разрешены -в списке с помощью ReadWritePaths=
. RuntimeDirectory=
для назначения службе каталога времени выполнения, который принадлежит пользователю службы и автоматически удаляется при завершении работы системы. DynamicUser=true
. Здесь есть хорошее объяснение разработчикаВ любом случае, если вы не используете User=
или DynamicUser=
, вы должны это сделать. Это не позволит вашей службе быть root
и иметь права на чтение /etc/shadow
или других секретов.
Мне очень нравится вариант 3. Его включение действительно защищает вашу систему от служб.