systemd пользовательская служба: ExecStartPost не запускается, служба застряла в состоянии ‘активируются’

Вопрос или проблема

systemd пользовательская служба: ExecStartPost не запускается, служба застряла в состоянии ‘активируются’

У меня есть файл сервиса пользователя systemd ~/.config/systemd/user/ssh-agent.service, цель которого – обеспечить постоянную работу моего ssh-agent и загрузку в него конкретного SSH-ключа без пароля. В настоящее время он выглядит так:

[Unit]
Description=SSH ключ агент

[Service]
Type=oneshot
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
Environment=DISPLAY=:0
ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK
ExecStartPost=/usr/bin/ssh-add $MYSSH

[Install]
WantedBy=default.target

После загрузки системы я проверяю, что ssh-agent запущен с помощью ps -aux | grep "ssh", и получаю следующее:

myuser       535  0.0  0.0   8008  5104 ?        Ss   15:22   0:00 /usr/bin/ssh-agent -D -a /run/user/1000/ssh-agent.socket

Однако, когда я проверяю, добавлен ли ключ, как я ожидал, с помощью ssh-add -l, я получаю У агента нет идентификаций.

Теперь я могу подтвердить, что команда /usr/bin/ssh-add $MYSSH, выполненная вручную, работает так, как мне нужно, так что это не может быть проблемой. Поэтому я проверяю статус сервиса с помощью systemctl --user status ssh-agent.service и получаю следующее:

● ssh-agent.service - SSH ключ агент
     Loaded: загружен (/home/myUser/.config/systemd/user/ssh-agent.service; включен; предустановлен: включен)
     Active: activating (start) с Вт 2024-09-17 15:22:27 EDT; 1ч 18мин назад
 Invocation: 6509facc63a8488780f5674e11c865f6
   Main PID: 535 (ssh-agent)
      Tasks: 1 (limit: 8976)
     Memory: 1.1M (peak: 1.5M)
        CPU: 6ms
     CGroup: /user.slice/user-1000.slice/[email protected]/app.slice/ssh-agent.service
             └─535 /usr/bin/ssh-agent -D -a /run/user/1000/ssh-agent.socket

Сен 17 15:22:27 mySystem systemd[525]: Запуск SSH ключа агента...
Сен 17 15:22:27 mySystem ssh-agent[535]: SSH_AUTH_SOCK=/run/user/1000/ssh-agent.socket; экспортировать SSH_AUTH_SOCK;
Сен 17 15:22:27 mySystem ssh-agent[535]: echo Агент pid 535;

Я замечаю, что команда ssh-add здесь не упоминается, и что сервис просто зависает в состоянии активирования, даже несмотря на то, что агент работает.

Похоже, что инструкция ExecStartPost никогда не выполняется. Я проверил, что это не связано с самой инструкцией, изменив эту строку на

ExecStartPost=/usr/bin/echo Привет, мир.

и перезапустив. Echo никогда не выполнялся, и ответ от systemctl --user status ssh-agent.service был таким же, как и раньше.

Единица сервиса запускает демон, поэтому не следует использовать Type=oneshot. Этот тип специально предназначен для процессов, которые выполняют короткое задание и завершаются, поэтому, естественно, запуск сервиса ожидает завершения процесса ssh-agent.

Поскольку вы использовали опцию -D, чтобы сделать ssh-agent «не форкающим», он, конечно, никогда не завершится (пока не будет остановлен вручную). Наилучший вариант для этого – Type=exec (или очень похожий, но чуть хуже Type=single).

В стандартном режиме работы ssh-agent (т.е. без опции -D) вы бы хотели использовать Type=forking, который ожидает, пока начальный процесс сфоркает дочерний и затем завершится; сервис будет отслеживать дочерний процесс и повысит его до MainPID.

(Последнее делает Type=forking отличным от Type=oneshot. Если вы попытаетесь удалить -D, сохранив Type=oneshot, сервис будет считаться остановленным сразу после форка родительского процесса и завершится, а дочерний процесс быстро будет убит как “остальное”.)

Среди хорошо написанных демонов, Type=forking (т.е. без -D) обычно является чуть более оптимальным выбором, чем Type=exec, так как позволяет любым ошибкам, пойманным до форка, распространяться как ошибки запуска сервиса.

Ответ или решение

Чтобы решить вашу проблему с запуском службы ssh-agent через user service в systemd, необходимо внести некоторые изменения в ваш файл службы. Основная проблема заключается в том, что вы используете Type=oneshot, что не подходит для длительных процессов, таких как демоны. Ваша служба застревает в состоянии ‘activating’, так как ssh-agent, запущенный с флагом -D, никогда не завершит свою работу.

Вот предложение по исправлению вашего файла службы:

[Unit]
Description=SSH key agent

[Service]
Type=forking
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
Environment=DISPLAY=:0
ExecStart=/usr/bin/ssh-agent -a $SSH_AUTH_SOCK
ExecStartPost=/usr/bin/ssh-add $MYSSH

[Install]
WantedBy=default.target

Изменения:

  1. Type=forking: Подходящий тип службы для демоноподобных процессов, таких как ssh-agent. Когда ssh-agent запускается без флага -D, он создает дочерний процесс, который затем можно отслеживать systemd.

  2. Удалите флаг -D: Уберите флаг -D из команды ExecStart. Это позволит ssh-agent создать дочерний процесс и завершить основной процесс, что даст systemd возможность считать службу успешной.

  3. Проверьте переменные окружения: Убедитесь, что переменная MYSSH правильно задана и указывает на ваш SSH-ключ. Если переменная не определена в системе, команда ssh-add не сможет выполниться.

Секреты:

После внесения изменений, не забудьте перезагрузить систему systemd для применения изменений:

systemctl --user daemon-reload

Затем перезапустите вашу службу:

systemctl --user restart ssh-agent.service

Проверяйте статус службы снова, используя:

systemctl --user status ssh-agent.service

Теперь, после успешного запуска службы, вы должны увидеть, что ssh-add выполняется корректно, и когда вы используете ssh-add -l, вы должны видеть ключи, добавленные в агента.

Эти изменения обеспечат правильную работу вашего ssh-agent под управлением systemd.

Оцените материал
Добавить комментарий

Капча загружается...