존재하다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 ..."
명령이 완료되자마자 메시지를 받을 수 있습니다.
이에 대해 자세히 알아보기비슷한 질문에 대한 로아이마의 답변.