SSD Nodes Learn
Посібники Matt ConnorВід Matt Connor · Оновлено 2026-07-24

Як запускати сервіси не від імені root

Запуск сервісів під 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; обліковий запис все ще зможе читати всі файли, доступні для читання всім користувачам (world-readable), але не зможе змінити решту системи.

Використання systemd для запуску від імені цього користувача

Після створення облікового запису вкажіть systemd запускати сервіс від його імені. У юніт-файлі це робиться одним рядком:

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

User=appsvc означає, що процес запускається з обмеженими привілеями цього облікового запису замість прав root. Це стандартний, перевірений спосіб запуску додатків через systemd, і його варто застосовувати для кожного сервісу, для якого ви пишете юніт.

Або повністю пропустіть створення облікового запису за допомогою DynamicUser

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

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

Під час запуску systemd виділяє невикористаний ID користувача; під час зупинки — звільняє його. Сервіс також отримує приватну директорію /tmp (read-only view більшості файлової системи) та директорію стану для запису під /var/lib/myapp, яку налаштовує та передає StateDirectory=. Для автономного сервісу, якому потрібна лише власна директорія стану, DynamicUser=yes є найпростішим способом забезпечити сильну ізоляцію, оскільки для зловмисника взагалі не існує довготривалого облікового запису, на який можна націлитися.

Написання юнітів вручну є складним процесом, а правильне налаштування директив захисту становить основну цінність. Генератор у the systemd service and timer guide може підготувати ці параметри за вас, щоб юніт був коректним з першого разу.

Як це взаємодіє з іншими засобами захисту

Принцип найменших привілеїв — це один із рівнів захисту, який працює разом з іншими, а не замінює їх. default-deny firewall контролює, що може дістатися до сервісу; запуск від імені непривілегованого користувача обмежує дії сервісу у разі зламу; а hardened SSH перешкоджає проникненню зловмисників на сервер. Жоден із цих методів сам по собі не є достатнім, але разом вони гарантують, що помилка в одному сервісі не призведе до компрометації всього сервера.

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

ToolVPS hardening checklist

FAQ

Why should I not run a service as root?

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

How do I create a user that cannot log in?

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

What is systemd DynamicUser?

DynamicUser=yes вказує systemd створити тимчасового користувача для сервісу, який існує лише під час його роботи, тому вам не потрібно керувати довготривалим обліковим записом. Це також надає сервісу приватну /tmp (переважно лише для читання) та керовану директорію стану. Це найпростіший спосіб запуску автономного сервісу під тимчасовою малопривілеговою особистістю.

Does running as a non-root user replace a firewall?

Ні. Вони захищають різні речі. Запуск від імені непривілегованого користувача обмежує дії сервісу у разі зламу, тоді як firewall обмежує те, що взагалі може дістатися до сервісу. Використовуйте обидва методи разом із hardened SSH, щоб кожен рівень захищав те, що не можуть покрити інші.

What files should the service user own?

Тільки ті файли, які дійсно потрібні сервісу, і нічого більше. Надайте обліковому запису право власності на його власну робочу директорію та дані, а все інше залиште під керуванням root. Гарний шаблон: sudo chown -R svc-app:svc-app /opt/svc-app для директорії додатка, тоді як конфігурація в /etc залишається власністю root і доступна для читання лише сервісу. Мета полягає в тому, щоб у разі компрометації процесу файли, які він може змінити, були обмежені лише його власними даними, а не всією системою.

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