한 시스템에서 다른 시스템으로 포트를 전달하는 방법은 무엇입니까?

한 시스템에서 다른 시스템으로 포트를 전달하는 방법은 무엇입니까?

다음 상황을 고려하십시오.

우리 집에는 라우터(인터넷에 연결됨), 서버(S) 및 호스트(M)가 있습니다. S는 인터넷(고정 IP 있음)을 통해 액세스할 수 있고 연중무휴 온라인 상태인 반면 M은 그렇지 않습니다.

때로는 외부 인터넷에서 액세스할 수 있는 일부 애플리케이션(예: 8888 M의 특정 포트에서 수신 대기)을 만들고 싶습니다.

이를 위해 S(2222)의 일부 포트를 M의 포트 8888로 전달하도록 설정하여 S:2222에 액세스하는 사람은 누구나 M:8888에 액세스하는 것처럼 느낄 수 있도록 하고 싶습니다.

SSH 포트 전달을 사용해 보았지만 최선의 시도는 다음과 같습니다.

ssh -L 2222:M:8888 -N M

하지만 이를 통해 다른 컴퓨터가 아닌 서버 자체에서만 포트 2222에 액세스할 수 있습니다.

이 작업을 올바르게 수행할 수 있는 방법이 있나요? 더 이상 전달이 필요하지 않을 때 ^C를 사용하여 시작하고 종료할 수 있는 간단한 명령이었으면 좋겠습니다.

답변1

예, 이것이 GatewayPortsSSH에서 호출되는 방식입니다. 발췌 ssh_config(5):

GatewayPorts
        Specifies whether remote hosts are allowed to connect to local
        forwarded ports.  By default, ssh(1) binds local port forwardings
        to the loopback address.  This prevents other remote hosts from
        connecting to forwarded ports.  GatewayPorts can be used to spec‐
        ify that ssh should bind local port forwardings to the wildcard
        address, thus allowing remote hosts to connect to forwarded
        ports.  The argument must be “yes” or “no”.  The default is “no”.

귀하의 질문을 올바르게 이해했다면 localhost전달하는 컴퓨터가 SSH를 사용하는 것과 동일한 컴퓨터이기 때문에 전달에 대신 사용할 수 있습니다.M

따라서 명령은 다음과 같습니다.

ssh -L 2222:localhost:8888 -N -o GatewayPorts=yes hostname-of-M

그리고 그것은 다음과 같습니다 netstat -nltp:

tcp        0      0    0.0.0.0:2222   0.0.0.0:*  LISTEN  5113/ssh

이제 TCP 포트 2222를 통해 이 컴퓨터에 액세스하는 사람은 컴퓨터 M에 표시된 대로 실제로 localhost:8888과 통신하게 됩니다. 이는 M으로 전달되는 일반 포트 8888과 다릅니다.

답변2

또 다른 방법이 있습니다. iptables를 사용하여 S:2222에서 W:8888로의 포트 전달을 설정할 수 있습니다. 단일 명령:

iptables -t nat -A PREROUTING -p tcp --dport 2222 \
         -j DNAT --to-destination 1.2.3.4:8888

여기서 1.2.3.4는 M의 IP 주소입니다. NAT(네트워크 주소 변환)이라고 합니다.

답변3

추가 대안: ( netcat전통적) 또는socat

서버에서:

socat tcp-listen:2222,reuseaddr,fork tcp:M:8888

또는

nc -l -p 2222 -c 'nc M 8888'

자세한 내용은 다음을 참조하세요. 한 로컬 포트에서 다른 포트로 터널을 만드는 간단한 방법은 무엇입니까?

답변4

간결한 답변

원래 명령은 대부분 괜찮지만 수신 대기할 주소를 지정하지 않아 프로세스가 127.0.0.1기본적으로 수신 대기하게 됩니다.

명령을 에서 ssh -L 2222:M:8888 -N M로 변경 ssh -L S:2222:M:8888 -N M하면 제대로 작동합니다.

자세한 답변

-L귀하가 겪고 있는 문제는 "localPort:remoteHost:remotePort"에 짧은 기호를 사용했기 때문에 발생합니다.

이용하시면 ssh꼭 들어보세요 127.0.0.1.

예를 들어:

ssh -L 2222:M:8888 -N M

결과는 다음과 같습니다(듣고 있는 주소를 참고하세요).

sudo netstat -nlp | grep 2222
tcp        0      0 127.0.0.1:2222          0.0.0.0:*               LISTEN      16208/ssh

전체 표기법("localAddress:localPort:remoteHost:remotePort")을 사용하는 경우:

ssh -L external-address-of-S:2222:M:8888 -N M

비슷한 결과가 나오겠지

sudo netstat -nlp | grep 2222
tcp        0      0 external-address-of-S:2222          0.0.0.0:*               LISTEN      16208/ssh

PS GatewayPorts는 보다 일반적인 솔루션이지만 서버에 IP 주소가 여러 개 있는 경우 다르게 작동합니다. 이 솔루션을 사용하면 GatewayPorts모든 IP를 수신하고 동일한 대상으로 전달하면서 수신할 IP를 선택할 수 있습니다(다른 IP의 동일한 포트를 다른 대상으로 전달할 수 있음) . 어느 것이 더 적합한지는 요구 사항에 따라 다르지만 둘 다 OP에 적합합니다.

PPS 나는 이것이 매우 오래된 질문이라는 것을 알고 있지만 오늘날에도 여전히 매우 관련성이 있으며(아마도 클라우드의 광범위한 사용으로 인해 더욱 그렇습니다) 유사한 문제를 가진 누구에게나 도움이 될 수 있는 간단한 대답이 누락되었다고 생각합니다.

관련 정보