포트를 한 번만 전달한 다음 (자동으로) 수신을 중지하는 SSH 클라이언트를 실행하는 방법은 무엇입니까?

포트를 한 번만 전달한 다음 (자동으로) 수신을 중지하는 SSH 클라이언트를 실행하는 방법은 무엇입니까?

를 실행하는 동안 ssh -R 2222:localhost:22 remotehostSSH 클라이언트는 클라이언트가 포트 22로 전달한 포트 2222에 대한 기존 TCP 연결 수 remotehost에 관계없이 포트 2222에서 계속 수신 대기합니다.remotehostlocalhost

포트를 전달하도록 SSH 클라이언트를 구성하는 방법이 있습니까?첫 번째 연결만 받기그런 다음그만 들어라전달된 포트에서(기존 전달된 TCP 연결을 방해하지 않고)? (사용자는 SSH 서버의 구성을 변경할 권한이 없습니다 remotehost.)

나는 다음과 같은 행동을 취하려고 노력하고 있습니다.socattcp4-listen(옵션이 없으면 두 번째 연결은 허용되지 않습니다 .) fork그러나 보안 SSH 채널을 통해 이루어집니다.

편집/부록: 내 문제는 가상의 "ssh 기능 요청"으로 설명될 수 있습니다. SSH에 ssh_config클라이언트 옵션이 있다고 가정ForwardLimit num,mins이 경우 num지난 몇 분 동안 연결 수에 도달하면 ssh는 일시적으로 수신을 중지하고, mins연결 수가 0이면 영구적으로 수신을 중지합니다. mins(이것은 방화벽 속도 제어와 비슷하지만 사용자 공간에서 실행되는 SSH 클라이언트에 의해 시행됩니다.) 그런 다음 옵션을 추가하여 문제를 해결할 수 있습니다 ForwardLimit 1,0. 그러나 그러한 기능이 존재하지 않기 때문에 최선의 해결 방법을 찾고 있습니다.

답변1

OpenSSH를 사용하여 이를 닫지 않고 열린 원격 전달을 끄는 방법은 다음과 같습니다.SSH연결을 시작하십시오. 이를 OP의 정확한 사용 사례에 쉽게 통합할 수 있어야 합니다.

이를 위해서는 다음을 사용해야 합니다.ControlMaster옵션, 그 동반자ControlPath(충분한 추가 사용자 정의를 사용해야 합니다.토큰, 여기서는 간단하게 유지하세요) 그리고-O매개변수 ssh.

ControlMaster

단일 네트워크 연결을 통해 여러 세션을 공유할 수 있습니다. 로 설정되면 yesssh(1)은 인수로 지정된 제어 소켓에서 연결을 수신합니다 ControlPath. 다른 세션은 (기본값 ControlPath) 으로 설정된 것과 동일한 방법을 사용하여 이 소켓에 연결할 수 있습니다 ControlMaster. no이러한 세션은 새 네트워크 연결을 시작하는 대신 마스터 인스턴스의 네트워크 연결을 재사용하려고 시도합니다. [...]

-O ctl_cmd

기본 프로세스에서 활성 연결 재사용을 제어합니다. -O 옵션이 지정되면 ctl_cmd 인수가 해석되어 기본 프로세스로 전달됩니다. 유효한 명령은 다음과 같습니다: "check"(기본 프로세스가 실행 중인지 확인), "forward"(명령을 실행하지 않고 전달 요청),"cancel"(전달 취소), "exit"(마스터 스테이션에 종료를 요청) 및 "stop"(마스터 스테이션에 추가 재사용 요청 수락을 중지하도록 요청).

첫 번째 ssh 명령은 옵션 ControlMaster=yes(또는 auto)을 사용해야 합니다.

ssh -o ControlMaster=yes -o ControlPath=/tmp/mysshcontrolpath -R 2222:localhost:22 remotehost

SSH호스트와 상호작용하는 명령SSH연결은 사용된 것과 정확히 동일하게 사용 ControlMaster=no되어야 auto합니다 ControlPath.

어떻게든 들어오는 SSH 연결을 기다리고(통합이 필요한 부분입니다) 다음 명령을 실행합니다. 동일한 사용자가 다시 연결하는 경우 현재 로컬 시스템에서 실행되고 있으므로 들어오는 연결을 통해 다음 명령을 실행할 수도 있습니다(비밀은 필요하지 않지만 ControlPath소켓에 액세스하려면 동일한 사용자를 사용해야 함).

ssh -o ControlMaster=no -o ControlPath=/tmp/mysshcontrolpath -O cancel -R 2222:localhost:22 remotehost

작은(비대화형 인증을 사용하는 경우) 경합 창 외에도 들어오는 연결이 즉시 실행되면 첫 번째 연결이 진행되는 동안 두 번째 연결이 성공하도록 허용할 수 있습니다.SSH성공적으로 연결되면 추가 연결을 방지하기 위해 청취 소켓이 닫힙니다.

이 명령은 연결을 시도하지 않습니다 remotehost(사용된 경우 -O구문에는 여전히 원격 호스트 인수가 필요하지만 무시됩니다). 마스터 서버에만 연결합니다(로컬 UNIX 소켓을 통해).SSH여전히 실행 중이며 지정된 원격 전달( )을 종료하도록 요청합니다 -O cancel -R 2222:localhost:22.

:) 를 사용하여 닫은 후 다른 내용이나 동일한 내용을 추가하는 데 사용할 수도 있습니다 -O forward -R 2222:localhost:22. 실제로 -O ...호스트가 아닌 경우 전달을 변경하는 유일한 방법은SSH명령(및 ControlPath해당 마스터 SSH에서 생성된 명령 사용): 이런 방식으로 사용되는 다른 SSH 명령은 해당 명령을 가질 수 없습니다.내 자신의메인 서버를 재사용하고 있기 때문에 앞으로SSH연결하다.

ControlPersist사용 사례에 따라 유용할 수 있는 항목(초기(기본) 또는 아님) 도 참조하세요 .SSH완료되면 열려 있거나 열려 있지 않습니다. 활성화되면 -N일종의 주문형 전달 메커니즘을 갖는 옵션과 함께 사용될 수 있습니다 . 그것은 또한 -O exit그 용도를 가질 수 있습니다.

답변2

이 답변은 -O cancelSSH 작업을 기반으로 @AB의 답변을 확장합니다. 여기서 취소 작업은 다음과 같습니다.자동 트리거 TCP 수준에서처음으로 전달된 연결이 시작되는 즉시. 또한 첫 번째 연결이 시작되었지만 취소 작업이 아직 완료되지 않은 기간에도 두 번째 연결이 차단됩니다.

(참고: 하드 코딩된 전달 포트 번호 2222(원격 수신 포트) 및 22(로컬 대상 포트)는 단지 예일 뿐입니다. 일반적으로 원격 전달은 모든 TCP 포트( -R remoteport:localhost:localport)를 사용합니다.)

전달된 첫 번째 연결이 추가 연결을 차단하는 작업을 자동으로 트리거하도록 설정

@AB의 답변에 대한 첫 번째 의견에서 설명했듯이 아이디어는 포크리스를 통해 localhost에 추가 TCP 전달 중간 단계를 삽입하는 것입니다.소캇"다음에서 전달되는 수신 연결을 가로채고" 최종 대상 포트로의 전달을 완료하기 전에 remotehost작업을 실행합니다 . -O cancel다음과 같이 진행하세요:

  1. 첫 번째 ssh 명령은 위의 AB 답변과 유사하지만 최종 대상 포트 22 대신 사용 가능한 권한이 없는 중간 포트(예: 1111)를 사용합니다.

    ssh -o ControlMaster=yes -o ControlPath=/tmp/mysshcontrolpath -R 2222:localhost:1111 remotehost
    

    (이 시점에서 포트 2222에 대한 연결 시도는 remotehost 로컬 측인 포트 1111로 전달되고 로컬 측은 포트 1111에서 수신 대기하지 않기 때문에 실패합니다.)

  2. 이제 첫 번째 수신 전달 연결에서 "ssh 원격 포트에서 추가 수신을 취소하고 현재 수신 TCP 연결 완료"를 트리거하는 localhost에서 다음 명령을 실행합니다.

    socat tcp4-listen:1111 system:'"ssh -o ControlMaster=no -o ControlPath=/tmp/mysshcontrolpath -O cancel -R 2222:localhost:1111 remotehost && socat - tcp4:localhost:22"',nofork
    

    (여기서는 공개 키, ssh-agent 등을 사용하여 비대화형 SSH 인증이 설정되었다고 가정합니다.)

미묘한 점. 이 설정에서는 첫 번째 원격 연결이 계속 작동하는 동안 경쟁 기간 중에도 두 번째 원격 연결이 성공적으로 완료되지 않습니다. 그러나 이는 두 번째 원격 연결이 완료되지 않기 때문에 상위 수준 보기(예: 위의 전송 계층)에서만 해당됩니다.로컬 컴퓨터의 최종 대상 포트로 연결을 완전히 전달합니다.. 그러나 낮은 수준의 방화벽 보기(예: 네트워크 계층)에서는 remotehost경합 기간 동안 원격 전달 포트에 대한 두 번째 연결이 설정되었습니다(첫 번째 연결이 여전히 작동 중이고 취소가 아직 적용되지 않은 동안).여전히 TCP 응답을 참조하세요.(실제로 전체 TCP 핸드셰이크가 발생합니다.) 이는 전혀 수신되지 않는 원격 전달 포트와 다릅니다 remotehost.

관련 정보