메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

SSH Tunneling 사용하기

한빛미디어

|

2002-11-22

|

by 이호재

72,911

SSH(Secure Shell)는 네트워크 보안에 있어 대중적이고 강력한 접근 방식을 제공하기 위해 만들어진 프로토콜이다. SSH에 기반한 제품은 서버와 클라이언트의 한 쌍으로 구성되어 있는데, 보통 사용자들은 SSH 클라이언트를 rsh (remote shell) 대용이나 telnet 대용으로 사용하고 있다. 이번 기사에서는 SSH의 간략한 소개와 이를 이용해서 할 수 있는 편리하고 유용한 작업들을 알아보도록 하겠다. 

 

Secure Shell이라는 이름에서 알 수 있듯이 SSH는 보안을 염두에 두고 만들어진 프로토콜이다. (유닉스/리눅스에서의 shell과 이름이 같지만, 이러한 종류의 shell은 아니다.) SSH 프로토콜은 다음과 같은 인증(Authentication), 암호화(Encryption), 무결성(Integrity), 압축(Compression) 등을 제공한다.

  • 인증(Authentication)사용자와 서버를 인증한다. 사용자는 SSH 서버에 접속할 때 신분을 증명해야 하는데, 전통적인 패스워드 인증 방식과 더불어 RSA, DSA등 공개키 방식의 인증 방법도 지원한다. 또한 SSH 클라이언트는 처음 접속한 서버의 키를 저장함으로써 서버가 변경되었을 경우에도 이를 판별할 수 있다.
  • 암호화(Encryption)보통의 다른 서버/클라이언트 방식의 접속과 달리 SSH는 네트워크를 통해 전달되는 데이터를 암호화한다. 그래서 누군가 중간에서 데이터를 가로채더라도 내용을 알 수가 없다. 3DES, blowfish 등의 대칭키 방식의 암호화 방식을 제공하고 새로운 암호화 기법을 추가할 수 있게 설계되어 있다.
  • 무결성(Integrity)네트워크를 통해 받은 데이터가 변경되지 않았음을 보장한다. 누군가 데이터를 가로채서 다른 정보를 보내는 것을 방지할 수 있다. MAC(Message Authentication Code)을 통해 이를 구현하고 있다.
  • 압축(Compression)SSH 연결을 통해 보낸 데이터를 압축 할 수 있다. SSH 클라이언트/서버 사이에서 데이터를 보내기 전에 압축하고 이를 암호화해서 전송한다. 데이터를 받는 쪽에서는 복호화(decryption)한 후 압축을 해제함으로써 구현한다.

SSH는 위와 같은 훌륭한 기능을 제공하고 있어 보안이 중요시되고 있는 오늘날에 많은 인기를 얻고 있다. 

 

보통 사용자들은 위에서 말했던 것처럼 ssh(편의상 SSH client를 ssh라 부르겠다)를 telnet 대용으로 많이 사용한다. 보안상 문제가 많은 telnet 대용으로 ssh를 사용하는 것은 훌륭한 선택이라 할 수 있다. 사용법도 telnet과 아주 비슷하다. 리눅스의 경우 보통 SSH 클라이언트와 서버가 이미 설치되어 있다. 리눅스에서 사용예를 알아보자.

 

$ ssh 서버명

 

윈도우의 경우 ssh 클라이언트를 기본적으로 제공하지 않는다. 윈도우용 SSH 클라이언트에는 다양한 무료 소프트웨어와 상용 소프트웨어가 있다. 윈도우용 클라이언트는 리눅스용과는 달리 UI를 제공하기 때문에 제품마다 약간씩 차이는 있지만 기능은 다를 것이 없다. 필자가 지금까지 알아본 바로는 국내에서 만든 윈도우용 SSH 클라이언트는 필자가 근무하고 있는 ㈜넷사랑 컴퓨터에서 만든 Xshell을 제외하고는 없는 것으로 알고 있다. PuTTY 등 윈도우용 공개 SSH 클라이언트가 있지만 편의성 측면에서 Xshell을 이용하여 설명하도록 하겠다. (필자의 회사에서 어떠한 대가도 받지 않았음을 밝힌다.) Xshell은 현재 beta 버전이 발표된 상태이며 http://www.netsarang.com에서 평가판을 무료로 다운로드해 사용할 수 있다. 사용방법은 리눅스에서처럼 직접 명령으로 실행할 수도 있고 UI를 통해서도 가능하다. 

 

이제 SSH의 아주 특별하고도 중요한 기능인 터널링(Tunneling)에 대해서 알아보도록 하겠다. Tunneling은 Forwarding이라고도 부르는데 다음 그림을 보면 이해하기가 쉬울 것이다.

 

ssh_tunneling1.gif

[그림 1] 『SSH, The Secure Shell: The Definitive Guide』 317p 참고, SSH 포워딩

 

위 [그림 1]에서처럼 Host A에는 SSH 클라이언트가 설치되어 있고 Host B에는 SSH 서버가 설치되어 있다고 하자. SSH 클라이언트를 통해 SSH 서버에 접속을 하면 둘 사이에 연결이 이루어지는데 이 연결 통로를 터널이라고 한다. 암호화 등을 통해 터널처럼 외부로부터 이 연결을 보호하기 때문이다. 그래서 터널링이라고 부른다. 여기서 중요한 사실은 이러한 SSH를 통해 만든 터널을 다른 애플리케이션이 이용할 수가 있다는 것이다. 이러한 일을 가능하게 하는 것이 포트 포워딩(Port Forwarding)이란 기술이므로 포워딩이라고도 부른다. 

 

그렇다면 이것이 무슨 의미가 있을까? 이 터널을 이용한다는 것은 곧 암호화 등의 SSH의 장점을 모두 사용할 수 있다는 것을 의미한다. 즉, 암호화를 지원하지 않는 프로그램을 안전하게 사용할 수 있다는 것이다. (참고로 TCP를 사용하는 프로그램만 지원하고 UDP 등 다른 프로토콜은 지원하지 않는다.) 다시 위의 [그림 1]을 살펴보도록 하자. Host A의 application client가 Host B의 application server로 접속할 때에 일반적으로는 직접 접속(direct connection)을 한다. 하지만 SSH 터널링을 이용하면 application client가 SSH 클라이언트에 접속을 하고 필요한 데이터를 SSH 서버를 통해 application server에 전달한다. 즉 그림에서처럼 forwarded connection을 하게 된다. 터널링은 SSH 클라이언트가 SSH 서버에 접속되어 있을 때에만 유효하고, 연결시에만 설정할 수 있다는 것에 유의하자. 

 

터널링에 대해서 좀 더 자세히 알아보도록 하자. 터널링은 크게 Local port forwarding과 Remote port forwarding으로 이루어져 있다. Local port forwarding은 리눅스 클라이언트에서는 다음과 같은 형식으로 사용할 수 있다.

$ ssh -L포트번호1:호스트명:포트번호2 서버명

 

ssh_tunneling2.gif

[그림 2] 『SSH, The Secure Shell: The Definitive Guide』 329p 참고, Local port forwarding

 

포트번호1은 SSH 클라이언트가 검사(Listen)하고 있을 포트번호를 지정하는 것이다. 보통 포트번호1은 1024부터 65535사이의 임의의 숫자로 지정한다. 1부터 1023까지의 포트는 예약된 포트로 보통 수퍼유저만이 지정할 수 있기 때문이다. 이 포트번호1로 데이터가 왔을 때 SSH 클라이언트가 SSH 서버로 데이터를 전송하고, SSH 서버는 이 데이터를 다시 호스트명의 포트번호2로 데이터를 보내준다. 이때 이 호스트명은 서버입장에서의 호스트명이다. 아래 그림을 보면서 이해하도록 하자. Local port forwarding을 사용하면 Host A의 SSH 클라이언트는 사용자가 지정한 로컬 포트를 검사(Listen)하고 있게 된다. Application client가 이 포트로 접속을 하면 SSH 클라이언트는 이 데이터를 Host B에 있는 SSH 서버에 전송하고, 다시 SSH 서버가 application server로 전송하는 것을 보여준다. Remote port forwarding은 이와는 정 반대이다. 우선 리눅스에서는 다음과 같은 형식으로 사용한다.

 

$ ssh -R포트번호1:호스트명:포트번호2 서버명

 

이때 포트번호1은 SSH 서버가 검사(Listen)하고 있게 되고 여기로 데이터가 왔을 때 SSH 클라이언트에게 이 데이터를 전해주고, SSH 클라이언트는 호스트명의 포트번호2로 데이터를 전송하게 된다. 이때에는 호스트명이 SSH 클라이언트 입장에서 호스트명이다. 아래 [그림 3]은 Remote port forwarding을 나타낸다.

 

ssh_tunneling3.gif

[그림 3] 『SSH, The Secure Shell: The Definitive Guide』 329p 참고, Remote port forwarding

 

이젠 터널링의 실제 사용 예에 대해서 알아보도록 하자. 터널링을 이용하여 방화벽을 우회하는 예제와 안전하게 메일을 송수신 하는 예제를 살펴볼 것이다. 

 

첫째 터널링을 이용하여 방화벽을 우회하는 방법에 대해 알아보자. 요즈음은 보안이 중요시되고 있어 회사에서는 방화벽이 설치되어 있는 곳이 많다. 서버, PC, 그리고 그 사이에도 방화벽이 있을 수 있다. 만약 방화벽이 설치 되어 있어 우리가 원하는 서비스에 접속할 수 없다면 그냥 그렇게 살아야 할까? 아니다. SSH 서비스가 방화벽에 의해 차단되지 않는다면 가능성은 있다. 바로 터널링인 것이다. 다음 [그림 3]을 살펴보자.

 

ssh_tunneling4.gif

[그림 4] 『SSH, The Secure Shell: The Definitive Guide』 333p 참고, 터널링을 이용한 방화벽 우회

 

mail reader가 IMAP mail server로 접속을 하려 하는데 IMAP 포트(143번)가 서버에서 방화벽으로 막혀있는 상황이다. 하지만 서버에 SSH 포트(22번)는 열려있다. 이럴 경우 mail reader는 그림에서처럼 터널링을 이용하여 IMAP mail server로 접속이 가능한 것이다. 

 

실제 예를 들어서 설명해보자. 사용자의 컴퓨터에서 www.netsarang.co.kr의 홈페이지에 접속하길 원한다고 하자. 그런데, 관리자가 사용자의 네트워크 환경에서는 웹서핑을 하지 못하도록 80번 포트를 막아 놓았다고 하자. 하지만 SSH 포트인 22번은 열려있다. 그리고 SSH 서버가 설치되어 있는 외부 서버가 있고 거기에는 방화벽이 없다고 하자. Xshell을 이용하여 설정을 하도록 하겠다. 우리의 목표는 http://www.netsarang.co.kr 홈페이지를 방문하는 것이라고 가정하면 다음과 같이 설정을 하면 된다. 처음이므로 자세히 설명을 하겠다. 우선 Xfile의 메인화면이다. 여기서 New를 선택해서 새로운 세션을 만들도록 하겠다.

 

ssh_tunneling5.gif

 

ssh_tunneling6.gif

 

Host에 SSH 서버의 호스트명이나 IP를 적어주면 된다.

 

ssh_tunneling7.gif

 

여기에서 Add를 누르고 다음 그림처럼 터널링(Local Forwarding)을 설정하도록 하자.

 

ssh_tunneling8.gif

 

위에서 SSH 클라이언트가 있는 곳의 8080번 포트로 접속을 하면 SSH 서버가 있는 곳에서 www.netsarang.co.kr의 80번 포트로 데이터를 넘겨 주도록 Local forwarding 설정을 하였다. 이렇게 한 후 SSH 서버에 접속을 하면 터널이 열리게 된다. SSH 서버에 접속후 윈도우에서 다음과 netstat -a 명령어로 8080번 포트를 SSH 클라이언트가 검사하고 있는지 확인할 수 있다.

 

ssh_tunneling9.gif

 

위 그림에서 볼 수 있듯이 8080번 포트가 LISTENING 상태로 정상적인 터널이 열렸다. 이제는 다음 그림처럼 http://localhost:8080/에 접속을 하면 우리가 원하는 홈페이지를 볼 수 있다.

 

ssh_tunneling10.gif

 

이는 간단한 예이므로 이를 응용해서 유용하게 사용할 수 있을 것이다. 여기서 잠시 투명성(Transparency)에 대해서 알아보자. 외부에서 볼 때 내부적으로 어떤 일이 일어나는지를 전혀 몰라도 될 때 투명성이 있다고 부른다. SSH 터널링은 이를 이용하는 프로그램에게는 투명성을 제공하지만 사용자에겐 제공하지 않는다. 위의 예에서 웹브라우저는 지금 터널링을 통해 접속하는지 여부를 전혀 모른다. 하지만 사용자는 알아야 한다. 정상적인 http://www.netsarang.co.kr/ 대신 http://localhost:8080/을 사용했기 때문이다. 

 

둘째, 터널링을 이용하여 안전하게 메일을 송수신 하는 방법을 알아보자. 보통 메일을 수신할 때에는 POP3(110번 포트)를 사용하고 송신할 때에는 SMTP(25번 포트)를 사용한다. 메일 서버 설정이 로컬에서만 POP3와 SMTP 포트로 접속이 가능하게 되어있고 외부에서는 접근할 수 없게 되어 있다고 하자. 이때 SSH 서버가 동작한다면 터널링을 사용하여 우리가 원하는 작업을 할 수 있다.(첫번째 경우와 같다.) 여기서 더욱 중요한 것은 보안이다. 기본적으로 POP3와 SMTP의 경우 아이디, 암호, 데이터 등이 전송될 때 암호화되지 않고 그대로 전송이 된다. 누군가 중간에서 엿듣는 다면 중요한 데이터를 훔쳐갈 수도 있는 보안상 취약점이 있는 것이다. 이럴 때에 터널링을 이용한다면 터널을 통과하는 동안에는 안심할 수 있다. 하지만, 메일 클라이언트와 SSH 클라이언트 사이, SSH 서버와 메일 서버 사이에는 터널이 없으므로 데이터가 암호화되지 않은 상태로 전달이 되고 보안상 취약할 수 있음을 유의하기 바란다. 그래서 터널링을 할 때 보안이 목적이라면 SSH 서버에서 외부로 포워딩을 하지 않는 것이 좋다. 

 

실제 테스트를 해보도록 하자. 다음과 같이 터널링(Local Forwarding)을 설정하자.

 

ssh_tunneling11.gif

 

이번에는 로컬호스트의 1025, 1110번 포트로 오는 데이터를 각각 서버(서버의 로컬호스트는 서버 자신이므로)의 25, 110번 포트로 포워딩하도록 설정하였다. 아웃룩에서 메일을 가져오는 것을 가정해보자. 아웃룩 설정을 다음과 같이 한다.

 

ssh_tunneling12.gif

 

받는 메일과 보내는 메일에 실제 메일 서버가 아닌 localhost로 등록을 하였다. 아웃룩에서 POP3 포트와 SMTP 포트 설정을 1110과 1025로 바꾼다.

 

ssh_tunneling13.gif

 

이제 모든 설정이 다 끝났다. 이번 역시 아웃룩이란 프로그램에는 SSH가 투명성을 제공하지만 사용자에겐 그렇지 못하다는 것을 알 수 있다. 메일을 확인하고 싶을 때 우선 SSH 클라이언트로 해당 서버에 접속한다. 터널을 만들어야 하기 때문이다. 터널은 일반적으로 처음 접속을 할 때에만 열리게 되어있고, 서버와 클라이언트 사이에 SSH 연결이 되어 있는 동안 유효하다. 중간에 설정을 바꾼다고 해서 터널이 생기거나 없어지지는 않는다. 접속을 하면 다음에서 보는 바와 같이 터널이 생긴 것을 알 수 있다.

 

ssh_tunneling14.gif

 

그림에서 1025와 1110을 LISTENING하고 있는 것을 볼 수 있다. 이제 아웃룩에서 보내기/받기를 누르면 정상적으로 작동하는 것을 확인할 수 있다. 

 

지금까지 SSH에 대한 간단한 설명과 이를 이용한 터널링에 대해 알아 보았다. 이제 여러분도 필요에 따라 터널링을 통해 방화벽을 우회할 수 있고, 데이터를 보다 안전하게 전달할 수 있을 것이다. Happy Life~ 

 

이 글을 쓸 수 있도록 동기를 제공한 필자가 아끼는 수제자에게 이 글을 헌정하고 싶다. 

 

참고자료

  • http://www.ssh.com/
  • http://openssh.com/
  • 『SSH, The Secure Shell: The Definitive Guide』 Daniel J. Barrett & Richard E. Silverman, O'REILLY
  • 『자바 보안과 암호화』 조나단 크누드센(Jonathan Knudsen), 한빛미디어
  • 『현대암호학』 이민섭, 교우사
TAG : SSH ,터널링
댓글 입력
자료실