ssh key 효율적인 관리 방법
이번 글은 ssh 키 기반으로 인증하는 경우 기존의 authorized_keys 파일이 아닌 저장소 또는 방법으로 key 정보를 가져오는 방법에 대해 소개합니다. CentOS에서 테스트하였습니다.
(이미지: https://www.engadget.com/2006/03/21/how-to-ssh-tunnels-for-secure-network-access/)
ssh 키 기반으로 인증을 하게 되면 별도의 패스워드 없이 원격 명령을 쉽게 실행할 수 있습니다. Hadoop과 같이 분산된 수십 ~ 수백대 이상의 서버에 있는 특정 데몬을 한번에 실행하고, 중지시킬 경우에 모든 서버에 접속할 때 마다 패스워드를 입력하는 것도 고통스러운 일입니다.
필자의 경우에는 ssh 터널링도 자주 사용하는데, 별도의 VPN 등을 설치하지 않고 특정 서버의 오픈된 포트에 접속하는 경우에 주로 활용합니다. 예를 들어 192.168.172.10 서버에 Hadoop NameNode의 웹 관리 화면 50070 포트에 접속해야 하는데 방화벽에서는 ssh 접속만 허용을 해 놓는 경우가 많습니다. 이런 경우에 다음과 같이 ssh 터널링을 사용해서 접속하게 되면 localhost:50070 으로 접속이 가능하게 됩니다.
1
ssh hadoop@192.168.127.10 -L 50070:192.168.127.10:50070
이때에도 ssh key 기반으로 인증을 주로 하게 됩니다. 이렇게 ssh 터널링을 이용하면 방화벽에서 공개되지 않은 포트에도 쉽게 접속이 가능하지만 다음과 같은 문제점이 있습니다.
- ssh 사용자 key는 주로 {user_home}/.ssh/authorized_keys 라는 파일에 저장되어 있음
- 해당 서버에 ssh 접속이 가능한 사용자는 해당 파일에 다른 사용자의 ssh 키를 등록함으로써 아무런 제한 없이 사용자를 임의로 추가할 수 있다.
- 이 부분 때문에 ssh 터널링은 편리함도 주지만 보안에 문제가 발생할 수 있음
그래서 ssh key를 임의의 사용자가 등록할 수 없고 관리자만 관리할 수 있는 방법이 없는 지 찾아 보았는데 다행히 다른 방법이 있었습니다. ssh 접속을 관리하는 데몬 프로그램인 sshd는 ssh key 정보를 가져오는 방법이 authorized_keys 뿐만 아니라 사용자가 정의한 방법도 사용할 수 있습니다.
다음은 필자가 사용하는 구성에 대한 예제입니다. 이 예제는 하나의 예제이며 다양하게 활용이 가능합니다.
- 서버에 접속 가능한 사용자는 N 명
- 각 N 명의 사용자에 대해 각각의 linux 계정 생성
- 각 사용자는 자신의 ssh key를 관리자에게 전달
- 관리자는 관리자와 sshd만 접근 가능한 디렉토리 및 파일에 ssh key 등록
- 예시에서는 /etc/ssh/KEYS/$user/authorized_keys 이용
- 사용자는 자신의 {user_home}/.ssh/autohrized_keys 파일을 생성 및 임의로 다른 사용자의 key를 추가할 수 있지만 sshd는 해당 파일을 사용하지 않음
/etc/ssh/sshd_config 파일에서 설정 변경
AuthorizedKeysCommand 설정 변경
ssh_config 설정 파일에는 sshd의 환경을 설정할 수 있는데 이 중 AutohrizedKeysCommand 설정 값을 변경합니다. 이 설정 값은 sshd가 사용자 key를 어떻게 가져올 것인가에 대한 설정입니다. 값이 설정되어 있지 않으면 우리가 흔히 알고 있는 login user의 {user_home}/.ssh/autohrized_keys 파일을 cat 해서 사용합니다.
이 값을 변경하여 git repository 또는 DB에 저장되어 있는 ssh key를 저장할 수도 있음. 필자의 경우 sshd만 인식할 수 있는 파일에서 가져오게 하는 것이 목표 였기 때문에 다음과 같이 수정하였습니다.
1
AuthorizedKeysCommand /usr/sbin/get_user_keys
/usr/sbin/get_user_keys 는 제가 임의로 만든 script 프로그램으로 이 프로그램에서 결과 값으로 사용자의 ssh key를 반환하면 됩니다.
다음은 /usr/sbin/get_user_keys 내용입니다.
1 2 3
#!/bin/bash user=$1 cat /etc/ssh/KEYS/$user/authorized_keys
위 코드에 보면 user=$1 이라고 되어 있는데 ssh 로그인 시에 입력한 사용자 명을 sshd가 get_user_keys 프로그램 호출 시 첫번째 인자로 전달해 줍니다.
AuthorizedKeysCommandUser 설정 변경
이 값은 AuthorizedKeysCommand를 실행 시키는 linux user에 대한 설정으로 sshd가 AuthorizedKeysCommand에 설정된 명령을 실행할 때 이 값에 설정된 사용자로 호출합니다. 보통은 nobody로 설정하며, nobody는 linux에서 이와 같은 용도로 사용하기 위해 이미 만들어져 있는 사용자입니다.
1
AuthorizedKeysCommandUser nobody
ssh 접속 사용자 추가
이렇게 구성하면 이제 sshd를 재 시작하고, 사용자 추가시 다음과 같은 스크립트를 실행하여 추가합니다. sshd 재시작 시 shell 하나는 반드시 접속 상태로 두시고 다른 shell에서 재시작 하는 것을 권장합니다. 이유는 위 설정이 잘못되어 sshd 가 동작하지 않는 경우 다시 접속할 수 없기 때문입니다.
1 2 3 4 5 6 7 8
#!/bin/bash user=$1 sudo adduser $user sudo mkdir /etc/ssh/KEYS/$user sudo touch /etc/ssh/KEYS/$user/authorized_keys sudo chown nobody.nobody -R /etc/ssh/KEYS/$user sudo chmod 700 /etc/ssh/KEYS/$user sudo chmod 600 /etc/ssh/KEYS/$user/authorized_keys
여기서 중요한 사항은 생성된 디렉토리의 사용자는 AuthorizedKeysCommandUser 에서 설정된 사용자(예제에서는 nobody)로 해야 하며 파일의 access mode는 600으로 해야 합니다.
그 다음에 /etc/ssh/KEYS/$user/authorized_keys 파일에 해당 사용자의 ssh key를 추가합니다.
여기까지 작업하면 정상적으로 관리자만 접근할 수 있는 하나의 디렉토리 내에서 모든 사용자의 ssh 키를 관리할 수 있습니다.관리해야 할 서버가 많다면 모든 서버에 사용자의 ssh key를 추가하지 않고 git 같은 저장소에 저장하고 AuthorizedKeysCommand 에서 이 저장소로부터 key를 가져오게 하면 쉽게 중앙 집중 관리가 가능합니다.