SSH는 Secure Shell의 약자로 원격지에 있는 컴퓨터를 안전하게 제어하기 위한 프로토콜, 또는 프로토콜을 사용하는 프로그램들. 클라이언트와 서버 사이에 강력한 암호화 방법을 통해 연결되어있어, 데이터를 중간에 가로채도 해석할 수 없는 암호화된 문자만이 노출된다.
리눅스와 Mac 등 유닉스 계열의 운영체제는 기본적으로 SSH 클라이언트가 설치되어 있다. 하지만 윈도우는 SSH 클라이언트가 설치되어 있지 않아, 아래처럼 SSH 클라이언트를 설치해야 한다.
원격지의 컴퓨터는 SSH server가 설치되어있어야 한다. 유닉스 계열은 open SSH가 많이 사용된다. Macdms SSH 클라이언트와 서버가 이미 설치되어 있어 따로 설치하지 않아도 된다.
SSH 프로토콜은 다음과 같은 인증(Authentication), 암호화(Encryption), 무결성(Integrity), 압축(Compression) 등을 제공한다.
인증(Authentication)
사용자와 서버를 인증한다. 사용자는 SSH 서버에 접속할 때 신분을 증명해야 하는데, 전통적인 패스워드 인증 방식과 더불어 RSA, DSA등 공개키 방식의 인증 방법도 지원한다. 또한 SSH 클라이언트는 처음 접속한 서버의 키를 저장함으로써 서버가 변경되었을 경우에도 이를 판별할 수 있다.
암호화(Encryption)
보통의 다른 서버/클라이언트 방식의 접속과 달리 SSH는 네트워크를 통해 전달되는 데이터를 암호화한다. 그래서 누군가 중간에서 데이터를 가로채더라도 내용을 알 수가 없다. 3DES, blowfish 등의 대칭키 방식의 암호화 방식을 제공하고 새로운 암호화 기법을 추가할 수 있게 설계되어 있다.
무결성(Integrity)
네트워크를 통해 받은 데이터가 변경되지 않았음을 보장한다. 누군가 데이터를 가로채서 다른 정보를 보내는 것을 방지할 수 있다. MAC(Message Authentication Code)을 통해 이를 구현하고 있다.
압축(Compression)
SSH 연결을 통해 보낸 데이터를 압축 할 수 있다. SSH 클라이언트/서버 사이에서 데이터를 보내기 전에 압축하고 이를 암호화해서 전송한다. 데이터를 받는 쪽에서는 복호화(decryption)한 후 압축을 해제함으로써 구현한다
서버에 접속할 때 비밀번호 대신 key를 제출하는 방식이다.
SSH key는 공개키와 비공개키로 이루어져있는데, 이 두 관계를 이해하는 것이 핵심이다.
키를 생성하면 공개키와 비공개키가 만들어진다. 비공개키는 로컬 머신에 위치해야 하고, 공개키는 원격 컴퓨터에 위치해야 한다.
SSH 접속을 시도하면 SSH client가 로컬 머신의 비공개키와 원격 컴퓨터의 비공개키를 비교해서 둘이 일치하는지 확인한다.
SSH Tunneling 혹은 SSH Port Forwarding이라고도 부른다. 특정 포트로 들어오는 접속을 SSH를 이용해서 통신하게 하는 방법이다.
SSH 클라이언트를 통해 SSH 서버에 접속을 하면 둘 사이에 연결이 이루어지는데 이 연결 통로를 터널이라고 한다. 이러한 SSH를 통해 만든 터널을 다른 애플리케이션이 이용할 수가 있다. 이러한 일을 가능하게 하는 것이 포트 포워딩(Port Forwarding)이란 기술이므로 포워딩이라고도 부른다.
터널을 이용한다는 것은 곧 암호화 등의 SSH의 장점을 모두 사용할 수 있다는 것을 의미한다. 즉, 암호화를 지원하지 않는 프로그램을 안전하게 사용할 수 있다는 것이다. (참고로 TCP를 사용하는 프로그램만 지원하고 UDP 등 다른 프로토콜은 지원하지 않는다.)
상황
데이터베이스에 접속하려고 한다. 데이터베이스는 Port 3306 포트를 사용한다. 하지만 데이터베이스가 설치된 리눅스는 22번 포트만이 개방되어 있다.
해결책
SSH 터널링을 이용해서 SSH 클라이언트 컴퓨터의 9000번 포트로 접속을 하면 SSH 서버에서는 이 접속을 3306 포트로 포워딩을 해준다. 방화벽에 의해서 차단되지 않은 22번 포트를 이용해서 3306포트를 사용할 수 있게 된 것이다.
일반적으로 사용되는 방식으로 사용자가 로컬 컴퓨터에서 다른 서버로, 즉 SSH(Secure Shell) 클라이언트와 동일한 컴퓨터에서 실행 중인 다른 클라이언트 응용프로그램에서 데이터를 안전하게 전달하기 위해 사용된다. Local port forwarding을 사용하면 특정 웹 페이지를 차단하는 방화벽을 우회할 수 있다.
SSH Client가 설치된 로컬 컴퓨터의 포트를 지정하면, 지정된 로컬 컴퓨터의 포트로 들어오는 접속을 미리 정의된 SSH Server가 설치된 리모트 머신으로 접속시킨 후에 미리 정의된 리모트 머신의 포트로 포워딩해준다.
$ ssh -L포트번호1:호스트명:포트번호2 서버명
포트번호1은 SSH 클라이언트가 검사(Listen)하고 있을 포트번호를 지정하는 것이다. 보통 포트번호1은 1024부터 65535사이의 임의의 숫자로 지정한다. 1부터 1023까지의 포트는 예약된 포트로 보통 수퍼유저만이 지정할 수 있기 때문이다.
포트번호1로 데이터가 왔을 때 SSH 클라이언트가 SSH 서버로 데이터를 전송하고, SSH 서버는 이 데이터를 다시 호스트명의 포트번호2로 데이터를 보내준다. (이때 이 호스트명은 서버입장에서의 호스트명이다. )
Host A의 SSH 클라이언트는 사용자가 지정한 로컬 포트(포트번호1)를 검사(Listen)한다.
Application client가 포트번호1로 접속을 하면 SSH 클라이언트는 이 데이터를 Host B에 있는 SSH 서버에 전송하고, 다시 SSH 서버가 application server로 전송하는 것을 보여준다.
참고
https://www.hanbit.co.kr/channel/category/category_view.html?cms_code=CMS5064906327&cate_cd=
https://opentutorials.org/module/432/3746