GitLab + SSH 공개키를 이용한 자동배포

GitLab + SSH 공개키를 이용한 자동배포

Start

Gitlab + AWS 연동에 관한 글을 참 많지만.. 저처럼 IDC 서버를 사용하는 사람들에겐 해당하지 않는 내용이라..

자료도 많지 않고, 설명이 부실한 글들이 많아서 직접 정리해봅니다.

무작정 따라하는것 보다, 공개키를 이용한 SSH 접속의 전체적인 흐름을 이해하고 읽는 것이 훨씬 더 도움됩니다.

SSH 공개키 인증을 사용하여 접속하기

Process

클라이언트 키쌍 생성 (공개키-비밀키) 패스워드 입력 없이 SSH 접속하기 위함.

패스워드 대신 공개키 및 비밀키 사용. Gitlab Variables 등록 배포할 서버의 IP 혹은 도메인 주소 (노출돼도 상관없으면 스크립트에 직접 넣어도 됩니다.)

SSH 비밀키 (생성한 키의 비밀키)

(옵션) 배포 서버의 SSH 공개키 (주의: 생성한 키의 공개키가 아님) known_hosts로 등록하기 위함 서버의 SSH 공개키는 /etc/ssh 경로에 있으며, ssh 설치 시 생성됨

배포 서버에 공개키 등록 (생성한 키의 공개키) ~.ssh/authorized_keys 파일에 등록.

SSH 클라이언트 접속 시, 등록되어있는 공개키의 해당하는 비밀키를 가지고 있다면 접속을 허용해줍니다. Gitlab 스크립트 작성 자동 배포 확인

1. 클라이언트 키쌍 생성

ssh-keygen 명령어를 이용하여 키쌍을 생성합니다. Windows 10이나 대부분 리눅스는 기본적으로 설치가 되어있는데, 없으면 설치하면 됩니다. cmd 창에 ssh-keygen 명령어를 입력하고, 엔터를 쭉쭉 눌러주면 C:Users\계정\.ssh\ 경로에 키쌍이 생성됩니다. ssh-keygen 명령어의 기본 값은 아래와 같습니다. RSA 3072 비트 (SHA256) 키 생성 경로: ~.ssh\ 윈도우, 리눅스 동일 비밀키 (id_rsa) 공개키 (id_rsa.pub) 키에 패스워드를 지정하지 않음.

2. Gitlab Variables 등록

Settings -> CI/CI -> Variables -> Add variable

저는 이미 변수를 등록해놓은 상태입니다.

비밀키 등록 Key 스크립트에서 사용할 변수명

Value 아까 생성한 비밀키(id_rsa)를 붙여넣습니다.

Type File로 변경

서버 IP or 도메인 등록

(Option) 배포 서버의 SSH 공개키 등록

서버에 접속하여, /etc/ssh/ssh_host_*.pub 파일들을 확인합니다.

보통 ssh-server를 설치하면 3개의 키쌍이 생성되는데, 이 중 아무 공개키를 사용해도 무관합니다.

아래와 같이 변수로 등록해줍니다. (서버 IP주소 입력 후 한칸 띄어야 합니다.)

만약 포트가 22번이 아니라면 [IP주소]:포트 형태로 입력합니다. ex) [111.111.111.111]:2243 ssh-ed25519 AAAA.........JJJ

형태로 입력합니다. 이 과정은 하지 않아도 되지만, 하는 이유와 하지않으면 어떤 문제가 있는지 설명합니다.

키를 등록하는 이유

서버에 처음 SSH 접속 시 아래와 같은 메시지를 많이 보셨을겁니다.

로컬에 서버의 키가 등록 되어있지 않은데, 이 서버를 신뢰할 수 있다면 로컬에 서버키를 추가 후 SSH 접속을 하고, 그렇지 않다면 접속하지 않습니다.

키를 추가하게 되면 다음부터 이 서버에 접속할 때 마다, 서버에 대한 인증을 위해 로컬에 저장되어있는 키를 이용하여 인증하는 과정을 거칩니다.

이런 과정을 통해 중간자 공격을 예방하여 안전하게 SSH 접속이 가능합니다.

Gitlab 변수로 등록하는 이유

SSH 클라이언트를 사용하는 우리 입장에서는, 엔터를 치거나 마우스 클릭으로 등록을 하면 됩니다.

그러나, 빌드 할 때마다 매번 새로운 도커 이미지가 생성되고 콘솔에서 조작이 불가능한 Gitlab에서는 스크립트를 통해 서버키를 미리 등록함으로써 해당 과정을 생략할 수 있습니다.

이 과정을 하지 않으면?

공개키 등록 대신에, ssh 설정으로 이 서버키 등록 과정을 생략하고 SSH 접속을 할 수 있습니다.

바로 Host Key Checking을 비활성화 하는 것인데요,

이 옵션을 추가하게 되면, 처음 접속할 때 공개키 등록 없이 바로 SSH 접속이 가능하게 되지만, 중간자 공격에 취약할 수 있습니다.

3. 배포 서버에 공개키 등록

키쌍으로 생성한 공개키를 서버의 ~/.ssh/authorized_keys 파일에 등록합니다. 많이 실수하는 부분인데, SSH로 접속할 계정의 홈디렉토리/.ssh 폴더입니다. 일반 유저계정으로 SSH 접속할건데, /root/.ssh/authorized_keys 파일을 수정하면 안됩니다.

공개키 등록 방법 직접 등록 vi와 같은 편집기를 통해 공개키 복사 및 붙여넣기 합니다. ssh-copy-id 명령어 이용 윈도우 윈도우는 ssh-copy-id 명령어가 없기 때문에, 다른 명령어로 대체합니다. type $env:공개키위치 | ssh 계정@IP "cat >> .ssh/authorized_keys" 만약 Windows에서 키쌍을 생성했다면 공개키의 경로는 C:\Users\계정\.ssh\id_rsa.pub 입니다. 위 명령어를 수행하면 공개키값을 변수에 담아서 SSH 접속 후, .ssh/authorized_keys에 붙여 넣게됩니다. 서버에 접속 후 authorized_keys을 확인해보면 공개키값이 잘 들어가있는 것을 확인 할수 있습니다. 리눅스계열 리눅스는 간단합니다. ssh-copy-id 계정@IP 해당 명령어를 입력하면 ~/.ssh 폴더에 있는 공개키를 해당 서버에 등록합니다.

4. 스크립트 작성

프로젝트 최상위 폴더에 .gitlab-ci.yml 파일을 생성합니다.

아래 스크립트 내용 붙여넣습니다.

stages: - build - deploy image: java:8-jdk # jdk8 도커 이미지 사용 (배포환경에 따라 변경할 것) cache: paths: # .gradle 캐시 적용 - .gradle/wrapper - .gradle/caches build: stage: build before_script: - chmod +x ./gradlew # gradlew 실행권한 부여 (초기 권한 666 [-rw-rw-rw-]) script: - ./gradlew build artifacts: paths: - build/libs/*.jar # build의 결과물인 jar파일을 artifacts로 지정. expire_in: 1 week # 1주일 동안 보관 deploy-to-server: stage: deploy before_script: - mkdir -p ~/.ssh - eval $(ssh-agent -s) # ssh-agent 백그라운드 실행 ############################################### # 공개키 등록을 안했다면 Host Key Checking 비활성화 옵션 추가 (중간자 공격 위험) # - '[[ -f /.dockerenv ]] && echo -e "Host *

\tStrictHostKeyChecking no

" >> ~/.ssh/config' # 공개키 등록을 했다면 known_hosts 등록 및 권한 변경 # - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts # - chmod 644 ~/.ssh/known_hosts ############################################### - chmod 600 "$SSH_KEY" # 개인키 파일 권한변경 - ssh-add "$SSH_KEY" # SSH 개인키 추가 script: # SSH를 이용한 원격 파일 업로드 - scp build/libs/*.jar 계정명@"$DEPLOY_SERVER_IP":~/BUILD_PATH/build.jar # 원격 스크립트 실행 - ssh 계정명@"$DEPLOY_SERVER_IP" /BUILD_PATH/start.sh

아래는 서버에서 실행 할 원격 스크립트 파일 내용입니다.

단순히 기존 프로세스가 있으면 kill 후 재실행, 없으면 그냥 실행합니다. #!/bin/sh cd ~/BUILD_PATH PID=$(ps -ef|grep build.jar|grep -v grep|awk '{print $2}') if [ "$PID" == "" ]; then echo "no process exist" else echo "process id (${PID}) killed" kill -9 ${PID} fi echo "Program Start" nohup java -jar build.jar 1 > /dev/null 2>&1

5. 자동 배포 확인

Gitlab으로 Push 하여 CI/CD를 동작시킵니다.

별다른 문제 없이 성공하였다면, 서버에 접속하여 프로세스가 동작하는지 확인합니다.

반응형

from http://2dongdong.tistory.com/75 by ccl(A) rewrite - 2021-09-14 15:27:13