devops
February 28

Создание systemd сервиса

TL;DR
Создание "сервисного" пользователя
Создание systemd-сервиса

Создание пользователя

Создание пользователя обычно чем-то подкрепляется. В моем случае нужно было создать "сервисного" юзера. У которого не будет домашней директории и через него нельзя будет залогиниться. А нужен он будет для запуска веб-сервера
Поэтому входные данные такие:

  • Имя группы
  • Имя пользователя
  • Путь до исполняемого файла
  • Путь до директорий, к которым нужен будет доступ

Создаем группу

sudo groupadd <имя_группы>

Создаем самого пользователя

sudo useradd -r -s /usr/sbin/nologin -g <имя_группы> <имя_пользователя>

-r - создает системного пользователя без домашней директории
-s /usr/sbin/nologin - запрещает авторизацию пользователя через терминал
-g <имя_группы> - добавляет пользователя в определенную группу

Полный список флагов здесь.

Назначаем права доступа

sudo chown -R <пользователь>:<группа> <путь_до_исполняемого_файла>

sudo chown -R <пользователь>:<группа> <дополнительные_директории>
...

Управление systemd-сервисом

Чтобы создать сервис, нужно описать его в конфигурационном файле. Располагаться он должен в /etc/systemd/system/<имя_сервиса>.service

Ниже приведен пример шаблона с пояснениями. Данный шаблон был использован для настройки Copyparty

Шаблон:

[Unit]
Description=CopyParty File Server # Описание
After=network.target # запуск после успешного поднятия сети

[Service]
Type=simple

User=copyparty # Пользователь, которого создали ранее
Group=copyparty # Группа, которую создали ранее

WorkingDirectory=/opt/copyparty # Директория, где лежит исполняемый файл

ExecStart=/usr/bin/python3 /opt/copyparty/copyparty-sfx.py -c /opt/copyparty/copyparty.conf # Команда запуска. На всякий случай пишем пути полностью

# Настройки перезапуска при сбоях
Restart=on-failure
RestartSec=5

# Базовые настройки безопасности
NoNewPrivileges=yes # Запрет процессу и его дочерним повышать привелегии
ProtectSystem=full # Делает системноважные папки неприкосаемыми

Environment="HOME=/opt/copyparty" # Т.к. пользователь copyparty был создан без домашней директории, то укажем ее вручную

AmbientCapabilities=CAP_NET_BIND_SERVICE # Дает разрешение на откртые системных портов(0-1023)
[Install]
WantedBy=multi-user.target # Устанавливает условие для запуска: система должна полностью загрузиться и быть готовой к работе

Изначально шабон не завелся из-за двух ошибок:

  1. srv.bind((ip, port)) -> [Errno 13] Permission denied
  2. Unable to store config in ~/.config

Чтобы их исправить были добавлены строчки:

Environment="HOME=/opt/copyparty" # Т.к. пользователь copyparty был создан без домашней директории, то укажем ее вручную

AmbientCapabilities=CAP_NET_BIND_SERVICE # Дает разрешение на откртые системных портов(0-1023)

Кстати список всех Capabilities лежит здесь.

🔥Hint

Если заполняли файл на winodws, то на всякий случай наш его преобразовать с dos на unix командой dos2unix /etc/systemd/system/copyparty.service

Теперь запустим наш сервис:

Перезагружаем конфиг systemd

sudo systemctl daemon-reload

Включаем наш сервис, тем самым добавляем его в автозагрузку

sudo systemctl enable copyparty

Запускаем наш сервис

sudo systemctl start copyparty

Проверяем статус сервиса

sudo systemctl status copyparty

Просмотр логов сервиса

sudo journalctl -u copyparty.service

На этом создание нашего сервиса завершено :)

Всем добра!