SSH 원격 포트 전달 실패

SSH 원격 포트 전달 실패

후속 조치:각 서버를 몇 달 동안 실행하면서 발생하는 일련의 급격한 연결 끊김은 아마도 우연일 것이며 실제 문제를 드러내는 역할을 한 것 같습니다. 다시 연결하지 못한 이유는 거의 확실하게 AliveInterval 값(kasperd의 답변) 때문입니다. ExitOnForwardFailure 옵션을 사용하면 다시 연결하기 전에 시간 초과가 적절하게 발생하여 대부분의 경우 문제가 해결됩니다. MadHatter의 제안(킬 스크립트)은 아마도 다른 모든 것이 실패하더라도 터널이 다시 연결될 수 있도록 하는 가장 좋은 방법일 것입니다.

방화벽 뒤에는 작은 DigitalOcean VPS(B)에 대한 여러 포트의 역방향 터널을 시작하는 서버(A)가 있으므로 B의 IP 주소를 통해 A에 연결할 수 있습니다. 터널은 약 3개월 동안 꾸준히 작동해 왔지만 지난 24시간 동안 4번이나 갑자기 고장이 났습니다. 얼마 전에 다른 VPS 제공업체에서도 같은 일이 일어났습니다. 몇 달 동안 완벽하게 작동한 후 갑자기 여러 번 급격한 실패가 발생했습니다.

머신 A에 터널 명령(각 포트 X에 대해)을 자동으로 실행하는 스크립트가 있지만 ssh -R *:X:localhost:X address_of_B실행되면 다음과 같이 표시됩니다 Warning: remote port forwarding failed for listen port X.

/var/log/secure서버의 sshd에 접속하면 다음 오류가 표시됩니다.

bind: Address already in use
error: bind: Address already in use
error: channel_setup_fwd_listener: cannot listen to port: X

해결하려면 VPS를 재부팅해야 합니다. 그때까지는 모든 재연결 시도에 "원격 포트 전달 실패" 메시지가 표시되며 작동하지 않습니다. 이제 터널은 멈추기까지 약 4시간 정도만 지속되는 지점에 이르렀습니다.

VPS에서는 아무것도 변경되지 않았으며 역방향 터널 끝점 역할만 하는 일회용 단일 사용자 시스템입니다. CentOS 6.5에서 OpenSSH_5.3p1을 실행 중입니다. 연결이 끊어졌을 때 sshd가 끝부분의 포트를 닫지 않는 것 같습니다. 나는 이유를, 거의 완벽하게 작동한 지 몇 달이 지난 지금 갑자기 왜 이런 일이 발생하는지 설명하기가 어렵습니다.

명확히 하기 위해 먼저 터널이 실패한 후 sshd가 포트 수신 대기를 거부하는 이유를 파악해야 합니다. 이는 sshd가 포트를 열어두고 절대 닫지 않기 때문에 발생하는 것 같습니다. 그게 가장 큰 문제인 것 같습니다. 몇 달 동안 예상대로 작동한 후(즉, 포트를 즉시 닫고 스크립트가 다시 연결되도록 허용한 후) 무엇이 이런 식으로 작동하는지 잘 모르겠습니다.

답변1

나는 존재하지 않는 SSH 연결로부터의 포트 전달일 가능성이 높다는 MadHatter의 의견에 동의합니다. 현재 문제가 다른 것으로 판명되더라도 조만간 그러한 존재하지 않는 SSH 연결이 발생할 것으로 예상할 수 있습니다.

이러한 존재하지 않는 연결이 발생할 수 있는 세 가지 방법이 있습니다.

  • 연결의 다른 쪽 끝이 완전히 유휴 상태인 동안 두 끝점 중 하나가 재부팅되었습니다.
  • 두 엔드포인트 중 하나가 연결을 종료했지만, 연결이 종료된 시점에 연결이 일시적으로 중단되었습니다. 연결이 종료된 후 몇 분 동안 중단이 지속되었으므로 상대방은 종료된 연결에 대해 전혀 알지 못했습니다.
  • 연결은 ssh 연결의 두 끝점 모두에서 여전히 완벽하게 작동하지만 누군가가 둘 사이 어딘가에 상태 저장 장치를 배치하여 유휴 상태로 인해 연결 시간이 초과되었습니다. 이 상태 저장 장치는 NAT 또는 방화벽이 될 수 있으며, 이미 언급한 방화벽이 유력한 용의자입니다.

위의 세 가지 중 어떤 일이 일어나고 있는지 파악하는 것은 그다지 중요하지 않습니다. 세 가지를 모두 해결하는 방법이 있기 때문입니다. 이것이 Keepalive 메시지를 사용하는 것입니다.

or 에 ClientAliveInterval대한 키워드 sshd_config와 간격을 살펴봐야 합니다 .ServerAliveIntervalssh_config~/.ssh/config

ssh루프에서 명령을 실행하면 정상적으로 작동할 수 있습니다. 어떤 이유로 연결이 실패할 때 서버가 넘치지 않도록 루프에 절전 모드를 삽입하는 것도 좋은 생각입니다.

서버에서 연결이 종료되기 전에 클라이언트가 다시 연결하면 새 SSH 연결이 활성화되지만 포트 전달이 없는 상황이 발생할 수 있습니다. 이를 방지하려면 ExitOnForwardFailure클라이언트 측에서 키워드를 사용해야 합니다.

답변2

터널 ssh연결이 끊어지면 연결이 재설정되는 데 시간이 좀 걸리므로 ssh프로세스가 계속 차단되어 활성 터널이 없어지고 그 이유를 모르겠습니다. 해결 방법은 이전 연결이 재설정될 때까지 기다리지 않고 새 연결을 생성하고 ssh백그라운드로 전환하는 것입니다. 새로운 프로세스의 수를 제한하는 데 사용할 수 있습니다 -f. -o ExitOnForwardFailure=yes그러면 -o ServerAliveInterval=60현재 연결의 안정성이 향상됩니다.

예를 들어 스크립트의 루프에서 또는 스크립트의 루프에서 ssh명령을 자주 반복할 수 있습니다. 예를 들어 다음에서는 3분마다 명령을 실행합니다.cronssh

while (1)
do
    ssh -f user@hostname -Rport:host:hostport -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=60
    sleep 180
done

답변3

해당 서버의 포트를 바인딩하는 프로세스를 찾을 수 있습니다.

sudo netstat -apn|grep -w X

반쯤 없어진 상태일 가능성이 매우 높은 것 같지만 sshd, 데이터를 가질 수 있는데 왜 가정을 합니까? 또한 스크립트가 터널을 다시 가져오기 전에 신호 9를 보낼 PID를 찾는 좋은 방법이기도 합니다.

답변4

내 경험에 따르면 ssh에는 원격 시스템에서 '무언가'가 여전히 실행 중인 경우 완전히 종료되지 않는 약간 짜증나는 습관이 있습니다. 예를 들어 백그라운드에서 시작되었습니다. 다음을 통해 이를 재현할 수 있습니다.

ssh <server>
while true; do  sleep 60; done&
exit

ssh는 로그아웃되지만 원격 프로세스가 종료될 때까지 실제로 세션을 닫지는 않습니다('while true' 루프이기 때문에 종료되지 않음). 비슷한 일이 일어나고 있을 수 있습니다. 세션에 ssh에 의해 생성되는 '멈춘' 프로세스가 있습니다. 포트는 계속 사용 중이므로 로컬 프로세스에서 다시 사용할 수 없습니다.

관련 정보