역방향 SSH 터널링은 어떻게 작동하나요?

역방향 SSH 터널링은 어떻게 작동하나요?

내가 이해한 바로는 방화벽(기본 설정 가정)은 이전에 해당하는 나가는 트래픽이 없는 모든 들어오는 트래픽을 거부합니다.

기반으로역방향 SSH 연결그리고SSH 터널링이 쉬워졌습니다, 역방향 SSH 터널링을 사용하면 성가신 방화벽 제한을 우회할 수 있습니다.

원격 컴퓨터에서 쉘 명령을 실행하고 싶습니다. 원격 컴퓨터에는 자체 방화벽이 있으며 추가 방화벽(라우터) 뒤에 있습니다. IP 주소는 192.168.1.126(또는 유사)과 같습니다. 저는 방화벽 뒤에 있지 않으며 인터넷에서 볼 수 있는 원격 컴퓨터의 IP 주소(192.168.1.126 주소가 아님)를 알고 있습니다. 또한 누군가에게 ssh (something)먼저 원격 컴퓨터에서 루트로 실행하도록 요청할 수도 있습니다 .

역방향 SSH 터널이 방화벽(로컬 및 원격 시스템의 방화벽과 그 사이의 추가 방화벽)을 우회하는 방법을 단계별로 설명할 수 있는 사람이 있습니까?

스위치( -R, -f, -L, -N)의 기능은 무엇입니까?

답변1

나는 이런 것을 시각화를 통해 설명하는 것을 좋아합니다. :-)

SSH 연결을 파이프로 생각하십시오. 큰 튜브. 일반적으로 이러한 파이프를 통해 원격 시스템에서 셸을 실행합니다. 쉘은 이 파이프를 통해 가상 터미널(tty)에서 실행됩니다. 하지만 이 부분은 이미 알고 계실 겁니다.

터널을 튜브 안의 또 다른 튜브로 생각하십시오. 여전히 더 큰 SSH 연결이 있지만 -L 또는 -R 옵션을 사용하면 그 안에 더 작은 파이프를 설정할 수 있습니다.

SSH 원격 셸은 실제로 stdio에 연결된 작은 내장 파이프 중 하나를 사용하여 사용자와 통신합니다.

각 튜브에는 시작점과 끝점이 있습니다. 큰 파이프, SSH 연결은 SSH 클라이언트에서 시작하여 연결하는 SSH 서버로 끝납니다. 모든 작은 튜브에는 동일한 끝점이 있습니다. 단, "시작" 또는 "끝"의 역할은 사용 -L또는 -R생성(별도)에 따라 달라집니다.

(아직 말씀하시지 않았지만 말씀하신 "원격" 머신, 즉 방화벽 뒤에 있는 머신이 NAT(Network Address Translation)를 사용하여 인터넷에 접속하고 있다고 가정하고 있습니다. 이것은 중요하므로 정정해 주십시오. 이 가정이 틀렸다면 나에게 알려주세요.)

터널을 생성할 때 터널이 응답할(또는 "바인딩") 주소와 포트, 그리고 전달할 주소와 포트를 지정합니다. 이 -L옵션은 터널이 터널의 로컬 측(클라이언트를 실행하는 호스트)에 바인딩되도록 지시합니다. 이 -R옵션은 터널이 원격 측(SSH 서버)에서 바인딩하도록 지시합니다.

SSH 터널 방향

따라서... 인터넷에서 방화벽 뒤의 호스트로 SSH를 실행할 수 있으려면 대상 호스트가 외부 호스트에 대한 SSH 연결을 열고 -R"원격" 측에 대한 "진입" 지점을 포함해야 합니다. 연결에 터널이 있습니다.

위에 표시된 두 모델 중 오른쪽 모델이 필요합니다.

~에서방화벽 포함주인:

ssh -f -N -T -R22222:localhost:22 yourpublichost.example.com

이는 대상 호스트의 클라이언트에게 -R표현식 진입점을 사용하여 터널을 설정하도록 지시합니다. 터널의 맨 끝 포트 22222에 연결된 모든 항목은 실제로 "localhost 포트 22"로 이동합니다. 여기서 "localhost"는 터널 종료 지점(예: 이 경우 대상 호스트의 SSH 클라이언트)의 관점에서 나타납니다.

다른 옵션은 다음과 같습니다:

  • -fsleep인증 후 ssh에 백그라운드 자체를 지시하면 터널을 활성 상태로 유지하기 위해 원격 서버에 앉아서 이와 같은 작업을 실행할 필요가 없습니다 .
  • -NSSH 연결을 원하지만 실제로는 원격 명령을 실행하고 싶지 않음을 나타냅니다. 생성 중인 것이 터널뿐인 경우 이 옵션을 포함하면 리소스를 절약할 수 있습니다.
  • -T대화형 셸을 생성하려는 것이 아니기 때문에 적절한 pseudo-tty 할당을 비활성화합니다.

비밀번호 없는 로그인을 위한 키를 설정하지 않으면 비밀번호 질문이 발생합니다.

(연결을 오랫동안 방치하여 연결이 ssh -O check <remotehost>끊어졌을 때 자동으로 연결을 새로 고치려는 경우(parsing을 통해) 특히 이 /server에 대해 별도의 고유한 SSH 키 터널/클라이언트를 설정하는 것이 좋습니다. RemoteForward를 사용하세요. 누구도 믿지 마세요).

이제 -R 서비스 터널이 활성화되었으므로 시작할 수 있습니다.당신의 공개 호스트, 터널을 통해 방화벽 호스트에 대한 연결 설정:

ssh -p 22222 username@localhost

이전에 호스트에 액세스한 적이 없기 때문에 호스트 키 질문을 받게 됩니다. 그런 다음 해당 계정에 대한 비밀번호 요청을 받게 됩니다 username(비밀번호 없는 로그인 키를 설정하지 않은 경우).

이 호스트에 정기적으로 액세스하려면 ~/.ssh/config다음 파일에 몇 줄을 추가하여 액세스를 단순화 할 수도 있습니다 yourpublichost.

host firewalledhost
    User firewalleduser
    Hostname localhost
    Port 22222

조정 firewalledhost하고 firewalleduser적응하세요. 이 firewalleduser필드는 원격 서버의 사용자 이름과 일치해야 하지만 firewalledhost귀하에게 적합한 이름이면 됩니다. 연결은 Hostname및 에 의해 제어되므로 이름은 확인 가능한 이름과 일치할 필요가 없습니다 Port.

또는 인터넷의 다른 곳에서 이 콘텐츠에 액세스하려면 다음을 에 추가할 수 있습니다 ~/.ssh/config.

host firewalledhost
    ProxyCommand ssh -fWlocalhost:22222 yourpublichost        

-W옵션은 SSH 세션을 계속하기 위해 원격 호스트에 대한 연결을 여는 데 사용됩니다. 그것은 -N과 를 의미합니다 -T.

또한보십시오:

답변2

나는 몇 가지 스케치를 만들었다.

SSH Tunnel 명령을 입력하는 머신은 다음과 같습니다."당신의 주인".

로컬에서 시작하는 SSH 터널


원격에서 시작하는 SSH 터널

소개하다

  1. 현지의:-L Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side.

    ssh -L sourcePort:forwardToHost:onPort connectToHost의미: SSH를 사용하여 연결 connectToHost하고 모든 연결 시도를 전달합니다.현지의 sourcePortonPort포트에 접근할 수 forwardToHost있는 이름의 컴퓨터 포트에 연결합니다 .connectToHost

  2. 외딴:-R Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side.

    ssh -R sourcePort:forwardToHost:onPort connectToHost의미: SSH를 사용하여 연결 connectToHost하고 모든 연결 시도를 전달합니다.외딴 sourcePortonPortforwardToHost로컬 컴퓨터에서 액세스할 수 있는 컴퓨터의 포트에 연결합니다 .

다른 옵션

  • -f인증 후 ssh에 직접 백그라운드로 들어가도록 지시하면 원격 서버에 앉아 터널을 유지하기 위해 무언가를 실행할 필요가 없습니다.
  • -NSSH 연결을 원하지만 실제로는 원격 명령을 실행하고 싶지 않음을 나타냅니다. 생성 중인 것이 터널뿐인 경우 이 옵션을 포함하면 리소스를 절약할 수 있습니다.
  • -T대화형 셸을 생성하려는 것이 아니기 때문에 적절한 pseudo-tty 할당을 비활성화합니다.

당신의 모범

세 번째 이미지는 이 터널을 나타냅니다.하지만"Your Host"라는 파란색 컴퓨터는 호스트가 있는 컴퓨터를 나타냅니다.누구SSH 터널(이 경우 방화벽으로 보호되는 컴퓨터)을 시작합니다.

그러니 물어보세요누구컴퓨터에 SSH 터널 연결을 시작합니다. 명령은 기본적으로 다음과 같습니다

ssh -R 12345:localhost:22 YOURIP

이제 터널이 열렸습니다. 이제 다음 명령을 사용하여 터널을 통해 SSH를 통해 방화벽이 있는 시스템에 연결할 수 있습니다.

ssh -p 12345 localhost

자신의 localhost포트(컴퓨터) 에 연결되지만 12345포트는 12345터널을 통해 방화벽이 있는 컴퓨터(즉, 방화벽이 있는 컴퓨터 자체)의 로컬 호스트 포트 22로 전달됩니다.

답변3

SSH 터널링은 설정된 SSH 연결을 사용하여 추가 트래픽을 보내는 방식으로 작동합니다.

원격 서버에 연결할 때 일반적으로 일반적인 사용자 상호 작용에는 채널이 1개만 있습니다(STDIN/STDOUT/STDERR을 독립적으로 간주하는 경우 채널 3개). 로컬 또는 원격 SSH 프로세스는 언제든지 기존 연결에서 추가 채널을 열 수 있습니다. 그런 다음 이러한 채널은 터널 트래픽을 전송/수신합니다. 트래픽을 보내거나 받을 때 ssh 프로세스는 단순히 "이 트래픽은 채널 foobar용입니다"라고 말합니다.

기본적으로 다음과 같이 작동합니다.

  1. ssh에 포트 XXXX에서 수신 대기를 시작하도록 지시하면 수신된 모든 트래픽은 터널링되어 포트 ZZZZ에서 YYYY로 전송되어야 합니다.
  2. 로컬 SSH는 포트 XXXX(일반적으로 에 있지만 127.0.0.1변경 가능)에서 수신 대기를 시작합니다.
  3. 일부 응용 프로그램은 로컬 컴퓨터의 XXXX 포트에 대한 연결을 엽니다.
  4. 로컬 SSH는 원격 SSH에 대한 채널을 열고 "이 채널의 모든 트래픽은 YYYY:ZZZZ로 전송됩니다"라고 말합니다.
  5. 원격 SSH를 YYYY:ZZZZ로 보내고 "확인, 채널이 열려 있습니다"를 다시 보냅니다.
  6. 이제 로컬 시스템의 XXXX 포트에 연결된 모든 트래픽은 생성된 채널을 사용하여 SSH를 통해 YYYY:ZZZZ로 프록시됩니다.

프로세스는 정방향 및 역방향 터널에서 완전히 동일합니다(위 프로세스에서 "로컬"과 "원격"이라는 단어만 바꾸면 됩니다). 어느 쪽이든 터널을 시작할 수 있습니다. SSH를 처음 시작할 필요도 없습니다. SSH가 실행되는 동안 터널을 열 수 있습니다( man ssh자세한 내용은 섹션 참조).ESCAPE CHARACTERS~C

-R-f, 및 무엇을 -L하는지 맨 페이지를 확인해야 합니다 -N. 가장 좋은 설명을 제공합니다. 그러나 나는 언급할 것이다 -R-L.
-R원격 SSH에 연결을 수신하도록 지시하고 로컬 SSH는 실제 대상에 연결해야 합니다. -L로컬 SSH에 연결을 수신하도록 지시하고 원격 SSH는 실제 대상에 연결해야 합니다.

이것은 매우 대략적인 설명이지만 무슨 일이 일어나고 있는지 이해하는 데 충분한 정보를 제공합니다.

답변4

KISS - 귀하의 컴퓨터 = your_computer_ip/your_user_name_at_your_computer 원격 서버 = REMOTE_ip/remote_user_name

ON - /etc/ssh/sshd_config 파일의 VPN 보호 컴퓨터(원격 서버):

AllowTcpForwarding all
PermitTunnel yes

그런 다음 SSH를 다시 ​​시작하십시오.

sudo service ssh restart

(우리는 포트 2222를 다음과 같이 구성했습니다.들어오는ssh 전송) (지속성이 필요하며 tmux 또는 -f 플래그 -> ssh -f -R을 사용할 수 있음) ** 여전히 VPN으로 보호됨 **

ssh -R 2222:localhost:22 your_user_name_at_your_computer@you_computer_ip
  • ** 2222는 임의 포트가 아닙니다! ! **
  • **루트 사용자만 1024 미만의 포트를 열 수 있습니다!!!**

이제 VPN이나 ​​사용한 다른 모든 것에서 연결을 끊을 수 있습니다

컴퓨터에서 터미널을 엽니다

이제 컴퓨터의 포트 2222가 원격 호스트에 매핑되었습니다!

ssh localhost -p 2222 -l remote_user_name

관련 정보