SSH 원격 포트 전달을 사용하여 동적으로 할당된 포트 번호를 기록합니다.

SSH 원격 포트 전달을 사용하여 동적으로 할당된 포트 번호를 기록합니다.

존재하다SSH 문서, 원격 포트 전달의 경우 다음과 같이 표시됩니다.

포트 매개변수가 "0"이면 수신 대기 포트가 서버에 동적으로 할당되고 런타임 시 클라이언트에 보고됩니다. 함께 사용하는 경우-O forward, 할당된 포트가 표준 출력으로 인쇄됩니다.

이 포트 번호를 어떻게 얻거나 사용합니까?

stdout으로 인쇄된 것을 볼 수 있지만 파일에 기록하고 싶습니다.


NAT 방화벽 뒤에 여러 대의 컴퓨터가 있고, 모두 중앙 서버에 연결되어 있고 SSH를 통해 다시 연결할 수 있도록 터널이 설정되어 있습니다.

현재 이 작업을 수행하기 위해 자체 포트 번호(예: 12345)를 지정합니다.

ssh -R 12345:localhost:22 1.2.3.4

이는 다음에 연결하여 1.2.3.4사용할 수 있기 때문에 작동합니다.

ssh -p 12345 localhost

그러나 기록을 유지하는 것이 힘들고 결국 연결이 실패하면 다시 연결이 작동하지 않는 경우가 있기 때문에 각 컴퓨터에 포트 번호를 하드코딩하고 싶지 않습니다(포트가 여전히 "사용 중"이기 때문에).

대신 다음을 사용할 수 있습니다.

ssh -R 0:localhost:22 1.2.3.4

보고되는 위치:

Allocated port 41191 for remote forward to localhost:22

하지만 해당 포트 번호를 어떻게 기록합니까?

나는 그것에 접근하는 방법에 대해 분명한 것을 놓치고 있다고 가정합니다.

포트 번호를 파일에 기록하기 위해 쉘 스크립트에서 수행할 수 있는 작업이 있습니까?


한 가지 옵션은 수신 대기 포트를 확인하는 것입니다. 이 옵션은 다음과 같은 작업을 수행하는 서버가 여러 개 있는 경우 작동하지 않습니다.

sudo netstat -tpln | grep "127.0.0.1" | grep sshd

다소 낭비적인 것처럼 보이지만 먼저 포트 번호를 가져와서 연결을 끊은 다음 사용할 수 있습니다.

port=`ssh -R 0:localhost:22 1.2.3.4 exit 2>&1 | grep 'Allocated port' | awk '/port/ { print $3 }'`;

ssh 1.2.3.4 record-port.sh "my-name" "${port}";

ssh -NTC -o ConnectTimeout=10 -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes -R "${port}:localhost:22" 1.2.3.4;

또 다른 옵션(아마도 더 나쁠 수도 있음)은 포트를 직접 무작위로 선택하고 사용하기 전에 기록하는 것입니다.

while true; do

  port=$(((RANDOM %= 1000) + 2000));

  ssh 1.2.3.4 record-port.sh "my-name" "${port}";

  ssh -NTC -o ConnectTimeout=10 -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes -R "${port}:localhost:22" 1.2.3.4;

  sleep 3;

done

답변1

먼저 포트 전달을 사용하지 않고 기본 연결을 연결합니다.

ssh -NMS /path/to/socket user@server

/path/to/socket당신이 결정합니다. 거기에 소켓이 생성됩니다. 사용하려는 스크립트에서 -f.

그런 다음 이를 사용하여 -S /path/to/socket -O …기본 연결을 제어합니다. 예를 들어, 여전히 유효한지 확인할 수 있습니다.

ssh -S /path/to/socket -O check placeholder

placeholder괜찮습니다. /path/to/socket제어하려는 기본 연결을 식별하는 것입니다.

이제 포트 전달을 요청할 수 있습니다.

ssh -S /path/to/socket -O forward -R 0:localhost:22 placeholder

이 명령은 포트를 알려줍니다. 즉시 종료되므로 출력을 캡처할 수 있습니다. 아무것도 손실되지 않습니다. 명령을 반복하면 두 번째 포트를 동일한 대상으로 전달하는 대신 동일한 포트를 다시 알려줍니다. 이제 출력을 변수에 저장해 보겠습니다.

port="$(ssh -S /path/to/socket -O forward -R 0:localhost:22 placeholder)"

이제 변수를 사용할 수 있습니다.

완벽을 기하기 위해 전달을 취소하는 방법은 다음과 같습니다.

ssh -S /path/to/socket -O cancel -R 0:localhost:22 placeholder

기본 연결을 종료하기 전에 명시적으로 취소할 필요는 없습니다. 다음과 같이 종료할 수 있습니다.

ssh -S /path/to/socket -O exit placeholder

가장 기본적인 스크립트에서는 위의 명령이 모두 필요한 것은 아닙니다. 다음이 필요합니다.

ssh -fNMS /path/to/socket user@server
port="$(ssh -S /path/to/socket -O forward -R 0:localhost:22 placeholder)"
   # anything you want, now you know the port
ssh -S /path/to/socket -O exit placeholder

처리해야 할 논리가 있을 수 있습니다 connection refused.

답변2

할당된 포트를 얻기 위해 원격 서버에 스크립트를 실행하거나 소켓 잠금을 생성할 필요가 없습니다.를 가짐으로써-o ExitOnForwardFailure=yes옵션.

터널이 설정될 때까지 기다리므로 "Allocated port ..."명령이 완료되자마자 메시지를 받을 수 있습니다.

이에 대해 자세히 알아보기비슷한 질문에 대한 로아이마의 답변.

관련 정보