git 알아보기 #8 : github 사용하기

지금까지는 가장 기본적인 기능들에 집중해서 remote라고 해봤자 로컬 폴더에 생성해 사용해 봤었다. 실제로 팀단위로가거나 규모가 큰 경우, github, gitlab, Bitbucket 등의 서비스를 사용하거나 직접 셀프호스팅하는 서비스를 사용하기도 한다. 셀프호스팅에는 오픈소스로 제공되는 Gitea, Forgejo 등이 있다. Forgejo는 Gitea가 상용 서비스 회사가 되자, 생겨난 것으로 보인다.

이러나 저러나 예전부터 막강한 기능과 제일 만만한(?) 존재는 github이다. 여기서는 github의 기본적인 연결방법만 간단하게 다루겠다. github은 단순한 git의 기능 이상으로 서비스를 제공한다. 프로젝트의 전반적 관리부터 개발에 꼭 필요한 버그 이슈트래킹, 릴리즈관리 등등 사실 나도 회사나 팀단위로는 써본적이 없어서 잘 모른다.

앞에서 로컬 디렉토리에 git을 remote로 사용해보긴 했지만, 이런 클라우드 서비스와 같은 존재들은 어떻게 git을 사용하는걸까 의문이 들것이다. 웹이 http로 연결되듯, git은 repository간 데이터를 주고받는 프로토콜로 ssh, http(s)를 지원한다. 보통은 ssh를 주로 사용하게 된다.

그럼, github의 사용에 대해 알아보자.

github

github은 개인프로젝트 수준에서 누구나 무료로 사용가능하다. 물론, 팀단위가 되기 시작하면 유료사용이 필요하다. 가격에 대해선 다음 링크를 참조. https://github.com/pricing

그냥 하면 되는 계정만들기 같은걸 설정하진 않을 것이다. 가입을 하고나서 새 repository를 만들고 로컬에서 어떻게 연결하는지만 설명할 것이다. 필요하다면 github의 공식 문서를 참조하기 바란다.

사실, github에서 제공하는 문서보다 잘 작성할 자신이 없다. 그냥 이 문서들을 참조하는게 좋을수도 있다. 굳이 내가 뭔가를 작성해야하나 생각하다가 그래도 앞에서 해왔던 내용이 있기때문에 아주 간단하게나마 github정도 연결해주는 내용이 필요하다고 느꼈다. 왜냐하면, 내가 오랫만에 사용하려다가 단순 id/password로 github repository사용이 불가능해졌다는걸 알았기 때문이다. github 웹사이트는 id/password로 로그인해서 사용이 가능하지만, remote repository사용은 보안문제로 더이상 이걸 지원하지 않는다. password 대신, ssh key를 생성해서 사용하는 방법과 github에서 제공하는 personal access token을 생성해서 사용하는 방법을 지원한다.

일단, repository를 생성해야 뭘 하든 말든 할테니 repository를 github에서 만들어보자. github 왼쪽에 repository 보여주는 곳을 보면 new 버튼이 있다.

버튼을 누르면 repository정보를 입력하는 창이 뜬다. 예를 들면 다음과 같다.

repository이름을 입력하고 Choose visibility를 Public 또는 Private으로 설정한다. 남에게 보여줘도 되는 작업은 Public이고, 코드를 보여주면 안되는 프로젝트라면 Private으로 반드시 설정한다. 여기서는 개발 프로젝트라기 보단, 내가 나중에 참조할만한 python 예제코드 모음정도로 사용할 repository로 이름을 py-snippetz 라고 정했다. s를 z로 적어 혼란스럽지 않게 유니크한 뻔하지 않은 이름으로 만들었다. visibility는 딱히 남에게 보여줘도 상관없고 도움이 될 수도 있으니까 public으로 설정했다.

repository 이름과 visibility설정 외에는 옵션이지만, 새로운 프로젝트라면 다 선택해주는게 좋다. Description은 프로젝트에 대한 간단 설명인데, 여기에 입력한 내용은 README.md 파일 생성시, 그 내용으로 들어간다. Add README는 off로 되어있는데, github에서 repository를 들어가면 처음 보여주는 화면이다. 간단하게 프로젝트 설명정도는 넣어서 추가해주는게 좋으니 On으로 바꿔준다. .gitignore는 repository에 올라가는 파일의 필터링 설정인데, 컴파일이든, 백업파일이든, 로컬에서만 생성되는 파일들이 존재하므로 대부분 필요하다. 드랍박스를 눌러보면, 친절하게도 프로젝트별로 이미 다 만들어 놨다. 프로젝트에 따라 원하는걸 선택해준다. Add license는 Private작업에는 굳이 넣어줄 필요가 없을 것이다. 하지만, Public으로 하는 순간 사실상 open source 프로젝트가 되기 때문에 선택을 해주는게 좋다. 라이센스를 선택하면 github에서 자동으로 라이센스가 표시되며, 파일이 추가된다. 보통 맘대로 써도 되는 소스의 경우 “Apache License 2.0” 이나 “MIT License”를 선택해 주는데, 둘 다 다른사람이 원작자 license표시만 해주면 그 외엔 거의 자유로운 저작권이다. 관련된 내용을 한 번씩 읽어보고 선택해줘도 좋다.

Create repository 버튼을 눌러주면 repository가 생성되며 다음과 같이 화면이 뜬다.

repository에 대한 정보들과 생성된 파일들이 보인다. 선택한 내용에 따라 .gitignore, LICENSE 파일이 자동으로 추가되어 있으며, README.md 파일도 추가되어 있고, 아래쪽으로 Description에 적은 내용이 표시되고 있다. 이 아래쪽에 표시되는 내용이 README.md 파일내용이다. md파일로 markdown 문서로 작성된 내용이 보여진다. 이렇게 repository생성은 손쉽게 되었다.

personal access token

이렇게 생성한 github repository에 remote로 접근하기 위해선 password사용이 금지됐으므로 다른 방법을 사용해야 한다. 첫번째로 알려주는 방법은 personal access token을 사용하는 것이다. 이에대한 자세한 내용은 공식문서를 참조하기 바란다.

personal access token은 github 사이트에서 직접 발행한 token을 로컬에서 password대신 사용하는 방식이다. token이라는 이름에서 유추가능한 부분인데, 원래는 github api를 사용할 때 쓰기 위한 것으로 보인다. 다만, remote로 사용시 password 대용으로도 사용가능하다.

먼저, token을 발행해보자. profile 사진을 클릭하고 settings에 들어간다.

제일 밑으로 스크롤하면 developer settings가 있다. 이걸 클릭.

왼쪽에 메뉴가 또 나오는데, Personal Access Token>Tokens(classic)을 선택한다. fine-grained tokens도 있는데, 이는 token의 세부권한부터 만료기한까지 세세한 부분까지 설정이 가능하다. 보안상 이게 더 좋다고 하지만, 그렇게 엄격한 상황이 아니므로, 보다 쓰기편한 classic을 선택했다.

위 화면은 이미 토큰이 하나 존재하는 화면으로, 토큰이 아예 없는 경우와 다를 수 있다. 어쨌든, “generate new token” 버튼을 클릭하여 토큰을 생성해보자. 여기서도 drop down메뉴가 나오는데 “generate new token(classic)” 을 선택한다.

엄청 많은 내용들이 나온다. 일단, Note에 토큰의 목적을 간단히 적자. 다음으로 Expiration이 있는데, 여기서는 “No expiration”을 선택해 영원히 사용가능하게 만들었지만, 보안상 권장하지는 않는다. 보통, 그냥 git push/pull 정도만 할거라면 repository 권한인 repo만 선택하면 충분하다. 체크할 항목들이 너무 많다고 고민하지 말자.

토큰이 생성되고 위 화면이 출력되는데, 정말 중요하고 주의할 것이 토큰은 단 한번만 노출된다. 내 토큰이라 빨간색으로 지우긴 했는데, 위 화면에서 카피해서 로컬에 저장해놓고 잘 간직하기 바란다. 이 토큰을 password대신 입력하면 된다. 다음과 같이 입력이 가능하다.

~> git clone https://github.com/USERNAME/REPO.git
Username: YOUR-USERNAME
Password: YOUR-PERSONAL-ACCESS-TOKEN

이렇게 clone을 하면, 자동으로 token이 저장되어 다시 입력할 필요가 없다고 하는 것 같다. 검증해보진 않았음. 다음과 같이, git에서 credential.helper를 설정하고 clone을 하면,

git config --global credential.helper store

clone이 인증 정보를 로컬에 저장한다고도 한다. 다만, 평문저장이므로 보안에 취약할 수 있다. 가능하면, 다음에 나오는 ssh key를 이용하는 방식이 보다 보편적이지 않을까 생각한다.

만약, repository별로 credential정보를 저장하고 싶다면, 다음과 같이 global을 빼고 실행한다.

git config credential.helper 'store --file=.git/my-credentials'

뒤에 –file 옵션으로 저장위치를 지정할 수도 있다.

ssh key

personal access token보단, 이 방법이 더 좋고 일반적이지 않을까 생각한다. ssh key사용법에 대해 알아보자. github에서 ssh key를 사용하는 방법은 공식 문서에 잘 나와있다.

직접 생성을 해보면 다음과 같다.

~>ssh-keygen -t ed25519 -C "batmask@naver.com"                 
Generating public/private ed25519 key pair.

ssh-keygen 툴을 사용하는데, -t 옵션은 생성 알고리즘을 선택하는 부분이다. 최근에는 ed25519 를 주로 사용한다. 공식문서를 보면, dsa는 github에서 더이상 지원하지 않는다고 하고, rsa는 사용할 수 있지만, 제약이 조금 있어 보인다.

다음으로 저장할 파일이름을 적으라고 나온다. default 이름이 있으므로 그냥 엔터를 친다.

Enter file in which to save the key (/home/batmask/.ssh/id_ed25519): 

다음으로는 passphrase를 입력하라고 나오는데, 생성한 ssh key 자체를 읽을 때 보안을 위해서 password설정을 하는 것이다. 보안을 위해서는 암호를 입력하는게 좋다. 암호가 없는데 누군가 내 계정을 탈취했다면, 바로 ssh key도 가져갈 수 있기 때문이다. 비번을 입력하고, 한 번 더 입력하라고 나올 때 한 번 더 입력 후 엔터.

Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in github
Your public key has been saved in github.pub
The key fingerprint is:
SHA256:Z4YfJEgYpDD1CyGXIT6xHCovbe7aCIwKAjuKfRICb8c batmask@naver.com
The key's randomart image is:
+--[ED25519 256]--+
|=+=+oo.          |
|+*=+.. .         |
|o=o . . . .      |
|oo.. .   +       |
|+.+..   S =      |
|==+ E    = .     |
|B+.o      .      |
|B*. .            |
|*.+o             |
+----[SHA256]-----+

키가 생성되었다. ~/.ssh/밑에 가보면 id_ed25519, id_ed25519.pub 두개 파일이 보일 것이다. 전자가 private key, 뒤에 pub 확장자가 붙은게 public key이다. 이 public key를 github에 등록해두면 되는 것이다.

여기서 의문이 들 수 있는데, public key만 github에 주는데 어떻게 암호화 네티워킹이 가능할까? 데이터 자체를 이 ssh key를 이용해 암호화 하는건 아니고, 사용자가 인증된 사용자인지 검증하는데만 사용된다. 간단히 말해, 등록된 public key에 대응하는 private key 를 가지고 있는지 테스트를 한다.

github에서 public key로 암호화한 랜덤 데이터(챌린지)를 보내면, 사용자는 private key로 이걸 풀어서 private key로 생성한 signature를 함께 github에 다시 보낸다. private key로 생성한 signature는 public key로만 풀 수 있고, github은 가지고 있는 public key를 이용해 이게 대응하는 private key로 sign되었다는걸 검증할 수 있다. 이 과정을 통해 password대신 사용자 인증을 진행한다.

마지막으로 ssh-agent에 키를 추가해야 한다. 윈도우즈의 경우엔 좀 다를텐데 공식문서의 windows 부분을 참고하자. 내가 사용하는 linux mint에서는 이미 알아서 실행이 되어 있다. 실행이 안되어 있으면, 터미널 연결시 자동으로 쉘에서 실행하도록 다음을 추가하면 된다.

eval "$(ssh-agent -s)"

eval 이란 주어진 문자열을 쉘에서 해석을 해서 실행을 시키는 커맨드이다. “ssh-agent -s” 커맨드를 그냥 실행해 보면,

SSH_AUTH_SOCK=/tmp/ssh-XWtf4E4m2ISF/agent.52363; export SSH_AUTH_SOCK;
SSH_AGENT_PID=52364; export SSH_AGENT_PID;
echo Agent pid 52364;

위와 같은 출력이 나온다. pid를 스스로 지정해서 SSH_AUTH_SOCK, SSH_AGENT_PID 환경변수를 설정하는 내용인데, 고정된 값이 아니다. 그래서 이 “ssh_agent -s”의 출력을 새로받아와 eval을 통해서 실행시키는 것이다.

이제 ssh-agent가 실행중이라면, 생성한 ssh key를 등록한다.

~>ssh-add ~/.ssh/id_ed25519
Enter passphrase for /home/batmask/.ssh/id_ed25519: 
Identity added: /home/batmask/.ssh/id_ed25519 (batmask@naver.com)

중간에 passphrase를 물어보는데, 설정한 값을 입력한다. 이제 등록된 값을 ssh-add -L 옵션으로 확인해보면,

~>ssh-add -L                                  
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAR29yRBuVAeMVGfitX0OhpSic00tnn4hRtd9zJY+14t batmask@naver.com

.ssh/밑에 있는 public key값이 그대로 들어가 있음을 확인할 수 있다. 재부팅마다 ssh-add를 해야하나 싶은데, 알아보니 OS에 따라 다르지만, 맥이나 ssh-agent가 자동 실행되는 linux mint같은 경우는 key-chain을 알아서 관리해서 그럴 필요가 없다고 한다. 실제로 재부팅을 해도 키 값을 확인할 수 있었다.

마지막으로 생성했던 public key를 github에 등록해야 한다. github 화면의 오른쪽 profile을 클릭해서 settings를 들어가보면,

왼쪽에 “SSH and GPG keys”라는 항목이 있고 이를 선택하면 SSH key를 등록하는 화면이 나온다. 여기서 생성한 키를 추가해보자.

먼저, 가지고 있는 public key를 확인해야 한다. 다음과 같이 cat 명령어로 public key 내용을 보고 복사하자.

~/output/python>  cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAR29yRBuVAeMVGfitX0OhpSic00tnn4hRtd9zJY+14t batmask@naver.com

리눅스 터미널에서 copy/paste는 shift+ctrl+c / shift+ctrl+v 로 이루어진다.

이제, github 화면으로 돌아가서 New SSH Key 버튼을 눌러 추가하자.

title은 그냥 이 키를 사용하는 컴퓨터 이름을 입력했다. key type은 authentication 과 signing이 있는데 authentication을 선택한다. 그리고 Key 부분에 확인했던 public key를 넣어준다. 그리고 나면, 다음과 같이 확인 창이 뜬다.

보안을 강화하는거 뭐 좋은데, 진짜 사람을 너무 괴롭힌다. password로 안되니 ssh key를 넣어야 하고, 이것도 또 이중으로 Passkey를 이용해서 2중 인증을 해야하고… 뭐 아뭏튼 해주자.

위와같이 키가 추가된걸 확인할 수 있다.

remote git 설정

이제 내 작업 PC에서 git을 설정해보자. 내가 작업한 내용을 올리는 경우는 remote를 직접 지정해야겠지만, 여기서는 첫 설정이라 가정하고 아까 생성한 repository를 clone해서 가져와보자.

github의 repository를 확인해서 “<>Code”버튼을 눌러보면 clone할 url이 표시된다. ssh 항목을 클릭해서 확인하고 카피하자.

이제, 작업할 디렉토리에서 위의 url을 이용해 git clone을 실행하자.

~/output/python>  git clone git@github.com:batmask77/py-snippetz.git
'py-snippetz' 복제합니다...
The authenticity of host 'github.com (20.200.245.247)' can't be established.
ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

위와같이 뜨는데, 이건 ssh 인증이 안된게 아니고 github에 처음 연결하게 되서 github이 맞는지 확인하라고 fingerprint를 보여주는 것이다. 이건 github쪽 내용을 보면 확인이 가능하다. 필요시, 링크의 내용을 보고 ~/.ssh/known_hosts 의 내용을 작성하면 이런 내용은 다시 안뜨게 될 것이다. “yes”를 입력하면 작업이 완료되고 해당 폴더가 생성된걸 확인할 수 있다.

~/o/python>  ls
anaconda  django  jupyter  py-snippetz
~/output/python>  cd py-snippetz      
~/o/p/py-snippetz │ main>  ls        
LICENSE  README.md
~/o/p/py-snippetz │ main>  ls -la    
합계 28
drwxrwxr-x 3 batmask batmask 4096  5 13 15:51 .
drwxrwxr-x 6 batmask batmask 4096  5 13 15:49 ..
drwxrwxr-x 7 batmask batmask 4096  5 13 15:51 .git
-rw-rw-r-- 1 batmask batmask 4628  5 13 15:51 .gitignore
-rw-rw-r-- 1 batmask batmask 1064  5 13 15:51 LICENSE
-rw-rw-r-- 1 batmask batmask   66  5 13 15:51 README.md

간단하게 remote push 확인을 위해 README.md 파일을 수정해보자. “project begins now”라는 문구를 넣어봤다.

# py-snippetz
This is the project for my python tips and snippets
project begins now.

다음과 같이 먼저 로컬 git에 commit하자.

~/o/p/py-snippetz │ main !1>  git add .  
~/o/p/py-snippetz │ main +1>  git commit -m "first commit"      

git push로 remote branch로 보내보면,

~/o/p/py-snippetz │ main ⇡1>  git push
오브젝트 나열하는 중: 5, 완료.
오브젝트 개수 세는 중: 100% (5/5), 완료.
Delta compression using up to 12 threads
오브젝트 압축하는 중: 100% (3/3), 완료.
오브젝트 쓰는 중: 100% (3/3), 314 bytes | 314.00 KiB/s, 완료.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.com:batmask77/py-snippetz.git
   1d12804..d734108  main -> main

성공적으로 push 가 된 것을 확인할 수 있다. 이는 github 사이트에 들어가서도 확인이 가능하다. 생성했던 repository 화면으로 들어가보면, 오른쪽에 Activity라는 항목이 보인다.

Activity를 클릭해보면,

커밋한 내용이 표시가 되는걸 확인 할 수 있다.

Previous post git 알아보기 #7 : git remote / push / pull / fetch/ clone

관련 글

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다