Physical Address
South Korea
Physical Address
South Korea

진행중인 프로젝트에서 어플리케이션 아키택터 요청으로 CI/CD 를 위한 배포 환경 구성을 위해 SSH Key 를 통한 배포 환경을 구성해 보았습니다. 현대적인 DevOps 환경에서 수동 배포는 더 이상 선택지가 아닙니다. 특히 보안이 강조되는 배포 프로세스에서 비밀번호 없는 인증(Passwordless Authentication)은 필수적인 요소입니다.
오늘 포스팅에서는 GitLab Runner(도커 기반)를 활용하여 개발(Dev), QA, 운영(Prod) 서버에 안전하게 접속하고 코드를 배포하기 위한 SSH Key 관리 및 환경 구성 전략을 상세히 알아보겠습니다.

일반적으로 서버 접속 시 비밀번호를 사용하면 무차별 대입 공격(Brute-force)에 노출될 위험이 큽니다. 반면, SSH 키 쌍(Public/Private Key)을 이용하면 다음과 같은 이점이 있습니다.
먼저 GitLab Runner가 사용할 SSH 키를 생성해야 합니다. 보안을 위해 Ed25519 알고리즘 사용을 권장합니다.
Bash
# 특정 환경을 위한 키 생성 (예: gitlab-deploy)
ssh-keygen -t ed25519 -C "gitlab-ci-deployment" -f ~/.ssh/id_ed25519_gitlab
보안과 안정성을 위해 각 환경은 물리적 또는 논리적으로 분리되어야 합니다. GitLab의 Environments 기능을 활용하면 효율적입니다.
배포 대상 서버에 접속하여 생성한 공개키를 등록합니다.
Bash
echo "ssh-ed25519 AAAAC3Nza..." >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
GitLab 프로젝트의 Settings > CI/CD > Variables 메뉴에서 다음 변수들을 등록합니다.
| 변수명 | 설명 | 보안 설정 |
| SSH_PRIVATE_KEY | 생성한 Private Key 내용 전체 | Masked & Protected |
| SERVER_IP_DEV | 개발 서버 IP 주소 | – |
| SERVER_IP_PROD | 운영 서버 IP 주소 | – |
도커 기반의 GitLab Runner에서 SSH 에이전트를 실행하고 키를 주입하는 과정입니다.
YAML
before_script:
- 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan $SERVER_IP >> ~/.ssh/known_hosts
deploy_prod:
stage: deploy
script:
- ssh root@$SERVER_IP_PROD "cd /var/www/app && git pull origin main && docker-compose up -d"
only:
- main
environment:
name: production효율적인 소프트웨어 개발 생태계에서 배포 자동화는 필수적입니다. 하지만 단순히 코드를 서버에 옮기는 것을 넘어, 어떤 구조로 데이터가 흐르고 보안을 어떻게 유지할 것인지에 대한 설계가 선행되어야 합니다. 이번 포스팅에서는 GitLab CI/CD를 활용한 표준 배포 아키텍처와 논리적 흐름을 상세히 살펴보겠습니다.
안정적인 배포 환경을 구축하기 위해서는 역할을 명확히 분리해야 합니다. 본 가이드에서 제안하는 아키텍처는 크게 세 가지 계층으로 나뉩니다.
GitLab 서버는 단순히 소스 코드를 저장하는 곳이 아닙니다. 배포 프로세스의 두뇌 역할을 하며 다음과 같은 핵심 데이터를 관리합니다.
실질적인 배포 명령을 수행하는 주체입니다. 도커 컨테이너 환경에서 동작하는 Runner를 사용하면 다음과 같은 장점이 있습니다.
코드가 실행될 실제 서버입니다. 보안 강화를 위해 root 계정이 아닌 webadmin과 같은 일반 계정을 사용하여 배포를 수행하는 것을 권장합니다. 이는 배포 프로세스에서 발생할 수 있는 실수나 해킹 공격으로부터 시스템 핵심 영역을 보호하는 최소 권한 원칙(Principle of Least Privilege)을 준수하기 위함입니다.
배포가 시작되면 코드는 다음과 같은 흐름을 거쳐 사용자에게 전달됩니다.
성공적인 아키텍처 구성을 위해 다음 사항을 반드시 점검하세요.

GitLab CI/CD를 활용해 자동화 배포 환경을 구축하다 보면, 분명히 SSH 키를 등록했음에도 불구하고 파이프라인 로그에서 패스워드를 요구하며 멈춰버리는 현상을 마주할 때가 있습니다. 자동화 배포에서 사용자 개입이 필요한 패스워드 입력 요구는 곧 배포 실패를 의미합니다.
오늘은 SSH 키 인증 대신 패스워드 입력을 요구하는 대표적인 원인 3가지와 그 해결 방법을 상세히 알아보겠습니다.
SSH 인증 시스템은 보안을 최우선으로 하기 때문에, 키 파일이나 관련 디렉토리의 권한이 지나치게 개방되어 있으면 보안 위협으로 간주하고 해당 키를 무시해 버립니다. 이 경우 시스템은 차선책으로 패스워드 인증을 시도하게 됩니다.
가장 먼저 배포 대상 서버에 접속하여 다음 권한들을 확인하십시오.
webadmin 계정의 홈 디렉토리는 그룹이나 타인에게 쓰기 권한이 있어서는 안 됩니다.
실제 키가 저장된 디렉토리와 파일 권한은 더욱 엄격해야 합니다.
만약 권한이 틀리다면 아래 명령어로 수정하세요.
Bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
두 번째로 점검할 항목은 현재 사용 중인 개인키와 서버에 등록된 공개키가 실제로 한 쌍인지 확인하는 것입니다.
로컬 환경이나 GitLab CI/CD Variables에 저장된 개인키가 서버의 authorized_keys에 등록된 공개키와 매칭되지 않으면 인증은 실패합니다. 키를 생성할 때 여러 개를 생성했다면 혼동이 생기지 않았는지 다시 확인해야 합니다.
여러 개의 SSH 키를 관리하는 경우, SSH 클라이언트가 엉뚱한 키를 사용하고 있을 수 있습니다. 배포 스크립트에서 명시적으로 -i 옵션을 사용하여 개인키 경로를 지정했는지 확인하십시오.
GitLab CI/CD 환경이라면 변수에 저장된 키가 파일로 정상적으로 생성되어 해당 경로를 가리키고 있는지 로그를 통해 검토해야 합니다.
디렉토리 권한과 키 쌍에 문제가 없다면, 배포 대상 서버 자체의 SSH 설정에서 키 인증이 비활성화되어 있을 가능성이 있습니다.
서버의 SSH 설정 파일인 /etc/ssh/sshd_config를 열어 다음 항목이 주석 처리되어 있거나 no로 되어 있는지 확인하십시오.
설정을 변경했다면 반드시 SSH 서비스를 재시작해야 변경 사항이 적용됩니다.
Bash
sudo systemctl restart sshd워드프레스 블로그 운영과 구글 검색 최적화(SEO)를 고려하여, 결론 및 권장사항을 중심으로 한 전문적인 기술 포스팅을 작성해 드립니다. 요청하신 대로 강조 기호()는 모두 제거했습니다.
성공적인 GitLab CI/CD 파이프라인 구축은 단순히 코드를 자동으로 배포하는 것에 그치지 않습니다. 진정한 자동화의 가치는 보안이 전제될 때 발휘됩니다. 지금까지 살펴본 SSH 키 설정과 환경 구성을 바탕으로, 실제 운영 환경에서 반드시 지켜야 할 보안 원칙과 관리 권장사항을 정리해 보겠습니다.
많은 개발자가 배포 설정의 편의성을 위해 root 계정을 직접 사용하려는 유혹에 빠지곤 합니다. 하지만 이는 보안 측면에서 매우 위험한 선택입니다.
배포는 반드시 root가 아닌 webadmin이나 deployer 같은 별도의 일반 계정을 생성하여 수행해야 합니다.
첫째, 시스템 보호입니다. 만약 배포 스크립트의 실수나 파이프라인 취약점으로 인해 공격자가 침입하더라도, 일반 계정은 시스템 전체를 제어할 수 있는 권한이 없으므로 피해 범위를 최소화할 수 있습니다. 둘째, 책임 소재의 명확화입니다. 서비스 구동에 필요한 파일에만 접근 권한을 부여함으로써 데이터베이스나 시스템 설정 파일이 의도치 않게 수정되는 것을 방지할 수 있습니다.
SSH 키 쌍을 생성한 후 가장 간과하기 쉬운 부분이 바로 로컬 PC나 임시 서버에 남은 개인키 파일 관리입니다.
GitLab CI/CD 변수(Variables)에 개인키 등록이 완료되었다면, 해당 키를 생성했던 Runner 서버나 로컬 PC의 .ssh 디렉토리에 있는 개인키 파일은 즉시 삭제해야 합니다.
이미 GitLab의 보안 변수 시스템에 안전하게 저장되었기 때문에 더 이상 로컬에 파일을 남겨둘 이유가 없습니다. 물리적인 파일이 존재하지 않는 것만으로도 잠재적인 키 유출 경로를 원천 차단하는 가장 확실한 방법이 됩니다.
보안은 한 번의 설정으로 끝나지 않습니다. 시간이 지남에 따라 관리자의 부주의나 알려지지 않은 취약점으로 인해 키가 노출될 가능성은 항상 존재합니다.
우리는 최소 1년 단위로 SSH 키를 재생성하여 교체하는 것을 강력히 권장합니다.
정기적인 갱신은 혹시 모를 키 복제 사고로부터 시스템을 보호하는 최후의 방어선이 됩니다.
GitLab CI/CD를 통한 배포 자동화는 개발 생산성을 비약적으로 향상시킵니다. 하지만 그 기반이 되는 SSH 인증 체계가 무너진다면 기업의 소중한 자산인 코드가 위협받을 수 있습니다.
오늘 강조한 세 가지 원칙, 즉 일반 계정 사용, 개인키 파일 폐기, 정기적인 키 갱신만 철저히 지켜도 훨씬 견고한 DevOps 환경을 운영할 수 있습니다. 지금 여러분의 배포 파이프라인 설정을 다시 한번 점검해 보시기 바랍니다.
[RHEL 9.6: Nginx – Tomcat 리버스 프록시 구성]