Systemd
自定義服務的 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 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
一些問題
- ssh 啟動後正在分叉。
- 一個 ssh 隧道應該在後台執行
- 預設情況下,systemd 程序以“simple”類型執行 - 它期望 StartExec 中的命令是主要服務(參見“1”)
- 為了讓 systemd 知道您的服務是否處於活動狀態,很多時候都需要 PIDFile。GuessMainPID 預設為 yes,但對於 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 建立一個 Master 連接和一個命名的 Socket 來控制 master。
- f - 轉到後台
- n - 防止從標準輸入讀取(由 -f 暗示)
- N - 沒有遠端命令
- T - 禁用偽 tty 分配
“開始”部分設置隧道和“主”。然後它向 master 查詢隧道的 pid 並將其保存到 pid 文件中以供 systemd 使用。如果以 root 身份執行,您可以保存到 /var/run/*pid。
“停止”部分連接到主節點並發出“退出”。然後刪除 pid 文件。