S/W 개발 기반 시스템 구성 – 9. mercurial + ssh 구성하기

이 글은 S/W 개발에 가장 기본이 되는 이슈 추적(Issue Tracker), 버전 관리(Version Control), 빌드(Build), 지속적인 통합(CI) 시스템을 구성하는 방법에 대한 일련의 글 중 아홉 번째이다. 이전 글에서 웹 서버를 통해 Mercurial(머큐리얼) 저장소에 접근할 수 있도록 구성했지만 한 가지 문제가 있다. 다음 상황을 생각해 보자.

서드 파티 라이브러리는 여러 프로젝트에서 공통으로 사용하기 때문에 중앙 서버에 각 라이브러리별 저장소를 구성해 둔다. 개발 프로젝트에서 서드 파티가 필요하면 관련 라이브러리만 하위 저장소(subrepo)로 설정한다. 이렇게 하면 개발 프로젝트를 복제(clone)할 때 관련 라이브러리 역시 자동으로 서버에서 복제하기 때문에 환경 구성이 매우 간편하다.

하지만 문제는 개발자가 아닌 서버에서 발생한다. 웹 서버를 통해 접근할 때 인증을 받아야 하므로 개발자는 인증 정보를 직접 입력하거나 Mercurial 설정 파일에 기록해 자동으로 처리할 수 있다. 그러나 CI 서버인 Jenkins(젠킨스)에서 제공하는 Mercurial 플러그 인에서는 아직 인증 정보를 설정할 수 없기 때문에 문제가 발생한다. 즉 빌드하기 위해 저장소 내용을 복제할 때 하위 저장소 정보를 통해 서드 파티 저장소에도 접근해야 하는데, 개발 프로젝트를 복제할 때는 로컬 경로로 처리하기 때문에 인증 없이 진행하지만 하위 저장소는 웹 주소로 접근[1]하기 때문에 인증을 처리할 방법이 없다.

Mercurial 인증 정보 처리 팁에서처럼 하위 저장소 주소 정보에 계정과 암호를 직접 넣어 해결할 수도 있지만 실제 사용할 만한 방법은 아니다. 또는 Mercurial 설정 파일인 .hgrc 파일에 인증 정보를 기록해 처리할 수도 있다. 서버에 아무도 접속하지 못하며 보안 문제가 없다면, 이처럼 설정 파일에 기록해 간편하게 처리하는 것도 그리 나쁘진 않을 것 같다. 하지만 여기서는 SSH를 통해 접근하는 방법을 추가로 제공해 개발자는 웹 서버를 통해 쉬운 주소를 사용하도록 하고 서드 파티 라이브러리는 SSH를 통해 접근하도록 하위 저장소 정보를 설정해 보안을 높인다. 물론 모든 저장소를 SSH로 접속하도록 바꿀 수도 있으니 적절히 선택하면 되겠다.

1. 미리 준비할 것

  • Copssh: OpenSSH를 윈도에서 쓸 수 있게 패키징한 것으로 현재 4.1.0 버전이다. 여기에서 받을 수 있다.
  • Putty Key Generator(PuTTYgen): RSA, DSA 키를 만드는 프로그램이며 여기에서 받을 수 있다.
  • Pageant: Putty 키 인증 에이전트이며 여기에서 받을 수 있다.
  • Mercurial: 여기에서 서버에 설치할 윈도용 설치 파일을 받는다.
  • TortoiseHg: 여기에서 클라이언트에 설치할 파일을 받는다.

2. 설치

참고: 윈도용 무료 SSH 서버로 freeSSHd가 있다. 간편하게 설치할 수 있으나 Mercurial과는 잘 맞지 않아 보인다. 명령 창에서 Mercurial 명령을 실행하면 처리를 마치지 못하고 중간에 멈추는 현상이 있는데 이는 아래와 같이 Use new console engine 부분을 해제하면 된다. 하지만 이렇게 하더라도 명령 처리 후 종료하지 못하는 현상(명령 프롬프트를 표시하지 못함)이 추가로 생긴다. 명령 창에서는 Ctlr+C로 종료하면 되지만 TortoiseHg와 같은 GUI 툴에서는 문제가 있으므로 여기서는 사용하지 않는다.

freeSSHd SSH

Mercurial 윈도용 설치 파일을 실행해 먼저 설치한다. 설치 과정은 특별한 게 없으므로 생략하지만 다음에 주의해야 한다. 설치를 마친 후에는 경로(C:\Program Files (x86)Mercurial 또는 C:\Program Files\Mercurial)를 시스템 PATH 환경변수에 추가해야 하는데, 반드시 이전에 설치한 Python용 패키지 경로(C:\Python26;C:\Python26\Scripts)보다 먼저 참조하도록 앞에 추가해야 한다. 그렇지 않으면 Python 패키지에 포함된 것을 먼저 실행해 다음과 같은 에러가 생긴다.

참고: 서버에서 path 경로를 바꾸면 opensshd 서버를 다시 실행해야 인식함

Mercurial Error

이제 Copssh 설치 파일을 실행해 설치를 시작한다.

Copssh Setup - Welcome

라이센스 동의와 설치 경로는 특별한 것이 없으므로 그대로 진행한다. 서비스를 실행할 계정을 등록해야 하는데 사용자 계정이나 administrator과 같이 설치할 때 기본으로 등록되는 계정은 사용하지 않도록 한다[2].

Copssh Setup Account

Install을 선택해 다음으로 진행하면 자동으로 OpenSSH 서버와 관련 파일을 설치한다.

Copssh Setup - OpenSSH

OpenSSH 설치를 마치면 SSH 서비스를 사용할 사용자를 추가해야 한다는 안내창이 뜬다.

Copssh Setup - OpenSSH Server Inform

OpenSSH 설치를 마치면 추가 내용을 설치한 후 Copssh 설치를 마치므로 Close 를 눌러 닫는다.

Copssh Setup Complete

정상적으로 설치를 마치면 ‘Openssh SSHD’ 서비스와 설치 과정에서 지정한 SvcCOPSSH 계정이 자동으로 등록된다. SSH 서비스를 사용할 계정을 등록하기 위해 ‘시작 메뉴 -> 모든 프로그램 -> Copssh’에서 COPSSH Control Panel을 실행한다. 이 화면에서는 사용자 계정을 관리하고 SSH 서버 상태도 확인할 수 있다.

Copssh Control Panel - Status

Configuration 탭에서는 Compression을 yes로 설정하면 전송율을 높일 수 있다.

Copssh Control Panel - Configuration

SFTP는 사용 여부에 따라 설정하면 되는데 여기서는 사용하지 않으므로 해제한다.

Copssh Control Panel - SFTP

사용자는 Users 탭에서 관리한다.

Copssh Control Panel - Users

SSH 사용자를 추가하려면 윈도에 계정을 먼저 추가해야 한다. 키 인증을 사용하므로 원격 데스크톱 등으로 서버에 임의로 접근하지 못하도록 암호는 임의로 설정하고 관리자가 아닌 일반 권한으로 계정을 만든다. 윈도에 계정을 추가했으면 COPSSH Control Panel을 실행하고 Users 탭에서 Add 버턴을 누르면 계정 활성화 과정을 시작한다. Forward를 선택한다.

COPSSH Control Panel - Activate a user

추가할 계정을 선택할 수 있다. SSH용으로 만든 계정을 선택하고 Forward를 선택한다.

Copssh Control Panel - Select a user

해당 계정에 대해 설정한다. Access type은 Linux shell and Sftp, Options에서는 Allow PKA authentication을 선택한 후 Forward를 선택한다.

Copssh Control Panel – Select options

Access type은 다음과 같다.

  • Linux shell: 리눅스 bash 셀 사용
  • Linux shell and Sftp: 리눅스 bash 셀과 SFTP를 사용
  • Windows shell: 윈도 셀(명령 행 입력, cmd.exe)을 사용
  • Sftp: SFTP를 사용
  • No shell access: 셀을 사용하지 않음

선택 사항은 다음과 같다.

  • Allow password authentication: 암호 인증
  • Allow PKA authentication: 공개 키 인증
  • Allow TCP forwarding: 포트 포워드(터널링) 사용

지금까지 진행 내용을 확인 후 맞으면 Apply를 눌러 마친다.

Copssh Control Panel – Confirm activation

SSH 접근 계정을 추가하면 Users 탭에서 볼 수 있으며 CopSSH 설치 폴더(C:Program FilesICW 또는 C:Program Files (x86)ICW) 아래 home 디렉터리에 추가한 계정의 홈 디렉터리도 만들어진다.

Copssh Control Panel - Activated users

3. 키 설정

키는 CopSSH에서 만드는 방법과 Putty Key Generator를 사용하는 방법이 있다.

3.1. CopSSH에서 만드는 방법

CopSSH Control Panel에서 Users 탭을 선택한다.  Activated users 목록에서 키를 만들 계정을 선택한 후 Keys… 버턴을 누르면 키 생성 과정을 시작한다.

Copssh Public Key Authorize

Add 버턴을 누른다.

Copssh - Create a PKA key pair

Forward 버턴을 누르면 키 종류와 길이를 선택할 수 있다. 키 종류와 길이는 어느 것을 선택해도 괜찮으나 여기서는 기본값 그대로 사용한다.

Copssh - Create a PKA key pair - Key type and length

Forward 버턴을 눌러 다음으로 진행하면 개인 키에 대한 암호 설정을 할 수 있다. 암호를 설정하지 않으면 서버와 키만 비교해 인증을 받으므로 키만 있으면 누구나 접속할 수 있다. 암호를 설정하면 인증 과정을 진행하기 전에 설정한 암호를 입력해야 한다. 당연히 보안을 높이려면 암호를 입력하는 게 좋으나 여기서는 우선 입력하지 않고 진행한다. 입력했을 때 인증 과정은 따로 보기로 하겠다.

암호를 입력하지 않으려면 ‘Yes, I am sure!’를 선택한다. Directory는 개인 키를 저장할 디렉터리인데 간편하게 해당 계정 홈 디렉터리를 지정하자. File name에는 개인 키 파일 이름을 지정한다.

Copssh - Create a PKA key pair - Private key file and passphrase

Forward 버턴을 눌러 진행하면 지금까지 진행 내용을 볼 수 있다. 확인 후 이상 없으면 Apply 버턴을 눌러 마친다.

Copssh - Create a PKA key pair - Confirmation

과정을 마치면 공개 키가 추가된 것을 확인할 수 있다. 실제 공개 키는 해당 계정 홈 디렉터리 아래 .sshauthorized_keys 파일에 저장한다. 또한 개인 키는 지정한 디렉터리에서 볼 수 있다.

Copssh Added Public Key

저장한 개인 키는 클라이언트에서 사용한다. CopSSH에서 만든 것은 OpenSSH 형식인데 사용할 SSH 클라이언트는 plink 또는 TortoisePlink이므로 putty 형식으로 바꿔야 한다. 미리 준비해 둔 Putty Key Generator를 실행한다.

Putty Key Generator

File -> Load private key 를 선택한다.

Putty Key Generator – Load private key

파일 로드 다이얼로그 창이 뜨면 확장자가 PuTTY Private Key 파일 형식(*.ppk)으로 선택되어 있어 확장자가 맞지 않으면 파일이 보이지 않는다. All Files (*.*)로 바꾼 후 해당 파일을 읽어 들이면 다음과 같이 OpenSSH 형식 개인 키 파일을 읽었다는 메시지 창이 뜬다. 또는 Conversions 메뉴 -> Import key를 선택해 개인 키 파일을 읽어도 되며 이 때는 따로 메시지를 띄우지 않는다. 그리고 이전에 개인 키에 대한 암호를 넣었으면 읽을 때도 같은 암호를 요구한다.

Putty Key Generator – Load private key Notice

OK를 눌러 닫으면 읽어 들인 키 정보를 Key 내용으로 볼 수 있다.

Putty Key Generator – Conversion Privatekey

개인 키를 읽은 후 Save private key를 눌러 저장하면 putty 형식으로 바꿀 수 있다. Parameters 부분은 지정하지 않아도 된다. 다만 Key passphrase 부분은 앞서 본 것처럼 개인 키에 대한 암호를 지정하는 것인데, 입력하지 않으면 다음과 같은 경고 창이 뜬다. Yes를 선택하면 된다.

Putty Key Generator - Warning

파일 저장 다이얼로그 창이 뜨면 적당한 이름과 함께 확장자로 ppk를 지정하면 된다. 여기서는 sandbox 계정에 대한 것이므로 sandbox.ppk로 저장하겠다.

3.2. Putty Key Generator에서 만드는 방법

Putty Key Generator를 실행하고 Generate 버턴을 선택한 후, 프로그램을 실행 창 위에서 마우스를 임의로 움직여 막대 그래프가 다 찰 때까지 하면 된다. 생성하기 전에 만들 키 종류는 SSH-2 RSA나 SSH-2 DSA로 선택하고 비트 수는 높을수록 암호화 정도가 큰데 1024나 2048이면 되겠다.

Putty Key Generator - Generate Key

앞에서 한 것과 달리 이번에는 키에 암호를 설정해 보겠다. 개인 키에 사용할 암호를 Key passphrase와 Confirm passphrase에 입력하고 Save private key를 선택하면 개인 키를 저장할 수 있다. 앞에서 한 것처럼 .ppk 확장자로 저장하면 된다.

Putty Key Generator – Key Passphrase

앞에서는 공개 키가 자동 저장됐지만 이번에는 직접 넣어야 한다.  Public key for pasting into OpenSSH authorized_keys file 항목 아래에 있는 내용을 모두 복사한 후, 해당 계정 아래 .sshauthorized_keys 파일을 만들고 내용을 붙여 넣는다. 내용이 한 줄로 되어 있는 것에 주의한다.

authorized_keys file

4. Mercurial 설정

Putty 형식으로 저장한 개인 키는 서버에 접속할 사용자 PC(클라이언트 PC)에 보관한다. 여기서는 C:ppksandbox.ppk로 저장했다. 클라이언트 PC에 TortoiseHg가 없으면 설치한다. 설치 과정은 간단하므로 생략하겠다.

TortoiseHg를 설치했으면 시작 메뉴 -> 실행을 선택하고 다음을 입력한 후 엔터를 누르면 설정 파일을 열 수 있다.

%USERPROFILE%mercurial.ini

[ui] 부분을 찾아 그 아래에 다음 내용을 추가한 후 저장한다.

ssh = TortoisePlink.exe -ssh -C -i "C:\ppksandbox.ppk"

이제 서버에 있는 저장소를 복제(clone)할 수 있다. 명령행에서 다음처럼 입력한다[3]. 주소 형식은 ssh:[email protected]/repo_path 이다.

hg clone ssh:[email protected]/d:/repos/hg/sandbox

처음 접속한다면 서버 정보를 보여주고 승인할 것인지 묻는다. 예를 선택해 한 번 등록하면 다음에는 묻지 않는다.

Tortoiseplink Alert

정상적으로 처리되면 다음처럼 저장소를 복제한다.

Mercurial - Clone Repository Through SSH

TortoiseHg에서 SSH를 통해 서버 저장소에 접근하는 주소는 다음과 같이 설정하면 된다.

TortoiseHg – SSH Syncronize Setting

이번에는 개인 키에 암호를 설정했을 때 어떤 과정을 거치는지 보자. 설정 과정이나 접속 주소 등은 차이가 없으며 단지 서버에 접속할 때 개인 키에 설정한 암호를 묻는다는 점만 다르다.

Mercurial – Key Passphrase

개인 키를 만들 때 사용한 암호를 넣으면 된다. 이처럼 개인 키 암호를 설정하면 항상 암호를 묻는데 이를 간편하게 하려면 Pageant를 사용한다. Pageant를 실행하면 트레이에서 모자 쓴 터미널 아이콘을 볼 수 있다.

Pageant

아이콘에 마우스 오른쪽 버턴을 누른 후 Add Key를 선택하면 파일 다이얼그로가 뜬다. 저장해 둔 개인 키 파일을 찾아 추가하면 개인 키 암호를 다시 물으므로 입력해 준다. 추가한 키 정보는 View Keys 메뉴로 볼 수 있다. 물론 이 화면에서도 키 정보를 추가 또는 삭제할 수 있다.

Pageant - View Keys

이렇게 pageant에 키 정보를 추가해 두면 개인 키 암호를 넣어야 할 때 자동으로 처리하므로 암호 입력 창이 뜨지 않는다.

5. 접근 제한 설정

SSH는 Secure Shell을 뜻하는데 암호화한 연결을 제공해 인증 과정을 안전하게 한다. 문제는 SSH 자체에서 접근 권한을 설정하는 것은 아니므로 인증만 되면 어디든 접근할 수 있다는 점이다. 즉 SSH 클라이언트를 사용해 서버에 로그인할 수도 있고 Mercurial 저장소에도 주소만 알면 모두 접근할 수 있다. 그러므로 이에 대한 제한이 필요하다.

  • hg-ssh: SSH를 사용할 때 저장소에 접근 권한을 제어하는 Python 스크립트이며 이 파일을 받으면 된다.

hg-ssh 파일을 받아 서버 D:hgweb 디렉터리에 넣고 다음 내용을 찾는다. 첫 줄이므로 찾기 쉽다.

#!/usr/bin/env python

이 내용을 다음처럼 python 설치 경로에 맞춰 고친 후 저장한다.

#!C:/Python26/python.exe

접근 권한을 설정할 계정 홈 디렉터리 아래 .sshauthorized_keys 파일을 열고 공개 키 정보 앞에 다음처럼 추가한다.

command="d:/hgweb/hg-ssh d:/repos/hg/*", ssh-rsa SSH-KEY

즉 hg-ssh 스크립트 경로와 저장소 위치를 공개 키 정보 앞에 추가하면 된다.

hg-ssh

이제 이 계정으로는 D:/Repos/hg 아래 있는 저장소만 접근할 수 있으며 다른 위치에 있는 저장소에는 접근할 수 없다. 이처럼 특정 위치 아래에 있는 모든 저장소에 대해 지정할 수도 있고 저장소를 하나씩 지정할 수도 있다.

ssh-hg - Access Control

다만 authorized_keys에 지정한 저장소 경로가 MS-DOS 형태인 것에 대해 경고를 하는데 이를 끄려면 시스템 환경 변수에 다음처럼 nodosfilewarning을 추가하면 된다. 추가한 후에는 서비스를 멈췄다 다시 실행해야 적용된다[4].

Cygwin - MS-DOS Style Path Warning Off

6. Jenkins에 사용

Subrepo 접근 경로에 SSH를 사용하면 Jenkins에서 빌드할 때 문제없이 하위 저장소 정보도 가져올 수 있다. 주의할 점은 실제 빌드하기 전에 미리 서버 정보를 인증해 둬야 한다는 것이다. 그렇지 않으면 빌드 과정 중에는 인증을 할 수 없으므로 빌드를 진행할 수 없다.

게다가 단점이 있다. Subrepo 접근 경로를 사용자마다 지정할 수 없으므로 키 하나를 모든 개발자가 공용으로 사용해야 한다. 그러므로 모든 개발자가 키를 잃어버리지 않도록 주의해야 한다.

7. 추가 보안 설정 방법

개인 키를 모든 프로젝트에 공용으로 사용해 접근할 수 있으므로 보안에 부담이 크다면 저장소를 주 프로젝트와 서드 파티용으로 분리하고, 상대적으로 보안에 부담이 적은 서드 파티용 저장소에만 키를 공용으로 사용해 SSH로 접근할 수 있도록 한다. 빌드할 때도 문제가 되는 부분이 subrepo로 가져오는 서드 파티 저장소 내용이므로 합리적이라 하겠다. 또한 개인 키를 유출하더라도 주 개발 저장소는 여전히 접근할 수 없으며 서드 파티 저장소만 접근할 수 있다.

이를 위해 저장소를 둘로 구분하는데 지금까지 사용한 D:Reposhg는 주 개발에 사용하고 D:Reposhgv를 새로 만들어 서드 파티 라이브러리를 저장한다. hgweb.config 파일을 열고 다음처럼 [paths] 정보에 추가한다.

[paths]
/=D:/Repos/hg/*
/vendor=D:/Repos/hgv/*

주 개발 저장소에는 http://plab.net/hg/…로 접근할 수 있고 서드 파티 저장소에는 http://plab.net/hg/vendor/…로 접근할 수 있다. 또한 SSH 접근을 제한하기 위해 계정별 .sshauthorized_keys 내용을 다음처럼 변경한다.

command="d:/hgweb/hg-ssh d:/repos/hgv/*", ssh-rsa SSH-KEY

이제 SSH로는 서드 파티 저장소 영역에만 접근할 수 있다. 물론 서드 파티용 저장소 위치를 바꾸면 redmine에서 참조하는 저장소 경로 역시 모두 수정해야 한다. 참고로 지금까지 변경한 내용은 서버를 재시작하지 않아도 변경 즉시 적용된다.

8. 사용자별로 키 인증을 하려면…

지금까지 과정을 잠깐 정리하면 다음과 같다.

  • Jenkins에서 사용하는 Mercurial 플러그 인에서는 계정 정보를 설정할 수 없으므로 인증을 해야 쓸 수 있는 저장소에 접근할 수 없다.
  • 인증을 자동으로 처리하기 위해 개인 키와 공개 키 기반 인증을 사용하는 SSH를 사용한다.
  • SSH를 사용해 Jenkins에서 빌드는 문제 없으나 팀 전체가 계정과 인증 키를 공유하므로 보안에 취약하다.

프로젝트에서 사용하는 서드 파티 라이브러리가 무엇인지 개발자가 신경쓰지 않고 자동으로 가져 오기 위해 사용하는 하위 저장소 정보(.hgsub 파일)에는 앞에서 본 것처럼 SSH 인증에 사용하는 계정 정보가 포함된다. 그러므로 SSH 인증에 사용하는 계정은 하나를 공통으로 써야 하며, 사용자별로 인증 키만 다르게 해 키가 맞지 않으면 인증하지 않는 방식을 사용해야 한다. 이는 다음과 같은 방법으로 처리할 수 있다.

앞에서 예로 든 것처럼 sandbox 계정을 공통으로 사용한다면 해당 계정의 authorized_keys 파일에 각 사용자별 키 정보를 추가하면 된다. 물론 사용자별 키 정보와 함께 경로를 다르게 지정한다면 해당 키를 사용하는 사용자에 대해 접근 경로 제한을 다르게 할 수도 있다.

hg-ssh: Multiple Keys

이처럼 설정한 후 각 개발자는 SSH 접속을 할 때 계정은 공통 계정을 사용하고 키 정보만 자기 것으로 사용하면 된다.


[1] 개발자는 웹 서버를 통해서만 Mercurial 저장소에 접근할 수 있다.
[2] 계정 정보를 지정할 수도 있지만 사용할 일이 없으므로 설치 기본값 그대로 사용해도 된다. 특히 암호를 다시 지정한다면해당 O/S에 대한 계정 정책에 어긋나지 않는지 주의한다. 맞지 않으면 서비스와 계정 등록이 되지 않아 모두 삭제 후 다시 설치해야 하므로 주의한다.
[3] 서버에 저장소가 있어야 한다.
[4] CopSSH 4.1.0에서 적용되지 않는다는 보고가 있다.

You may also like...