ssh는 Secure SHell의 축약 형태로 만들어진 이름인데, 기원으로 보자면 원격지 서버에서 명령을 수행하기 위한 r* 명령어 가족 중 rsh(Remote SHell)의 보안 관점의 취약점을 개선하여 통신계층을 암호화한 일종의 "원격 쉘"이다. 그런데, 이 보안 원격 쉘의 기능을 이용하여 ssh 연결을 타 서비스 연결을 위한 터널로 활용할 수 있다.

가정하는 상황은 다음과 같다.

  • 내가 접근하려는 서버는 192.168.10.0/24 망에 있고,
  • 나에게는 192.168.10.2 서버(A)의 ssh 접근만 허용되어 있다.
  • 그런데 나는, 같은 서버의 허용되지 않은 8100 포트(WAS 관리용)와 같은 네트워크 내의 192.168.10.4 서버(B)에 ssh 접속을 하고 싶다.

정리하면, 나는 192.168.10.2:22 로 접근할 수 있고 192.168.10.2:8100과 192.168.10.4:22로 추가 접속을 원한다. 그렇다면, 다음과 같은 옵션을 사용하여 (A)를 통과하여(Tunnel) (B)까지 접속할 수 있다.

$ ssh user@192.168.10.2 -L48100:192.168.10.2:8100 -L40022:192.168.10.4:22
위의 명령을 보면, -L 옵션을 이용하여 Local Port Forwarding을 지정하고 있으며, 그 자세한 뜻은 아래와 같다.
옵션 Local Port Remote Addr Remote Port
-L48100:192.168.10.2:8100 48100 192.168.10.2 8100
Local 48100 포트로 들어오는 접속을 ssh 접속을 경유하여 원격지에서 접근 가능한 192.168.10.2 서버의 8100 포트로 돌림
-L40022:192.168.10.4:22 40022 192.168.10.4 22
Local 40022 포트로 들어오는 접속을 ssh 접속을 경유하여 원격지에서 접근 가능한 192.168.10.4 서버의 8100 포트로 돌림

이렇게 ssh를 써서 Tunnel을 만들고 나면, 다음과 같이 원하는 접속을 할 수 있다.

ssh-tunnel-web.png
웹 접속 예시
$ ssh -p 40022 user@localhost
ssh 접속 예시

해보면 쉬운 얘기인데 설명이 더 어렵다. 위의 연결 구조를 그림으로 보면 다음과 같다.

ssh-tunnel.png
ssh tunnel diagram

이 때, 당연한 얘기인데, 최종 접속 대상이 되는 서버에서는 각 연결을 192.168.10.2로부터의 연결로 인식하게 된다.

ssh는 위와 같은 Local Port Forwarding 외에도 Remote Port에 대한 Forwarding을 통해서 접근한 서버로부터 이 쪽(Client 쪽)에 위치한 서버로의 접속을 만들어 낼 수도 있고, 별도로 기술한 바 있는 간단한 SOCK Proxy를 구현할 수도 있다.