컨테이너 스캐닝

Tier: Free, Premium, Ultimate Offering: GitLab.com, 자체 관리, GitLab Dedicated
  • 변경됨 GitLab 15.0에서 메이저 분석기 버전을 4에서 5로 수정했습니다.
  • 이전되었음 GitLab Ultimate에서 GitLab Free로 이전되었습니다.(15.0)
  • GitLab 15.4에서 도커를 참조하는 컨테이너 스캐닝 변수가 이름이 변경되었습니다.
  • GitLab 15.6에서 컨테이너 스캐닝 템플릿이 Security/Container-Scanning.gitlab-ci.yml 에서 Jobs/Container-Scanning.gitlab-ci.yml이동되었습니다.

당신의 어플리케이션의 도커 이미지 자체가 이미 알려진 취약점을 포함한 도커 이미지를 기반으로 할 수 있습니다. 병합 요청에서 그 취약점을 검색하고 표시하는 추가 컨테이너 스캐닝 작업을 파이프라인에 포함함으로써 GitLab을 사용하여 도커 기반 애플리케이션을 감사할 수 있습니다.

컨테이너 스캐닝은 종종 소프트웨어 조합 분석(SCA)의 일부로 간주됩니다. SCA에는 코드에서 사용하는 항목을 조사하는 측면이 포함될 수 있습니다. 이러한 항목에는 대부분 외부 소스에서 가져온 응용 프로그램 및 시스템 종속성이 포함되어 있으며 자체적으로 작성한 항목이 아닙니다.

GitLab은 모든 이러한 종속성 유형에 대한 커버리지를 보장하기 위해 컨테이너 스캐닝과 의존성 스캐닝을 제공합니다. 가능한 범위 내에서 가능한 많은 보안 스캐너를 사용하도록 권장합니다. 이러한 기능을 비교하려면 의존성 스캐닝과 컨테이너 스캐닝 비교를 참조하세요.

GitLab은 취약점 정적 분석을 수행하기 위해 Trivy 보안 스캐너와 통합됩니다.

경고: Grype 분석기는 지원이 중단되었으며, 그 이유는 지원 성명에 설명되어 있습니다. Grype 분석기 이미지의 현재 주요 버전은 GitLab 19.0까지 최신 공지 데이터베이스 및 운영 체제 패키지로 계속 업데이트됩니다. 이후에는 분석기가 작동하지 않습니다.

GitLab은 소스 및 타겟 브랜치에서 발견된 취약점을 비교한 다음:

컨테이너 스캐닝 위젯

특징

기능 무료 및 프리미엄 얼티메이트
설정 사용자 정의(변수, 재정의, 오프라인 환경 지원 등)
CI 작업 아티팩트로 JSON 보고서 보기
CI 작업 아티팩트로 CycloneDX SBOM JSON 보고서 생성
GitLab UI에서 컨테이너 스캐닝을 활성화하는 능력
UBI 이미지 지원
Trivy 지원
GitLab 공지 데이터베이스 포함 GitLab advisories-communities 프로젝트의 지연된 콘텐츠로 제한됨 최신 콘텐츠가 모두 포함된 Gemnasium DB
병합 요청 및 CI 파이프라인 작업의 보안 탭에서 보고 데이터 제공 아니요
취약점에 대한 솔루션(자동 복구) 아니요
취약점 허용 목록 지원 아니요
의존성 목록 페이지 액세스 아니요

구성

CI/CD 파이프라인에서 컨테이너 스캐닝 분석기를 활성화하세요. 파이프라인이 실행되면 애플리케이션이 종속되어 있는 이미지가 취약점을 스캔됩니다. 컨테이너 스캐닝은 CI/CD 변수를 사용하여 사용자 정의할 수 있습니다.

분석기 활성화

사전 요구 사항:

  • .gitlab-ci.yml 파일에 테스트 단계가 필요합니다.
  • 자체 관리 러너를 사용하는 경우 Linux/amd64에서 docker 또는 kubernetes executor가 있는 GitLab 러너가 필요합니다. GitLab.com에서 인스턴스 러너를 사용하는 경우, 기본적으로 활성화됩니다.
  • 지원되는 배포에 일치하는 이미지가 필요합니다.
  • 프로젝트의 컨테이너 레지스트리에 이미지 빌드 및 푸시가 되어 있어야 합니다.
  • 제3자 컨테이너 레지스트리를 사용하는 경우 CS_REGISTRY_USERCS_REGISTRY_PASSWORD 구성 변수를 통해 인증 자격 증명을 제공해야 할 수 있습니다. 이러한 변수를 사용하는 방법에 대한 자세한 내용은 원격 레지스트리에 인증를 참조하세요.

분석기를 활성화하려면 다음 중 하나를 수행하세요:

  • 의존성 스캐닝을 포함하는 Auto DevOps를 활성화합니다.
  • 미리 구성된 병합 요청을 사용합니다.
  • 컨테이너 스캐닝을 강제하는 스캔 실행 정책을 만듭니다.
  • .gitlab-ci.yml 파일을 직접 편집합니다.

미리 구성된 병합 요청 사용

이 방법은 .gitlab-ci.yml 파일에 컨테이너 스캐닝 템플릿이 포함된 병합 요청을 자동으로 준비합니다. 그런 다음 병합 요청을 병합하여 종속성 스캐닝을 활성화합니다.

참고: 이 방법은 기존의 .gitlab-ci.yml 파일이 없거나 최소한의 구성 파일이 있는 경우 가장 잘 작동합니다. 복잡한 GitLab 구성 파일이 있으면 파싱되지 않을 수 있으며 오류가 발생할 수 있습니다. 그런 경우에는 대신 수동 방법을 사용하십시오.

컨테이너 스캐닝을 활성화하려면:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하여 프로젝트를 찾습니다.
  2. 보안 > 보안 구성을 선택합니다.
  3. 컨테이너 스캐닝 행에서 병합 요청으로 구성을 선택합니다.
  4. 병합 요청 생성을 선택합니다.
  5. 병합 요청을 검토한 후 병합을 선택합니다.

이제 파이프라인에는 컨테이너 스캐닝 작업이 포함됩니다.

.gitlab-ci.yml 파일 수동으로 편집

이 방법은 기존의 .gitlab-ci.yml 파일을 수동으로 편집해야 합니다. 이 방법은 GitLab CI/CD 구성 파일이 복잡하거나 기본 옵션을 사용하지 않아야 할 경우에 사용합니다.

컨테이너 스캐닝을 활성화하려면:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하여 프로젝트를 찾습니다.
  2. 빌드 > 파이프라인 편집기를 선택합니다.
  3. .gitlab-ci.yml 파일이 없는 경우 파이프라인 구성을 선택한 후 예시 내용을 삭제합니다.
  4. 다음 내용을 .gitlab-ci.yml 파일의 맨 아래에 복사하여 붙입니다. 이미 include 줄이 있는 경우에는 아래에 template 줄만 추가합니다.

    include:
      - template: Jobs/Container-Scanning.gitlab-ci.yml
    
  5. 검증 탭을 선택한 후 파이프라인 검증을 선택합니다.

    메시지 시뮬레이션이 성공적으로 완료되었습니다가 파일이 유효함을 확인합니다.

  6. 편집 탭을 선택합니다.
  7. 필드를 작성합니다. 브랜치 필드에 기본 브랜치를 사용하지 마십시오.
  8. 이 변경 사항으로 새 병합 요청 시작 확인란을 선택한 후 변경 사항 커밋을 선택합니다.
  9. 표준 워크플로에 따라 필드를 작성하고 병합 요청 생성을 선택합니다.
  10. 표준 워크플로에 따라 병합 요청을 검토하고 편집한 후, 파이프라인이 통과될 때까지 기다린 후 병합을 선택합니다.

이제 파이프라인에는 컨테이너 스캐닝 작업이 포함됩니다.

분석기 동작 사용자화

컨테이너 스캐닝을 사용자화하려면 CI/CD 변수를 사용합니다.

자세한 출력 활성화

문제 해결 시 세부 내용을 자세히 보려면 자세한 출력을 활성화합니다.

다음 예제에서는 컨테이너 스캐닝 템플릿이 포함되어 있으며 자세한 출력이 활성화되어 있습니다.

include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

variables:
    SECURE_LOG_LEVEL: 'debug'

원격 레지스트리에서 이미지 스캔

프로젝트의 외부에 있는 레지스트리에 있는 이미지를 스캔하려면 다음 .gitlab-ci.yml을 사용합니다:

include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

container_scanning:
  variables:
    CS_IMAGE: example.com/user/image:tag
원격 레지스트리에 인증

개인 레지스트리에 있는 이미지를 스캔하려면 CS_REGISTRY_USER 변수에 사용자 이름을, CS_REGISTRY_PASSWORD 구성 변수에 비밀번호를 제공해야 합니다.

예를 들어, AWS Elastic Container Registry에서 이미지를 스캔하려면:

container_scanning:
  before_script:
    - ruby -r open-uri -e "IO.copy_stream(URI.open('https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip'), 'awscliv2.zip')"
    - unzip awscliv2.zip
    - sudo ./aws/install
    - aws --version
    - export AWS_ECR_PASSWORD=$(aws ecr get-login-password --region region)

include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

variables:
    CS_IMAGE: <aws_account_id>.dkr.ecr.<region>.amazonaws.com/<image>:<tag>
    CS_REGISTRY_USER: AWS
    CS_REGISTRY_PASSWORD: "$AWS_ECR_PASSWORD"
    AWS_DEFAULT_REGION: <region>

원격 레지스트리에 인증하는 것은 FIPS 모드가 활성화된 경우 지원되지 않습니다.

언어별 결과 보고

CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN CI/CD 변수는 프로그래밍 언어와 관련된 발견 보고를 제어합니다.

기본 설정은 운영 체제(OS) 패키지 관리자(예: yum, apt, apk, tdnf)에서 관리되는 패키지만 보고서에 포함됩니다. 비-OS 패키지에서 보안 문제를 보고하려면 CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN"false"로 설정합니다:

include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

container_scanning:
  variables:
    CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN: "false"

이 기능을 활성화하면 프로젝트에 Dependency Scanning이 활성화된 경우 중복 발견이 발생할 수 있습니다. 이는 GitLab이 다른 유형의 스캔 도구를 통해 발견된 사항을 자동으로 중복 처리하지 못하기 때문에 발생합니다.

병합 요청 파이프라인에서 작업 실행

병합 요청 파이프라인에서 보안 스캔 도구를 사용하려면 Use security scanning tools with merge request pipelines을 참조하십시오.

사용 가능한 CI/CD 변수

컨테이너 스캐닝을 사용자화하려면 CI/CD 변수를 사용합니다. 다음 표에는 컨테이너 스캐닝에 특화된 CI/CD 변수가 나열되어 있습니다. 또한 사전 정의된 CI/CD 변수 중 하나를 사용할 수 있습니다.

경고: 기본 브랜치로 이러한 변경을 병합하기 전에 병합 요청에서 GitLab 분석기의 사용자화를 테스트하십시오. 이렇게 하지 않을 경우 예기치 않은 결과가 발생할 수 있습니다. (예: 거대한 거짓 긍정의 수 증가).

| CI/CD 변수 | 기본값 | 설명 | | —————————— | ————- | ———– |

지원되는 배포

다음 Linux 배포본이 지원됩니다:

  • Alma Linux
  • Alpine Linux
  • Amazon Linux
  • CentOS
  • CBL-Mariner
  • Debian
  • Distroless
  • Oracle Linux
  • Photon OS
  • Red Hat (RHEL)
  • Rocky Linux
  • SUSE
  • Ubuntu

FIPS 활성화된 이미지

GitLab은 또한 컨테이너 스캔 이미지의 FIPS 활성화 Red Hat UBI 버전을 제공합니다. 따라서 표준 이미지를 FIPS 활성화 이미지로 교체할 수 있습니다. 이미지를 구성하려면 CS_IMAGE_SUFFIX-fips로 설정하거나CS_ANALYZER_IMAGE 변수를 표준 태그와 -fips 확장자로 수정하세요.

참고: FIPS 모드가 GitLab 인스턴스에서 활성화되면 -fips 플래그가 자동으로 CS_ANALYZER_IMAGE에 추가됩니다.

인증된 레지스트리의 이미지에 대한 컨테이너 스캔은 FIPS 모드가 활성화된 경우 지원되지 않습니다. CI_GITLAB_FIPS_MODE"true"로 설정되고CS_REGISTRY_USER 또는 CS_REGISTRY_PASSWORD가 설정된 경우, 분석기는 오류로 종료되어 스캔을 수행하지 않습니다.

컨테이너 스캔 템플릿 재정의

작업 정의를 재정의하려면(예: variable와 같은 속성 변경), 템플릿 포함 후 작업을 선언 및 재정의해야 합니다. 그런 다음 추가 키를 지정하세요.

다음 예제는 GIT_STRATEGYfetch로 설정합니다.

include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

container_scanning:
  variables:
    GIT_STRATEGY: fetch

기본 브랜치 이미지 설정

기본적으로 컨테이너 스캔은 이미지 이름 규칙이 이미지 태그에 브랜치별 식별자를 저장하는 것으로 가정합니다. 이미지 이름이 기본 브랜치와 비기본 브랜치 간에 다른 경우, 이전에 감지된 취약점이 병합 요청에서 새로 감지된 것으로 나타납니다.

동일한 이미지가 기본 브랜치 및 비기본 브랜치에서 다른 이름을 가질 때, CS_DEFAULT_BRANCH_IMAGE 변수를 사용하여 그 이미지의 이름이 기본 브랜치에서 무엇인지 나타낼 수 있습니다. 이렇게 하면 GitLab에서 비기본 브랜치에서 스캔을 실행할 때 취약점이 이미 존재하는지를 올바르게 판별합니다.

예를 들어 다음과 같은 경우:

  • 비기본 브랜치는 이미지를 다음과 같은 이름 관행으로 게시합니다. $CI_REGISTRY_IMAGE/$CI_COMMIT_BRANCH:$CI_COMMIT_SHA.
  • 기본 브랜치는 이미지를 다음과 같은 이름 관행으로 게시합니다. $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA.

이 예에서 다음과 같은 CI/CD 구성을 사용하여 취약점이 중복되지 않도록 할 수 있습니다.

include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

container_scanning:
  variables:
    CS_DEFAULT_BRANCH_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  before_script:
    - export CS_IMAGE="$CI_REGISTRY_IMAGE/$CI_COMMIT_BRANCH:$CI_COMMIT_SHA"
    - |
      if [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]; then
        export CS_IMAGE="$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
      fi

특정 CS_IMAGE에 대해 CS_DEFAULT_BRANCH_IMAGE는 동일해야 합니다. 값이 변경되면 수동으로 폐기해야 할 중복 취약점이 만들어집니다.

Auto DevOps를 사용할 때, CS_DEFAULT_BRANCH_IMAGE는 자동으로 $CI_REGISTRY_IMAGE/$CI_DEFAULT_BRANCH:$CI_APPLICATION_TAG로 설정됩니다.

사용자 지정 SSL CA 인증 기관 사용

ADDITIONAL_CA_CERT_BUNDLE CI/CD 변수를 사용하여 HTTPS를 사용하는 레지스트리에서 Docker 이미지를 가져올 때 사용되는 사용자 지정 SSL CA 인증 기관을 구성할 수 있습니다. ADDITIONAL_CA_CERT_BUNDLE 값은 X.509 PEM 공개키 인증서의 텍스트 표현을 포함해야 합니다. 예를 들어 .gitlab-ci.yml 파일에서 이 값을 구성하려면 다음과 같이 사용하세요:

container_scanning:
  variables:
    ADDITIONAL_CA_CERT_BUNDLE: |
        -----BEGIN CERTIFICATE-----
        MIIGqTCCBJGgAwIBAgIQI7AVxxVwg2kch4d56XNdDjANBgkqhkiG9w0BAQsFADCB
        ...
        jWgmPqF3vUbZE0EyScetPJquRFRKIesyJuBFMAs=
        -----END CERTIFICATE-----

ADDITIONAL_CA_CERT_BUNDLE 값은 또한 UI에서 사용자 정의 변수로 구성될 수 있으며, 이때 file로 설정되면 인증서의 경로가 필요하고 변수로 설정되면 인증서의 텍스트 표현이 필요합니다.

취약점 허용 목록

Tier: Ultimate Offering: GitLab.com, Self-managed, GitLab Dedicated

특정 취약점을 허용하려면 다음 단계를 따르세요:

  1. 컨테이너 스캐닝 템플릿 재정의에서 설명된 지침을 따라 .gitlab-ci.yml 파일에 GIT_STRATEGY: fetch를 설정하세요.
  2. vulnerability-allowlist.yml이라는 YAML 파일에 허용된 취약점을 정의하세요. 이는 vulnerability-allowlist.yml 데이터 형식에 설명된 형식을 사용해야 합니다.
  3. vulnerability-allowlist.yml 파일을 프로젝트 Git 리포지토리의 루트 폴더에 추가하세요.

vulnerability-allowlist.yml 데이터 형식

vulnerability-allowlist.yml 파일은 거짓 양성인지 또는 적용되지 않는지에 대한 취약점의 CVE ID 목록을 지정하는 YAML 파일입니다.

vulnerability-allowlist.yml 파일에서 일치 항목을 찾으면 다음이 발생합니다:

  • 분석기가 gl-container-scanning-report.json 파일을 생성할 때 취약점이 포함되지 않습니다.
  • 파이프라인의 보안 탭에서 해당 취약점을 표시하지 않습니다. 보안 탭의 진실의 원천인 JSON 파일에 포함되지 않습니다.

예제 vulnerability-allowlist.yml 파일:

generalallowlist:
  CVE-2019-8696:
  CVE-2014-8166: cups
  CVE-2017-18248:
images:
  registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256:
    CVE-2018-4180:
  your.private.registry:5000/centos:
    CVE-2015-1419: libxml2
    CVE-2015-1447:

이 예제는 다음과 같은 항목을 gl-container-scanning-report.json에서 제외시킵니다:

  1. CVE-2019-8696, CVE-2014-8166, _CVE-2017-18248_의 모든 취약점.
  2. registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256 컨테이너 이미지에서 발견된 모든 취약점 중 _CVE-2018-4180_이 있는 경우.
  3. your.private.registry:5000/centos 컨테이너에서 발견된 CVE-2015-1419, _CVE-2015-1447_의 모든 취약점.
파일 형식
  • generalallowlist 블록을 사용하면 CVE ID를 전역으로 지정할 수 있습니다. 일치하는 CVE ID를 가진 모든 취약성은 스캔 보고서에서 제외됩니다.

  • images 블록을 사용하면 각 컨테이너 이미지에 대해 독립적으로 CVE ID를 지정할 수 있습니다. 일치하는 CVE ID를 가진 주어진 이미지의 모든 취약성이 스캔 보고서에서 제외됩니다. 이미지 이름은 검사할 도커 이미지를 지정하는 데 사용되는 환경 변수 중 하나에서 검색됩니다. (예: $CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG 또는 CS_IMAGE). 이 블록에서 제공된 이미지는 이 값과 일치해야 하며 태그 값을 포함해서는 안됩니다. 예를 들어, CS_IMAGE=alpine:3.7를 사용하여 이미지를 스캔하도록 지정했다면 images 블록에서 alpine을 사용하지만 alpine:3.7을 사용할 수는 없습니다.

    여러 가지 방법으로 컨테이너 이미지를 지정할 수 있습니다:

    • 이미지 이름만(예: centos)으로 지정합니다.
    • 레지스트리 호스트 이름이 포함된 전체 이미지 이름(예: your.private.registry:5000/centos)으로 지정합니다.
    • 레지스트리 호스트 이름과 sha256 라벨이 포함된 전체 이미지 이름(예: registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256)으로 지정합니다.

참고: 이전 예제에서 CVE ID 이후의 문자열(cupslibxml2)은 선택적 주석 형식입니다. 이는 취약성 처리에 영향을 미치지 않습니다. 취약성을 설명하는 데 주석을 추가할 수 있습니다.

컨테이너 스캔 작업 로그 형식

container_scanning 작업 세부 정보에서 컨테이너 스캔 분석기가 생성한 로그를 확인하여 스캔 결과 및 vulnerability-allowlist.yml 파일의 정확성을 검증할 수 있습니다.

로그에는 테이블 형식으로 발견된 취약성 목록이 포함되어 있습니다. 예를 들어:

+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+
|   STATUS   |      CVE SEVERITY       |      PACKAGE NAME      |    PACKAGE VERSION    |                            CVE DESCRIPTION                             |
+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+
|  Approved  |   High CVE-2019-3462    |          apt           |         1.4.8         | Incorrect sanitation of the 302 redirect field in HTTP transport metho |
|            |                         |                        |                       | d of apt versions 1.4.8 and earlier can lead to content injection by a |
|            |                         |                        |                       |  MITM attacker, potentially leading to remote code execution on the ta |
|            |                         |                        |                       |                             rget machine.                              |
+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+
| Unapproved |  Medium CVE-2020-27350  |          apt           |         1.4.8         | APT had several integer overflows and underflows while parsing .deb pa |
|            |                         |                        |                       | ckages, aka GHSL-2020-168 GHSL-2020-169, in files apt-pkg/contrib/extr |
|            |                         |                        |                       | acttar.cc, apt-pkg/deb/debfile.cc, and apt-pkg/contrib/arfile.cc. This |
|            |                         |                        |                       |  issue affects: apt 1.2.32ubuntu0 versions prior to 1.2.32ubuntu0.2; 1 |
|            |                         |                        |                       | .6.12ubuntu0 versions prior to 1.6.12ubuntu0.2; 2.0.2ubuntu0 versions  |
|            |                         |                        |                       | prior to 2.0.2ubuntu0.2; 2.1.10ubuntu0 versions prior to 2.1.10ubuntu0 |
|            |                         |                        |                       |                                  .1;                                   |
+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+
| Unapproved |  Medium CVE-2020-3810   |          apt           |         1.4.8         | Missing input validation in the ar/tar implementations of APT before v |
|            |                         |                        |                       | ersion 2.1.2 could result in denial of service when processing special |
|            |                         |                        |                       |                         ly crafted deb files.                          |
+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+

로그의 취약성은 해당 CVE ID가 vulnerability-allowlist.yml 파일에 추가되면 Approved로 표시됩니다.

오프라인 환경에서 컨테이너 스캔 실행

인터넷을 통한 외부 리소스에 제한적이거나 접근이 불가능한 환경에서 자체 관리형 GitLab 인스턴스의 경우 컨테이너 스캐닝 작업을 성공적으로 실행하려면 몇 가지 조정이 필요합니다. 자세한 정보는 오프라인 배포를 참조하십시오.

오프라인 컨테이너 스캔 요구 사항

오프라인 환경에서 컨테이너 스캔을 사용하려면 다음이 필요합니다:

  • docker 또는 kubernetes 실행기를 사용하는 GitLab Runner(#enabling-the-analyzer)가 있어야 합니다.
  • 컨테이너 스캔 이미지의 사본이 있는 로컬 도커 컨테이너 레지스트리를 구성해야 합니다. 각 레지스트리에서 해당 이미지를 찾을 수 있습니다:
GitLab Analyzer 컨테이너 레지스트리
컨테이너-스캐닝 컨테이너-스캐닝 컨테이너 레지스트리

GitLab Runner는 기본 pull policyalways 설정되어 있으므로, 로컬 사본이 있는 상태에서도 GitLab 컨테이너 레지스트리에서 도커 이미지를 가져 오려고 시도합니다. 오프라인 환경에서는 GitLab Runner의 pull_policyif-not-present로 설정하여 로컬로만 사용 가능한 도커 이미지를 사용하는 것이 좋습니다. 그러나 CI/CD 파이프라인에서 업데이트된 스캐너를 사용하기위해 오프라인 환경이 아닌 경우 pull policy 설정을 always로 유지하는 것이 좋습니다.

커스텀 인증 기관 지원

Trivy의 커스텀 인증 기관 지원은 4.0.0 버전에 도입되었습니다.

GitLab 컨테이너 스캐닝 분석기 이미지를 로컬 Docker 레지스트리에 제공

컨테이너 스캐닝을 위해 registry.gitlab.com에서 다음 이미지를 로컬 Docker 컨테이너 레지스트리로 가져오세요(../../packages/container_registry/index.md):

registry.gitlab.com/security-products/container-scanning:7
registry.gitlab.com/security-products/container-scanning/trivy:7

로컬 오프라인 Docker 레지스트리로 Docker 이미지를 가져오는 프로세스는 네트워크 보안 정책에 따라 다릅니다. 외부 리소스를 가져오거나 임시로 접근하는 승인된 절차를 찾기 위해 IT 직원과 상의하세요. 이러한 스캐너들은 정기적으로 업데이트되며 가끔씩 자체 업데이트를 수행할 수 있을 수도 있습니다.

자세한 정보는 파이프라인을 사용하여 이미지 업데이트하는 구체적인 단계를 참조하세요.

Docker 이미지를 파일로 저장하고 전송하는 세부 정보는 Docker 문서의 docker save, docker load, docker export, docker import를 확인하세요.

로컬 컨테이너 스캐너 분석기를 사용하는 컨테이너 스캐닝 CI/CD 변수 설정

  1. .gitlab-ci.yml 파일에서 Docker 이미지를 로컬 Docker 컨테이너 레지스트리에 있는 이미지로 참조하기 위해 컨테이너 스캐닝 템플릿 재정의하세요:

    include:
      - template: Jobs/Container-Scanning.gitlab-ci.yml
    
    container_scanning:
      image: $CI_REGISTRY/namespace/container-scanning
    
  2. 로컬 Docker 컨테이너 레지스트리가 HTTPS를 통해 안전하게 실행되지만 자체 서명된 인증서를 사용하는 경우, 위의 .gitlab-ci.yml 파일의 container_scanning 섹션에서 CS_DOCKER_INSECURE: "true"로 설정해야 합니다.

파이프라인을 사용하여 컨테이너 스캐닝 취약점 데이터베이스 자동 업데이트

일정된 일정에 따라 최신 취약점 데이터베이스를 가져오도록 예약된 파이프라인을 설정하는 것을 권장합니다. 이를 파이프라인으로 자동화하면 매번 수동으로 작업할 필요가 없습니다. 다음의 .gitlab-ci.yml 예제를 템플릿으로 사용할 수 있습니다.

variables:
  SOURCE_IMAGE: registry.gitlab.com/security-products/container-scanning:7
  TARGET_IMAGE: $CI_REGISTRY/namespace/container-scanning

image: docker:latest

update-scanner-image:
  services:
    - docker:dind
  script:
    - docker pull $SOURCE_IMAGE
    - docker tag $SOURCE_IMAGE $TARGET_IMAGE
    - echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY --username $CI_REGISTRY_USER --password-stdin
    - docker push $TARGET_IMAGE

위의 템플릿은 로컬 설치 중인 GitLab Docker 레지스트리에 적합합니다. 그러나 GitLab Docker 레지스트리를 사용하지 않는 경우 $CI_REGISTRY 값을 변경하고 로컬 레지스트리의 정보에 맞게 docker login 자격증을 업데이트해야 합니다.

외부 프라이빗 레지스트리에 있는 이미지 스캔

외부 프라이빗 레지스트리에 있는 이미지를 스캔하려면 컨테이너 스캐닝 분석기가 이미지를 스캔하기 전에 자격증을 인증할 수 있도록 액세스 자격증을 구성해야 합니다.

GitLab 컨테이너 레지스트리를 사용하는 경우, CS_REGISTRY_USERCS_REGISTRY_PASSWORD 구성 변수가 자동으로 설정되므로 이러한 구성을 건너뛰어도 됩니다.

이 예제는 프라이빗 Google Container Registry에 이미지를 스캔하기 위해 필요한 구성을 보여줍니다:

include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

container_scanning:
  variables:
    CS_REGISTRY_USER: _json_key
    CS_REGISTRY_PASSWORD: "$GCP_CREDENTIALS"
    CS_IMAGE: "gcr.io/path-to-you-registry/image:tag"

이 구성을 커밋하기 전에, 프로젝트에 대한 CI/CD 변수를 추가하여 GCP_CREDENTIALS를 JSON 키를 포함시키도록 Google Cloud Platform Container Registry 설명서에 설명된 대로 해야 합니다.

또한:

  • 변수의 값은 마스크 변수 옵션의 마스킹 요구 사항에 맞지 않을 수 있어 작업 로그에 값이 노출될 수 있습니다.
  • 만약 보호 변수 옵션을 선택하지 않으면 보호되지 않은 기능 브랜치에서 스캔이 실행되지 않을 수 있습니다.
  • 옵션을 선택하지 않을 경우 읽기 전용 권한으로 자격증을 생성하고 정기적으로 회전시키는 것이 좋습니다.

FIPS 모드가 활성화된 경우 외부 프라이빗 레지스트리에서 이미지를 스캔하는 것은 지원되지 않습니다.

Trivy Java 데이터베이스 미러 생성 및 사용

trivy 스캐너를 사용하고 검사 중인 컨테이너 이미지에서 jar 파일을 만나면, trivy는 추가적인 trivy-java-db 취약점 데이터베이스를 다운로드합니다. 기본적으로 trivy-java-db 데이터베이스는 ghcr.io/aquasecurity/trivy-java-db:1OCI artifact로 호스팅됩니다. 만일 이 레지스트리가 접근할 수 없거나 TOOMANYREQUESTS로 응답하는 경우, trivy-java-db를 더 접근 가능한 컨테이너 레지스트리에 미러링하는 것이 한 가지 해결책입니다.

mirror trivy java db:
  image:
    name: ghcr.io/oras-project/oras:v1.1.0
    entrypoint: [""]
  script:
    - oras login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - oras pull ghcr.io/aquasecurity/trivy-java-db:1
    - oras push $CI_REGISTRY_IMAGE:1 --config /dev/null:application/vnd.aquasec.trivy.config.v1+json javadb.tar.gz:application/vnd.aquasec.trivy.javadb.layer.v1.tar+gzip

취약점 데이터베이스는 일반적인 Docker 이미지가 아니기 때문에 docker pull 명령어를 사용하여 가져오는 것은 불가능합니다. 이미지는 GitLab UI에서 접근하면 오류가 표시됩니다.

만약 위의 컨테이너 레지스트리가 gitlab.example.com/trivy-java-db-mirror라면, 컨테이너 스캐닝 작업은 다음과 같이 구성되어야 합니다. 끝에 태그 :1을 추가하지 마세요. trivy에서 추가됩니다:

include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

container_scanning:
  variables:
    CS_TRIVY_JAVA_DB: gitlab.example.com/trivy-java-db-mirror

독립형 컨테이너 스캐닝 도구 실행

CI 작업의 맥락에서 실행하지 않고도 도커 컨테이너에 대해 GitLab 컨테이너 스캐닝 도구를 실행할 수 있습니다. 이미지를 직접 스캔하려면 다음 단계를 따르세요:

  1. Docker Desktop 또는 Docker Machine을 실행합니다.
  2. 분석 도커 이미지를 실행하여 이미지와 분석할 태그를 CI_APPLICATION_REPOSITORYCI_APPLICATION_TAG 변수로 전달합니다:

     docker run \
       --interactive --rm \
       --volume "$PWD":/tmp/app \
       -e CI_PROJECT_DIR=/tmp/app \
       -e CI_APPLICATION_REPOSITORY=registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256 \
       -e CI_APPLICATION_TAG=bc09fe2e0721dfaeee79364115aeedf2174cce0947b9ae5fe7c33312ee019a4e \
       registry.gitlab.com/security-products/container-scanning
    

결과는 gl-container-scanning-report.json에 저장됩니다.

보고서 JSON 형식

컨테이너 스캐닝 도구는 GitLab Runner가 CI 구성 파일의 artifacts:reports 키워드를 통해 인식하는 JSON 보고서를 생성합니다.

CI 작업이 완료되면 Runner가 이러한 보고서를 GitLab에 업로드하여 CI Job artifacts로 사용할 수 있습니다. GitLab Ultimate에서는 이러한 보고서를 해당 파이프라인에서 볼 수 있으며 취약점 보고서의 일부가 됩니다.

이러한 보고서는 보안 보고서 스키마에서 정의된 형식을 따라야 합니다. 자세한 내용은 다음을 참조하십시오:

추가 정보는 보안 스캐너 통합을 참조하세요.

CycloneDX 소프트웨어 부품 목록

JSON 보고서 파일 외에도 컨테이너 스캐닝 도구는 스캔된 이미지에 대한 CycloneDX 소프트웨어 부품 목록 (SBOM)을 출력합니다. 이 CycloneDX SBOM은 gl-sbom-report.cdx.json이라고 하며 JSON 보고서 파일과 동일한 디렉터리에 저장됩니다. 이 기능은 Trivy 분석 도구를 사용할 때에만 지원됩니다.

이 보고서는 의존성 목록에서 볼 수 있습니다.

CycloneDX SBOM은 다른 작업 artifacts와 동일한 방법으로 다운로드할 수 있습니다.

레지스트리용 컨테이너 스캐닝

Tier: Ultimate Offering: GitLab.com, Self-Managed, GitLab Dedicated
  • GitLab 17.1에서 enable_container_scanning_for_registry라는 플래그로 도입되었습니다. 기본적으로 비활성화됩니다.
  • GitLab 17.2에서는 셀프 관리 및 GitLab 전용에서 활성화되었습니다.
  • GitLab 17.2에서 일반 사용으로 변경되었습니다. 기능 플래그 enable_container_scanning_for_registry가 제거되었습니다.

컨테이너 이미지가 latest 태그로 푸시되면 새로운 파이프라인에서 기본 브랜치에 대해 컨테이너 스캐닝 작업이 자동으로 트리거됩니다.

일반적인 컨테이너 스캐닝과 달리 스캔 결과에는 보안 보고서가 포함되지 않습니다. 대신 레지스트리용 컨테이너 스캐닝은 스캔으로 감지된 구성 요소를 검사하기 위해 연속적인 취약성 스캐닝을 활용합니다.

보안 문제가 식별되면 GitLab은 취약점 보고서에 이러한 결과를 채웁니다. 취약점은 취약점 보고서 페이지의 컨테이너 레지스트리 취약성 탭에서 볼 수 있습니다.

참고: 레지스트리용 컨테이너 스캐닝은 GitLab 고위험 알림 데이터베이스에 새로운 알림이 발행될 때에만 취약점 보고서를 채우며, 새로 감지된 데이터가 아닌 모든 이전 데이터로 취약점 보고서를 채우는 지원은 epic 8026에서 제안됩니다.

전제 조건

  • 레지스트리용 컨테이너 스캐닝을 활성화하려면 프로젝트에서 적어도 관리자(Maintainer) 권한이 있어야 합니다.
  • 사용 중인 프로젝트는 비어있어서는 안 됩니다. 컨테이너 이미지를 저장하는 데만 사용하는 빈 프로젝트의 경우 이 기능이 의도한대로 작동하지 않습니다. 이를 해결하기 위해 기본 브랜치에 초기 커밋이 있는지 확인하세요.
  • 프로젝트당 하루에 50회의 스캔 제한이 있습니다.
  • 컨테이너 레지스트리 알림을 구성해야 합니다.

레지스트리용 컨테이너 스캐닝 활성화

GitLab 컨테이너 레지스트리에 대해 컨테이너 스캔을 활성화하려면 다음을 수행하세요:

  1. 좌측 사이드바에서 검색 또는 이동을 선택하여 프로젝트를 찾습니다.
  2. 보안 > 보안 구성을 선택합니다.
  3. 페이지 아래로 스크롤하여 Container Scanning For Registry 섹션을 찾아 토글을 켭니다.

취약점 데이터베이스

모든 분석 도구 이미지는 매일 업데이트됩니다.

이미지는 상위 제공 업체의 알림 데이터베이스를 사용합니다:

  • AlmaLinux 보안 공지
  • Amazon Linux 보안 센터
  • Arch Linux 보안 트래커
  • SUSE CVRF
  • CWE 공지
  • Debian 보안 버그 추적기
  • GitHub 보안 알림
  • Go 취약점 데이터베이스
  • CBL-Mariner 취약점 데이터
  • NVD
  • OSV
  • Red Hat OVAL v2
  • Red Hat 보안 데이터 API
  • Photon 보안 공지
  • Rocky Linux UpdateInfo
  • Ubuntu CVE 추적기 (2021년 중반 이후의 데이터 소스만)

이러한 스캐너에서 제공하는 소스 외에도 GitLab은 다음과 같은 취약점 데이터베이스를 유지합니다:

GitLab Ultimate 티어에서는 외부 소스의 데이터를 보강하기 위해 GitLab 취약점 데이터베이스의 데이터가 병합됩니다. GitLab Premium 및 Free 티어에서는 외부 소스의 데이터를 보강하기 위해 오픈 소스 버전의 GitLab 취약점 데이터베이스의 데이터가 병합됩니다. 현재 이 보강은 Trivy 스캐너용 분석 도구 이미지에만 적용됩니다.

다른 분석 도구에 대한 데이터베이스 업데이트 정보는 유지 관리 표에서 확인할 수 있습니다.

취약점에 대한 솔루션 (자동 복구)

Tier: Ultimate Offering: GitLab.com, Self-Managed, GitLab Dedicated

일부 취약점은 GitLab이 자동으로 생성하는 해결책을 적용하여 해결할 수 있습니다.

복구 지원을 활성화하려면 스캔 도구가 CS_DOCKERFILE_PATH CI/CD 변수에서 지정한 Dockerfile에 액세스해야 합니다. 스캔 도구가 이 파일에 액세스할 수 있도록 하려면 이 문서의 컨테이너 스캔 템플릿 무시 섹션에 설명된 지침을 따라 .gitlab-ci.yml 파일에 GIT_STRATEGY: fetch를 설정해야합니다.

취약점에 대한 솔루션에 대해 더 읽어보세요.

문제 해결

docker: Error response from daemon: failed to copy xattrs

런너가 docker 실행자를 사용하고 NFS가 사용될 때 (예를 들어, /var/lib/docker가 NFS 마운트에 있는 경우) 컨테이너 스캔이 다음과 같은 오류로 실패할 수 있습니다.

docker: Error response from daemon: failed to copy xattrs: failed to set xattr "security.selinux" on /path/to/file: operation not supported.

이는 Docker의 버그로 인한 것으로 현재 고쳐졌습니다. 오류를 방지하려면 러너가 사용 중인 Docker 버전이 18.09.03 이상인지 확인하세요. 자세한 정보는 이슈 #10241를 참조하세요.

경고 메시지 gl-container-scanning-report.json: no matching files 가져오기

이와 관련된 정보는 일반 응용프로그램 보안 문제 해결 섹션을 참조하세요.

AWS ECR에서 이미지를 스캔할 때 unexpected status code 401 Unauthorized: Not Authorized 발생

AWS 지역이 구성되지 않았고 스캐너가 인가 토큰을 검색할 수 없는 경우 발생할 수 있습니다. SECURE_LOG_LEVELdebug로 설정하면 아래와 같은 로그 메시지가 표시됩니다.

[35mDEBUG[0m failed to get authorization token: MissingRegion: could not find region configuration

이를 해결하려면 AWS_DEFAULT_REGION을 CI/CD 변수에 추가하세요.

variables:
  AWS_DEFAULT_REGION: <AWS_REGION_FOR_ECR>

unable to open a file: open /home/gitlab/.cache/trivy/ee/db/metadata.json: no such file or directory 해결

압축된 Trivy 데이터베이스가 컨테이너의 /tmp 폴더에 저장되며 실행 시 /home/gitlab/.cache/trivy/{ee|ce}/db로 추출됩니다. 이 오류는 러너 구성에서 /tmp 디렉토리에 대한 볼륨 마운트가 있는 경우 발생할 수 있습니다.

이를 해결하려면 /tmp 폴더를 바인딩하는 대신 /tmp의 특정 파일이나 폴더를 바인딩하세요 (예: /tmp/myfile.txt).

context deadline exceeded 오류 해결

이 오류는 타임아웃이 발생했음을 의미합니다. 이를 해결하려면 container_scanning 작업에 충분히 긴 기간을 가진 TRIVY_TIMEOUT 환경 변수를 추가하세요.

변경 사항

컨테이너 스캐닝 분석기의 변경 내용은 프로젝트의 변경 로그에서 확인할 수 있습니다.