Как ограничить linux-сервису запись в файловую систему через systemd?
По умолчанию systemd-сервис имеет доступ к файловой системе в пределах прав своего пользователя. Однако иногда требуется запретить изменение системных каталогов, разрешив запись только в определённую директорию.
Для этого используются
Практика рассчитана на обычную линукс систему с systemd и поддержкой mount namespaces. В контейнерах с ограниченными привилегиями поведение может отличаться. Создадим каталог для данных приложения:
Создадим тестовый сервис, который попытается записать файлы в разрешённый каталог и в защищённый
Сервис намеренно запускается от
Убедимся, что тестовый файл в
На типичной системе запуск завершится ошибкой: первая операция
Проверим результат и журнал сервиса:
Первый файл должен существовать, второй — отсутствовать, а журнал должен содержать ошибку записи в
Проверим загруженные параметры изоляции и оценим конфигурацию безопасности:
При этом
🔥
🚪 Linux Ready | #практика
По умолчанию systemd-сервис имеет доступ к файловой системе в пределах прав своего пользователя. Однако иногда требуется запретить изменение системных каталогов, разрешив запись только в определённую директорию.
Для этого используются
ProtectSystem=strict и ReadWritePaths. Они ограничивают запись через отдельное пространство монтирования (mount namespace), не изменяя глобальные права файлов.Практика рассчитана на обычную линукс систему с systemd и поддержкой mount namespaces. В контейнерах с ограниченными привилегиями поведение может отличаться. Создадим каталог для данных приложения:
sudo mkdir -p /var/lib/test-app
Создадим тестовый сервис, который попытается записать файлы в разрешённый каталог и в защищённый
/etc:sudo tee /etc/systemd/system/test-app.service >/dev/null <<'EOF'
[Unit]
Description=Filesystem isolation test
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'touch /var/lib/test-app/ok && touch /etc/test-app-file'
ProtectSystem=strict
ReadWritePaths=/var/lib/test-app
EOF
Сервис намеренно запускается от
root (без User=), чтобы продемонстрировать именно ограничения systemd, а не обычные права доступа к файлам. ProtectSystem=strict делает почти всю файловую иерархию доступной только для чтения внутри mount namespace сервиса, за исключением отдельных API-файловых систем.ReadWritePaths исключает /var/lib/test-app из ограничения read-only, но не отменяет обычные права доступа и не позволяет записывать данные на файловую систему, изначально смонтированную только для чтения.Убедимся, что тестовый файл в
/etc отсутствует:if [ -e /etc/test-app-file ] || [ -L /etc/test-app-file ]; then
echo "Ошибка: /etc/test-app-file уже существует"
else
sudo systemctl daemon-reload
sudo systemctl start test-app.service
fi
На типичной системе запуск завершится ошибкой: первая операция
touch выполнится успешно, а вторая получит EROFS (Read-only file system). Поскольку используется Type=oneshot, юнит перейдёт в состояние failed.Проверим результат и журнал сервиса:
test -f /var/lib/test-app/ok && echo "OK: запись разрешена"
if [ ! -e /etc/test-app-file ] && [ ! -L /etc/test-app-file ]; then
echo "OK: файл в /etc не создан"
fi
journalctl -u test-app.service -n 20 --no-pager
Первый файл должен существовать, второй — отсутствовать, а журнал должен содержать ошибку записи в
/etc. Совокупность этих результатов подтверждает ожидаемое поведение изоляции. Если первый файл не создан, необходимо проверить журнал и причину сбоя.Проверим загруженные параметры изоляции и оценим конфигурацию безопасности:
systemctl show test-app.service \
-p ProtectSystem \
-p ReadWritePaths
systemd-analyze security test-app.service
systemd-analyze security оценивает защитные настройки юнита, но не проверяет фактические права записи.При этом
ProtectSystem не изолирует сеть и процессы. Сервис с достаточными привилегиями, в частности с CAP_SYS_ADMIN, потенциально способен изменять ограничения монтирования. После проверки удалим тестовое окружение:sudo systemctl stop test-app.service
sudo rm -f /etc/systemd/system/test-app.service
sudo rm -rf /var/lib/test-app
sudo systemctl daemon-reload
sudo systemctl reset-failed test-app.service
ProtectSystem=strict совместно с ReadWritePaths позволяет ограничить запись сервиса без изменения глобальных прав файловой системы. В продакшене эти настройки рекомендуется дополнять User, NoNewPrivileges и CapabilityBoundingSet, а для управления каталогами данных использовать StateDirectory.Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥9❤7🤝1
Ansible позволяет автоматизировать настройку серверов, развертывание приложений и управление инфраструктурой без установки агентов на управляемые узлы.
На картинке — схема архитектуры Ansible: взаимодействие управляющего узла с серверами по SSH, а также основные компоненты —
Inventory, ansible.cfg и Playbook.Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤14👍9🔥6
This media is not supported in your browser
VIEW IN TELEGRAM
В репозитории собраны пошаговые задания по безопасности системы, настройке сетей, RAID и файловых хранилищ, резервному копированию, журналированию и автоматизации с помощью Bash и Ansible. Особенно полезно, что есть готовые скрипты, конфигурации, инструкции на русском языке и автоматические проверки выполнения заданий.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
❤12👍7🔥5
Знали, что можно заставить многие Linux-программы создавать временные файлы в отдельном каталоге, не меняя их исходный код?
Обычно приложения используют
Но многие утилиты и библиотеки учитывают переменную окружения
Теперь программа, если она поддерживает
После выполнения можно посмотреть, что осталось:
Это полезно при отладке сборок, генераторов, компиляторов и скриптов, которые создают промежуточные файлы.
Для автоматической очистки в Bash можно использовать обработчик завершения:
Важно:
🔥
🚪 Linux Ready | #совет
Обычно приложения используют
/tmp, из-за чего бывает сложно понять, какие временные файлы создала конкретная программа.Но многие утилиты и библиотеки учитывают переменную окружения
TMPDIR:tmp=$(mktemp -d)
TMPDIR="$tmp" ./myapp
Теперь программа, если она поддерживает
TMPDIR, будет использовать указанный каталог для временных файлов.После выполнения можно посмотреть, что осталось:
find "$tmp" -maxdepth 2 -type f
Это полезно при отладке сборок, генераторов, компиляторов и скриптов, которые создают промежуточные файлы.
Для автоматической очистки в Bash можно использовать обработчик завершения:
tmp=$(mktemp -d)
trap 'rm -rf -- "$tmp"' EXIT
TMPDIR="$tmp" ./myapp
Важно:
TMPDIR — не механизм изоляции. Программы с жёстко заданными путями могут продолжать писать в /tmp или другие каталоги.TMPDIR позволяет быстро выделить программе собственное пространство для временных файлов, упростить диагностику и контролировать очистку без контейнеров и изменений в коде.Please open Telegram to view this post
VIEW IN TELEGRAM
❤8🔥8👍6
Сервис не видит изменения в файле после его замены?
Иногда конфигурационный файл уже обновлён, но работающий процесс продолжает читать старое содержимое. Перезапуск сервиса решает проблему, однако причина может быть не в кэшировании, а в открытом файловом дескрипторе.
В линукс файловый дескриптор ссылается на открытый файловый объект, а не на строковый путь. Если файл заменили через
Проверим это на практике. Создадим файл:
Запустим питон-процесс, который откроет файл один раз и будет перечитывать его через тот же дескриптор:
В другом терминале подготовим новую версию и атомарно заменим файл:
Несмотря на замену, питон продолжит выводить:
Посмотрим inode текущего файла:
Теперь найдём PID питон-процесса и проверим его дескрипторы:
Среди них можно обнаружить:
Пометка
Сравним inode открытого дескриптора и файла по пути:
Номера будут различаться, поскольку процесс и файловый путь теперь ссылаются на разные inode.
Найти открытые удалённые файлы можно через:
Команда показывает открытые файлы с количеством жёстких ссылок меньше единицы. Это также полезно при поиске удалённых логов, которые продолжают занимать место на диске.
Для устранения проблемы приложение должно закрыть старый дескриптор и повторно открыть файл по пути. В зависимости от реализации это может происходить при reload или только при полном перезапуске.
🔥 Атомарная замена через
🚪 Linux Ready | #практика
Иногда конфигурационный файл уже обновлён, но работающий процесс продолжает читать старое содержимое. Перезапуск сервиса решает проблему, однако причина может быть не в кэшировании, а в открытом файловом дескрипторе.
В линукс файловый дескриптор ссылается на открытый файловый объект, а не на строковый путь. Если файл заменили через
rename(), процесс с уже открытым дескриптором продолжит работать со старым inode.Проверим это на практике. Создадим файл:
echo "version=1" > /tmp/app.conf
Запустим питон-процесс, который откроет файл один раз и будет перечитывать его через тот же дескриптор:
python3 - <<'PY'
import time
with open("/tmp/app.conf") as f:
while True:
f.seek(0)
print(f.read().strip(), flush=True)
time.sleep(2)
PY
В другом терминале подготовим новую версию и атомарно заменим файл:
echo "version=2" > /tmp/app.conf.new
mv /tmp/app.conf.new /tmp/app.conf
Несмотря на замену, питон продолжит выводить:
version=1
Посмотрим inode текущего файла:
stat -c '%i %n' /tmp/app.conf
Теперь найдём PID питон-процесса и проверим его дескрипторы:
sudo ls -l /proc/<PID>/fd/
Среди них можно обнаружить:
3 -> /tmp/app.conf (deleted)
Пометка
(deleted) означает, что inode больше не имеет прежнего имени в файловой системе, но продолжает существовать благодаря открытым ссылкам.Сравним inode открытого дескриптора и файла по пути:
sudo stat -Lc '%i %n' /proc/<PID>/fd/3
stat -c '%i %n' /tmp/app.conf
Номера будут различаться, поскольку процесс и файловый путь теперь ссылаются на разные inode.
Найти открытые удалённые файлы можно через:
sudo lsof +L1
Команда показывает открытые файлы с количеством жёстких ссылок меньше единицы. Это также полезно при поиске удалённых логов, которые продолжают занимать место на диске.
Для устранения проблемы приложение должно закрыть старый дескриптор и повторно открыть файл по пути. В зависимости от реализации это может происходить при reload или только при полном перезапуске.
rename() гарантирует переключение имени файла, но не обновляет уже открытые файловые дескрипторы. При диагностике конфигураций, логов и файлов данных полезно сравнивать inode через stat и проверять /proc/<PID>/fd, прежде чем искать проблему в кэшировании.Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤7🔥5
Запускаем временные команды в Linux под управлением systemd!
При разработке часто приходится запускать временные серверы, сборщики и фоновые процессы. Проблема в том, что после закрытия терминала некоторые из них продолжают работать, занимая порты и потребляя ресурсы.
В Linux есть полезный инструмент
Например, запустим
Команда создаёт отдельный
Для временных задач удобнее использовать
Сборка запускается как отдельный сервис и по умолчанию выполняется асинхронно. Если она не завершится за 10 минут,
Проверить состояние задачи можно без поиска
А если процесс завис или больше не нужен, достаточно остановить unit. По умолчанию systemd завершит процессы в его cgroup согласно настройкам сервиса.
Ещё одна полезная возможность — ограничение потребления памяти:
Лимит применяется ко всей
Посмотреть логи задачи можно через
Команды предполагают работающий пользовательский
🔥 Это удобно для сборок, тестов и временных фоновых задач: не нужно вручную управлять PID, перенаправлять вывод в файлы или писать отдельные
🚪 Linux Ready | #практика
При разработке часто приходится запускать временные серверы, сборщики и фоновые процессы. Проблема в том, что после закрытия терминала некоторые из них продолжают работать, занимая порты и потребляя ресурсы.
В Linux есть полезный инструмент
systemd-run, позволяющий запускать процессы в отдельных временных units без создания service-файлов.Например, запустим
dev-сервер:systemd-run --user --scope \
--unit=dev-server npm run dev
Команда создаёт отдельный
scope в пользовательском systemd. Но есть нюанс: --scope сам по себе не гарантирует завершение процесса при закрытии терминала.Для временных задач удобнее использовать
transient service с ограничением времени:systemd-run --user \
--unit=temp-build \
--working-directory="$PWD" \
-p RuntimeMaxSec=10min \
npm run build
Сборка запускается как отдельный сервис и по умолчанию выполняется асинхронно. Если она не завершится за 10 минут,
systemd инициирует остановку сервиса.Проверить состояние задачи можно без поиска
PID:systemctl --user status temp-build.service
А если процесс завис или больше не нужен, достаточно остановить unit. По умолчанию systemd завершит процессы в его cgroup согласно настройкам сервиса.
systemctl --user stop temp-build.service
Ещё одна полезная возможность — ограничение потребления памяти:
systemd-run --user \
--unit=limited-build \
--working-directory="$PWD" \
-p MemoryMax=1G \
npm run build
Лимит применяется ко всей
cgroup сервиса, включая дочерние процессы. При превышении ограничения возможен OOM-kill. Для работы необходим доступный контроллер памяти cgroups.Посмотреть логи задачи можно через
journalctl:journalctl --user -u limited-build.service -f
Команды предполагают работающий пользовательский
systemd. Окружение transient service отличается от текущего shell: например, npm, установленный через nvm, может быть недоступен. Также имена units должны быть свободны при запуске.service-файлы.Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤7🔥6🤝3
В этой статье:
• Узнаете, почему Docker может открывать порты PostgreSQL и Redis в интернет, несмотря на запреты UFW;• Разберётесь, как работают правила Netfilter, DNAT и цепочки iptables, а также что делают боты после обнаружения открытых баз данных;• Изучите практические способы защиты контейнеров: привязку портов к localhost, внутренние Docker-сети и фильтрацию трафика.🔊 Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤7🔥7
Обычные
ls -l и stat покажут время изменения файла, но не ответят, какой процесс и пользователь за этим стояли. В Linux для этого существует подсистема аудита — auditd, которая позволяет отслеживать операции с файлами на уровне ядра.Как работает:
• auditctl -w добавляет правило наблюдения за выбранным файлом;
• -p wa включает регистрацию операций записи и изменения атрибутов;
• ausearch -k находит зарегистрированные события по заданной метке, включая сведения о процессе и пользователе;
• aureport -f формирует сводный отчёт по файловым операциям на основе собранных событий.
Приём полезен для аудита конфигураций, расследования неожиданных изменений и контроля критичных файлов на Linux-серверах.
Для работы необходим установленный и запущенный
auditd. Правило следует включить заранее: события, произошедшие до его активации, восстановить таким способом нельзя. Правила, добавленные через auditctl, не сохраняются автоматически после перезагрузки.Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥7🤝4❤1
По данным Минфин 32% граждан покинули своё место работы поскольку в среднем уже в первый месяц смогли заработать 250 000 рублей, а через 2-3 месяца с легкостью вышли на семизначные числа.
Самое смешное, что лишь 8% россиян что-то слышали об этой профессии хотя все инструкции бесплатно лежат на канале Арбитраж Криптовалют
Там объясняют, как имея телефон и доступ в интернет заработать свои первые $3000. Причём разжёвывают так доступно, что поймёт даже ребенок. Кстати, на канале сегодня вышла новая рабочая связка!
Ссылка для входа — https://t.me/+lvVed8tyOGg5ZWNi
Please open Telegram to view this post
VIEW IN TELEGRAM
👎8😁3
Восстанавливаем случайно удалённые файлы через Git без переключения веток!
При работе над проектом иногда нужно достать один файл из старого коммита или другой ветки. Обычно для этого начинают переключать ветки, искать нужный коммит или временно откатывать изменения. Но
Например, восстановить конкретный файл из последнего коммита:
Команда заменит рабочую копию файла версией из HEAD, не изменяя остальные файлы. Важно: несохранённые изменения именно этого файла будут потеряны.
Если файл существовал несколько коммитов назад, можно достать его из истории:
Ещё интереснее — извлечь файл из другой ветки без checkout:
Текущая ветка останется прежней, а в рабочей директории появится версия файла из
Если нужно только посмотреть содержимое старой версии, не изменяя файлы проекта:
Команда выведет содержимое файла из указанного коммита прямо в терминал. Результат можно перенаправить в отдельный файл или использовать в скрипте.
А чтобы восстановить только отдельные изменения, пригодится интерактивный режим:
🔥
🚪 Linux Ready | #практика
При работе над проектом иногда нужно достать один файл из старого коммита или другой ветки. Обычно для этого начинают переключать ветки, искать нужный коммит или временно откатывать изменения. Но
Git позволяет извлекать файлы напрямую, не трогая текущую ветку.Например, восстановить конкретный файл из последнего коммита:
git restore --source=HEAD -- config.json
Команда заменит рабочую копию файла версией из HEAD, не изменяя остальные файлы. Важно: несохранённые изменения именно этого файла будут потеряны.
Если файл существовал несколько коммитов назад, можно достать его из истории:
git restore --source=HEAD~3 -- config.json
Git возьмёт версию файла из третьего предка HEAD. Это удобно, когда конфигурацию случайно изменили или удалили, а откатывать весь проект не хочется.Ещё интереснее — извлечь файл из другой ветки без checkout:
git restore --source=feature/api -- src/api.js
Текущая ветка останется прежней, а в рабочей директории появится версия файла из
feature/api.Если нужно только посмотреть содержимое старой версии, не изменяя файлы проекта:
git show HEAD~2:src/api.js
Команда выведет содержимое файла из указанного коммита прямо в терминал. Результат можно перенаправить в отдельный файл или использовать в скрипте.
А чтобы восстановить только отдельные изменения, пригодится интерактивный режим:
git restore -p --source=HEAD -- src/api.js
Git предложит выбрать конкретные фрагменты изменений. Так можно вернуть нужные участки кода, сохранив остальные правки.git restore и git show позволяют работать с историей проекта точечно, доставать файлы из других веток, восстанавливать удалённый код и откатывать отдельные изменения без переключения веток и сброса всего проекта.Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤7🔥5
This media is not supported in your browser
VIEW IN TELEGRAM
На сайте собрана большая подборка статей по администрированию Linux: настройка серверов, работа с сетями, файловыми системами, службами, безопасностью, резервным копированием и другими задачами, с которыми регулярно сталкиваются системные администраторы. Материалы охватывают как базовые, так и продвинутые темы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥7🤝2❤1👎1