FortiGate VPN과 Docker를 활용한 보안 강화 CI/CD 파이프라인 구축

문한성·2025년 2월 26일
0

소개

현대 소프트웨어 개발에서 CI/CD(지속적 통합/지속적 배포) 파이프라인은 빠른 개발 사이클과 안정적인 배포를 위한 핵심 요소가 되었습니다. 특히 보안이 중요한 프로젝트에서는 VPN과 같은 보안 인프라를 CI/CD 파이프라인과 결합하는 것이 필수적입니다. 이 글에서는 GitHub Actions, FortiGate VPN, Docker Private Registry를 활용한 실제 CI/CD 파이프라인 구축 사례를 공유하고자 합니다.

아키텍처

아키텍처 개요

이 CI/CD 파이프라인은 다음과 같은 구성 요소로 이루어져 있습니다:

  1. GitHub Actions: 코드 변경 감지 및 워크플로우 실행
  2. FortiGate VPN: 내부망 접근을 위한 보안 연결
  3. Docker Private Registry: 컨테이너 이미지 저장소
  4. 내부 서버: Docker Compose로 관리되는 컨테이너 배포 환경

GitHub Actions 워크플로우 상세 분석

다음은 실제 사용된 GitHub Actions 워크플로우 파일을 민감한 정보를 제거하고 분석한 내용입니다:

name: Deploy to Docker Private Registry via FortiGate VPN
on:
  push:
    branches:
      - topic/ci-cd  # 특정 브랜치에 push될 때 워크플로 실행
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest  # Ubuntu 최신 버전에서 실행
    steps:
      # 리포지토리 체크아웃
      - name: Checkout repository
        uses: actions/checkout@v2
        
      # openfortivpn 설치
      - name: Install openfortivpn
        run: sudo apt-get update && sudo apt-get install -y openfortivpn
        
      # Forti VPN 연결
      - name: Connect to FortiGate VPN
        run: |
          sudo openfortivpn [VPN_SERVER]:[VPN_PORT] \
            -u [VPN_USERNAME] \
            -p "[VPN_PASSWORD]" \
            --trusted-cert "[VPN_CERT_SHA1]" &
          sleep 10
          
      # Docker Private Registry 인증서 적용
      - name: Apply Docker Private Registry Cert
        run: |
          echo "[CERTIFICATE_CONTENT]" | sudo tee /usr/local/share/ca-certificates/dpr.crt
          sudo update-ca-certificates
          sudo systemctl restart docker
          
      # Docker 이미지 빌드 및 태그
      - name: Build and tag Docker image
        run: |
          docker build -t api-service-dev .
          docker tag api-service-dev [REGISTRY_URL]/api-service-dev:latest
          
      # Docker Private Registry에 로그인
      - name: Login to Docker Private Registry
        run: echo [REGISTRY_PASSWORD] | docker login [REGISTRY_URL] -u [REGISTRY_USERNAME] --password-stdin
        
      # SSH 설정
      - name: Setup SSH
        run: |
          mkdir -p ~/.ssh
          echo "[SSH_PRIVATE_KEY]" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan [SERVER_IP] >> ~/.ssh/known_hosts
          
      # 내부 서버 컨테이너 교체
      - name: Deploy on Server
        run: |
          ssh -o StrictHostKeyChecking=no root@[SERVER_IP] "bash -s" << 'EOF'
            cd /app/config
            docker-compose -f app-service.yml pull api-service
            docker-compose -f app-service.yml up -d --no-deps api-service
            echo "api-service container deployment completed."
          EOF

주요 구성 요소 분석

1. GitHub Actions 워크플로우 트리거

on:
  push:
    branches:
      - topic/ci-cd

이 설정은 topic/ci-cd 브랜치에 코드가 푸시될 때만 워크플로우가 실행되도록 합니다. 특정 브랜치를 지정함으로써 모든 브랜치의 변경에 반응하지 않고, 배포 준비가 완료된 코드만 파이프라인에 들어가도록 제한합니다.

2. FortiGate VPN 연결

- name: Install openfortivpn
  run: sudo apt-get update && sudo apt-get install -y openfortivpn

- name: Connect to FortiGate VPN
  run: |
    sudo openfortivpn [VPN_SERVER]:[VPN_PORT] \
      -u [VPN_USERNAME] \
      -p "[VPN_PASSWORD]" \
      --trusted-cert "[VPN_CERT_SHA1]" &
    sleep 10

이 단계에서는 openfortivpn 클라이언트를 설치하고 FortiGate VPN에 연결합니다. GitHub Secrets에 저장된 VPN 접속 정보를 사용하여 내부망에 안전하게 접근합니다. & 연산자를 사용하여 VPN 연결을 백그라운드로 실행하고, sleep 10 명령으로 연결이 완전히 설정될 때까지 기다립니다.

3. Docker Private Registry 설정

- name: Apply Docker Private Registry Cert
  run: |
    echo "[CERTIFICATE_CONTENT]" | sudo tee /usr/local/share/ca-certificates/dpr.crt
    sudo update-ca-certificates
    sudo systemctl restart docker

Docker Private Registry가 자체 서명된 인증서를 사용하는 경우, 이 단계에서 인증서를 시스템에 추가합니다. 이를 통해 Docker 클라이언트가 프라이빗 레지스트리를 신뢰할 수 있게 됩니다.

4. Docker 이미지 빌드 및 푸시

- name: Build and tag Docker image
  run: |
    docker build -t api-service-dev .
    docker tag api-service-dev [REGISTRY_URL]/api-service-dev:latest

- name: Login to Docker Private Registry
  run: echo [REGISTRY_PASSWORD] | docker login [REGISTRY_URL] -u [REGISTRY_USERNAME] --password-stdin

이 단계에서는 리포지토리의 코드로 Docker 이미지를 빌드하고, 적절한 태그를 붙인 후, 프라이빗 레지스트리에 로그인합니다. GitHub Secrets에 저장된 레지스트리 자격 증명을 사용하여 인증합니다.

5. 애플리케이션 배포

- name: Setup SSH
  run: |
    mkdir -p ~/.ssh
    echo "[SSH_PRIVATE_KEY]" > ~/.ssh/id_rsa
    chmod 600 ~/.ssh/id_rsa
    ssh-keyscan [SERVER_IP] >> ~/.ssh/known_hosts

- name: Deploy on Server
  run: |
    ssh -o StrictHostKeyChecking=no root@[SERVER_IP] "bash -s" << 'EOF'
      cd /app/config
      docker-compose -f app-service.yml pull api-service
      docker-compose -f app-service.yml up -d --no-deps api-service
      echo "api-service container deployment completed."
    EOF

마지막 단계에서는 SSH를 설정하고 내부 서버에 접속하여 배포를 수행합니다. Docker Compose를 사용하여 이미지를 풀하고 컨테이너를 업데이트합니다. --no-deps 옵션은 종속 서비스를 재시작하지 않고 해당 서비스만 업데이트하도록 합니다.

보안 측면의 이점

이 CI/CD 파이프라인은 다음과 같은 보안 이점을 제공합니다:

  1. 격리된 네트워크 접근: FortiGate VPN을 통해 내부 네트워크에 안전하게 접근
  2. 비밀 정보 보호: GitHub Secrets을 사용하여 민감한 정보 관리
  3. 프라이빗 레지스트리: 외부에 노출되지 않는 이미지 저장소 사용
  4. SSH 키 기반 인증: 패스워드 대신 SSH 키를 사용한 서버 접근

기술적 이점

이 파이프라인의 기술적 이점은 다음과 같습니다:

  1. 자동화된 배포: 코드 푸시부터 배포까지 전 과정 자동화
  2. 일관된 환경: Docker를 통한 동일한 개발/테스트/운영 환경 보장
  3. 최소 다운타임: Docker Compose를 통한 효율적인 컨테이너 교체
  4. 유연한 확장성: 워크플로우에 추가 단계(테스트, 보안 검사 등) 용이

발전 방향

현재 CI/CD 파이프라인은 기본적인 기능을 제공하지만, 다음과 같은 방향으로 발전시킬 수 있습니다:

  1. 자동화된 테스트: 이미지 빌드 후 자동 테스트 추가
  2. 롤백 메커니즘: 배포 실패 시 자동 롤백 구현
  3. 점진적 배포: 블루-그린 또는 카나리 배포 방식 도입
  4. 모니터링 통합: 배포 후 자동 모니터링 알림 설정

결론

GitHub Actions와 FortiGate VPN을 결합한 CI/CD 파이프라인은 보안성과 자동화를 동시에 달성할 수 있는 효과적인 솔루션입니다. 내부망 접근이 필요한 프로젝트에서도 현대적인 CI/CD 프로세스를 구현할 수 있으며, 특히 Private Docker Registry와 연계하여 컨테이너 기반 애플리케이션의 배포를 안전하게 자동화할 수 있습니다.

이러한 접근 방식은 개발 생산성을 향상시키면서도 보안 요구사항을 충족시켜, 엔터프라이즈 환경에서 DevSecOps 문화를 정착시키는 데 큰 도움이 됩니다.


profile
기록하고 공유하려고 노력하는 DevOps 엔지니어

0개의 댓글

관련 채용 정보