화요일, 9월 24, 2013

[B급 프로그래머] git를 위한 공개 키 인증 해법 정리

윈도와 각종 *nix 환경에서 산전수전 공중전에 잠수함전까지 다 겪은 B급 프로그래머지만, 제대로 사용하기 위해 git 만큼 머리를 써야하는 환경을 아직 보지 못했다. git는 사용법도 아주 복잡하지만 설정 자체도 (과거에 비해 쉬워졌다고는 하나...) 사용법에 못지 않게 상당히 복잡하다. 오늘은 그 중에서 특히 공개 키 인증 해법을 애독자 여러분 뿐만 아니라 B급 프로그래머 본인을 위해(!) 총정리하겠다(지금 키 설정하다 잠시 길을 잃은 상황...).

가장 먼저 공개 키 인증이 무엇인지부터 간단하게 설명할 필요가 있다. 대다수 무따기(약어처럼 무작정 따라할 수 있으면 좋겠지만 SSH 관련 무따기 문서들은 잘되면 다행이지만 혹시라도 문제가 생겼을 경우 지옥으로 가는 급행 티켓이다. T_T)에서는 독자들이 여기에 대해 충분히 안다고 가정하고 넘어가는 경향이 있는데... 나중에 뒷목 잡지 않기 위해 우분투의 공식 문서인 SSH/OpenSSH/Keys를 읽어보는 편이 바람직하다. 공개 키 인증 방식은 텍스트 암호 입력을 사용한 인증 방식에 비해 훨씬 더 보안이 강화되고 편의성도 높다는 장점이 있다. 이 글에서 암호학을 설명할 의도는 없으므로 문서 중에 가장 중요한 내용만 요약해 함께 읽어보자.

With public key authentication, every computer has a public and a private "key" (a large number with particular mathematical properties). The private key is kept on the computer you log in from, while the public key is stored on the .ssh/authorized_keys file on all the computers you want to log in to.

한글로 정리하면 다음과 같다. 공개 키 인증을 위해, 컴퓨터마다 공개 키와 개인 키를 설치해야 하는데, 개인 키는 여러분이 다른 곳으로 접속할 출발지 컴퓨터에 보관해야 하고, 공개 키는 여러분이 실제 접속할 목표 컴퓨터에 보관해야 한다. 이제 한 가지 사실은 명확해졌다. git 중앙 저장소(좋은 예: github.org나 bitbucket.com)에는 반드시 여러분의 공개 키를 올려야 한다(하긴 개인 키를 만인에게 공개한다는 생각 자체가 우습긴 하지만 실수는 누구나 한다. T_T). 참고로 깃허브나 비트버킷 사이트로는 원격 셸 접속이 가능하지 않으므로 .ssh/authroized_keys에 공개 키를 저장하는 대신 관리 도구를 사용해야 한다. 잠시 후에 살펴보기로 하고... 우선 음식 재료인 공개 키와 개인 키를 만드는 방법에 집중하자.

공개 키와 개인 키는 쌍(pair)으로 존재한다. 따라서 하나를 잃어버리면... 재앙이 닥친다 새로 만들어 항상 쌍을 유지해야 한다. 공개 키와 개인 키를 만드는 방법을 간단히 설명하겠다. 리눅스를 사용하는 분들이라면 OpenSSH 패키지에 들어 있는 ssh-keygen 명령을 사용해 다음과 같이 한 방에 키 쌍을 생성할 수 있다(보안 강화를 위해 DSA 대신 RSA를 사용하자. '-t rsa' 옵션을 붙이면 된다).

$ ssh-keygen -t rsa

윈도를 사용하시는 분들이라면 putty에 들어있는 PuTTYgen(Putty Key Generator)을 떠올리실지도 모르겠는데, Msys기반 Git for Windows를 설치했다면 ssh-keygen.exe가 따라오므로 리눅스와 동일한 방식으로 공개 키와 개인 키를 생성하면 된다. ssh-keygen이 기본으로 키를 생성하는 위치는 (리눅스와 윈도 모두) 사용자 홈의 .ssh 디렉터리 아래다. id_rsa가 개인 키이며 id_rsa.pub가 공개 키라는 사실을 기억하자. 보안을 높이려면 passphrase를 입력해 개인 키 자체에 암호를 거는 방법도 있다(물론 이렇게 암호를 걸어놓으면 SSH로 접속할 때마다 암호를 물어볼 것이다. 물론 나중에 설명하겠지만 한번만 암호를 입력하면 되는 방법도 있다!). 이제 재료를 구했으니 본격적으로 요리를 시작하자.

앞서 만든 공개 키($HOME/.ssh/id_rsa.pub 또는 %HOME%\.ssh\id_rsa.pub)를 깃허브와 비트버킷에 올리자. 로컬 컴퓨터에서 적당한 편집기로 id_rsa.pub를 열어 텍스트 내용을 복사한 다음 웹 브라우저의 Key textarea 영역에 붙여넣고 저장하면 된다. 백문이 불여일견이라는 충고에 따라 그림으로 정리해봤다.


(깃허브: Title과 Key 예는 비트버킷 내용을 참조한다)

(비트버킷: 여기 나온 키는 가짜 공개 키이므로 생긴 모양새만 확인하기 바란다.)

그리고 나서... 정말 제대로 동작하는지 시험해보자. 가장 손쉬운 방법은 ssh를 사용해 직접 접속해보면 된다. 리눅스나 Msys 기반 Git for Windows가 설치된 환경이라면 다음과 같이 확인하면 된다. (주의: 직관에 반하는 이야기처럼 들리겠지만... git라는 계정을 개인 계정으로 바꾸면 안 된다.)

$ ssh -vT git@github.com
$ ssh -vT git@bitbucket.org

처음 접속할 경우 'The authenticity of host 'bitbucket.org (131.103.20.167)' can't be established." 또는 "The authenticity of host 'github.com (192.30.252.130)' can't be established."와 유사한 경고 메시지가 뜨며 RSA key fingerprint를 보여주며 접속할지 말지를 물어본다. 'yes'라 답하면 로컬 컴퓨터의 $HOME/.ssh/known_hosts나 %HOME%\.ssh\known_hosts에 공개 키가 영구적으로 등록되어 자동으로 해당 호스트를 신뢰하게 된다. 가장 마지막 부분에 주목하자. 혹시라도 다음과 같은 메시지가 나오면 키 쌍에 문제가 생긴 상황이다.

debug1: Next authentication method: publickey
debug1: Trying private key: $HOME/.ssh/identity
debug1: Offering public key: $HOME/.ssh/id_rsa
debug1: Authentications that can continue: publickey
debug1: Trying private key: $HOME/.ssh/id_dsa
debug1: No more authentication methods to try.
Permission denied (publickey).

제대로 키 쌍을 맞췄는지 다시 한번 확인하고 로그를 확인하며 디버깅을 반복하자.

자 여기까지 읽었으면 기초 지식은 습득한 셈이다. '해법'이라 부르기에 너무 싱겁다고? 그렇다면... 두 가지 고급 지식을 전수해드리겠다. 만일 개인 키-공개 키 쌍이 여러 개인 경우에는 어떻게 될까? 예를 들어, 사내 리눅스 운영체제에 셸 접속을 위한 개인 키 - 공개 키 쌍과 비트버킷 접속을 위한 개인 키 - 공개 키 쌍이 다르다면? 그럴 경우에는 ssh 설정 파일을 활용하면 된다. $HOME/.ssh/config 또는 %HOME%\.ssh\config 파일을 만들고 다음 내용을 채우자. 여기서 id_rsa_bitbucket은 구분을 위해 이름을 변경한 비트버킷용 개인 키다.

Host bitbucket.org
  IdentityFile ~/.ssh/id_rsa_bitbucket

이렇게 하고 나서 ssh -vT 명령을 사용해 비트버킷 사이트에 테스트 접속하면 중간 디버깅 로그에 id_rsa_bitbucket을 사용한다는 메시지(debug1: Trying private key: $HOME/.ssh/id_rsa_bitbucket)가 나올 것이다.

마지막으로 앞서 언급했던 개인 키에 passphrase를 걸어놓아 매번 git 명령을 내릴 때마다 암호를 입력해야 하는 번거로운 상황을 피하려면 어떻게 해야 할까? 리눅스나 맥OS X이라면 OpenSSH 패키지에 들어 있는 인증 에이전트를 사용하면 된다. '$ ssh-agent /bin/bash; ssh-add ~/.ssh/id_rsa/id_rsa_bitbucket'라는 명령을 내리면 ssh-agent가 id_rsa_bitbucket 개인 키에 대한 암호를 기억해 클라이언트에 (사람) 대신 자동으로 입력해준다. 그렇다면 윈도는? 다행히 누군가 이미 해법을 만들어 놓았다. $HOME/.bashrc라는 파일을 만들고(눈치 빠른 독자들이라면 bashrc 셸 초기화 스크립트는 윈도 명령 프롬프트에서 동작하지 않는다는 사실을 지적할 것이다. 잠시 뒤에 이에 대한 다른 해법을 소개할테니 조금만 참고 기다리자) 다음 내용을 입력하자. 앞서 나온 id_rsa_bitbucket 개인 키에 passphrase를 걸어놓았다면 다음 내용 중간에 나오듯 '/usr/bin/ssh-add ~/.ssh/id_rsa_bitbucket'처럼 명시적으로 개인 키 이름을 설정해야 한다.

SSH_ENV=$HOME/.ssh/environment

# start the ssh-agent
function start_agent {
    echo "Initializing new SSH agent..."
    # spawn ssh-agent
    /usr/bin/ssh-agent | sed 's/^echo/#echo/' > ${SSH_ENV}
    echo succeeded
    chmod 600 ${SSH_ENV}
    . ${SSH_ENV} > /dev/null
    /usr/bin/ssh-add ~/.ssh/id_rsa_bitbucket
}

if [ -f "${SSH_ENV}" ]; then
     . ${SSH_ENV} > /dev/null
     ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
        start_agent;
    }
else
    start_agent;
fi

git 패키지에 들어있는 git bash를 수행하면 다음과 같은 문구가 나오며 passphrase 입력을 1회 요청한다.

Initializing new SSH agent...
succeeded
Enter passphrase for $HOME/.ssh/id_rsa_bitbucket:
Identity added: $HOME/.ssh/id_rsa_bitbucket ($HOME/.ssh/id_rsa_bitbucket)

입력을 끝내고 나면 identity가 추가되었다는 문구가 출력된다. 다음 명령을 내려 제대로 인증 정보가 들어갔는지 확인하자.

$ ssh-add -l

git bash에서 ssh 명령을 내리면 passphrase가 걸려 있는 개인 키인 경우에도 암호 입력 없이 접속에 성공할 것이다.

$ ssh -vT git@bitbucket.org

혹시 윈도 환경에서 Source Tree 등을 사용하거나 git bash 이외 윈도 명령 프롬프트나 명령 프롬프트 대체품인 ckw을 사용한다면 PuTTY 패키지의 Pageant를 활용하는 방법도 생각해봐야 한다. Pageant는 ppk 형식의 키만 사용 가능하므로, 먼저 PuTTY 패키지의 Puttygen을 사용해 RSA 개인 키를 ppk로 변환하고 나서('Conversions' 메뉴에서 'Import key'를 선택하고 파일 선택 대화 상자가 나오면 개인 키인 id_rsa_bitbucket 파일을 선택하고 passphrase를 입력하면 키를 로드한다. 화면 상단에서 개인 키가 맞는지 확인한 다음 'Save the generated key' 항목의 [Save private key] 버튼을 눌러 적당한 이름을 붙인 ppk 개인 키로 저장하면 된다) Pageant를 띄운 다음 변환된 개인 키를 등록하면 된다.

준비가 끝나면 GIT_SSH 환경 변수를 설정하자. 참고로 Putty 다운로드 페이지에서 Windows Installer 버전을 받으면 Putty, Puttygen, Plink, Pageant를 한번에 설치할 수 있다. 다음과 같이 명령 프롬프트에서 plink 설치 경로를 GIT_SSH 환경 변수에 설정하기 바라며, 윈도 고급 시스템 설정에도 해당 환경 변수를 추가하면 더욱 간편하게 사용할 수 있다.

C:\> set GIT_SSH=C:\Program Files (x86)\PuTTY\plink.exe

아쉽게도 git 패키지에 들어있는 ssh 명령은 GIT_SSH 환경 변수를 인지해 passphrase를 자동으로 입력받지 못하므로 ssh 명령 자동화가 필요한 경우 git bash를 사용하기 바란다.

이 정도 내용이면 윈도/리눅스/맥OS X 환경에서 git 공개 키 인증 설정에 별다른 무리가 없으리라 본다. 혹시 빠진 내용이 있으면 댓글에 달아주면 감사하겠다.

EOB

댓글 없음:

댓글 쓰기