목공책 하나 들이셔요~

2014년 6월 13일 금요일

SSH 자동 로그인하기

예전에는 유닉스 계열 OS에서 원격 접속을 하기 위해서 Telnet을 많이 이용했습니다. Telnet이 처음 개발된 것이 1969년이니 이 프로그램은 보기 드문 천연기념물 급입니다. 그 당시만 해도 제한적인 사람들만이 네트워크에 연결할 수 있었기 때문에 보안에 관한 고려사항이 없었습니다. 주고 받는 명령 뿐 아니라 심지어 로그인 계정과 암호까지도 평문으로 전달되었습니다. 그래서 해커들은 패킷 분석기를 통해 시스템의 암호를 쉽게 알아낼 수 있었습니다.

Telnet의 취약한 보안 문제를 해결하기 위해 여러가지 대안이 나왔지만 가장 대중적인 대체품은 1995년에 발표된 Secure Shell(이하 SSH)입니다. SSH는 1999년 OpenSSH라는 오픈소스 프로젝트가 릴리즈되면서 대중화되기 시작했으며 현재 사용되는 거의 모든 SSH 구현체는 바로 이 OpenSSH입니다.

SSH는 공개키 암호화 방식(Public Key Cryptography)을 이용하여 암호화된 인증 정보를 교환하며, 주고 받는 일반 통신문도 모두 암호화됩니다. 그러므로 패킷 분석기를 통해서 주고 받는 패킷을 취득하더라도 해석은 하지 못하는 안전한 원격 접속 환경을 제공합니다. 게다가 SSH가 사용하는 22번 포트를 통해 원격 쉘 뿐 아니라 SFTP를 통한 파일 전송도 가능합니다. 하나의 포트만 열어서 거의 모든 관리 기능을 할 수 있으니, 예전의 Telnet + FTP 조합보다 훨씬 안전하고 편리합니다.

게다가 SSH 터널링이라는 막강한 도구가 제공되기도 합니다. (SSH 터널링에 대해서는 다음 기회에 소개 드리겠습니다) 어쨌든 아직도 Telnet을 쓰는 시스템이 있다면 과감하게 정지시키고 SSH로 바꾸어야 합니다.

SSH로 원격 접속을 할 때는 아이디와 암호를 입력해야 합니다. 그런데 동일한 서버 시스템에 계속 접속하는 경우라면 이것이 매우 번거로운 일입니다. 지난 글에서 Expect 툴을 이용하여 자동으로 암호를 입력하는 방법을 소개 드렸는데, 그건 사실 편법에 가깝습니다. 암호가 Expect 스크립트에 노출되어야 하기 때문이죠.

SSH는 매번 암호를 입력하지 않고도 클라이언트에서 생성된 공개키를 접속하고자 하는 서버에 설치하면 그 클라이언트가 자동으로 인증 과정을 거쳐 서버에 접속할 수 있는 방법을 제공합니다. 즉 사용자에게 아이디와 암호를 묻지 않는다는거죠.

이 글에서는 이 방법을 이용하여 SSH로 자동 로그인하는 방법을 알아봅니다.

SSH 로그인 과정을 자동화하기

"클라이언트"에서 "서버"로 접속을 한다고 할 때, SSH 로그인 과정을 자동화한다는 것은 서버에서 클라이언트의 특정 계정에 대해 신뢰할 수 있는 어떤 증명을 가지고 있음을 의미합니다. 만일 서버에 대해 전적인 제어 권한이 있다면 ssh_known_hosts 파일에 접속을 허용하는 클라이언트들의 공개키들을 저장하고 있으면 됩니다. 하지만 대부분의 경우 서버에 대해 제한적인 권한만 가지고 있는 경우가 많으므로 다른 접근법이 필요합니다.

"서버"에 접속하는 "클라이언트"는 로그인 과정을 거칩니다. 사용자명과 암호를 입력함으로서 그 사용자라는 신뢰를 할 수 있다는 거지요. 비슷한 원리로 공개키 암호화 알고리즘을 이용하여 이 과정을 자동화할 수 있습니다. 공개키 암호화는 암호화하는 키와 복호화하는 키가 서로 다를 수 있는 암호화 방식입니다.


공개키와 비밀키는 쌍으로 항상 존재하는데 이것이 큰 의미가 있는 이유는 공개키는 아무에게나 공개를 해도 괜찮다는 겁니다. 하지만 공개키로는 암호화만 할 수 있지 비밀키로 암호화된 암호문을 해독하지는 못합니다. 그러므로 클라이언트에서 생성된 공개키/비밀키 쌍 중 공개키만 서버에 전달해두면 클라이언트와 서버간에 이 공개키/비밀키 쌍을 검증하여 그 클라이언트가 믿을 만한지 알 수 있습니다.

그럼 차례로 그 과정을 살펴 보겠습니다.

먼저 클라이언트의 홈 디렉토리에서 "ssh-keygen -t rsa"라는 커맨드를 입력합니다. 이 커맨드는 RSA 공개키 방식의 키쌍을 생성하겠다는 뜻입니다. 파일명과 암호를 묻는 질문에는 그냥 ENTER만 입력하면 됩니다.

user@client ~ $ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
54:d2:65:6d:3f:f4:a5:98:a3:1b:9f:6c:51:76:e3:2a user@client
The key's randomart image is:
+--[ RSA 2048]----+
|        ....o.   |
|         o..  o..|
|        .    +.oo|
|       .    + +o+|
|        S  . +..o|
|          o .  . |
|           = o.  |
|          .E=.   |
|           ..    |
+-----------------+

이제 홈 디렉토리의 .ssh 폴더에 들어가 보면 id_rsa 파일과 id_rsa.pub 파일을 볼 수 있습니다. id_rsa 파일은 생성된 비밀키가 저장된 파일이고, id_rsa.pub 파일은 그 비밀키와 쌍을 이루는 공개키입니다. 비밀키의 경우 소유권한이 자신만 읽을 수 있도록 되어 있음을 알 수 있습니다. 이 비밀키는 절대로 외부에 공개되면 안되기 때문입니다.

user@client ~ $ ls -al .ssh
합계 28
drwx------  2 user user  4096  6월 12 21:36 .
drwxr-xr-x 66 user user  4096  6월 11 23:05 ..
-rw-------  1 user user  1679  6월 12 21:31 id_rsa
-rw-r--r--  1 user user   401  6월 12 21:31 id_rsa.pub
-rw-r--r--  1 user user 10294  6월  5 16:31 known_hosts

이제 이 공개키 파일인 id_rsa.pub를 서버의 사용하고자 하는 계정의 홈 디렉토리 아래 .ssh/authorized_keys 라는 파일로 옮겨 놓으면 됩니다. 파일을 옮기는 방법은 여러가지가 있겠지만 편한 방법을 쓰면 됩니다.

서버에서 사용할 계정을 ruser라고 한다면 ruser 홈디렉토리 아래에 .ssh 디렉토리가 존재해야 합니다. 만일 없다면 미리 만들어 둡니다. 이 .ssh 디렉토리는 권한이 반드시 700 (rwx --- ---)여야 합니다. 권한이 안전하게 설정되어 있지 않으면 OpenSSH는 에러를 뱉어내고 제대로 동작하지 않습니다.

그리고 다음 명령으로 만들어진 클라이언트 측의 공개키를 서버측에 복사합니다.

user@client~$ cat .ssh/id_rsa.pub | ssh ruser@server 'cat >> .ssh/authorized_keys'

위 명령은 파이프를 이용하여 클라이언트의 공개키 id_rsa.pub 파일을 서버측의 .ssh/authorized_keys 파일에 덧붙이는 것입니다. 암호를 입력하라고 하면 서버측 ruser 계정의 암호를 입력하면 됩니다.

위 명령에서 >> 지시자를 통해 파일을 병합하라고 하는 건 서버의 경우 여러 클라이언트의 공개키들을 저장할 필요가 있기 때문입니다. 공개키 자체는 한줄로 된 텍스트 파일인데, authorized_keys 파일에 여러 클라이언트의 공개키들을 병합하여 둘 수 있습니다.


마지막으로 해야 할 작업은 만들어진 authorized_keys 파일의 권한을 안전하게 바꾸는 것입니다. chmod 명령을 이용하여 600 (rw- --- ---)로 변경해야 합니다. 만일 이 작업을 하지 않으면 OpenSSH는 안전하지 않다고 생각하고 암호를 묻게 됩니다. 다음 명령을 실행하면 됩니다.

user@client~$ ssh ruser@server 'chmod 600 .ssh/authorized_keys'

이제 다음 명령으로 서버에 ssh로 접속해 봅니다.

user@client~$ ssh ruser@server

암호를 묻지 않고 바로 접속이 됨을 알 수 있습니다. 이렇게 한번 공개키 교환을 통해 영구적인 신뢰관계를 맺어 놓으면 ssh뿐 아니라 sftp, scp 등의 명령도 암호를 묻지 않습니다.

만일 제대로 되지 않는다고 생각된다면 생성된 클라이언트의 공개키가 서버측의 authorized_keys 파일 내로 잘 옮겨졌는지 확인하고, .ssh 디렉토리와 authorized_keys 파일의 권한이 각각 700과 600으로 설정되었는지 확인하면 됩니다.

이렇게 암호없이 접근할 수 있게 되었으므로 Expect 툴을 이용한 SFTP 자동화 스크립트에도 암호를 쓰지 않고 안전한 스크립트를 만들 수 있습니다.

댓글 없음:

댓글 쓰기