About

이번 블로그에서는 SSH(Secure Shell)에 대해 작성하고자 한다.

$ ssh -i key.pem user_name@ip_addr

위의 ssh를 이용한 접속은 개발을 하는 사람이라면 너무나 익숙한 명령문일 것이다. 필자도 처음 개발을 시작하면서 AWS EC2 문서가 시키는 대로 ssh 접속을 무슨 의미인지도 모른 채 따라 했던 기억이 있다.

$ ssh-keygen -t rsa -b 2048 -C "user@email.com"

애매하게 이해했던 시기에는 무작정 위의 명령을 실행하여.. 다른 서버와 잘 연결해놓은 private key를 override해서 접속이 안되게 된적도 있다(만약 지금 이 말이 이해가 안된다면 읽어야할 블로그를 잘 찾았다고 보면 된다).

그런 실수들이 반복되면서 다시 실수하지 않고자 제대로 공부를 하게 된 것인데, 이제 그 내용을 블로그로 남겨서 더욱 공고히 하고자 한다.

SSH key의 기본 작동원리

SSH를 이용하여 서버에 접속하는 방법은 다양하게 존재하는데, 그 중 가장 단순한 방법은 비밀번호로 접속하는 것이다. 하지만 비밀번호의 문제점은 보안이 취약하다는 점이다. 물론 비밀번호도 보안되어서 전달은 되지만, brute force(무작위 대입 공격) 에 의해서 해킹을 당하는 경우가 종종 있다고 한다. 그에 반해 Key를 이용한 ssh 접속은 보안적으로 믿을만하다고 증명된 바 있다.

Key는 private keypublic key의 쌍으로 이뤄져있고 이를 비대칭 키라고 부른다. 이 부분을 기억하는 것이 가장 중요하다. private key는 client(사용자 컴퓨터)에서 안전하게 보관되어야 하는 key이고 public key는 server(AWS EC2 등 서버)에 공유되는 key를 의미한다. 밑에서 다시 한번 설명하겠지만 server의 ~/.ssh/authorized_keyspublic key를 저장하면 된다.

어쨋든 client가 ssh 명령으로 접속을 시도하면 server에서는 상대방이 private key를 가졌는지 테스트를 통해 확인하고 연결 여부를 결정하게 되는 것이다.

SSH Key 생성

명령문은 위에서 이미 소개한 바가 있다.

$ ssh-keygen -t rsa -b 2048 -C "user@email.com"

위의 옵션외에도 다양한 옵션이 있지만 자세한 옵션은 여기서 설명하지 않겠다. 간단하게 자주 사용되는 것만 한번 살펴보도록 하자.

  • t : 암호화하는 타입이다. 특별한 경우가 아니라면 가장 자주 사용하는 rsa 타입으로 설정하면 되겠다.
  • b : 암호의 bit수를 의미하며 default값은 2048이다.
  • f : 저장할 파일 위치와 이름.
  • C : 주석 부분으로 역할이 특별히 없다.

만약 위의 명령어를 실행하면 아래같은 문구가 뜬다.

Generating public/private rsa key pair.
Enter file in which to save the key (/home/username/.ssh/id_rsa):

만약 enter를 하게되면 (/home/username/.ssh/id_rsa)위치에 id_rsa(private key), id_rsa.pub(public key)가 생성이 된다. 하지만, 만약 이미 이전에 생성한적이 있다면

/home/username/.ssh/id_rsa already exists.
Overwrite (y/n)?

라고 묻는데 이때 정말 조심해야한다. 덮어쓰기가 되면서 이전에 이미 연결해놓은 서버와의 연결은 끊어지게 되기 때문이다. 아마 이유를 이해했겠지만 노파심에 설명을 하자면 아래와 같은 상황이다.

  1. 기존의 서버 A와 연결하기 위해서 서버 A에 id_rsa.pub 키 값을 ~/.ssh/authorized_keys 에 저장했던 적이 있다.
  2. 그 당시의 public key와 한 쌍이었던 private key가 덮어쓰기로인해 사라지면 나중에 서버 A와 접속을 시도할 때, 즉 서버가 나에게 private key가 있는지 확인하는 테스트를 진행할 때에 값이 불일치하여 실패하게된다.

필자는 멍청하게도 이런 실수를 한적이 있는데 부디 이 블로그의 독자분들에게는 그런 일이 생기지 않길 바란다.

여기서 부가설명을 좀 더 하자면, 필자는 서버마다 다른 key를 만든다거나 아마 다음 블로그에서 설명하게될 github ssh clone을 할 때 repo마다 다른 key를 설정하는 등의 권한 관리를 생각했었다. 이런 경우에는 위에서 설명한 옵션인 -f path/file_name 을 추가하거나, Enter file in which to save the key (/home/username/.ssh/id_rsa): 물음에서 그냥 Enter가 아닌 path/file_name을 입력하여 원하는 이름으로 만들어서 처리하면 된다.

어쨋든 생성이 끝나고나면

Created directory '/home/username/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again: 

passphrase를 설정하라고 한다. 이 부분은 옵션이므로 빈칸으로 진행하여도 되고, 만약 더 강한 보안을 위해서는 client에서 private key를 사용하거나 확인할 때 비밀번호를 통해서만 가능하도록 할 수도 있다.

필자는 이 부분도 시도했었는데 혹시라도 github private repo를 Docker Container에 설치하고자하면 복잡하여 생성하지는 않는 것을 추천하며(Docker에 설치하는 법을 소개한 블로그 링크) 단순히 github에 ssh clone을 하고자 할 때에는 생성해도 된다.

passphrase를 진행하신 분들은 ssh-agent를 함께 이용해서 매번 비밀번호를 입력하는 수고를 줄이는 것이 좋다. 그 방법은 아래의 명령을 실행하면 된다.

$ eval `ssh-agent -s`
$ ssh-add ~/path/id_rsa[private_key_path]

간단하게 설명하자면 ssh-agent는 비밀번호를 암호화하여 저장하는 key chain의 역할을 하는 것이다.

Server에 Public Key 복사하기

  1. 가장 쉬운 방법은 ssh-copy-id 명령을 사용하는 것이다.

    $ ssh-copy-id -i ~/path/id_rsa[private_key_path] user_name@remote_ip

    만약 i없이 진행하면 ~/.ssh/id_rsa를 default 위치로 진행하게된다.

  2. 직접 copy를 진행한다.

    $ cat ~/path/id_rsa[private_key_path] | ssh user_name@remote_ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys

우리가 ssh key를 사용하기전 상태인 1, 2번은 어떤 경우이든 user_namepassword 조합으로 통신을 하는 것이므로 아래와 같은 질문을 받게 될 것이다.

user_name@remote_ip's password:

password를 입력하여 진행을하면 된다.

SSH Password를 이용한 접속 막기

이제 Key를 이용한 ssh 접속이 가능해졌으니 password를 이용한 접속은 막도록하자.

$ sudo vi /etc/ssh/sshd_config

이제 vi 편집기에서 원래는 주석처리 돼있는 PasswordAuthentication를 주석을 풀고 아래처럼 변경하자.

PasswordAuthentication no

저장이 완료되면 Ubuntu or Debian의 경우는

$ sudo service ssh restart

CentOS/Fedora의 경우에는

$ sudo service sshd restart

를 실행하면 된다.

Conclusion

이 블로그를 통해서 SSH key의 기본 작동원리에 대해서 알아봤다. 이제 다음 블로그에서는 SSH key를 이용하여 Github에 ssh를 접근하는 밥법을 자세히 살펴보도록 하자.