web-dev-qa-db-ja.com

カスタムサービスのjournactlにエラーメッセージはありません

カスタムサービスファイルを書こうとしています。

残念ながら、journalctlに出力が表示されません。

これが私のユニットファイルです:

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 [email protected]
ExecStartPre=-/usr/bin/ssh [email protected] "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 

ログ出力:

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出力が失われると思います。

4
guettli

前書き

元の質問は、systemdからより多くの出力を取得する方法に関するものです。 systemdユニットExecStartをデバッグする方法 をご覧ください

しかし、最初にサービスを機能させることができないかどうかを見てみましょう。

Systemdについて

いくつかの問題

  1. sshは、開始後forkingです。
  2. Sshトンネルはバックグラウンドで実行する必要があります
  3. Systemdプロセスは、デフォルトで「simple」タイプとして実行されます。これは、StartExecのコマンドがmain serviceであると想定しています(「1」を参照)。
  4. Systemdがサービスが稼働しているかどうかを知るには、PIDFileが多くの時間必要です。 GuessMainPIDのデフォルトはyesですが、そうである可能性があり、sshに関してはisと誤解されています。
  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
[email protected]

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-stdinからの読み取りを防止します(-fによって暗示されます)
  • N-リモートコマンドなし
  • T-疑似tty割り当てを無効にする

「開始」部分は、トンネルと「マスター」を設定します。次に、マスターにトンネルのpidを照会し、systemdの利益のためにこれをpidファイルに保存します。 rootとして実行する場合は、/ var/run/* pidに保存できます。

「stop」部分はマスターに接続し、「exit」を発行します。次に、pidファイルを削除します。

クレジット https://stackoverflow.com/a/15198031/2045924

3
sastorsl

この線 User=autosshは間違いでした。

このユーザーは存在しませんでした。

ユーザーを作成した後、うまくいきました。

デフォルト Type=simpleうまくいきます。

ラッパースクリプトは必要ありません。

0
guettli