Systemd

自定義服務的 journactl 中沒有錯誤消息

  • April 10, 2017

我嘗試編寫自定義服務文件。

不幸的是,我在 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 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 

日誌輸出:

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'.

我怎樣才能調試出了什麼問題。我猜一些標準錯誤輸出會失去。

介紹

您最初的問題與如何從 systemd 獲得更多輸出有關。看看如何調試 systemd 單元 ExecStart

但是讓我們看看我們是否不能讓您的服務先執行。

關於 systemd

一些問題

  1. ssh 啟動後正在分叉
  2. 一個 ssh 隧道應該在後台執行
  3. 預設情況下,systemd 程序以“simple”類型執行 - 它期望 StartExec 中的命令是主要服務(參見“1”)
  4. 為了讓 systemd 知道您的服務是否處於活動狀態,很多時候都需要 PIDFile。GuessMainPID 預設為 yes,但對於 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 建立一個 Master 連接和一個命名的 Socket 來控制 master。
  • f - 轉到後台
  • n - 防止從標準輸入讀取(由 -f 暗示)
  • N - 沒有遠端命令
  • T - 禁用偽 tty 分配

“開始”部分設置隧道和“主”。然後它向 master 查詢隧道的 pid 並將其保存到 pid 文件中以供 systemd 使用。如果以 root 身份執行,您可以保存到 /var/run/*pid。

“停止”部分連接到主節點並發出“退出”。然後刪除 pid 文件。

歸功於https://stackoverflow.com/a/15198031/2045924

引用自:https://serverfault.com/questions/841929