如果我运行这样的事情:
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
然后假设连接已关闭或因某种原因中断。比如说计算机由于维护或错误而重新启动,或者出现互联网连接问题或其他问题 -> 我们遇到了大问题。创建的套接字文件不会被 sshd 删除。因此,当反向隧道/home/dude/lol.socket
发起者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 个“家伙”,在任何端口上为 m 个“lol”服务创建反向隧道,并且使用套接字可以更容易地确保“家伙”只能访问和绑定到他自己的套接字,而不是其他人的套接字。它还使我不必记录哪个家伙正在使用哪个端口来公开哪个服务。当家伙想要连接到其他服务器上的服务时,他需要知道的只是服务的名称并将其绑定到某个随机的本地端口(或套接字,如果他愿意的话),即
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
答案1
TL;博士;
解决方案是设置值流本地绑定取消链接到是的在服务器上的 sshd 配置中:sudo sh -c 'echo "StreamLocalBindUnlink yes" >> /etc/ssh/sshd_config'
.
很长的故事
发生这种情况的原因是因为当套接字关闭时,unix 套接字文件不会自动删除。如果需要通过使用文件路径调用remove
/来关闭它们,则需要在关闭时手动清理它们unlink
,但 openssh 不会这样做。然而,当我进一步研究这个主题时,我意识到 unix 套接字的“最佳实践”是unlink
正确的前绑定到它(检查此 SO 答案以获取更多详细信息)。这正是告诉StreamLocalBindUnlink yes
sshd 要做的事情。
手册页说:
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 连接通过该连接保持不变,但所有新连接都进入新隧道。此外,旧隧道似乎永久且不可逆地与文件系统套接字地址分离,即使新隧道关闭,也无法接收更多新连接。