SSH 원격 포트 전달 실패 공급 업체에서 한

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

방화벽 뒤에 서버 (A)가 있는데 여러 포트에서 작은 DigitalOcean VPS (B)에 대한 역방향 터널을 시작하여 B의 IP 주소를 통해 A에 연결할 수 있습니다. 터널은 약 3 개월 동안 일관되게 작동했지만 지난 24 시간 동안 갑자기 4 번 실패했습니다. 동일한 작업이 다른 VPS 공급 업체에서 한 달 전에 완벽하게 작동 한 후 갑자기 여러 번의 빠른 오류가 발생했습니다.

머신 A에 자동으로 터널 명령을 실행하는 스크립트가 있습니다 ( ssh -R *:X:localhost:X address_of_B각 포트 X에 대해) 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는 포트를 열어두고 절대 닫지 않기 때문에 발생합니다. 이것이 주요 문제인 것 같습니다. 나는 예상대로 몇 달간 행동 한 후 (예 : 즉시 포트를 닫고 스크립트를 다시 연결할 수 있도록) 어떻게 작동하는지 확실하지 않습니다.



답변

MadHatter에 동의합니다. 이는 ssh 연결이 끊긴 포트 포워딩 일 가능성이 큽니다. 현재 문제가 다른 것으로 밝혀 지더라도 조만간 그러한 ssh 연결이 발생할 수 있습니다.

이러한 기능 불능 연결이 발생할 수있는 세 가지 방법이 있습니다.

  • 연결의 다른 쪽 끝이 완전히 유휴 상태 인 동안 두 끝점 중 하나가 재부팅되었습니다.
  • 두 끝점 중 하나가 연결을 닫았지만 연결이 닫힐 때 연결이 일시적으로 중단되었습니다. 연결이 끊어진 후 몇 분 동안 정전이 지속되었으므로 다른 쪽 끝은 닫힌 연결에 대해 알지 못했습니다.
  • 연결은 여전히 ​​ssh 연결의 두 끝점에서 완전히 작동하지만 누군가가 상태 저장 장치를 그들 사이에 배치하여 유휴로 인해 연결 시간이 초과되었습니다. 이 상태 저장 장치는 NAT 또는 방화벽 일 것입니다. 이미 언급 한 방화벽은 의심스러운 부분입니다.

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

당신은에 보일 것입니다 ClientAliveInterval에 대한 키워드 sshd_configServerAliveInterval대한 간격 ssh_config또는 ~/.ssh/config.

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

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


답변

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

sudo netstat -apn|grep -w X

절반의 손실이 될 것 sshd같지만 왜 데이터를 가질 수 있다고 가정합니까? 또한 스크립트가 터널을 다시 불러 오기 전에 신호 9를 보낼 PID를 찾는 좋은 방법입니다.


답변

나를 위해 때 ssh소위는 연결을 위해 잠시 걸리는 터널의 연결이 끊어 재설정 ssh과정이 더 활성화 된 터널로 날 떠나 차단하기 위해 계속 나는 이유를 알지 못한다. 해결 방법은 이전 연결이 재설정 될 때까지 기다리지 않고 ssh백그라운드 에 넣고 -f새 연결을 생성하는 것입니다. 은 -o ExitOnForwardFailure=yes새로운 프로세스의 수를 LIMT하는 데 사용할 수 있습니다. 는 -o ServerAliveInterval=60현재 연결의 신뢰성을 향상시킨다.

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

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

답변

내 경험상 ssh는 원격 시스템에서 ‘뭔가’가 계속 실행되고 있으면 깨끗하게 종료되지 않는 약간의 습관을 가지고 있습니다. 예를 들어 백그라운드에서 시작했습니다. 다음을 통해이를 재현 할 수 있습니다.

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

ssh는 로그 아웃하지만 원격 프로세스가 종료 될 때까지 실제로 세션을 닫지 않습니다 ( ‘while true’루프이므로 종료되지 않습니다). 세션이 ssh에 의해 생성되는 ‘고착 된’프로세스를 가지고 있습니다. 포트는 계속 사용 중이므로 로컬 프로세스에서 재사용 할 수 없습니다.