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 key
와 public key
의 쌍으로 이뤄져있고 이를 비대칭 키라고 부른다. 이 부분을 기억하는 것이 가장 중요하다. private key
는 client(사용자 컴퓨터)에서 안전하게 보관되어야 하는 key이고 public key
는 server(AWS EC2 등 서버)에 공유되는 key를 의미한다. 밑에서 다시 한번 설명하겠지만 server의 ~/.ssh/authorized_keys
에 public 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)?
라고 묻는데 이때 정말 조심해야한다. 덮어쓰기가 되면서 이전에 이미 연결해놓은 서버와의 연결은 끊어지게 되기 때문이다. 아마 이유를 이해했겠지만 노파심에 설명을 하자면 아래와 같은 상황이다.
- 기존의 서버 A와 연결하기 위해서 서버 A에
id_rsa.pub
키 값을~/.ssh/authorized_keys
에 저장했던 적이 있다. - 그 당시의
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 복사하기
-
가장 쉬운 방법은
ssh-copy-id
명령을 사용하는 것이다.$ ssh-copy-id -i ~/path/id_rsa[private_key_path] user_name@remote_ip
만약
i
없이 진행하면~/.ssh/id_rsa
를 default 위치로 진행하게된다. -
직접 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_name
과 password
조합으로 통신을 하는 것이므로 아래와 같은 질문을 받게 될 것이다.
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를 접근하는 밥법을 자세히 살펴보도록 하자.