원격 서버에 접속하기 위해서 ssh 명령을 사용한다. sshd가 구동되어 있는 원격 서버에 ssh 명령으로 접속하게 된다.
ssh 명령은 기본적으로 사용자를 식별할 수 있는 아이디와 원격 서버를 찾아갈 수 있는 호스트 정보를 인자로 받는다.
$ ssh userId@server_host
ssh 클라이언트가 서버에 있는 sshd에 연결되면 사용자를 인증(Authentication)하는 절차를 진행한다. 가장 간단한 방법은 비밀번호(Password)를 사용하는 방법이다. 사용자가 입력한 비밀번호를 해싱해서 sshd 서버가 가지고 있는 해시값과 비교해 사용자를 인증하게 된다.
비밀번호를 이용해 사용자를 인증하는 방법은 간단하고 편리하지만 보안에 취약하다. 따라서 서버에 접속하기 위한 비밀번호를 주기적으로 변경해야 한다. 또 쉘 스크립트에서 원격 서버에 접속해야 하는 경우 스크립트에 비밀번호를 넣어두기도 애매하고, 자동화되어 있는 시스템에서 매번 사용자가 비밀번호를 입력하기도 애매하다.
물론 Kerberos의 Keytab 파일을 이용해 인증을 자동화할 수도 있다. 하지만 그것보다 좀 더 간단한 ssh-keygen을 이용한 Public-Private Key를 이용한 ssh 접속 방법 설정에 대해 알아보겠다.
목차
ssh-keygen 이란?
ssh-keygen은 Private Key와 Public Key 쌍을 생성해준다. ssh는 이런 키 쌍을 이용해 사용자를 인증할 때 사용된다. 이름에서 알 수 있듯이 Private Key와 Public Key로 구성된 비대칭키를 생성해준다.
Private Key(비공개키)와 Public Key(공개키)는 한 쌍으로 동작한다. 마치 자물쇠와 열쇠처럼 어떤 정보를 Public Key로 암호화하면 그 것과 한쌍으로 구성된 Private Key만 복호화 할 수 있다. Public Key는 자물쇠처럼 많은 사람들이 접근할 수 있지만 Private Key는 오직 인증된 사용자만 가지고 있어야 한다. 따라서 Public Key는 원격 서버에서 설치되어 있고, Private Key는 클라이언트가 보관한다.
ssh-keygen을 이용한 사용자 인증은 이런 Public Key와 Private Key의 특성을 이용한다.
ssh 접속 과정
정확한 ssh 접속 과정은 여기에서 설명하는 것보다 더 복잡한 과정을 거친다. 이 포스트에서는 ssh 접속을 비밀번호 없이 할 수 있도록 서버를 세팅하는 것이 초점을 맞출 예정이라 설명을 단순화하겠다.
우선 클라이언트가 원격 서버로 ssh 접속을 요청한다. 그러면 서버에서 클라이언트로 어떤 정보를 전달한다. 클라이언트는 이 정보를 Private Key로 암호화하여 서버에 전달한다. 서버는 사용자에 해당하는 Public Key를 이용해서 클라이언트가 전달한 정보를 복호화하고, 원래 보냈던 정보와 비교한다. 원래 보냈던 정보와 같다면 사용자 인증을 마치고 세션이 생성된다.
비밀번호 없이 미리 설치된 Public Key와 Private Key를 이용해서 사용자를 인증하고 ssh 세션이 생성된다.
ssh-keygen
ssh 접속에 사용할 Public Key와 Private Key를 생성하기 위해 ssh-keygen 명령을 하자.
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
-t 옵션으로 어떤 암호화 알고리즘을 사용할지 결정할 수 있따. 예제에서는 rsa라는 암호화 알고리즘을 사용해 키를 생성했다.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
ssh-keygen을 이용해 생성된 Private Key와 Public Key가 저장될 경로를 입력할 수 있다. 기본 값으로 사용자의 홈 디렉토리의 .ssh 디렉토리에 id_rsa와 id_rsa.pub이라는 이름의 키 파일이 생성된다.
.ssh 디렉토리에 id_rsa, id_rsa.pub 파일이 이미 존재할 경우 덮어쓰겠냐고 물어본다. 파일을 덮어쓸 경우 기존 파일을 이용해 인증하던 ssh 접속이 제대로 동작하지 않을 수 있으므로 주의해야한다.
Enter passphrase (empty for no passphrase):
그 다음 passphrase를 입력한다. passphrase는 비밀번호 같은 개념으로 비공개키를 입력한 passphrase 값으로 암호화한다. 10~30 글자 정도를 입력하는 것을 권장하며 그냥 엔터를 누르면 생략할 수 있다. 자동 로그인을 원할 경우에는 생략해야한다. 엔터를 눌러서 진행한다.
Enter same passphrase again:
Your identification has been saved in /Users/user/.ssh/id_rsa.
Your public key has been saved in /Users/user/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:QKjQckiEv/1SoDyFHbxKJAiemJdbUNza/HBePxYe57E user@AD01326042.local
The key's randomart image is:
+---[RSA 3072]----+
|B=.+.o. |
|X.=o=.. |
|oXo+.*. |
| .=o* +.. . o o |
| o.* . =S. o = o |
| * . . o = E |
| . o . . |
| . . |
| . |
+----[SHA256]-----+
passphrase를 다시 한번 물어본다. 역시 그냥 엔터를 눌러준다. /Users/user/.ssh
디렉토리 아래에 id_rsa
파일과 id_rsa.pub
파일이 생성되었다. 이 두 개의 파일이 비공개키와 공개키다.
id_rsa 파일은 비공개키로 비밀번호에 해당한다. 때문에 절대로 다른 사람에게 복사해주면 안된다. 자신이 로그인할 클라이언트 호스트에만 위치시키자. id_rsa.pub 파일은 원격 서버의 authroized_keys
에 위치시켜 id_rsa 파일을 확인시켜주는 역할을 한다.
ssh key 배포
생성된 공개키를 원격 서버에 배포해야한다. 파일서버를 이용하거나 rsync, scp 등의 도구를 이용해 id_rsa.pub 파일을 로그인할 원격 서버로 복사하자.
$ scp $HOME/.ssh/id_rsa.pub user@remote.server.com:id_rsa.pub
원격 서버로 공개키를 복사했다.
$ ssh user@remote.server.com
user's password:
원격 서버로 접속하자.
$ cat id_rsa.pub >> ~/.ssh/authroized_keys
$ chmod 700 ~/.ssh/authorized_keys
가져온 id_rsa.pub 파일을 ~/.ssh/authroized_keys
파일에 추가(append)해준다. 기존 파일을 덮어쓰면 원격 서버에 잘 접속하던 다른 클라이언트의 접속이 끊기기 때문에 새롭게 추가해준다.
이제 키 배포가 끝났다.
ssh 접속
다시 클라이언트 호스트로 돌아가서 배포된 SSH Key를 이용해 접속해보자.
$ ssh user@remote.server.com
비밀번호를 묻지 않고 접속이 성공된다면 SSH Key 배포가 성공한 것이다.
만약 SSH Key 파일을 별도의 디렉토리에 생성해놓았다면 -i 옵션을 이용해 ~/.ssh/id_rsa
파일 대신 이용할 수 있다.
$ ssh -i /temp/newPrivateKey user@remote.server.com
만약 정상적으로 로그인이 안된다면 어디서 문제가 발생했는지 -v 옵션을 추가해서 디버깅할 수 있다. (더 자세한 정보는 -vv, -vvv 옵션으로 확인할 수 있다. 대신 내용이 엄청많다)
ssh config
로컬 머신에서 여러개의 원격 서버에 SSH Key를 이용한 로그인을 하려고 할 때 호스트마다 다른 SSH Key를 설정할 수도 있다. 마치 하나의 비밀번호를 모든 사이트에 동일하게 사용하는 것이 안전하지 않은 것처럼 하나의 SSH Key를 이용해 모든 호스트로 접속하는 것도 바람직하지 않을 수 있다.
~/.ssh/config
파일을 열어보자. ssh와 관련된 설정을 모아두는 곳이다. config 파일에 다음 내용을 추가할 수 있다.
Host github
HostName github.com
Port 22
User myGitAccount
PreferredAuthentications publickey
IdentityFile ~/.ssh/github/id_rsa
Host 옆에 오는 이름은 ssh 명령에 사용하는 이름이다. ssh github
이라고 입력하면 Host github 아래에 인덴트로 구분되어 있는 설정이 적용된다.
HostName은 Host에 지정된 이름이 매핑되는 실제 호스트 이름이다.
Port는 접속할 ssh 서버가 열어 놓고 있는 포트 번호다.
User는 ssh 로그인에 사용할 사용자 이름이다.
이 설정을 이용해서 ssh github
명령을 입력하면, ssh myGitAccount@github.com:22
를 입력한 것과 동일하게 된다. 물론 여기서 입력한 것은 기본값으로 사용자가 별다른 입력을 하지 않으면 사용되는 값이다. 사용자가 ssh 명령에 명시한 값이 있다면 그 값이 우선 쓰여지게 된다.
PreferredAuthentications 값은 어떤 인증 방법을 우선적으로 이용할 것인지를 나타낸다. publickey를 입력했으면 SSH Key를 이용한다. 그 밖에 값으로 password, gssapi-with-mic, keyboard-interactive 등이 있다.
IdentityFile 값은 비공개키의 경로가 적힌다. 이 값을 다르게 주면 호스트마다 다른 ssh key를 사용할 수 있다.
댓글