자기 서명된 인증서 또는 사용자 지정 인증 기관

Tier: Free, Premium, Ultimate Offering: GitLab.com, Self-managed
  • GitLab Runner 0.7.0에 도입됨

GitLab Runner는 TLS 피어를 확인하는 데 사용할 인증서를 구성할 수 있는 두 가지 옵션을 제공합니다:

  • GitLab 서버와의 연결용: 인증서 파일은 다음 섹션의
    GitLab 서버를 대상으로 하는 자기 서명된 인증서의 지원 옵션에서 자세히 설명된 대로 지정할 수 있습니다.

    이는 러너를 등록할 때 x509: certificate signed by unknown authority 문제를 해결합니다.

    기존 러너의 경우 작업을 확인할 때 러너 로그에서 동일한 오류를 확인할 수 있습니다:

      Couldn't execute POST against https://hostname.tld/api/v4/jobs/request:  
      Post https://hostname.tld/api/v4/jobs/request: x509: certificate signed by unknown authority  
    
  • 사용자 스크립트, 캐시 서버 또는 외부 Git LFS 저장소에 연결하는 등의 다른 시나리오를 포함하는 보다 일반적인 접근 방식:
    인증서를 지정하고 컨테이너에 설치할 수 있으며, 이는 다음 섹션에 자세히 설명되어 있습니다.
    Docker 및 Kubernetes 실행자를 위한 TLS 인증서 신뢰

    인증서가 누락된 Git LFS 작업과 관련된 예제 작업 로그 오류:

      LFS: Get https://object.hostname.tld/lfs-dev/c8/95/a34909dce385b85cee1a943788044859d685e66c002dbf7b28e10abeef20?X-Amz-Expires=600&X-Amz-Date=20201006T043010Z&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=svcgitlabstoragedev%2F20201006%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-SignedHeaders=host&X-Amz-Signature=012211eb0ff0e374086e8c2d37556f2d8ca4cc948763e90896f8f5774a100b55: x509: certificate signed by unknown authority  
    

GitLab 서버를 위한 자기 서명된 인증서의 지원 옵션

이 섹션은 GitLab 서버만 사용자 지정 인증서를 필요로 할 때를 설명합니다.
기타 호스트(예: 프록시 다운로드가 활성화되지 않은 객체 저장소 서비스)도 사용자 지정 인증 기관(CA)을 필요로 하는 경우,
다음 섹션을 참조하십시오.
#trusting-tls-certificates-for-docker-and-kubernetes-executors.

GitLab Runner는 다음 옵션을 지원합니다:

  • 기본값 - 시스템 인증서 읽기: GitLab Runner는 시스템 인증서 저장소를 읽고
    시스템에 저장된 인증 기관(CA)과 대조하여 GitLab 서버를 검증합니다.

  • 사용자 지정 인증서 파일 지정: GitLab Runner는 등록 중에 tls-ca-file 옵션을 노출합니다
    (gitlab-runner register --tls-ca-file=/path) 및 [[runners]] 섹션 아래의 config.toml에서.
    이를 통해 사용자 지정 인증서 파일을 지정할 수 있습니다.
    이 파일은 러너가 GitLab 서버에 액세스할 때마다 읽힙니다.
    GitLab Runner Helm 차트를 사용하는 경우, 사용자 지정 인증서로 GitLab에 액세스하기에서 설명한 대로 인증서를 구성해야 합니다.

  • PEM 인증서 읽기: GitLab Runner는 미리 정의된 파일에서 PEM 인증서를 읽습니다 (DER 형식은 지원되지 않음):

    • GitLab Runner가 root로 실행될 때 *nix 시스템에서 /etc/gitlab-runner/certs/gitlab.example.com.crt.

      서버 주소가 https://gitlab.example.com:8443/인 경우,
      인증서 파일은 다음 위치에 생성해야 합니다: /etc/gitlab-runner/certs/gitlab.example.com.crt.

      openssl 클라이언트를 사용하여 GitLab 인스턴스의 인증서를 /etc/gitlab-runner/certs에 다운로드할 수 있습니다:

      openssl s_client -showcerts -connect gitlab.example.com:443 -servername gitlab.example.com < /dev/null 2>/dev/null | openssl x509 -outform PEM > /etc/gitlab-runner/certs/gitlab.example.com.crt  
      

      파일이 올바르게 설치되었는지 확인하려면 openssl과 같은 도구를 사용할 수 있습니다. 예를 들면:

      echo | openssl s_client -CAfile /etc/gitlab-runner/certs/gitlab.example.com.crt -connect gitlab.example.com:443 -servername gitlab.example.com  
      
    • GitLab Runner가 비 root로 실행될 때 *nix 시스템에서 ~/.gitlab-runner/certs/gitlab.example.com.crt.
    • 다른 시스템에서 ./certs/gitlab.example.com.crt. GitLab Runner를 Windows 서비스로 실행할 때는
      작동하지 않습니다. 대신 사용자 지정 인증서 파일을 지정하십시오.

Notes:

  • GitLab 서버 인증서가 귀하의 CA에 의해 서명된 경우, 귀하의 CA 인증서를 사용하십시오
    (귀하의 GitLab 서버 서명 인증서가 아님). 중간 인증서를 체인에 추가해야 할 수도 있습니다.
    예를 들어, 기본, 중간 및 루트 인증서가 있는 경우,
    이들을 모두 하나의 파일에 넣을 수 있습니다:

      -----BEGIN CERTIFICATE-----  
      (귀하의 주요 SSL 인증서: your_domain_name.crt)  
      -----END CERTIFICATE-----  
      -----BEGIN CERTIFICATE-----  
      (귀하의 중간 인증서)  
      -----END CERTIFICATE-----  
      -----BEGIN CERTIFICATE-----  
      (귀하의 루트 인증서)  
      -----END CERTIFICATE-----  
    
  • 기존 러너의 인증서를 업데이트하는 경우, 재시작하십시오.
  • 이미 HTTP를 통해 구성된 러너가 있는 경우, config.toml에서 GitLab 인스턴스의 새로운 HTTPS URL로
    인스턴스 경로를 업데이트하십시오.
  • 임시 및 안전하지 않은 해결 방법으로, 인증서 검증을 건너뛰려면,
    .gitlab-ci.yml 파일의 variables: 섹션에서 CI 변수를 GIT_SSL_NO_VERIFYtrue로 설정하십시오.

Git 복제

Runner는 CI_SERVER_TLS_CA_FILE을 사용하여 CA 체인을 구성하는 데 필요한 인증서를 주입합니다.

이로 인해 git clone과 아티팩트가 공인 인증서를 사용하지 않는 서버와 함께 작동할 수 있습니다.

이 접근 방식은 안전하지만, Runner를 신뢰의 단일 지점으로 만듭니다.

Docker 및 Kubernetes 실행자를 위한 TLS 인증서 신뢰

컨테이너에 인증서를 등록할 때 고려해야 할 두 가지 컨텍스트가 있습니다:

  • 사용자 이미지, 사용자 스크립트를 실행하는 데 사용됩니다.

    사용자 스크립스에 대한 인증서를 신뢰하는 시나리오의 경우 사용자 스크립트를 설치하는 방법에 대해 주인이 되어야 하며, 이는 이미지 자체에 매우 의존적이므로 Runner는 각 가능한 시나리오에서 인증서를 설치하는 방법을 알 수 없습니다.

  • Runner 헬퍼 이미지, Git, 아티팩트 및 캐시 작업을 처리하는 데 사용됩니다.

    다른 CI/CD 단계에 대한 인증서를 신뢰하는 시나리오에서는 사용자가 특정 위치(예: /etc/gitlab-runner/certs/ca.crt)에 인증서 파일을 사용할 수 있도록 하면 Docker 컨테이너가 이를 자동으로 사용자의 인증서로 설치합니다.

사용자 스크립스를 위한 인증서 신뢰

빌드 스크립트가 TLS를 통해 피어와 통신해야 하고 자기 서명된 인증서나 맞춤형 인증 기관(Certificate Authority)에 의존해야 하는 경우,

빌드 작업에서 인증서 설치를 수행해야 합니다. 이는 사용자 스크립트를 실행하는 Docker 컨테이너가 기본적으로 인증서 파일을 설치하지 않기 때문입니다.

이는 사용자 정의 캐시 호스트를 사용하거나, 두 번째 git clone을 수행하거나, 예를 들어 wget과 같은 도구를 통해 파일을 가져오기 위해 필요할 수 있습니다.

인증서를 설치하려면:

  1. Docker 볼륨으로 필요한 파일을 매핑하여 스크립트를 실행할 Docker 컨테이너에서 볼 수 있도록 합니다.

    이것은 config.toml 파일의 [runners.docker]의 해당 키 내에 볼륨을 추가하여 수행합니다, 예를 들어:

    • Linux:

      [[runners]]
        name = "docker"
        url = "https://example.com/"
        token = "TOKEN"
        executor = "docker"
      
        [runners.docker]
           image = "ubuntu:latest"
      
           # ca.crt 파일 경로를 볼륨 목록에 추가
           volumes = ["/cache", "/path/to-ca-cert-dir/ca.crt:/etc/gitlab-runner/certs/ca.crt:ro"]
      
  2. Linux 전용: 매핑된 파일(예: ca.crt)을 pre_build_script에서 사용하여:

    1. Docker 컨테이너 내의 /usr/local/share/ca-certificates/ca.crt로 복사합니다.

    2. update-ca-certificates --fresh를 실행하여 설치합니다. 예를 들어(명령은 사용하는 배포판에 따라 다릅니다):

      • Ubuntu에서:

        [[runners]]
          name = "docker"
          url = "https://example.com/"
          token = "TOKEN"
          executor = "docker"
        
          # 각 작업 전에 CA 인증서를 복사하고 설치합니다.
          pre_build_script = """
          apt-get update -y > /dev/null
          apt-get install -y ca-certificates > /dev/null
        
          cp /etc/gitlab-runner/certs/ca.crt /usr/local/share/ca-certificates/ca.crt
          update-ca-certificates --fresh > /dev/null
          """
        
      • Alpine에서:

        [[runners]]
          name = "docker"
          url = "https://example.com/"
          token = "TOKEN"
          executor = "docker"
        
          # 각 작업 전에 CA 인증서를 복사하고 설치합니다.
          pre_build_script = """
          apk update >/dev/null
          apk add ca-certificates > /dev/null
          rm -rf /var/cache/apk/*
        
          cp /etc/gitlab-runner/certs/ca.crt /usr/local/share/ca-certificates/ca.crt
          update-ca-certificates --fresh > /dev/null
          """
        

GitLab 서버 CA 인증서만 필요하다면, CI_SERVER_TLS_CA_FILE 변수에 저장된 파일에서 이를 가져올 수 있습니다:

curl --cacert "${CI_SERVER_TLS_CA_FILE}"  ${URL} -o ${FILE}

다른 CI/CD 단계에 대한 인증서 신뢰

Linux에서는 인증서 파일을 /etc/gitlab-runner/certs/ca.crt에 매핑할 수 있으며,

Windows에서는 C:\GitLab-Runner\certs\ca.crt에 매핑할 수 있습니다.

Runner 헬퍼 이미지는 시작할 때 이 사용자 정의 ca.crt 파일을 설치하며, 예를 들어 클론하거나 아티팩트를 업로드하는 작업을 수행할 때 이를 사용합니다.

Docker

  • Linux:

    [[runners]]
      name = "docker"
      url = "https://example.com/"
      token = "TOKEN"
      executor = "docker"
    
      [runners.docker]
        image = "ubuntu:latest"
    
        # 볼륨 목록에 ca.crt 파일 경로 추가
        volumes = ["/cache", "/path/to-ca-cert-dir/ca.crt:/etc/gitlab-runner/certs/ca.crt:ro"]
    
  • Windows:

    [[runners]]
      name = "docker"
      url = "https://example.com/"
      token = "TOKEN"
      executor = "docker"
    
      [runners.docker]
        image = "mcr.microsoft.com/windows/servercore:21H2"
    
        # 볼륨 목록에 ca.crt 파일이 있는 디렉터리 추가
        volumes = ["c:\\cache", "c:\\path\\to-ca-cert-dir:C:\\GitLab-Runner\\certs:ro"]
    

Kubernetes

Kubernetes에서 실행 중인 작업에 인증서 파일을 제공하려면:

  1. 인증서를 네임스페이스에 Kubernetes 비밀로 저장합니다:

    kubectl create secret generic <SECRET_NAME> --namespace <NAMESPACE> --from-file=<CERT_FILE>
    
  2. <SECRET_NAME><LOCATION>을 적절한 값으로 바꾸어 러너에서 비밀을 볼륨으로 마운트합니다:

    gitlab-runner:
      runners:
       config: |
         [[runners]]
           [runners.kubernetes]
             namespace = "{{.Release.Namespace}}"
             image = "ubuntu:latest"
           [[runners.kubernetes.volumes.secret]]
               name = "<SECRET_NAME>"
               mount_path = "<LOCATION>"
    

    mount_path는 인증서가 저장되는 컨테이너 내의 디렉터리입니다.

    /etc/gitlab-runner/certs/mount_path로 사용하고 ca.crt를 인증서 파일로 사용했다면,

    컨테이너 내에서 /etc/gitlab-runner/certs/ca.crt에서 인증서를 사용할 수 있습니다.

  3. 작업의 일환으로 매핑된 인증서 파일을 시스템 인증서 저장소에 설치합니다.

    예를 들어, Ubuntu 컨테이너에서:

    script:
      - cp /etc/gitlab-runner/certs/ca.crt /usr/local/share/ca-certificates/
      - update-ca-certificates
    

    Kubernetes 실행기의 헬퍼 이미지의 ENTRYPOINT 처리에 알려진 문제로 인해, 매핑된 인증서 파일이 시스템 인증서 저장소에 자동으로 설치되지 않습니다.

문제 해결

일반 SSL 문제 해결 문서를 참조하세요.

또한, tlsctl 도구를 사용하여 Runner 쪽에서 GitLab 인증서를 디버거할 수 있습니다.

x509: certificate signed by unknown authority 이미지를 개인 레지스트리에서 풀하려고 할 때 발생하는 오류

이 오류는 실행자를 예약하는 Docker 호스트 또는 Kubernetes 노드가 개인 레지스트리에서 사용하는 인증서를 신뢰하지 않을 때 발생합니다. 오류를 수정하려면 관련 루트 인증 기관 또는 인증서 체인을 시스템의 신뢰 저장소에 추가하고 컨테이너 서비스를 다시 시작하십시오.

Ubuntu 또는 Alpine을 사용하는 경우 다음 명령어를 실행하십시오:

cp ca.crt /usr/local/share/ca-certificates/ca.crt
update-ca-certificates
systemctl restart docker.service

Ubuntu 또는 Alpine 이외의 운영 체제를 사용하는 경우, 신뢰할 수 있는 인증서를 설치하는 데 적합한 명령어를 찾기 위해 운영 체제의 문서를 참조하십시오.

GitLab Runner의 버전과 Docker 호스트 환경에 따라, FF_RESOLVE_FULL_TLS_CHAIN 기능 플래그를 비활성화해야 할 수도 있습니다.

apt-get: not found 오류가 작업에서 발생하는 경우

pre_build_script 명령은 러너가 실행하는 모든 작업 전에 실행됩니다. 특정 배포판에 대한 명령을 추가하면, 예를 들어 사용자 스크립트에 대한 인증서를 설치할 때 apk 또는 apt-get과 같은 명령을 추가하면, CI 작업이 서로 다른 배포판 기반의 이미지를 사용할 경우 실패할 수 있습니다.

예를 들어, 일부 CI 작업이 Ubuntu 기반 이미지를 실행하고 일부는 Alpine 기반 이미지를 실행하며 Ubuntu 명령어를 추가하면, Alpine 기반 이미지의 작업에서 apt-get: not found 오류가 발생합니다. 이를 해결하려면 다음 중 하나를 수행하십시오:

  • 배포판에 의존하지 않도록 pre_build_script를 작성하십시오.
  • 태그를 사용하여 러너가 호환되는 이미지를 가진 작업만 선택하도록 하십시오.