본문 바로가기
프로그래밍 놀이터/Tips

[도서 정리] 4. Git 서버 - ProGit

by 돼지왕 왕돼지 2020. 1. 8.
반응형

4. Git 서버 - ProGit



-

리모트 저장소는 일반적으로 워킹 디렉터리가 없는 bare 저장소다.

이 저장소는 협업용이기 때문에 체크아웃이 필요 없다.

그냥 git 데이터만 있으면 된다.

다시 말해 bare 저장소는 .git 디렉토리만 있는 저장소다.





4.1. 프로토콜


-

Local, HTTP, SSH, Git 이렇게 네 가지 프로토콜을 사용할 수 있다.




* 로컬 프로토콜


-

리모트 저장소가 단순히 디스크의 다른 디렉터리에 있을 때 사용한다.

팀원들이 전부 한 시스템에 로그인하여 개발하거나 아니면 NFS(Network File System) 같은 것으로 파일 시스템을 공유하고 있을 때 사용한다.

이런 상황은 문제가 될 수도 있다.

모든 저장소가 한 시스템에 있기 때문에 한 순간에 모두 잃을 수 있다.



-

$ git clone /somewhere/project.git

$ git clone file:///somewhere/project.git


git 은 파일 경로를 직접 쓸 때와 file:// 로 시작하는 url 을 사용할 때를 약간 다르게 처리한다.

디렉터리 경로를 그대로 사용하면 git 은 필요한 파일을 직접 복사하거나 하드 링크를 사용한다.

하지만 file:// 로 시작하면 git 은 네트워크를 통해서 데이터를 전송할 때처럼 프로세스를 별도로 생성하여 처리한다.

file:// 을 사용하는 것은 비효율적이긴 하지만, 저장소를 깨끗한 상태로 남겨두기에 좋다.



-

파일 기반 저장소의 장점은 간단하다는 것이다.

파일의 권한 등을 설정하기 쉽고, 팀 전체가 접근할 수 있는 파일 시스템을 가지고 있다면 저장소를 아주 쉽게 구성할 수 있다.

다른 디렉터리를 공유할 때처럼 모든 동료가 읽고 쓸 수 있는 공유 디렉터리에 bare 저장소를 만들면 된다.




-

단점은 다양한 상황에서 접근할 수 있도록 디렉터리를 공유하는 것 자체가 일반적으로 어렵다는 것이다.

집에 있을 때 push 해야 하면 리모트 저장소가 있는 디스크를 마운트해야 하는데, 이것은 다른 프로토콜을 이용하는 방법보다 느리고 어렵다.

게다가 파일 시스템을 마운트해서 사용하는 중이라면 별로 빠르지도 않다.

로컬 저장소는 데이터를 빠르게 읽을 수 있을 때만 빠르다.


마지막으로 이 프로토콜은 저장소에 우발적인 사고가 발생하지 않도록 보호해주지 않는다.

모든 사용자는 셸에서 리모트 디렉터리에 무슨 짓이든지 할 수 있다.




* HTTP 프로토콜


-

1.6.6. 이전 버전에서는 읽기만 가능한 단순한 방법밖에 사용할 수 없었다.

1.6.6. 버전부터는 스마트(smart) 프로토콜을 사용할 수 있다.

이 프로토콜을 git 데이터를 전송할 때 SSH 처럼 서로 협상한다.



-

스마트 HTTP 프로토콜은 SSH 나 Git 프로토콜처럼 통신한다.

다만 HTTP 나 HTTPS 포트를 이용해 통신하고 다양한 HTTP 인증 방식을 사용한다는 것이 다르다.

SSH 는 키를 발급하고 관리해야 하는 번거로움이 있지만, HTTP 는 익숙한 사용자 이름과 비밀번호 방식을 사용하기 때문에 더 편리하게 사용할 수 있다.


아마 지금은 Git 에서 가장 많이 사용하는 프로토콜일 것이다.

git:// 프로토콜처럼 익명으로 사용할 수도 있고, SSH 처럼 인증을 거쳐 push 할 수도 있다.

이 두가지 동작을 하나의 URL 로 통합해서 사용할 수도 있다.

그냥 인증 기능을 켜놓은 저장소에 push 를 하면 서버는 사용자 이름과 비밀번호를 물어본다.



-

Git 서버가 스마트 HTTP 요청에 응답하지 않으면 git 클라는 차선책으로 멍청한 HTTP 프로토콜을 시도한다.

이 프로토콜은 원격 저장소를 그냥 파일 건네주는 웹 서버로 취급한다.

기본적으로 HTTP 도큐먼트 루트 밑에 bare 저장소를 두고 post-update 훅을 설정하는 것이 해야 하는 일의 전부다.


post-update 훅은 아래와 같이 설정한다.

$ mv hooks/post-update.sample hooks/post-update

$ chmod a+x hooks/post-update


post-update 훅은 git 에 포함되어 있으며, git update-server-info 라는 명령어를 실행시킨다.

$ git update-server-info

이 명령어를 써야 http 로 fetch 와 clone 명령이 제대로 동작한다.

누군가 SSH 를 통해서 저장소에 push 하면 post-update 훅이 실행된다.



-

스마트 HTTP 프로토콜은 읽기와 쓰기에 하나의 URL 만 사용한다.

그리고 사용자에게 익숙한 아이디와 비밀번호 방식의 인증을 사용한다. (SSH 보다 간단하다.)

SSH 는 사용자가 알아서 키를 만들고 공개키를 서버에 올린 후에야 비로소 인증을 받을 수 있다.

게다가 SSH 만큼이나 빠르고 효율적이기도 하다.


또 HTTP 대신 HTTPS 를 이용해서 데이터를 암호화는 것도 클라에서 서명된 SSL 인증서를 요구하는 것도 가능하다.

HTTP 는 매우 보편적인 프로토콜이기 때문에 거의 모든 회사 방화벽에서 통과하도록 돼있다는 장점도 있다.



-

HTTP 나 HTTPS 를 사용하도록 설정하는 것이 SSH 로 설정하는 것보다 까다로운 서버가 있다.

그리고 push 할 때 HTTP 인증을 사용하면 SSH 인증키를 사용하는 것보다 좀 더 복잡하다.

그래도 인증 캐싱 툴을 사용하면 좀 나은데, OSX 에는 키체인(keychain access), 윈도우에는 인증서 관리자(Credential Manager)가 있다.




* SSH 프로토콜


-

GIt 의 대표 프로토콜은 SSH 이다.

이를 사용하면 아무런 외부도구 없이 git 서버를 구축할 수 있다.

대부분 서버는 SSH 로 접근할 수 있도록 설정돼 있고, 설정돼 있지 않더라도 쉽게 설정할 수 있다.

그리고 SSH는 인증 기능이 있고 어디에서든 사용할 수 있으며 사용하기도 쉽다.



-

SSH 프토토콜을 사용하면 ssh:// 로 시작하는 url 을 사용한다.


ex) 

$ git clone ssh://user@server/project.git


아래와 같이 SCP(Secure Copy) 형태의 구문으로 줄여 쓸 수도 있다.


ex) 

$ git clone user@server:project.git



-

SSH 장점은 정말 많다.

첫째 상대적으로 설정하기 쉽다. SSH 데몬은 정말 흔하다.

둘째, SSH 를 통해 접근하면 보안에 안전하다. 모든 데이터는 암호화되어 인증된 상태로 전송된다.

마지막으로 SSH 는 전송 시 데이터를 가능한 한 압축하기 때문에 효율적이다.



-

SSH 는 익명으로 접근할 수 없다는 단점이 있다.

심지어 읽기 전용인 경우에도 접근할 수 없다.

회사에서만 사용할 거라면 SSH 가 가장 적합한 프로토콜일 테지만, 오픈소스 프로젝트는 SSH 만으로는 부족하다.

만약 SSH 를 사용하는 프로젝트에 익명으로 접근할 수 있게 하려면, push 할 때는 SSH 로 하고 다른 사람들이 fetch 할 때는 다른 프로토콜을 사용하도록 설정해야 한다.




* Git 프로토콜


-

Git 프로토콜은 git 에 포함된 데몬을 사용하는 것이다.

포트는 9418 이며 SSH 프로토콜과 비슷한 서비스를 제공하지만, 인증 메커니즘이 없다.

저장소에 git-export-daemon-ok 파일을 만들면 git 프로토콜로 서비스할 수 있지만, 보안은 없다.

이 파일이 없는 저장소는 서비스되지 않는다.



-

이 저장소는 누구나 clone 할 수 있거나 아무도 clone 할 수 없거나 둘 중의 하나만 선택할 수 있다.

그래서 이 프로토콜로는 push 하게 할 수 없다.

엄밀히 말하자면 push 할 수 있도록 설정할 수 있지만, 인증하도록 할 수 없다.

다시 말해 누군가 push 할 수 있으면 이 프로젝트의 url 을 아는 사람은 누구나 push 할 수 있다.

거의 쓰지 않는다.



-

git 프로토콜은 전송 속도가 가장 빠르다.

전송량이 많은 공개 프로젝트나 별도의 인증이 필요 없고 읽기만 허용하는 프로젝트를 서비스할 때 유용하다.

암호화와 인증을 빼면 SSH 와 전송 메커니즘이 별반 다르지 않다.



-

git 프로토콜의 단점은 인증 메커니즘이 없는 거다.

git 만 사용하는 경우는 없고 보통 ssh 나 https 프로토콜과 함께 사용한다.

소수의 개발자만 push 할 수 있고 대다수 사람은 git:// 을 사용하여 읽을 수만 있게 한다.

이 방법은 가장 설치하기 어려운 방법 중 하나이다.








4.2. 서버에 Git 설치하기


-

어떤 서버를 설치하더라도 일단 저장소를 bare 저장소로 만들어야 한다.

bare 저장소는 워킹 디렉터리가 없는 저장소이다.

—bare 옵션을 주고 clone 하면 새로운 bare 저장소가 만들어진다.

bare 저장소 디렉터리는 관례에 따라 .git 확장자로 끝난다.


ex) 

$ git clone —bare my_project my_project.git


이는 아래와 같이 실행한 것과 비슷하다


ex) 

$ cp -Rf my_project/.git my_project.git




* 서버에 bare 저장소 넣기


-

예를 들어 git.example.com 이라는 이름의 서버를 하나 준비하자.

그리고 그 서버에 SSH 로 접속할 수 있게 만들고 git bare 저장소를 /opt/git 에 저장한다.

ex) 

$ scp -r my_project.git user@git.example.com:/opt/git 

( scp 는 secure copy 의 줄임말로 ssh 를 이용해 네트워크로 연결된 호스트간 파일을 주고 받는 명령 )


이제 다른 사용자들도 SSH 서버에 접근해서 저장소를 clone 할 수 있다.

사용자는 /opt/git 디렉터리에 읽기 권한이 있어야 한다.


이 서버에 SSH 로 접근할 수 있는 사용자가 /opt/git/my_project.git 디렉터리에 쓰기 권한까지 가지고 있으면 바로 push 할 수 있다.

git init 명령에 —shared 옵션을 추가하면 git 은 자동으로 그룹 쓰기 권한을 추가한다.


ex) 

& git init —bare —shared



-

동료와 함께 개발할 때 꼭 필요한 것은 SSH 서버와 Bare 저장소뿐이라는 것을 기억하자.




* 초 간단 뚝딱


-

사용자를 관리하는 것이 Git 서버를 설정할 때 가장 골치 아픈 일 중 하나다.

사람이 많으면 어떤 사용자는 읽기만 가능하게 하고 어떤 사용자는 읽고 쓰기 둘 다 가능하게 해야 한다.



-

모든 개발자가 SSH 로 접속할 수 있는 서버가 있으면 쉽게 저장소를 만들 수 있다.

저장소의 권한을 꼼꼼하게 관리해야 하면 운영체제의 파일 시스템 권한 관리를 이용할 수 있다.



-

팀원들이 접속할 수 있도록 하는 방법엔 몇 가지가 있다.

첫째로 모두에게 계정을 만들어 주는 방법이다. 제일 단순하지만 다소 귀찮다. 팀원마다 adduser 를 실행시키고 임시 암호를 부여해야 한다.

둘째로 서버마다 git 이라는 계정을 하나씩 만드는 방법이다. 쓰기 원한이 필요한 사용자의 SSH 공개키를 모두 모아서 git 계정의 ~/.ssh/authorized_keys 파일에 모든 키를 입력한다. 그러면 모두 git 계정으로 그 서버에 접속할 수 있다. 이는 접속하는 데 사용한 SSH 계정과 커밋에 저장되는 사용자는 아무런 상관이 없게 된다.

SSH 서버 인증을 LDAP 서버를 이용할 수도 있다.





4.3. SSH 공개키 만들기


-

Git 서버들은 SSH 공개키로 인증한다.

공개키를 사용하려면 일단 공개키를 만들어야 한다.

사용자의 SSH 키들은 기본적으로 사용자의 ~/.ssh 디렉터리에 저장한다.

이 안에 .pub 파일이 있다면 그 녀석이 공개키이고 다른 파일들은 개인키이다.

만약 파일들이 없거나 .ssh 디렉터리도 없으면 ssh-keygen 이라는 프로그램으로 키를 생성해야 한다.





4.4. 서버 설정하기


-

$ sudo adduser git

$ su git

$ mkdir .ssh && chmod 700 .ssh

$ touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys


이렇게 git 계정과 .ssh 폴더, authorized_keys 파일을 만든 후 authroized_keys 에 SSH 공개키를 추가해야 사용자가 접근할 수 있다.


ex) 

$ cat /tmp/aUser.pub >> ~/.ssh/authorized_keys



-

개발자들이 git 계정으로 로그인할 수 없게 하려면, passwd 파일에서 로그인 셸을 바꿔야 한다.

단순히 로그인 셸을 git-shell 로 바꾸기만 하면 git 계정으로는 Git 만 사용할 수 있다.

이 로그인 셸은 서버의 다른 부분은 건들 수 없도록 돼 있다.

git-shell 을 사용자의 로그인 셸로 지정해야 한다.


$ cat /etc/shells # 이미 git-shell 이 등록돼 있는지 확인

$ which git-shell # git-shell 실행파일이 설치돼 있는지 확인

$ sudo vim /etc/shells # 위 명령으로 확인된  git-shell 실행파일의 절대경로를 추가


chsh account_name 명령어를 통해 특정 계정의 셸을 바꿀 수 있다.


$ sudo chsh git # git-shell 경로를 입력, 보통 /usr/bin/git-shell


이제 git 계정으로 Push 와 Pull 을 할 수 있지만 서버의 셸은 가질 수 없다.





4.5. Git 데몬


-

$ git daemon —reuseaddr —base_path=/opt/git/ /opt/git/


—reuseaddr 는 서버가 기존의 연결이 타임아웃될 때까지 기다리지 않고 바로 재시작하게 하는 옵션이다.

—base-path 옵션을 사용하면 사람들이 프로젝트를 clone 할 때 전체 경로를 사용하지 않아도 된다.

그리고 마지막에 있는 경로는 노출할 저장소의 위치를 git 데몬에 알려주는 것이다.

마지막으로 방화벽을 사용하고 있으면 9418 포트를 열어주어야 한다.



-

보안을 위해서 저장소를 읽을 수만 있는 사용자로 데몬을 실행시키는 것이 좋다.








4.6. 스마트 HTTP


-

CGI 서버로 아파치를 사용한다. 없으면 설치할 수 있다.

$ sudo apt-get install apache2 apache2-utils

$ a2enmod cgi alias env rewrite


/opt/git 디렉터리의 유닉스 사용자 그룹도 www-data 로 설정해야 한다.

그래야 웹 서버가 저장소를 읽고 쓸 수 있다.


아파치 서버는 cgi 스크립트를 이 사용자로 실행시킨다. (기본 설정이다.)


$ chgrp -R www-data /opt/git


그리고 아파치 설정 파일을 수정한다.

그러면 git http-backend 를 실행했을 때 모든 요청을 /git 경로로 받을 수 있다.


SetEnv GIT_PROJECT_ROOT /opt/git

SetEnv GIT_HTTP_EXPORT_ALL

ScriptAlias /git/ /usr/lib/git-core/git-http-backend/


GIT_HTTP_EXPORT_ALL 환경 변수를 설정하지 않으면 git-daemon-export-ok 파일이 있는 저장소에는 아무나 다 접근할 수 있게 된다.


마지막으로 아파치가 git-http-backend 에 요청하는 것을 허용하고 쓰기 접근시 인증하게 한다.


RewriteEngine On

RewriteCond %{QUERY_STRING} service=git-receive-pack [OR]

RewriteCond %{REQUEST_URI} /git-receive-pack$

RewriteRule ^/git/ - [E=AUTHREQUIRED]


<Files “git-http-backend”>

    AuthType Basic

    AuthName “Git Access”

    AuthUserFile /opt/git/.htpasswd

    Require valid-user

    Order deny, allow

    Deny from env=AUTHREQUIRED

    Satisfy any

</Files>



.htpasswd 파일에는 접근을 허가하려는 사용자의 비밀번호가 들어가 있어야 한다.


$ htpasswd -c /opt/git/.htpasswd user_name


아파치에는 사용자 인증 방법이 많은데 위의 예는 가장 간단한 방식 중 하나다.



-

웹 서버는 아파치 말고도 다른 서버를 사용할 수도 있고, 인증 방식도 다르다.

그러나 HTTP 를 이용한 모든 통신에서는 git http-backend 와 git 을 함께 사용한다는 것이다.

git 그 자체로는 인증 기능을 가지고 있지 않다.

하지만 웹 서버의 인증 레이어와 손쉽게 연동할 수 있게 돼 있다.

CGI 를 실행할 수 있는 웹 서버라면 어떤 서버든지 붙일 수 있다.





4.7. GitWeb


-

git 은 웹에서 저장소를 조회할 수 있는 GitWeb 이라는 CGI 스크립트를 제공한다.

git 은 GitWeb 을 쉽게 사용해 볼 수 있도록 서버를 즉시 띄우는 명령을 제공한다.

시스템에 lighttpd 나 webrick 과 같은 경량 웹 서버가 설치돼 있어야 사용할 수 있다.

………





4.8. GitLab


-

간단하게 쓰기엔 GitWeb 이 꽤 좋다.

그런데 좀 더 기능이 많은 git 서버를 쓰려면 다른 서버를 찾아 설치해야 한다.

GitLab 은 널리 사용하는 서버 중 하나이다.

…….





4.9. 또 다른 선택지, 호스팅


-

git 서버를 직접 운영하기 부담스러운 경우 git 호스팅 서비스를 이용하면 된다.

이는 설정이 쉽고 서버 관리 비용을 아낄 수 있다는 장점이 있다.





4.10. 요약




반응형

댓글