Ssh

連接關閉後如何清理 SSH 反向隧道套接字?

  • October 2, 2021

如果我執行這樣的東西:

ssh -4 -f -N -T -R "/home/dude/lol.socket:192.168.4.44:4444" dude@someserver -p 22 -i privatekey -o "ExitOnForwardFailure yes" -o ConnectTimeout=5 -o ConnectionAttempts=3 -o ServerAliveInterval=15 -o

然後讓我們說連接因任何原因關閉或死亡..說電腦由於維護或錯誤或網際網路連接問題或其他原因重新啟動 - >我們有一個大問題。/home/dude/lol.socket在 sshd上創建的套接字文件someserver不會被刪除。因此,當反向隧道發起者正在恢復並嘗試重新創建隧道時,它不能,因為:

Error: remote port forwarding failed for listen path /home/dude/lol.socket

在伺服器端,你會得到類似的東西:

error: bind: Address already in use
error: unix_listener: cannot bind to path: /home/dude/lol.socket

斷開連接後清理套接字的支持方式/最佳方法是什麼?這是 sshd 中的一個錯誤,如果/當注意到斷開連接時,它不應該自動執行嗎?

背景故事:

使用套接字背後的想法很簡單,伺服器將處理 n 個“dudes”,為任何埠中的 m 個“lol”服務創建反向隧道,使用套接字可以更容易地確保“dude”只能訪問和綁定到他自己的插座,但不是其他帥哥的插座。它還使我不必記錄哪個傢伙正在使用哪個埠來公開哪個服務。當老兄想連接到其他伺服器上的服務時,他只需要知道服務的名稱並將其綁定到某個隨機的本地埠(或套接字,如果他願意),即

ssh -v -i -4 -N -T -L “127.0.0.1:3334:/home/dude/lol.sock” -p 22 dude@someserver -o “ExitOnForwardFailure yes” -o ConnectTimeout=5 -o ConnectionAttempts= 3 -o ServerAliveInterval=15 -o ServerAliveCountMax=3

不需要知道伺服器上的反向隧道應該在其上執行的某個魔術埠號。所以,如果你有更好的想法如何解決這個問題,我會全力以赴。

使用 openssh-client/server 版本測試客戶端/伺服器都在執行Debian 9(客戶端實際上在 docker 容器內的 mac 上)7.4p1-10+deb9u2

TL;博士;

解決方法是在伺服器的 sshd 配置中將 StreamLocalBindUnlink的值設置為yessudo sh -c 'echo "StreamLocalBindUnlink yes" >> /etc/ssh/sshd_config' : 。

很長的故事

發生這種情況的原因是,當套接字關閉時,unix 套接字文件不會自動刪除。remove如果需要通過使用文件路徑呼叫/來關閉它們,則需要在關閉時手動清理它們unlink,但 openssh 不會這樣做。但是,當我進一步研究該主題時,我意識到使用 unix 套接字的“最佳實踐”是綁定到它之前進行(unlink查看此 SO 答案以獲取更多詳細資訊)。這正是告訴 sshd 要做的事情。StreamLocalBindUnlink yes

手冊頁說:

StreamLocalBindUnlink
        Specifies whether to remove an existing Unix-domain socket file for local or remote port forwarding before creating a new
        one.  If the socket file already exists and StreamLocalBindUnlink is not enabled, sshd will be unable to forward the port to
        the Unix-domain socket file.  This option is only used for port forwarding to a Unix-domain socket file.

        The argument must be yes or no.  The default is no.

這種方法的缺點是現在允許重新綁定到套接字,即使舊連接仍然存在。這樣做似乎會使舊隧道掛在那裡,因此任何現有的 tcp 連接都通過它保持不變,但所有新連接都會進入新隧道。此外,舊隧道似乎永久且不可逆地與文件系統套接字地址分離,即使新隧道關閉,也無法再接收新連接。

參考

引用自:https://unix.stackexchange.com/questions/427189