SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-08-26

Как запустить сервис от непривилегированного пользователя

Запуск сервисов от root дает злоумышленнику полный контроль над сервером. Используйте отдельные учетные записи или директиву DynamicUser в systemd для ограничения прав.

Почему не стоит запускать всё от имени root

Пользователь root обладает полными правами в системе: он может читать любые файлы, изменять любые настройки и удалить всю систему целиком. Запуская сервис от имени root, вы передаёте ему все эти полномочия. Если в сервисе есть уязвимость, которой может воспользоваться злоумышленник, он получает не просто доступ к сервису, а права root, что означает полный контроль над сервером. Запуск от имени непривилегированного пользователя ограничивает масштаб ущерба. Ошибка в сервисе, работающем под ограниченной учётной записью, даёт злоумышленнику доступ только к тому, что разрешено этой учётной записи, — то есть практически ни к чему.

Это принцип минимальных привилегий: предоставьте каждой части системы ровно те права, которые необходимы для выполнения её задач, и ничего больше. Это самый эффективный способ ограничить зону поражения при взломе, и на современном сервере его применение практически не требует усилий.

Отдельная учетная запись для каждого сервиса

Классический подход заключается в создании отдельного системного пользователя для каждого сервиса. Этот пользователь владеет только файлами своего сервиса и не имеет возможности войти в систему. Системная учетная запись для веб-приложения может выглядеть так:

sudo useradd --system --no-create-home --shell /usr/sbin/nologin appsvc

Каждый флаг имеет значение. --system делает учетную запись сервисной, а не пользовательской. --no-create-home отключает создание домашнего каталога, который не требуется. --shell /usr/sbin/nologin означает, что даже если злоумышленник получит доступ к учетной записи, он не сможет запустить оболочку (shell). Учетная запись существует только для владения процессом и его файлами.

Затем предоставьте этому пользователю доступ только к необходимым файлам:

sudo chown -R appsvc:appsvc /opt/myapp

Теперь сервис читает и записывает данные только в своем каталоге и не имеет доступа к остальным частям диска. В случае взлома злоумышленник сможет изменить только файлы в /opt/myapp. Учетная запись по-прежнему может читать любые общедоступные файлы, но не может изменять остальную часть системы.

Настройка запуска от имени пользователя в systemd

После создания учетной записи укажите systemd запускать сервис от ее имени. В файле юнита за это отвечает одна строка:

[Service]
ExecStart=/opt/myapp/bin/server
User=appsvc
Group=appsvc

User=appsvc означает, что процесс запускается с ограниченными правами этой учетной записи, а не с правами root. Это стандартный и проверенный способ запуска приложений в systemd, который рекомендуется использовать для каждого сервиса, для которого вы создаете юнит. Однако снижение привилегий не поможет, если systemd отслеживает не тот процесс. Если юнит сообщает о статусе active после того, как демон незаметно завершил работу, убедитесь, что вы выбрали правильный параметр Type= для способа запуска вашего процесса.

Или полностью откажитесь от учетной записи с помощью DynamicUser

systemd может пойти еще дальше и создать для вас временного пользователя, который существует только во время работы службы. Установите DynamicUser=yes, и вам вообще не придется управлять учетной записью:

[Service]
ExecStart=/opt/myapp/bin/server
DynamicUser=yes
StateDirectory=myapp

При запуске systemd выделяет неиспользуемый идентификатор пользователя (UID), а при остановке — освобождает его. Служба также получает собственный /tmp, представление большинства файловых систем только для чтения и доступную для записи директорию состояния в /var/lib/myapp, которую StateDirectory= создает и передает службе. Ничего подобного нельзя было реализовать в SysV init, где снижение привилегий зависело от того, что именно делает скрипт запуска конкретной службы. Этот пробел — одна из главных причин, почему дистрибутивы в первую очередь перешли на systemd. Для автономной службы, которой требуется только собственная директория состояния, DynamicUser=yes — это способ с минимальными усилиями обеспечить строгую изоляцию, поскольку у злоумышленника нет долгоживущей учетной записи для атаки.

Написание юнитов вручную — кропотливая работа, а правильная настройка директив безопасности составляет основную ценность. Генератор в руководстве по сервисам и таймерам systemd может заполнить эти параметры за вас, чтобы юнит был корректным с первого раза.

Как это сочетается с остальными мерами

Принцип наименьших привилегий — это лишь один уровень защиты, который работает в связке с остальными, а не заменяет их. Межсетевой экран с политикой default-deny ограничивает доступ к сервису извне; запуск от имени непривилегированного пользователя ограничивает возможности сервиса в случае его взлома; а защищенный SSH предотвращает несанкционированный доступ к серверу. Ни одна из этих мер по отдельности не является достаточной, но вместе они гарантируют, что ошибка в одном сервисе не приведет к компрометации всего сервера. Размещение сервисов, хранящих секретные данные, наглядно показывает границы этих уровней: ограниченная учетная запись не дает взломанному процессу доступа к критическим файлам, однако безопасность самохостируемого менеджера паролей, например Vaultwarden, по-прежнему зависит от защиты административного токена и резервных копий, которые изоляция пользователей не затрагивает.

Прежде чем двигаться дальше, выполните проверку системы по контрольному списку безопасности и создайте персональную копию этого списка для дальнейшей работы:

ToolVPS hardening checklist

FAQ

Почему не следует запускать сервис от имени root?

Поскольку root обладает неограниченными правами в системе, взлом сервиса, работающего от имени root, дает злоумышленнику контроль над всем сервером, а не только над самим сервисом. Запуск сервиса от имени ограниченной, непривилегированной учетной записи локализует ущерб пределами прав этой записи. Оставьте root для администрирования, а все постоянно работающие сервисы запускайте от имени ограниченного пользователя.

Как создать пользователя, который не может войти в систему?

Выполните sudo useradd --system --no-create-home --shell /usr/sbin/nologin NAME. Оболочка nologin означает, что учетная запись не сможет открыть интерактивный сеанс, даже если учетные данные будут украдены, --system помечает ее как сервисную учетную запись, а --no-create-home отменяет создание домашнего каталога, который ей не нужен. Назначьте владельцем только ее собственных файлов с помощью chown.

Что такое DynamicUser в systemd?

DynamicUser=yes указывает systemd создать временного пользователя для сервиса, который существует только во время его работы, поэтому вам не нужно управлять долгоживущей учетной записью. Это также предоставляет сервису приватный /tmp, файловую систему с режимом «только чтение» для большинства областей и управляемый каталог состояния. Это самый простой способ запуска изолированного сервиса от имени одноразовой учетной записи с низкими привилегиями.

Заменяет ли запуск от имени пользователя без прав root межсетевой экран?

Нет. Они защищают разные уровни. Запуск от имени непривилегированного пользователя ограничивает возможности сервиса в случае его взлома, в то время как межсетевой экран ограничивает доступ к сервису извне. Используйте оба инструмента вместе с защищенным SSH, чтобы каждый уровень покрывал то, что не могут защитить остальные.

Какие файлы должны принадлежать пользователю сервиса?

Только те файлы, которые действительно нужны сервису, и ничего больше. Назначьте учетную запись владельцем ее рабочего каталога и данных, а все остальное оставьте в собственности root. Хорошая практика — sudo chown -R svc-app:svc-app /opt/svc-app для каталога приложения, в то время как конфигурация в /etc остается в собственности root и доступна сервису только для чтения. Цель состоит в том, чтобы в случае компрометации процесса злоумышленник мог изменить только собственные данные сервиса, а не всю систему целиком.

#security#least-privilege#systemd#users#hardening#linux