LINUX.ORG.RU

Кастомный systemd сервис с CentOS 7 не работает на CentOS 9 Stream

 ,


0

1

Есть Minecraft сервер на CentOS 7, который при крашах рестартится systemd сервисом. Все работает как надо и проблем нет.

Конфиг серсиса лежит в /etc/systemd/system/my_minecraft_server.service:

[Unit]
Description=my_minecraft_server

[Service]
Type=simple
WorkingDirectory=/home/my_user/my_server/
ExecStart=/home/my_user/my_server/start.sh
User=my_user
Restart=always
Sockets=my_minecraft_server.socket
StandardInput=socket
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

Сокет к нему лежит в = /etc/systemd/system/my_minecraft_server.socket:

[Unit]
PartOf=my_minecraft_server.service

[Socket]
ListenFIFO=%t/my_minecraft_server.stdin

Но после переезда на CentOS 9 Stream сервис перестал работать:

$ sudo systemctl start my_minecraft_server.service
Job for my_minecraft_server.service failed because of unavailable resources or another system error.
See "systemctl status my_minecraft_server.service" and "journalctl -xeu my_minecraft_server.service" for details.

Вот вывод из systemctl status my_minecraft_server.service:

$ systemctl status my_minecraft_server.service
× my_minecraft_server.service - my_minecraft_server
     Loaded: loaded (/etc/systemd/system/my_minecraft_server.service; enabled; preset: disabled)
     Active: failed (Result: resources) since Fri 2024-05-03 00:36:59 EDT; 1min 9s ago
TriggeredBy: ○ my_minecraft_server.socket
        CPU: 0

May 03 00:36:59 systemd[1]: my_minecraft_server.service: Scheduled restart job, restart counter is at 5.
May 03 00:36:59 systemd[1]: Stopped my_minecraft_server.
May 03 00:36:59 systemd[1]: my_minecraft_server.service: Start request repeated too quickly.
May 03 00:36:59 systemd[1]: my_minecraft_server.service: Failed with result 'resources'.
May 03 00:36:59 systemd[1]: Failed to start my_minecraft_server.

Вот вывод из journalctl -xeu my_minecraft_server.service:

░░ Subject: A stop job for unit my_minecraft_server.service has finished
░░ Defined-By: systemd
░░ Support: https://access.redhat.com/support
░░
░░ A stop job for unit my_minecraft_server.service has finished.
░░
░░ The job identifier is 133423 and the job result is done.
May 03 00:36:59 systemd[1]: my_minecraft_server.service: Start request repeated too quickly.
May 03 00:36:59 systemd[1]: my_minecraft_server.service: Failed with result 'resources'.
░░ Subject: Unit failed
░░ Defined-By: systemd
░░ Support: https://access.redhat.com/support
░░
░░ The unit my_minecraft_server.service has entered the 'failed' state with result 'resources'.
May 03 00:36:59 systemd[1]: Failed to start my_minecraft_server.
░░ Subject: A start job for unit my_minecraft_server.service has failed
░░ Defined-By: systemd
░░ Support: https://access.redhat.com/support
░░
░░ A start job for unit my_minecraft_server.service has finished with a failure.
░░
░░ The job identifier is 133423 and the job result is failed.

Я уже вообще без понятия в чем может быть дело. Скрипт start.sh работает корректно, если я запускаю его вручную. Эксперимента ради оставил в start.sh только echo "hello" и результат тот же. Кажется я как-то не так описал сервис. В чем может быть проблема?Почему мой сервис перестал работать и как это починить?

Есть Minecraft сервер на CentOS 7, который при крашах рестартится systemd сервисом

судя по логам у тебя как раз происходят эти краши, на 5-й раз сустемд перестает пытаться запустить сервис с вердиктом «Start request repeated too quickly».

Я бы начал с того что запустил эти юниты в пользовательской сессии, то есть положил в /home/my_user/.config/systemd/ или как там эта папка называется. Потому что какой смысл делать так как у тебя сейчас?

ListenFIFO=%t/my_minecraft_server.stdin

этот пайп есть в наличии?

PartOf=my_minecraft_server.service

[Install]
WantedBy=multi-user.target

по-моему это можно убрать из юнитов

Lrrr ★★★★★
()
Ответ на: комментарий от intelfx

Я использую сокет чтобы проталкивать команды в сервер следующим образом:

$ echo "stop" > /run/my_minecraft_server.stdin
RareScrap
() автор топика

Скрипт start.sh работает корректно, если я запускаю его вручную.

(Всякое бывает), не забыл права на исполнение?

papin-aziat ★★★★★
()
Ответ на: комментарий от Lrrr

Я бы начал с того что запустил эти юниты в пользовательской сессии

Вообще не принципиально. Было бы здорово запускать сервис без sudo-прав. Однако хочется чтобы оно хотя бы работало для начала.

этот пайп есть в наличии?

Нет, похоже я забыл его создать. Не помню как создается подобный файл. Через touch my_minecraft_server.stdin?

по-моему это можно убрать из юнитов

Понятия не имею, честно говоря, зачем оно вообще там. Не шарю за тонкости systemd-сервисов. Мне лишь хочется перенести один единственный сервис со старой центоси на новую.

RareScrap
() автор топика
Ответ на: комментарий от papin-aziat

Отчаялся и выдал 777 на конфиг сокета и сервиса. Сделал restorecon чтобы selinux теги засетил. Хз что еще делать.

RareScrap
() автор топика
Ответ на: комментарий от intelfx

Пардон. Вывод:

$ sudo systemctl status my_minecraft_server.socket
Unit my_minecraft_server.socket could not be found

Попытался зарегать сокет - творится дичь. Он не видит файл. Но он лежит в /etc/systemd/system:

$ sudo systemctl enable my_minecraft_server.socket
Failed to enable unit: Unit file my_minecraft_server.socket does not exist
RareScrap
() автор топика
Ответ на: комментарий от papin-aziat

Пардон, да. Права в наличии. Яж могу его из под юзера запустить.

RareScrap
() автор топика
Ответ на: комментарий от RareScrap

он должен создаваться сервисом my_minecraft_server.socket при его запуске.

А, я понял. Ты похоже его не запускаешь. Если ты хочешь настроить сокет-активацию, то запускать надо сокет, а не сервис

$ systemctl start my_minecraft_service.socket
$ echo "start" > /run/my_minecraft_server.stdin

после этого сервер должен запуститься.

Кстати строчку

Sockets=my_minecraft_server.socket

можно убрать из юнита, она нужна только когда у файлов service и socket разные имена.

Lrrr ★★★★★
()
Ответ на: комментарий от Lrrr

Если ты хочешь настроить сокет-активацию

Такое мне не нужно. Сокет нужен лишь для того чтобы я мог команды откравлять в уже запущенный сервак. Если он на запущен, я не хочу чтобы сокет трегерил его запуск.

systemctl start my_minecraft_service.socket

Не стартует сокет:

$ sudo systemctl enable /home/user/services/my_minecraft_server.socket
Created symlink /etc/systemd/system/my_minecraft_server.socket → /home/user/services/my_minecraft_server.socket.
The unit files have no installation config (WantedBy=, RequiredBy=, Also=,
Alias= settings in the [Install] section, and DefaultInstance= for template
units). This means they are not meant to be enabled or disabled using systemctl.

Possible reasons for having this kind of units are:
• A unit may be statically enabled by being symlinked from another unit's
  .wants/ or .requires/ directory.
• A unit's purpose may be to act as a helper for some other unit which has
  a requirement dependency on it.
• A unit may be started when needed via activation (socket, path, timer,
  D-Bus, udev, scripted systemctl call, ...).
• In case of template units, the unit is meant to be enabled with some

Добавил в конец:

[Install]
WantedBy=multi-user.target

И теперь он хотя бы загерался. При попытке стартануть получаю в статусе это:

$ sudo systemctl status my_minecraft_server.socket
× my_minecraft_server.socket
     Loaded: loaded (/etc/systemd/system/my_minecraft_server.socket; enabled; preset: disabled)
     Active: failed (Result: resources)
   Triggers: ● my_minecraft_server.service
     Listen: /run/my_minecraft_server.stdin (FIFO)

May 06 17:20:47 localhost.localdomain systemd[1]: my_minecraft_server.socket: Failed with result 'resources'.
May 06 17:20:47 localhost.localdomain systemd[1]: Failed to listen on my_minecraft_server.socket.
May 06 17:21:47 localhost.localdomain systemd[1]: my_minecraft_server.socket: Failed to open FIFO /run/my_minecraft_server.stdin: Permission denied
May 06 17:21:47 localhost.localdomain systemd[1]: my_minecraft_server.socket: Failed to listen on sockets: Permission denied
May 06 17:21:47 localhost.localdomain systemd[1]: my_minecraft_server.socket: Failed with result 'resources'.
May 06 17:21:47 localhost.localdomain systemd[1]: Failed to listen on my_minecraft_server.socket.
May 06 17:23:56 localhost.localdomain systemd[1]: my_minecraft_server.socket: Failed to open FIFO /run/my_minecraft_server.stdin: Permission denied
May 06 17:23:56 localhost.localdomain systemd[1]: my_minecraft_server.socket: Failed to listen on sockets: Permission denied
May 06 17:23:56 localhost.localdomain systemd[1]: my_minecraft_server.socket: Failed with result 'resources'.
May 06 17:23:56 localhost.localdomain systemd[1]: Failed to listen on my_minecraft_server.socket.

Откуда берется Permission denied? Сервис рутовый, 777 у пайпа:

$ stat /run/my_minecraft_server.stdin
  File: /run/my_minecraft_server.stdin
  Size: 0               Blocks: 0          IO Block: 4096   fifo
Device: 17h/23d Inode: 1283        Links: 1
Access: (0777/prwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:var_run_t:s0
Access: 2024-05-06 17:19:21.874239640 +0800
Modify: 2024-05-06 17:19:21.874239640 +0800
Change: 2024-05-06 17:21:23.616796067 +0800
 Birth: 2024-05-06 17:19:21.874239640 +0800

Хз что и думать

RareScrap
() автор топика
Ответ на: комментарий от papin-aziat

Да, дело оказалось в нем. Перевел его в permissive режим, дал постоять пару дней чтоб залогировались все нарушения существующих политик, и потом сгенерил кастомную политику при помощи audit2allow.

my_policy.te:

module my_policy 1.0;

require {
        type user_home_t;
        type init_tmp_t;
        type httpd_t;
        type init_t;
        type var_run_t;
        type unreserved_port_t;
        type http_port_t;
        type user_tmp_t; 
        class file { append create execute execute_no_trans getattr ioctl map open read rename write };
        class lnk_file { read };
        class fifo_file { ioctl read write };
        class process execmem;
        class tcp_socket name_connect;
}

#============= httpd_t ==============

#!!!! This avc can be allowed using one of the these booleans:
#     httpd_can_network_connect, nis_enabled
allow httpd_t unreserved_port_t:tcp_socket name_connect;

#!!!! This avc can be allowed using the boolean 'httpd_read_user_content'
allow httpd_t user_home_t:file { open read };

#!!!! This avc can be allowed using the boolean 'httpd_read_user_content'
allow httpd_t user_tmp_t:file open;

#============= init_t ==============
allow init_t init_tmp_t:file execute;
allow init_t self:process execmem;
allow init_t user_home_t:file { append create execute execute_no_trans ioctl map open read rename write };

#!!!! This avc can be allowed using the boolean 'nis_enabled'
allow init_t http_port_t:tcp_socket name_connect;

#!!!! This avc can be allowed using the boolean 'domain_can_mmap_files'
allow init_t user_home_t:file map;
allow init_t user_home_t:lnk_file read;
allow init_t user_tmp_t:file { create map open write }; 
allow init_t var_run_t:fifo_file { ioctl read write };

Потом скомпилил из нее pp-файл и установил:

checkmodule -M -m -o my_policy.mod my_policy.te
semodule_package -o my_policy.pp -m my_policy.mod
sudo semodule -i my_policy.pp

Вернул SELinux в enforcing режим, перезагрузился и пока все гуд

RareScrap
() автор топика
Ответ на: комментарий от RareScrap

ОДНАКО!

Нефига это не выглядит безопасно. Я не могу точно сказать зачем нужно каждое из выданных прав. И более того, я не могу быть уверен что я разрешаю минимально необходимые права. К пример:

  1. Похоже что любой процесс с httpd_t контекстом может стучатся в любые пользовательские директории. А мне нужно чтобы только nginx мог стучаться только в конкретного пользователя. Как такое настроить на уровне политики?
  2. Что значит This avc can be allowed using one of the these booleans? Мне нужно включать эти флаги вдобавок к установленной политике?

Я к тому, что такое решение порождает еще больше вопросов. Нефига это не безопасно. Вот сижу и хз что и думать.

RareScrap
() автор топика
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.