저는 시스템 제어를 원격 지원으로 전달하는 작업인 Linux 스크립트를 작성 중입니다. 이 스크립트에서 명령 중 하나는 원격 카메라의 라이브 비디오 스트림 포트를 전달하는 ssh 포트 전달 명령입니다. 원격 카메라가 있는 시스템에서는 시스템을 알 수 없으므로 항상 방화벽 뒤에 있다고 가정하며, 사용자는 라우터를 포트 포워딩하고 동적 DNS를 얻는 방법에 대한 지식도 부족합니다. 이 문제를 극복하기 위해 "클라이언트" 시스템 또는 카메라 컴퓨터는 다음 명령을 실행합니다.
ssh -R 8089:dc-bb7925e7:8085 -p 2250 [email protected] -fNT
카메라 소스(8085)의 클라이언트 포트를 원격 지원 서버(8089)로 전달합니다. 원격 지원은 localhost:8089에 액세스하고 라이브 스트림을 볼 수 있어야 합니다. 문제는 이것이 작동하지 않는다는 것입니다. -f 플래그를 명령에 삽입하자마자 명령이 모든 것을 중단하고 전달합니다.
플래그에 관계없이 문제는 이 ssh 명령이 실행될 때 TTY가 연결이 끊어질 때까지 스크립트 종료를 허용하지 않기 때문에 실행되어야 하는 다른 모든 스크립트와 프로세스가 보류된다는 것입니다. 그래서 -f를 사용하여 ssh를 백그라운드로 포크해 보았습니다. 포트가 전달되지 않기 때문에 작동하지 않습니다. 이유를 모르겠습니다.
필요한 것은 포트를 전달한 다음 연결이 열려 있는 동안 잊어버리는 것입니다. 중요한 점은 클라이언트 시스템이 계속 실행되는 동안 원격 지원이 SSH를 제어할 수 있다는 것입니다. 내가 뭘 잘못했나요?
-fNT를 사용하지 않으면 다른 모든 스크립트가 실행되지 않는다는 점을 제외하면 이 함수는 제대로 작동합니다.
이것은 데비안 시스템입니다.
답변1
나는 이것이 실제로 당신의 문제를 일으키는 것이라고 생각하지 않습니다 -f
. 나는 당신의 명령에 잘못된 것이 없다고 생각합니다. 이는 올바른 상황에서 잘 작동할 것입니다.
그러나 SSH 클라이언트와 SSH 서버 사이의 경로에 상태 저장 미들웨어가 있는 경우 해당 미들웨어의 상태가 손실되면 SSH 연결이 종료되거나 중지됩니다. 이는 경로에 NAT나 방화벽이 있는 경우 각별히 주의해야 함을 의미합니다.
Keepalive 메시지는 시간 초과로 인해 연결이 중단되는 것을 방지합니다. 다른 이유로(예: 미들웨어 다시 시작) 연결이 종료되는 것을 막지는 못하지만, 이러한 경우 Keepalive는 연결이 중단되지 않고 즉시 종료되는지 감지하고 연결이 즉시 종료되도록 할 수 있습니다.
클라이언트에서는 -o ServerAliveInterval=299
이와 유사한 것을 사용하여 keepalive를 보낼 수 있으며 연결이 끊어질 경우 ssh 명령이 곧 종료되는지 확인할 수 있습니다. 이를 반복 쉘 스크립트로 래핑하면 이전 연결이 종료될 때마다 새 SSH 연결이 열리도록 할 수 있습니다(그러나 분명히 이 경우 SSH 명령이 아닌 스크립트 포크가 필요합니다).
-L
포트 전달을 활성 상태 로 유지하려면 ServerAliveInterval
ssh 명령을 다시 생성하는 것으로 충분합니다. 그러나 -R
잘못될 수 있는 또 다른 일이 있습니다.
서버의 포트에서 이미 수신 대기 중인 항목이 있으면 -R
포트 전달이 설정되지 않지만 ssh 명령은 계속 실행됩니다. 따라서 이 경우 ssh 명령 재생성을 목표로 하는 루프는 아무 소용이 없습니다.
이 문제에 대한 해결책은 이를 -o ExitOnForwardFailure=yes
ssh 명령에 전달하는 것입니다. 분명히 해당 플래그 조합을 사용하여 루프에서 ssh를 시작하면 동일한 점유 포트에 연속해서 여러 번 바인딩을 시도할 수 있습니다. 그러므로 연속적인 시도 사이에는 잠시 휴식을 취하는 것이 매우 좋습니다. ssh 명령이 종료될 때마다 스크립트는 몇 초 동안 대기 상태에 있다가 다시 시도해야 합니다.
위에서 설명한 모든 작업을 수행하는 여러 스크립트가 존재하지 않는다면 놀랄 것입니다.
지금까지 언급한 내용이 필요한 모든 내용을 다루지는 않습니다.
연결이 중지되고 클라이언트가 이를 인지하고 ssh 명령을 다시 시작하려고 하면 서버가 아직 인지하지 못했을 수 있으므로 서버측 포트가 여전히 점유되어 있을 수 있습니다. 누군가 어리석은 방법으로 방화벽을 구성한 경우 클라이언트의 스크립트가 여전히 차단된 포트에 반복적으로 바인딩을 시도하므로 문제가 무한정 지속될 수 있습니다.
모든 사람이 방화벽 구성을 수정하도록 설득하는 것이 잘 끝나지 않을 가능성이 높으므로 설정을 조정하여 문제를 피하는 것이 좋습니다. sshd_config
설정 을 조정 ClientAliveInterval
하면 서버가 클라이언트에 연결 유지 메시지를 보내고 수신하지 못한 경우 연결을 닫는 데 사용할 수 있습니다. 회신하다.
위의 모든 사항을 결합하면 포트 전달을 항상 활성 상태로 유지하기에 충분합니다(클라이언트와 서버 간에 네트워크 연결이 있다고 가정).