Нет сообщения об ошибке в журнале пользовательского сервиса
Я пытаюсь написать файл пользовательского сервиса.
К сожалению, я не вижу вывода в журнале.
Вот мой файл модуля:
root@om:~# cat /etc/systemd/system/ssh-tunnel-foo-de.service
[Unit]
Description=Tunnel For ssh-tunnel-foo-de
After=network.target
[Service]
User=autossh
ExecStart=/usr/bin/ssh -o "ExitOnForwardFailure yes" -o "ServerAliveInterval 60" -N -R 1080:localhost:1080 tunnel@foo.de
ExecStartPre=-/usr/bin/ssh tunnel@foo.de "for pid in $$(ps -u tunnel | grep sshd| cut -d' ' -f1); do kill -9 $$pid; echo kill old ssh process $$pid; done"
Restart=always
RestartSec=5s
StartLimitInterval=0
[Install]
WantedBy=multi-user.target
Logoutput:
root@om:~# journalctl -u ssh-tunnel-foo-de
Apr 01 10:12:28 om systemd[1]: Stopped Tunnel For ssh-tunnel-foo-de.
Apr 01 10:12:28 om systemd[1]: Starting Tunnel For ssh-tunnel-foo-de...
Apr 01 10:12:28 om systemd[1]: Started Tunnel For ssh-tunnel-foo-de.
Apr 01 10:12:28 om systemd[1]: ssh-tunnel-foo-de.service: Main process exited, code=exited, status=217/USER
Apr 01 10:12:28 om systemd[1]: ssh-tunnel-foo-de.service: Unit entered failed state.
Apr 01 10:12:28 om systemd[1]: ssh-tunnel-foo-de.service: Failed with result 'exit-code'.
Как я могу отладить что не так. Я предполагаю, что некоторый вывод stderr теряется.
2 ответа
Вступление
Ваш первоначальный вопрос касается того, как вы можете получить больше результатов от systemd. Посмотрите, как отлаживать системный модуль ExecStart
Но давайте посмотрим, сможем ли мы сначала заставить ваш сервис работать.
О системе
Некоторые вопросы
- SSH разветвляется после начала.
- Туннель SSH должен работать в фоновом режиме
- Процесс systemd по умолчанию запускается с типом "простой", который ожидает, что команда в StartExec является основной службой (см. "1")
- Чтобы systemd знал, работает ли ваш сервис или нет, PIDFile требуется много времени. GuessMainPID по умолчанию да, но может быть, и в отношении ssh, ошибочно.
- Ты убиваешь туннель локально - не нужно уходить с мечом за границу
Это создает большую сложность, которая лучше обрабатывается скриптом-оберткой.
/etc/systemd/system/ssh-tunnel-foo-de.service
[Unit]
Description=Tunnel For ssh-tunnel-foo-de
After=network-online.target
[Unit]
Description=Tunnel For ssh-tunnel-foo-de
After=network-online.target
[Service]
User=autossh
ExecStart=/home/autossh/bin/ssh-tunnel.sh start
ExecStop=/home/autossh/bin/ssh-tunnel.sh stop
PIDFile=/home/autossh/bin/ssh-tunnel.pid
Restart=always
RestartSec=5s
StartLimitInterval=0
SuccessExitStatus=255
Type=forking
[Install]
WantedBy=multi-user.target
Пояснения к systemd
Скрипт-обертка сохраняет pid в PIDFile. Если вы меняете местоположение, вы должны синхронизировать файл службы и скрипт-обертку.
Вы должны установить "Тип" на разветвление, чтобы systemd знал, что происходит разветвление.
SuccessExitStatus - кажется, что процесс умирает с 255 - поэтому мы обрабатываем это так, чтобы остановленная служба не была указана как "сбойная" после ее остановки.
Подождите, пока не будет запущен network-online.target. Это означает, что у вас действительно есть сетевое соединение, а не просто стек управления сетью. https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/ https://www.freedesktop.org/software/systemd/man/systemd.unit.html
Скрипт оболочки:
/home/autossh/bin/ssh-tunnel.sh
Конечно, вам нужно решить, куда вы действительно хотите поместить это и соответственно исправить пути.
#!/bin/bash
MYHOST=tunnel@foo.de
usage () {
echo "usage: $0 {start|stop}"
exit
}
cd $HOME/bin
case $1 in
"start")
/usr/bin/ssh -M -S socket-${MYHOST} -fnNT -o BatchMode=yes -o ExitOnForwardFailure=yes -o ServerAliveInterval=60 -R 1080:localhost:1080 ${MYHOST}
EC=$? ; [ $EC -ne 0 ] && exit $EC
PID=$(/usr/bin/ssh -S socket-${MYHOST} -O check socket-${MYHOST} 2>&1 | awk '/Master running \(pid=/ { sub(/^.+pid=/,"") ; sub(")","") ; print }')
echo $PID > $HOME/bin/ssh-tunnel.pid
;;
"stop")
/usr/bin/ssh -S socket-${MYHOST} -O exit ${MYHOST}
/bin/rm -f $HOME/bin/ssh-tunnel.pid
exit 0
;;
*) usage ;;
esac
Некоторые объяснения:
Посмотрите некоторые параметры для ssh.
- -M и -S устанавливают мастер-соединение и именованный сокет для управления мастером.
- f - перейти на задний план
- n - Запрет чтения из стандартного ввода (подразумевается -f)
- N - Нет удаленной команды
- T - отключить псевдо-tty распределение
Часть "начало" устанавливает туннель и "мастер". Затем он запрашивает у мастера pid туннеля и сохраняет его в pid-файл в пользу systemd. Если вы запускаете от имени пользователя root, вы можете сохранить его в / var/run/*pid.
Часть "стоп" соединяется с мастером и выдает "выход". Затем удаляет файл PID.
Кредиты для https://stackoverflow.com/a/15198031/2045924
Линия User=autossh
была ошибка
Этот пользователь не существовал.
После создания пользователя все заработало.
По умолчанию Type=simple
работает хорошо.
Там нет необходимости для сценария оболочки.