Вопрос или проблема
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
Изменения:
-
Type=forking: Подходящий тип службы для демоноподобных процессов, таких как
ssh-agent
. Когдаssh-agent
запускается без флага-D
, он создает дочерний процесс, который затем можно отслеживатьsystemd
. -
Удалите флаг
-D
: Уберите флаг-D
из командыExecStart
. Это позволитssh-agent
создать дочерний процесс и завершить основной процесс, что дастsystemd
возможность считать службу успешной. - Проверьте переменные окружения: Убедитесь, что переменная
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
.