역방향 SSH 터널링은 어떻게 작동합니까?


350

이것을 이해하면서 방화벽 (기본 설정 가정)은 이전에 해당하는 나가는 트래픽이없는 들어오는 트래픽을 모두 거부합니다.

ssh 연결 취소 및 SSH 터널링 용이 화를 기반으로 역 SSH 터널링을 사용하여 성가신 방화벽 제한을 극복 할 수 있습니다.

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

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

스위치 (의 역할은 무엇이며 -R, -f, -L,는 -N)?


답변:


402

시각화를 통해 이런 종류의 설명을 좋아합니다. :-)

SSH 연결을 튜브로 생각하십시오. 큰 튜브. 일반적으로이 튜브를 통해 원격 컴퓨터에서 쉘을 실행할 수 있습니다. 셸은 가상 터미널 (tty)에서 실행됩니다. 하지만이 부분은 이미 알고 있습니다.

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

모든 튜브에는 시작과 끝이 있습니다. 큰 튜브 인 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 클라이언트)의 관점에서옵니다.

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

  • -f 인증 후 ssh에 백그라운드를 지정하도록 지시하므로, 터널이 활성 상태를 유지하기 위해 원격 서버에서 무언가를 실행하지 않아도됩니다.
  • -NSSH 연결을 원하지만 실제로 원격 명령을 실행하고 싶지는 않습니다. 작성하는 것이 모두 터널 인 경우이 옵션을 포함하면 자원이 절약됩니다.
  • -T 의사 -tty 할당을 비활성화합니다. 이는 대화식 셸을 만들려고하지 않기 때문에 적절합니다.

비밀번호없는 로그인을 위해 DSA 또는 RSA 키를 설정하지 않으면 비밀번호 문제가 발생합니다.

이 터널 / 고객 / 서버에 대해 설정 한 자신의 로그인이 아닌 일회용 계정을 사용하는 것이 좋습니다.

이제 publichost 의 쉘에서 터널을 통해 방화벽 호스트에 연결하십시오.

ssh -p 22222 username@localhost

이전에는이 ​​호스트를 공격 한 적이 없기 때문에 호스트 키 문제가 발생합니다. 그런 다음 username비밀번호없는 로그인을위한 키를 설정하지 않은 경우 계정에 대한 비밀번호 확인 요청이 표시 됩니다.

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

host remotehostname
    User remoteusername
    Hostname localhost
    Port 22222

조정 remotehostname하고 remoteusername적합하십시오. 이 remoteusername필드는 원격 서버의 사용자 이름과 일치해야하지만 사용자 remotehostname에게 적합한 호스트 이름 일 수 있으며 해결 가능한 항목과 일치 할 필요는 없습니다.

( 로컬 호스트아닌 IP 에서 역방향 끝점을 노출하려면 이 게시물을 확인하십시오 )


2
ssh -D는 어떻습니까? 같은 방법으로 설명하십시오.
BigSack

6
SOCKS 프록시는 터널과 다릅니다. 사용 방법에 대해 궁금한 점이 있으면 문의하십시오 .
ghoti

12
서버, 클라이언트, 로컬 컴퓨터, 원격 컴퓨터, 호스트, yourpublichost, localhost, remotehostname이라는 용어를 느슨하게 사용했기 때문에이 설명을 따르는 데 어려움을 겪고 있습니다. 이 느슨하고 정의되지 않은 용어가 있으면이를 설정하려면 누군가 최대 8 대의 컴퓨터가 필요하다고 가정 할 수 있습니다. 나는 다른 모든 측면에서 아주 좋은 설명처럼 보이기 때문에 이것을 언급합니다. 용어를 줄이고 정의하십시오.
Rucent88

4
@ Rucent88, 어떤 축소가 가능한지 잘 모르겠습니다. 클라이언트가 서버에 연결합니다. 그것은 네트워킹 세계에서 공통된 용어입니다. 로컬 및 원격 컴퓨터는 자명 한 것처럼 보입니다. 문서를 읽은 후 SSH 또는 일반 유닉스 용어에 대해 혼란 스러우면 여기에서 사람들이 질문에 대한 답변을 기꺼이 찾는 데 어려움을 겪지 않을 것입니다.
ghoti

9
@ghoti 로컬 컴퓨터와 원격 컴퓨터가 상대적이기 때문에 혼란 스럽습니다. 직장에 앉아있을 때 집에있는 컴퓨터는 리모컨이고 집에 앉아있을 때 직장 컴퓨터는 멀리 있습니다. 터널링을 말할 때 서버와 클라이언트도 혼동됩니다. 예를 들어 ssh -R을 사용하여 직장에서 집에 연결하는 경우. localhost를 연결하여 가정용 컴퓨터에서 작업에 연결합니다. 소켓 관점에서 서버는 가정용 컴퓨터입니다. 그러나 논리적으로 저는 업무용 컴퓨터에 연결했습니다. 혼란 스럽습니다.
Calmarius

357

스케치를 그렸습니다

ssh tunnel 명령이 입력 된 머신은 »your host« 입니다.

로컬에서 시작하는 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모든 연결 시도를 라는 기계 의 로컬 sourcePort 포트 onPort로 전달하십시오. 이 포트 는 기계 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 to connectToHost에 연결하고 모든 연결 시도를 원격 컴퓨터 로 전달하여 로컬 컴퓨터에서 도달 할 수있는 컴퓨터의 sourcePort포트 onPort로 전달하십시오 forwardToHost.

추가 옵션

  • -f 인증 후 ssh에 백그라운드를 지정하도록 지시하므로, 터널이 활성 상태를 유지하기 위해 원격 서버에서 무언가를 실행하지 않아도됩니다.
  • -NSSH 연결을 원하지만 실제로 원격 명령을 실행하고 싶지는 않습니다. 작성하는 것이 모두 터널 인 경우이 옵션을 포함하면 자원이 절약됩니다.
  • -T 의사 -tty 할당을 비활성화합니다. 이는 대화식 셸을 만들려고하지 않기 때문에 적절합니다.

당신의 예

세 번째 이미지는이 터널을 나타냅니다. 그러나 "호스트"라는 파란색 컴퓨터는 누군가 가 ssh 터널을 시작하는 컴퓨터 ( 이 경우 방화벽 컴퓨터)를 나타냅니다.

따라서 누군가 에게 컴퓨터에 대한 ssh 터널 연결을 시작 하도록 요청 하십시오. 명령은 기본적으로 다음과 같아야합니다

ssh -R 12345:localhost:22 YOURIP

이제 터널이 열립니다. 이제 명령을 사용하여 ssh를 통해 터널을 통해 방화벽 컴퓨터에 연결할 수 있습니다

ssh -p 12345 localhost

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


9
좋은 답변입니다! 이것을 프리젠 테이션에서 사용할 것입니다.
이사야 터너

4
감사합니다. 천만에요. 벡터 이미지 (svg 또는 pdf)를 원한다면 나에게 메시지를 쓰십시오.
erik

1
@ 에릭,이 이미지들을 어떻게 그리 셨나요?
Pacerier

31
오 남자, 나는 man 페이지가 이와 같은 설명을 가질 수 있기를 바란다! 감사!
Lucas Pottersky

30
그거 알아? 나는 텍스트 설명을 읽을 필요조차 없었다. 훌륭한 일 !
deppfx

21

ssh 터널링은 추가 트래픽 전송을 위해 이미 설정된 ssh 연결을 사용하여 작동합니다.

원격 서버에 연결할 때 일반적으로 정상적인 사용자 상호 작용을위한 1 개의 채널 만 있습니다 (또는 STDIN / STDOUT / STDERR을 별도로 고려하면 3 개의 채널). 로컬 또는 원격 ssh 프로세스는 언제든지 기존 연결에서 추가 채널을 열 수 있습니다. 그런 다음이 채널은 터널 트래픽을 보내거나받습니다. 트래픽을 보내거나받을 때 ssh 프로세스는 단순히 "이 트래픽은 채널 foobar에 대한 것"이라고 말합니다.

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

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

이 과정은 정방향 및 역방향 터널링에서 모두 동일합니다 (위 절차에서 'local'및 'remote'라는 단어 만 바꾸십시오). 어느 쪽이든 터널을 시작할 수 있습니다. ssh를 처음 시작할 때조차 필요하지 않습니다. ssh가 이미 실행중인 동안 터널을 열 수 있습니다 ( ESCAPE CHARACTERS특히 참조 ~C).

의 역할에 대해 -R, -f, -L, 그리고 -N, 당신은 정말 매뉴얼 페이지를 참조해야합니다, 그것은 당신에게 최상의 설명을 제공합니다. 그러나 나는 말할 것이다 -R-L.
-R원격 ssh에게 연결을 수신하고 로컬 ssh가 실제 대상에 연결하도록 지시합니다. -L로컬 ssh에게 연결을 수신하도록 지시하고 원격 ssh는 실제 대상에 연결해야합니다.

이것은 매우 조잡한 설명이지만 진행 상황을 알 수있는 충분한 정보를 제공해야합니다.


16

이것은 SSH 매뉴얼, 특히 -L(로컬)과 -R(원격) 의 차이점에 설명되어 있습니다 .


-L

-L [bind_address:]port:host:hostport

하도록 지정 로컬 (클라이언트)에 대한 호스트 특정 포트가 원격 측에 지정된 호스트 및 포트로 전달한다 .

이것은 로컬 측의 포트를 청취하도록 소켓을 할당하고, 선택적으로 지정된 bind_address에 바인드함으로써 작동합니다.

연결이이 포트에 만든 때마다 연결이 전달됩니다 보안 채널을 통해, 그리고 연결이 만들어 host포트 hostport원격 시스템에서 .

다음 예제는 포트 1234를 사용하여 클라이언트 시스템 127.0.0.1( localhost)에서 원격 서버 로 IRC 세션을 터널링 합니다 server.example.com.

$ ssh -f -L 1234:localhost:6667 server.example.com sleep 10

참고 : -f옵션 backgrounds ssh 및 remote 명령 sleep 10은 터널링 될 서비스를 시작할 시간을 허용하도록 지정됩니다.

예:

ssh `-N` -L 22000:localhost:11000 remote.server.com
  • -N 연결 한 후 바로 전화를 끊습니다 (쉘 프롬프트가 표시되지 않음).

    원격 명령을 실행하지 마십시오.

  • -L 22000연결은 개인용 L ocal 시스템 의 포트 22000에서 시작됩니다.

  • localhost:11000- remote.server.com터널의 다른 쪽 끝이 localhost포트 인지 확인합니다.11000

ssh -N -L 22000 : 192.168.1.2 : 11000 remote.server.com

출처 : ssh tunneling에 대한 설명 된 가이드, 자습서, 방법 .


-R

-R [bind_address:]port:host:hostport

하도록 지정 원격 (서버)에 지정된 호스트 포트 로컬 측에 지정된 호스트 및 포트로 전달한다 .

이것은 듣는 소켓을 할당하여 작동하는 port원격 측에, 그리고 연결이이 포트에 될 때마다, 연결이 전달됩니다 보안 채널을 통해, 그리고 연결이 만들어 host포트 hostport로컬 컴퓨터에서 .

예:

ssh -N -R 22000:localhost:11000 remote.server.com
  • -N 연결 한 후 바로 전화를 끊습니다 (쉘 프롬프트가 표시되지 않음).

    원격 명령을 실행하지 마십시오.

  • -R22000 연결이 포트 (22000)에 기인한다 R의 감정 표현 컴퓨터 (이 경우 remote.server.com)

  • localhost:11000개인 로컬 컴퓨터는 터널의 다른 쪽 끝이 localhost포트 인지 확인합니다11000

ssh -N -R 22000 : localhost : 11000 remote.server.com

출처 : ssh tunneling에 대한 설명 된 가이드, 자습서, 방법 .


6
귀와 입이 누가 말하고 누가 듣고 있는지 분명하게 보여줍니다!
Thufir

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