「한빛 네트워크 기사 공모전」 가작: 이호재
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, The Secure Shell: The Definitive Guide |
보통 사용자들은 위에서 말했던 것처럼 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이라고도 부르는데 다음 그림을 보면 이해하기가 쉬울 것이다.
[그림 1] 『SSH, The Secure Shell: The Definitive Guide』 317p 참고, SSH 포워딩
그렇다면 이것이 무슨 의미가 있을까? 이 터널을 이용한다는 것은 곧 암호화 등의 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 서버명
[그림 2] 『SSH, The Secure Shell: The Definitive Guide』 329p 참고, Local port forwarding
$ ssh -R포트번호1:호스트명:포트번호2 서버명이때 포트번호1은 SSH 서버가 검사(Listen)하고 있게 되고 여기로 데이터가 왔을 때 SSH 클라이언트에게 이 데이터를 전해주고, SSH 클라이언트는 호스트명의 포트번호2로 데이터를 전송하게 된다. 이때에는 호스트명이 SSH 클라이언트 입장에서 호스트명이다. 아래 [그림 3]은 Remote port forwarding을 나타낸다.
[그림 3] 『SSH, The Secure Shell: The Definitive Guide』 329p 참고, Remote port forwarding
첫째 터널링을 이용하여 방화벽을 우회하는 방법에 대해 알아보자. 요즈음은 보안이 중요시되고 있어 회사에서는 방화벽이 설치되어 있는 곳이 많다. 서버, PC, 그리고 그 사이에도 방화벽이 있을 수 있다. 만약 방화벽이 설치 되어 있어 우리가 원하는 서비스에 접속할 수 없다면 그냥 그렇게 살아야 할까? 아니다. SSH 서비스가 방화벽에 의해 차단되지 않는다면 가능성은 있다. 바로 터널링인 것이다. 다음 [그림 3]을 살펴보자.
[그림 4] 『SSH, The Secure Shell: The Definitive Guide』 333p 참고, 터널링을 이용한 방화벽 우회
실제 예를 들어서 설명해보자. 사용자의 컴퓨터에서 www.netsarang.co.kr의 홈페이지에 접속하길 원한다고 하자. 그런데, 관리자가 사용자의 네트워크 환경에서는 웹서핑을 하지 못하도록 80번 포트를 막아 놓았다고 하자. 하지만 SSH 포트인 22번은 열려있다. 그리고 SSH 서버가 설치되어 있는 외부 서버가 있고 거기에는 방화벽이 없다고 하자. Xshell을 이용하여 설정을 하도록 하겠다. 우리의 목표는 http://www.netsarang.co.kr 홈페이지를 방문하는 것이라고 가정하면 다음과 같이 설정을 하면 된다. 처음이므로 자세히 설명을 하겠다. 우선 Xfile의 메인화면이다. 여기서 New를 선택해서 새로운 세션을 만들도록 하겠다.
여기에서 Add를 누르고 다음 그림처럼 터널링(Local Forwarding)을 설정하도록 하자.
위에서 SSH 클라이언트가 있는 곳의 8080번 포트로 접속을 하면 SSH 서버가 있는 곳에서 www.netsarang.co.kr의 80번 포트로 데이터를 넘겨 주도록 Local forwarding 설정을 하였다. 이렇게 한 후 SSH 서버에 접속을 하면 터널이 열리게 된다. SSH 서버에 접속후 윈도우에서 다음과 netstat -a 명령어로 8080번 포트를 SSH 클라이언트가 검사하고 있는지 확인할 수 있다.
위 그림에서 볼 수 있듯이 8080번 포트가 LISTENING 상태로 정상적인 터널이 열렸다. 이제는 다음 그림처럼 http://localhost:8080/에 접속을 하면 우리가 원하는 홈페이지를 볼 수 있다.
이는 간단한 예이므로 이를 응용해서 유용하게 사용할 수 있을 것이다. 여기서 잠시 투명성(Transparency)에 대해서 알아보자. 외부에서 볼 때 내부적으로 어떤 일이 일어나는지를 전혀 몰라도 될 때 투명성이 있다고 부른다. SSH 터널링은 이를 이용하는 프로그램에게는 투명성을 제공하지만 사용자에겐 제공하지 않는다. 위의 예에서 웹브라우저는 지금 터널링을 통해 접속하는지 여부를 전혀 모른다. 하지만 사용자는 알아야 한다. 정상적인 http://www.netsarang.co.kr/ 대신 http://localhost:8080/을 사용했기 때문이다.
둘째, 터널링을 이용하여 안전하게 메일을 송수신 하는 방법을 알아보자. 보통 메일을 수신할 때에는 POP3(110번 포트)를 사용하고 송신할 때에는 SMTP(25번 포트)를 사용한다. 메일 서버 설정이 로컬에서만 POP3와 SMTP 포트로 접속이 가능하게 되어있고 외부에서는 접근할 수 없게 되어 있다고 하자. 이때 SSH 서버가 동작한다면 터널링을 사용하여 우리가 원하는 작업을 할 수 있다.(첫번째 경우와 같다.) 여기서 더욱 중요한 것은 보안이다. 기본적으로 POP3와 SMTP의 경우 아이디, 암호, 데이터 등이 전송될 때 암호화되지 않고 그대로 전송이 된다. 누군가 중간에서 엿듣는 다면 중요한 데이터를 훔쳐갈 수도 있는 보안상 취약점이 있는 것이다. 이럴 때에 터널링을 이용한다면 터널을 통과하는 동안에는 안심할 수 있다. 하지만, 메일 클라이언트와 SSH 클라이언트 사이, SSH 서버와 메일 서버 사이에는 터널이 없으므로 데이터가 암호화되지 않은 상태로 전달이 되고 보안상 취약할 수 있음을 유의하기 바란다. 그래서 터널링을 할 때 보안이 목적이라면 SSH 서버에서 외부로 포워딩을 하지 않는 것이 좋다.
실제 테스트를 해보도록 하자. 다음과 같이 터널링(Local Forwarding)을 설정하자.
이번에는 로컬호스트의 1025, 1110번 포트로 오는 데이터를 각각 서버(서버의 로컬호스트는 서버 자신이므로)의 25, 110번 포트로 포워딩하도록 설정하였다. 아웃룩에서 메일을 가져오는 것을 가정해보자. 아웃룩 설정을 다음과 같이 한다.
받는 메일과 보내는 메일에 실제 메일 서버가 아닌 localhost로 등록을 하였다. 아웃룩에서 POP3 포트와 SMTP 포트 설정을 1110과 1025로 바꾼다.
이제 모든 설정이 다 끝났다. 이번 역시 아웃룩이란 프로그램에는 SSH가 투명성을 제공하지만 사용자에겐 그렇지 못하다는 것을 알 수 있다. 메일을 확인하고 싶을 때 우선 SSH 클라이언트로 해당 서버에 접속한다. 터널을 만들어야 하기 때문이다. 터널은 일반적으로 처음 접속을 할 때에만 열리게 되어있고, 서버와 클라이언트 사이에 SSH 연결이 되어 있는 동안 유효하다. 중간에 설정을 바꾼다고 해서 터널이 생기거나 없어지지는 않는다. 접속을 하면 다음에서 보는 바와 같이 터널이 생긴 것을 알 수 있다.
그림에서 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), 한빛미디어
- 『현대암호학』 이민섭, 교우사