Нет сообщения об ошибке в журнале пользовательского сервиса

Я пытаюсь написать файл пользовательского сервиса.

К сожалению, я не вижу вывода в журнале.

Вот мой файл модуля:

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

Но давайте посмотрим, сможем ли мы сначала заставить ваш сервис работать.

О системе

Некоторые вопросы

  1. SSH разветвляется после начала.
  2. Туннель SSH должен работать в фоновом режиме
  3. Процесс systemd по умолчанию запускается с типом "простой", который ожидает, что команда в StartExec является основной службой (см. "1")
  4. Чтобы systemd знал, работает ли ваш сервис или нет, PIDFile требуется много времени. GuessMainPID по умолчанию да, но может быть, и в отношении ssh, ошибочно.
  5. Ты убиваешь туннель локально - не нужно уходить с мечом за границу

Это создает большую сложность, которая лучше обрабатывается скриптом-оберткой.

/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 работает хорошо.

Там нет необходимости для сценария оболочки.

Другие вопросы по тегам