OpenSSH RemoteForward에 동적으로 할당 된 포트 결정


13

질문 (TL; DR)

원격 전달 (일명 -R옵션)을 위해 포트를 동적으로 할당 할 때 원격 시스템의 스크립트 (예 : 소스 .bashrc)는 OpenSSH에서 선택한 포트를 어떻게 확인할 수 있습니까?


배경

OpenSSH (양쪽 끝)를 사용하여 여러 다른 사용자와 공유하는 중앙 서버에 연결합니다. 내 원격 세션 (현재)에 대해 X, 컵 및 펄스 오디오를 전달하고 싶습니다.

가장 사소한 것은 -X옵션을 사용하여 X를 전달하는 것입니다. 할당 된 X 주소는 환경 변수에 저장되며 DISPLAY그로부터 대부분의 경우 해당 TCP 포트를 결정할 수 있습니다. 그러나 Xlib이 영광이기 때문에 거의 필요하지 않습니다 DISPLAY.

컵과 펄스 오디오에도 비슷한 메커니즘이 필요합니다. 두 서비스에 대한 기본 사항은 각각 환경 변수 CUPS_SERVER및 의 형태로 존재합니다 PULSE_SERVER. 사용 예는 다음과 같습니다.

ssh -X -R12345:localhost:631 -R54321:localhost:4713 datserver

export CUPS_SERVER=localhost:12345
lowriter #and I can print using my local printer
lpr -P default -o Duplex=DuplexNoTumble minutes.pdf #printing through the tunnel
lpr -H localhost:631 -P default -o Duplex=DuplexNoTumble minutes.pdf #printing remotely

mpg123 mp3s/van_halen/jump.mp3 #annoy co-workers
PULSE_SERVER=localhost:54321 mpg123 mp3s/van_halen/jump.mp3 #listen to music through the tunnel

문제는 설정입니다 CUPS_SERVERPULSE_SERVER올바르게.

포트 포워딩을 많이 사용하므로 동적 포트 할당이 필요합니다. 정적 포트 할당은 옵션이 아닙니다.

OpenSSH에는 0원격 전달을위한 바인드 포트 ( -R옵션) 를 지정하여 원격 서버에서 동적 포트 할당을위한 메커니즘 이 있습니다. 다음 명령을 사용하면 OpenSSH가 컵 및 펄스 전달을위한 포트를 동적으로 할당합니다.

ssh -X -R0:localhost:631 -R0:localhost:4713 datserver

해당 명령을 사용 ssh하면 다음을 인쇄합니다 STDERR.

Allocated port 55710 for remote forward to 127.0.0.1:4713
Allocated port 41273 for remote forward to 127.0.0.1:631

내가 원하는 정보가 있습니다! 궁극적으로 나는 생성하고 싶다 :

export CUPS_SERVER=localhost:41273
export PULSE_SERVER=localhost:55710

그러나 "할당 된 포트 ..."메시지가 로컬 컴퓨터에서 생성되어로 전송되어 STDERR원격 컴퓨터에서 액세스 할 수 없습니다. 이상하게도 OpenSSH는 포트 전달에 대한 정보를 검색 할 수단이없는 것 같습니다.

어떻게 적절하게 설정하는 쉘 스크립트에 넣어 그 정보를 가져 않는 CUPS_SERVERPULSE_SERVER원격 호스트에?


막 다른 골목

내가 찾을 수있는 유일한 것은 sshd로그에서 정보를 읽을 수있을 때까지의 자세한 정보를 늘리는 것이 었 습니다. 정보가 루트가 아닌 사용자가 액세스 할 수있는 것보다 훨씬 많은 정보를 공개하기 때문에 이는 실행 불가능합니다.

내부 구조체의 멋진 표현을 인쇄하는 추가 이스케이프 시퀀스를 지원하기 위해 OpenSSH를 패치하는 것에 대해 생각하고 permitted_opens있었지만, 원하는 경우에도 서버 측에서 클라이언트 이스케이프 시퀀스에 액세스하는 스크립트를 작성할 수 없습니다.


더 좋은 방법이 있어야합니다

다음 접근 방식은 매우 불안정하고 사용자 당 하나의 SSH 세션으로 제한됩니다. 그러나 적어도 두 개의 동시 세션과 다른 사용자가 더 필요합니다. 그러나 나는 시도했다 ...

닭이 하나 또는 두 개를 희생하여 별이 제대로 정렬되면 sshd사용자로 시작되지 않은 사실을 남용 할 수 있지만 성공적인 로그인 후 권한을 삭제하여 다음을 수행 할 수 있습니다.

  • 내 사용자의 모든 청취 소켓에 대한 포트 번호 목록을 얻습니다.

    netstat -tlpen | grep ${UID} | sed -e 's/^.*:\([0-9]\+\) .*$/\1/'

  • 사용자가 시작한 프로세스에 속하는 모든 청취 소켓의 포트 번호 목록을 얻습니다.

    lsof -u ${UID} 2>/dev/null | grep LISTEN | sed -e 's/.*:\([0-9]\+\) (LISTEN).*$/\1/'

  • 첫 번째 세트에있는 모든 포트이지만 두 번째 세트 내 전달 포트, 실제로 세트 수율을 감산 할 수있는 높은 동반 할 가능성이없는 41273, 557106010; 컵, 펄스 및 X.

  • 6010를 사용하여 X 포트로 식별됩니다 DISPLAY.

  • 41273은 컵 포트이며을 lpstat -h localhost:41273 -a반환 하기 때문 0입니다.
  • 55710는를 pactl -s localhost:55710 stat반환 하기 때문에 펄스 포트 0입니다. (내 클라이언트의 호스트 이름도 인쇄합니다!)

(설정된 빼기 I을 수행하고 sort -u위 명령 줄의 출력을 저장 comm하고 빼기를 수행하는 데 사용 합니다.)

Pulseaudio를 사용하면 클라이언트를 식별 할 수 있으며 모든 의도와 목적에 따라 분리해야하는 SSH 세션을 분리하는 앵커 역할을 할 수 있습니다. 그러나, 나는 넥타이를하는 방법을 발견하지 않은 41273, 55710그리고 6010동일로 sshd처리. netstat해당 정보를 루트가 아닌 사용자에게 공개하지 않습니다. 나는 단지를 얻을 수 -에서 PID/Program name내가 읽고 싶은 열 2339/54(이 특정 인스턴스에서). 너무 가까이 ...


그러나 netstat소유하지 않거나 커널 공간 인 프로세스의 PID를 표시하지 않는 것이 더 정확 합니다. 예를 들어
Bratchley

가장 강력한 방법은 sshd를 패치하는 것입니다 ... 빠른 & 더티 패치는 서버가 OS에서 로컬 포트를 가져 와서 포트 번호를 파일, 사용자, 원격 호스트 및 포트. 서버가 클라이언트 측의 포트를 알고 있다고 가정하면 확실하지 않을 수도 있습니다 (그렇지 않으면 이미 기능이 존재할 것입니다).
하이드

@ 하이드 : 정확히. 원격 서버는 전달 된 포트에 대해 알지 못합니다. 단지 몇 개의 청취 소켓을 생성하고 데이터는 ssh 연결을 통해 전달됩니다. 로컬 대상 포트에 대해서는 알지 못합니다.
Bananguin

답변:


1

두 가지를 취하십시오 ( 서버 측에서 scp 를 수행하고 조금 더 간단한 버전은 히스토리 참조 ). 그것의 요지는 이것입니다 :

  1. 클라이언트에서 서버로 환경 변수를 전달하여 포트 정보가 사용 가능한시기를 감지 한 후 가져 와서 사용할 수있는 방법을 서버에 알려줍니다.
  2. 일단 포트 정보가 사용 가능하면, 클라이언트에서 서버로 정보를 복사하여 서버가 정보를 얻도록 허용하십시오 (위 1 부의 도움으로).

먼저 원격 측에서 설정하려면 sshd 구성 에서 env 변수를 보내야 합니다.

sudo yourfavouriteeditor /etc/ssh/sshd_config

줄을 찾아서 AcceptEnv추가 MY_PORT_FILE하십시오 (또는 Host아직없는 경우 오른쪽 섹션 아래에 줄을 추가하십시오 ). 나에게 줄은 이것이었다 :

AcceptEnv LANG LC_* MY_PORT_FILE

또한 이를 적용하려면 sshd 를 다시 시작 해야합니다.

또한 아래 스크립트가 작동하려면 mkdir ~/portfiles원격 에서 수행하십시오 !


그런 다음 로컬 측면에서 스크립트 스 니펫은

  1. stderr 경로 재 지정을위한 임시 파일 이름 작성
  2. 파일에 내용이있을 때까지 백그라운드 작업을 남겨 두십시오.
  3. ssh stderr를 파일로 리디렉션하는 동안 파일 이름을 env 변수로 서버에 전달 하십시오.
  4. 백그라운드 작업은 별도의 scp를 사용하여 stderr temp 파일을 서버 측으로 복사합니다.
  5. 백그라운드 작업은 또한 stderr 파일이 준비되었음을 나타내는 플래그 파일을 서버에 복사합니다.

스크립트 스 니펫 :

REMOTE=$USER@datserver

PORTFILE=`mktemp /tmp/sshdataserverports-$(hostname)-XXXXX`
test -e $PORTFILE && rm -v $PORTFILE

# EMPTYFLAG servers both as empty flag file for remote side,
# and safeguard for background job termination on this side
EMPTYFLAG=$PORTFILE-empty
cp /dev/null $EMPTYFLAG

# this variable has the file name sent over ssh connection
export MY_PORT_FILE=$(basename $PORTFILE)

# background job loop to wait for the temp file to have data
( while [ -f $EMPTYFLAG -a \! -s $PORTFILE ] ; do
     sleep 1 # check once per sec
  done
  sleep 1 # make sure temp file gets the port data

  # first copy temp file, ...
  scp  $PORTFILE $REMOTE:portfiles/$MY_PORT_FILE

  # ...then copy flag file telling temp file contents are up to date
  scp  $EMPTYFLAG $REMOTE:portfiles/$MY_PORT_FILE.flag
) &

# actual ssh terminal connection    
ssh -X -o "SendEnv MY_PORT_FILE" -R0:localhost:631 -R0:localhost:4713 $REMOTE 2> $PORTFILE

# remove files after connection is over
rm -v $PORTFILE $EMPTYFLAG

그런 다음 .bashrc에 적합한 원격 측 스 니펫 :

# only do this if subdir has been created and env variable set
if [ -d ~/portfiles -a "$MY_PORT_FILE" ] ; then

       PORTFILE=~/portfiles/$(basename "$MY_PORT_FILE")
       FLAGFILE=$PORTFILE.flag
       # wait for FLAGFILE to get copied,
       # after which PORTFILE should be complete
       while [ \! -f "$FLAGFILE" ] ; do 
           echo "Waiting for $FLAGFILE..."
           sleep 1
       done

       # use quite exact regexps and head to make this robust
       export CUPS_SERVER=localhost:$(grep '^Allocated port [0-9]\+ .* localhost:631[[:space:]]*$' "$PORTFILE" | head -1 | cut -d" " -f3)
       export PULSE_SERVER=localhost:$(grep '^Allocated port [0-9]\+ .* localhost:4713[[:space:]]*$' "$PORTFILE" | head -1 | cut -d" " -f3)
       echo "Set CUPS_SERVER and PULSE_SERVER"

       # copied files served their purpose, and can be removed right away
       rm -v -- "$PORTFILE" "$FLAGFILE"
fi

참고 : 위의 코드는 물론 철저하게 테스트되지 않았으며 모든 종류의 버그, 복사 붙여 넣기 오류 등을 포함 할 수 있습니다.이 코드를 사용하는 사람은 누구나 이해하고 위험을 감수해야합니다! 로컬 호스트 연결을 사용하여 테스트했으며 테스트 환경에서 저에게 효과적이었습니다. YMMV.


물론 scp원격 측에서 로컬 측으로 할 수있는 것은 필요합니다. 비슷한 접근 방식이 있었지만 ssh연결을 설정 한 후 백그라운드로 랩핑 한 다음 해당 파일을 로컬에서 원격을 통해 보낸 scp다음 ssh클라이언트를 포 그라운드 로 가져 와서 원격 측에서 스크립트를 실행합니다. 백그라운드 및 포 그라운드 로컬 및 원격 프로세스를 스크립팅하는 방법을 알지 못했습니다. 로컬 ssh클라이언트를 이와 같은 원격 스크립트로 래핑하고 통합하는 것은 좋은 방법이 아닙니다.
Bananguin

아 나는 당신이 클라이언트 쪽 scp 만을 배경으로 생각해야한다고 생각한다 (while [ ... ] ; do sleep 1 ; done ; scp ... )&. 그런 다음 .bashrc파일이 나타날 때까지 서버의 포 그라운드에서 기다립니다 (클라이언트가 올바른 env 변수를 전송한다고 가정). 테스트 후 나중에 답변을 업데이트 할 것입니다 (아마 내일까지는 시간이 없을 것입니다).
하이드

@Bananguin 새 버전이 완료되었습니다. 나에게 도움이되는 것 같으므로 사용 사례에 적합해야합니다. "좋은 접근 방식"에 대해서는 그렇습니다.하지만 여기서는 정말 좋은 접근 방식이 없다고 생각합니다. 정보는 어떻게 든 전달되어야하며 단일 연결을 통해 ssh 클라이언트와 서버를 모두 패치하여 깔끔하게 처리하지 않는 한 항상 해킹이 될 것입니다.
하이드

그리고 openssh 패치에 대해 점점 더 생각하고 있습니다. 큰 일이 아닌 것 같습니다. 정보는 이미 사용 가능합니다. 서버로 보내면됩니다. 서버가 그러한 정보를받을 때마다~/.ssh-${PID}-forwards
Bananguin

1

.bashrc에 적합한 로컬 측 스 니펫 :

#!/bin/bash

user=$1
host=$2

sshr() {
# 1. connect, get dynamic port, disconnect  
port=`echo "exit" | ssh -R '*:0:127.0.0.1:52698' -t $1 2>&1 | grep 'Allocated port' | awk '/port/ {print $3;}'`
# 2. reconnect with this port and set remote variable
cmds="ssh -R $port:127.0.0.1:52698 -t $1 bash -c \"export RMATE_PORT=$port; bash\""
($cmds)
}

sshr $user@$host

0

로컬 클라이언트에서 파이프를 만든 다음 stderr을 파이프로 리디렉션하여 ssh의 입력으로 리디렉션하여 동일한 결과를 얻었습니다. 실패 할 수있는 사용 가능한 알려진 포트를 가정하기 위해 여러 개의 ssh 연결이 필요하지 않습니다. 이렇게하면 로그온 배너 및 "할당 된 포트 ### ..."텍스트가 원격 호스트로 리디렉션됩니다.

getsshport.sh리디렉션 된 입력을 읽고 포트를 구문 분석하는 원격 호스트에서 실행 되는 호스트에 간단한 스크립트 가 있습니다. 이 스크립트가 끝나지 않는 한 ssh 원격 전달은 열린 상태로 유지됩니다.

국부

mkfifo pipe
ssh -R "*:0:localhost:22" user@remotehost "~/getsshport.sh" 3>&1 1>&2 2>&3 < pipe | cat > pipe

3>&1 1>&2 2>&3 stderr과 stdout을 바꾸는 작은 트릭이므로 stderr이 cat에 파이프되고 ssh의 모든 일반 출력이 stderr에 표시됩니다.

원격 측 ~ / getsshport.sh

#!/bin/sh
echo "Connection from $SSH_CLIENT"
while read line
do
    echo "$line" # echos everything sent back to the client
    echo "$line" | sed -n "s/Allocated port \([0-9]*\) for remote forward to \(.*\)\:\([0-9]*\).*/client port \3 is on local port \1/p" >> /tmp/allocatedports
done

grepssh를 통해 보내기 전에 먼저 로컬에서 "할당 된 포트"메시지를 시도 했지만 ssh가 stdin에서 파이프가 열리기를 기다리는 것을 차단하는 것 같습니다. grep은 무언가를 받기 전까지는 쓰기 위해 파이프를 열지 않으므로 기본적으로 교착 상태입니다. cat그러나 똑같은 동작을하지 않는 것 같고 ssh가 연결을 열 수 있도록 즉시 쓰기 위해 파이프를 엽니 다.

이것은 원격 쪽에서도 같은 문제이며 readstdin에서 grep 대신 한 줄씩 표시하는 이유입니다.

~/getsshport.sh명령, 배너 텍스트 또는 파이프에있는 다른 항목을 원격 쉘에서 실행하지 않기 때문에 ssh의 stderr를 같은 명령으로 파이프하는 것이 좋습니다.


좋은. renice +10 $$; exec cat전에 done자원을 절약 하기 위해 추가했습니다 .
Spongman

0

이것은 까다로운 하나의 추가 서버 측 처리 라인을 따라 SSH_CONNECTION또는 DISPLAY훌륭하지만 추가하기는 쉽지 않습니다. 문제의 일부는 ssh클라이언트 만 로컬 대상을 알고 요청 패킷 (서버)이 포함한다는 것입니다 원격 주소와 포트만

다른 답변에는이 클라이언트 측을 캡처하여 서버로 보내는 다양한 예쁘지 않은 솔루션이 있습니다. 여기에 솔직히 더 예쁘지 않은 대체 접근법이 있지만 적어도이 추악한 당사자는 클라이언트 측에 보관됩니다.

  • 클라이언트 측에서 추가 / 수정 SendEnv하여 ssh를 통해 기본적으로 일부 환경 변수를 보낼 수 있습니다 (아마 기본값이 아님)
  • 서버 측에서 AcceptEnv동일하게 추가 / 수정 (기본적으로 활성화되어 있지 않음)
  • ssh동적으로로드 된 라이브러리로 클라이언트 stderr 출력을 모니터하고 연결 설정 중에 ssh 클라이언트 환경을 업데이트하십시오.
  • 프로파일 / 로그인 스크립트에서 환경 변수 서버 측을 선택하십시오.

환경이 교환되기 전에 원격 순방향이 설정되고 기록되기 때문에 (행복하게도 지금은 행복하게) 작동합니다 (로 확인하십시오 ssh -vv ...). 동적으로로드 된 라이브러리는 write()libc 함수 ( ssh_confirm_remote_forward()logit()do_log()write()) 를 캡처해야합니다 . 재 컴파일없이 ELF 바이너리로 함수를 재지향 또는 래핑하는 것은 동적 라이브러리의 함수에 대해 수행하는 것보다 훨씬 복잡합니다.

클라이언트 .ssh/config(또는 명령 행 -o SendEnv ...)

Host somehost
  user whatever
  SendEnv SSH_RFWD_*

서버에서 sshd_config(루트 / 관리 변경 필요)

AcceptEnv LC_* SSH_RFWD_*

이 접근 방식은 Linux 클라이언트에서 작동하며 서버에서 특별한 작업이 필요하지 않으며 약간의 미세 조정이있는 다른 * nix에서도 작동합니다. OpenSSH 5.8p1에서 7.5p1까지 작동합니다.

다음과 같이 gcc -Wall -shared -ldl -Wl,-soname,rfwd -o rfwd.so rfwd.c 호출하여 컴파일하십시오 .

LD_PRELOAD=./rfwd.so ssh -R0:127.0.0.1:4713 -R0:localhost:631 somehost

코드:

#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
#include <string.h>
#include <stdlib.h>

// gcc -Wall -shared  -ldl -Wl,-soname,rfwd -o rfwd.so rfwd.c

#define DEBUG 0
#define dfprintf(fmt, ...) \
    do { if (DEBUG) fprintf(stderr, "[%14s#%04d:%8s()] " fmt, \
          __FILE__, __LINE__, __func__,##__VA_ARGS__); } while (0)

typedef ssize_t write_fp(int fd, const void *buf, size_t count);
static write_fp *real_write;

void myinit(void) __attribute__((constructor));
void myinit(void)
{
    void *dl;
    dfprintf("It's alive!\n");
    if ((dl=dlopen(NULL,RTLD_NOW))) {
        real_write=dlsym(RTLD_NEXT,"write");
        if (!real_write) dfprintf("error: %s\n",dlerror());
        dfprintf("found %p write()\n", (void *)real_write);
    } else {
        dfprintf(stderr,"dlopen() failed\n");
    }
}

ssize_t write(int fd, const void *buf, size_t count)
{
     static int nenv=0;

     // debug1: Remote connections from 192.168.0.1:0 forwarded to local address 127.0.0.1:1000
     //  Allocated port 44284 for remote forward to 127.0.0.1:1000
     // debug1: All remote forwarding requests processed
     if ( (fd==2) && (!strncmp(buf,"Allocated port ",15)) ) {
         char envbuf1[256],envbuf2[256];
         unsigned int rport;
         char lspec[256];
         int rc;

         rc=sscanf(buf,"Allocated port %u for remote forward to %256s",
          &rport,lspec);

         if ( (rc==2) && (nenv<32) ) {
             snprintf(envbuf1,sizeof(envbuf1),"SSH_RFWD_%i",nenv++);
             snprintf(envbuf2,sizeof(envbuf2),"%u %s",rport,lspec);
             setenv(envbuf1,envbuf2,1);
             dfprintf("setenv(%s,%s,1)\n",envbuf1,envbuf2);
         }
     }
     return real_write(fd,buf,count);
}

(이 방법으로 심볼 버전 관리와 관련된 일부 glibc 베어 트랩이 있지만 write()이 문제는 없습니다.)

용감하다고 생각되면 setenv()관련 코드를 가져 와서 ssh.c ssh_confirm_remote_forward()콜백 함수에 패치 할 수 있습니다 .

이것은 환경 변수 이름을 설정 SSH_RFWD_nnn하고, 예를 들어bash

for fwd in ${!SSH_RFWD_*}; do
    IFS=" :" read lport rip rport <<< ${!fwd}
    [[ $rport -eq "631" ]] && export CUPS_SERVER=localhost:$lport
    # ...
done

주의 사항 :

  • 코드에 오류 검사가별로 없습니다.
  • 환경을 변경 하면 스레드 관련 문제 발생할 있으며 PAM은 스레드를 사용하지만 문제는 예상하지 않지만 테스트하지는 않았습니다.
  • ssh현재 * local : port : remote : port * 형식의 전체 전달을 명확하게 기록하지는 않지만 (필요한 경우 추가 debug1메시지 구문 분석 ssh -v이 필요한 경우) 유스 케이스에 필요하지 않습니다.

이상하게도 OpenSSH는 포트 전달에 대한 정보를 검색 할 수단이없는 것 같습니다.

이스케이프를 사용하여 (부분적으로) 대화식 으로이 작업을 수행 할 수 있습니다 ~#. 이상하게 구현은 청취중인 채널을 건너 뛰고 열려있는 (예 : TCP ESTABLISHED) 채널 만 나열하며 어떤 경우에도 유용한 필드를 인쇄하지 않습니다. 보다channels.c channel_open_message()

이 기능을 패치하여 SSH_CHANNEL_PORT_LISTENER슬롯에 대한 세부 정보를 인쇄 할 수 있지만 로컬 전달 만 가져옵니다 ( 채널 은 실제 전달 과 동일하지 않습니다 ). 또는 전역 options구조체 에서 두 개의 전달 테이블을 덤프하도록 패치 할 수 있습니다 .

#include "readconf.h"
Options options;  /* extern */
[...]
snprintf(buf, sizeof buf, "Local forwards:\r\n");
buffer_append(&buffer, buf, strlen(buf));
for (i = 0; i < options.num_local_forwards; i++) {
     snprintf(buf, sizeof buf, "  #%d listen %s:%d connect %s:%d\r\n",i,
       options.local_forwards[i].listen_host,
       options.local_forwards[i].listen_port,
       options.local_forwards[i].connect_host,
       options.local_forwards[i].connect_port);
     buffer_append(&buffer, buf, strlen(buf));
}
snprintf(buf, sizeof buf, "Remote forwards:\r\n");
buffer_append(&buffer, buf, strlen(buf));
for (i = 0; i < options.num_remote_forwards; i++) {
     snprintf(buf, sizeof buf, "  #%d listen %s:%d connect %s:%d\r\n",i,
       options.remote_forwards[i].listen_host,
       options.remote_forwards[i].listen_port,
       options.remote_forwards[i].connect_host,
       options.remote_forwards[i].connect_port);
     buffer_append(&buffer, buf, strlen(buf));
}

이 방법은 "프로그래밍"솔루션은 아니지만 클라이언트 코드가 전달을 추가 / 제거 할 때 (즉, 소스에서 XXX로 표시됨) 목록을 업데이트하지 않는다는 경고와 함께 잘 작동합니다 ( ~C)


서버가 Linux 인 경우 옵션이 하나 더 있습니다. 원격이 아닌 로컬 전달을 위해 일반적으로 사용하는 옵션입니다. lo127.0.0.1/8, Linux 에서는 127/8의 모든 주소에 투명하게 바인딩 할 수 있으므로 고유 한 127.xyz 주소를 사용하는 경우 고정 포트를 사용할 수 있습니다. 예 :

mr@local:~$ ssh -R127.53.50.55:44284:127.0.0.1:44284 remote
[...]
mr@remote:~$ ss -atnp src 127.53.50.55
State      Recv-Q Send-Q        Local Address:Port          Peer Address:Port 
LISTEN     0      128            127.53.50.55:44284                    *:*    

이것은 1024 미만의 특권 포트를 바인딩해야하며 OpenSSH는 Linux 기능을 지원하지 않으며 대부분의 플랫폼에서 하드 코딩 된 UID 검사를합니다.

현명하게 선택된 옥텟 (제 경우에는 ASCII 서수 니모닉)이 하루의 끝에서 혼란을 풀도록 도와줍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.