원격 포트 전달을 통한 Jumphost를 통한 SSH 세션

원격 포트 전달을 통한 Jumphost를 통한 SSH 세션

원격 포트 전달을 통해 SSH 연결을 수행하는 데 문제가 있습니다.

시나리오는 내부 네트워크("원본"이라고 함)의 서버가 SSH를 통해 DMZ("대상")에 있는 서버에 로그인해야 하는 엔터프라이즈 네트워크입니다. DMZ의 대상 서버는 내부 네트워크로부터의 연결을 위해 잠겨 있으므로(그리고 내부 네트워크에서도 볼 수 없음) 우리가 통과하는 DMZ에는 점프 호스트("jumphost")가 있습니다. 점프호스트에서 원격 포트 전달을 설정하여 이를 수행합니다.

내부 네트워크의 원본 서버에서 점프 호스트로 이 명령을 실행합니다.

origin> ssh -R *:1234:target:22 myusername@jumphost

이는 점프호스트에서 SSH 세션을 설정하고 포트 1234(임의의 포트 번호 예)에서 수신 대기를 시작한 다음 해당 포트의 연결을 대상 서버 포트 22(SSH)로 전달하는 것입니다.

그런 다음 원본 서버에서 점프 호스트까지 포트 1234에서 두 번째 SSH 세션을 설정합니다. 그러면 실제로 포트 22에서 대상 서버에 연결됩니다. 이것이 작업을 수행할 수 있는 '실제' SSH 세션입니다. 대상 서버:

origin> ssh jumphost -P 1234

구성

점프 호스트는 sshd_config에서 다음 설정을 사용하여 원격 포트 전달을 허용하도록 구성되었습니다.

AllowTcpForwarding yes
GatewayPorts yes

또한 원본 서버와 점프 호스트 사이에는 포트 22(원격 포트 전달을 설정하기 위한 초기 SSH 연결용)와 포트 1234(전달된 포트의 후속 SSH 연결용)에 대한 방화벽 개방이 있습니다. 점프호스트와 대상 사이에는 포트 22에서 열린 방화벽도 있습니다.

결과

두 번째 연결(전달된 포트를 통한 연결)을 설정하면 연결이 즉시 닫힙니다('원격 호스트에 의해 닫힌 연결').

대상 서버에서 tcpdump를 실행하면 활동이 표시되지 않습니다. 즉, 연결이 차단된 것 같습니다.

그러나 점프호스트에서 대상까지 일반 SSH 세션을 성공적으로 설정할 수 있습니다. 전달된 포트를 통해 들어오는 경우에만 연결이 닫히지만 둘 다 포트 22의 대상에 연결됩니다.

게다가 포트 전달 지점을 내부 네트워크의 서버로 설정하면(즉, 내부 네트워크의 원본에서 DMZ의 점프 호스트로 연결하고 다시 내부 네트워크의 세 번째 서버로 연결) SSH는 세션이 성공적으로 설정되었습니다.

추측과 질문

이 모든 것은 점프 서버의 전달된 포트를 통해 DMZ 내의 대상 서버에 연결하는 것을 방지하는 일부 네트워크 보안 설정이 작동 중이라고 믿게 만듭니다. 불행히도 나는 다음 사항을 알 만큼 지식이 부족합니다.

(1) 원본 서버에서 점프 서버의 전달된 포트를 통해 들어오는 SSH 연결은 네트워크 보안 정책 관점에서 '다르게' 기술적으로 차단될 수 있습니까? 그렇다면 어떻게 차단됩니까? 그리고 그 제한을 해제하려면 어떻게 해야 합니까?

(2) 방화벽 구성, 라우터 구성, 원본 또는 점프 호스트의 SSH 설정 등 이 연결이 허용되지 않는 다른 이유가 있습니까?

(3) 원본 서버가 대상 서버를 알지 못하여 첫 번째 ssh 명령이 의도한 대로 작동하지 않아 실패할 수 있습니까? 즉, 첫 번째 ssh 명령("target")에 지정된 호스트 이름이 클라이언트(원본) 또는 터널을 생성하기 위해 연결하는 서버(점프 호스트)에서 해석됩니까?

저를 가장 당황하게 만드는 것은 점프 호스트에서 대상으로 일반 SSH 세션을 설정할 수 있다는 것입니다. 전달된 포트를 통해 들어오는 SSH 연결은 동일할 것이라고 생각하지만 어쨌든 그렇지 않습니다.

어떤 의견이라도 대단히 감사하겠습니다.

답변1

원격 포트 포워딩 대신 로컬 포트 ​​포워딩을 사용해야 할 것 같습니다. Dirk Loss의 다음 유용한 블로그 게시물을 참조할 수 있습니다.

여기에는 다음 예시 다이어그램이 포함됩니다.

SSH 포트 전달: 로컬 대 원격

다이어그램을 읽으려면 SSH 터널 생성 및 활용과 관련된 4가지 역할 간의 관계를 설명한다는 점을 알아야 합니다.

  • 터널을 설정하는 데 사용되는 SSH 클라이언트(예 ssh: OpenSSH 명령줄 클라이언트)
  • sshd터널의 다른 쪽 끝을 유지하는 데 사용되는 SSH 서버(예 : OpenSSH 서버 데몬)
  • 애플리케이션 서버(예: 다른 SSH 서버 또는 http 서버);
  • 터널을 통해 애플리케이션 서버에 액세스하려는 애플리케이션 클라이언트(예: 다른 SSH 클라이언트 또는 웹 브라우저).

두 가지 전달 유형이 두 가지 사용 사례에 해당한다는 점을 이해하는 것도 중요합니다.

  • 로컬 전달: 애플리케이션 클라이언트가 SSH 클라이언트를 통해 연결하는 경우

  • 원격 전달: 애플리케이션 클라이언트가 SSH 서버를 통해 연결하는 경우

원격 전달은 전달이 로컬(ssh 클라이언트)이 아닌 원격(ssh 서버)에서 수행되기 때문에 그렇게 불립니다. 나는 또한 "원격 전달 = 역방향 전달"이 유용한 니모닉이라고 생각합니다.

보시다시피 호스트 ssh의 클라이언트에서 프록시의 서버를 origin통해 세 번째 호스트로 연결을 시작하려면 로컬 포트 ​​전달을 사용해야 합니다. 원격 포트 전달은 터널에 대한 진입점이 클라이언트 를 실행하는 호스트가 아닌 서버를 실행하는 호스트에 위치하도록 하려는 경우에 사용됩니다 .sshdjumphosttargetsshdssh

매뉴얼 페이지에서 로컬 포트 ​​전달 구문은 다음과 같이 작성됩니다.

ssh -L [bind_address:]port:host:hostport user@remote

이는 다음과 같이 보다 직관적으로 작성할 수 있습니다.

ssh -L [local_bind_address:]local_port:remote_host:remote_host_port user@proxy_host

또는 명명 규칙을 사용하여:

ssh -L [origin_bind_address:]origin_port:target_host:target_host_port user@jump_host

대신 로컬 포트 ​​전달을 사용하도록 명령을 수정하면 다음과 같이 끝납니다.

user@origin:~$ ssh -L *:1234:target:22 myusername@jumphost

관련 정보