連接關閉後如何清理 SSH 反向隧道套接字?
如果我執行這樣的東西:
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的值設置為yes
sudo 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 連接都通過它保持不變,但所有新連接都會進入新隧道。此外,舊隧道似乎永久且不可逆地與文件系統套接字地址分離,即使新隧道關閉,也無法再接收新連接。
參考