TL;박사;

TL;박사;

다음과 같이 실행하면:

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 "guys"를 처리하고 모든 포트에서 m "lol" 서비스에 대한 역방향 터널을 생성하며 소켓을 사용하면 "guys"가 다음에만 액세스하고 바인딩할 수 있도록 보장하는 것이 더 쉬워집니다. 다른 사람의 소켓이 아닌 자신의 소켓입니다. 또한 어떤 사람이 어떤 포트를 사용하여 어떤 서비스를 노출하는지 추적하지 않아도 됩니다. 어떤 사람이 다른 서버의 서비스에 연결하려고 할 때 그가 알아야 할 것은 서비스의 이름과 이를 임의의 로컬 포트(또는 원하는 경우 소켓)에 바인딩하는 것뿐입니다.

ssh -v -i -4 -N -T -L "127.0.0.1:3334:/home/dude/lol.sock" -p 22 친구@someserver -o "ExitOnForwardFailure 예" -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'.

아주 긴 이야기

이런 일이 발생하는 이유는 소켓이 닫힐 때 유닉스 소켓 파일이 자동으로 삭제되지 않기 때문입니다. 파일 경로와 함께 / 를 호출하여 닫아야 하는 경우 removeshutdown 시 수동으로 정리해야 unlink하지만 openssh는 이를 수행하지 않습니다. 그러나 주제에 대해 더 자세히 조사하면서 유닉스 소켓에 대한 "모범 사례"가 unlink정확 하다는 것을 깨달았습니다.앞으로그것에 바인딩 (자세한 내용은 이 SO 답변을 확인하세요.). 이것이 바로 StreamLocalBindUnlink yessshd에게 지시하는 것입니다.

매뉴얼 페이지에는 다음과 같이 나와 있습니다.

 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 연결은 그대로 유지되지만 모든 새 연결은 새 터널로 이동합니다. 또한 이전 터널은 파일 시스템 소켓 주소에서 영구적이고 되돌릴 수 없게 분리된 것으로 나타나며 새 터널이 닫히더라도 더 이상 새 연결을 수신할 수 없습니다.

인용하다

관련 정보