역방향 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.