컨테이너 스캐닝

Tier: Free, Premium, Ultimate Offering: GitLab.com, 자체 관리형, GitLab Dedicated

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

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

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

GitLab은 컨테이너의 취약점을 정적으로 분석하기 위해 오픈 소스 도구와 통합됩니다:

경고: Grype에 대한 지원은 GitLab 16.9에서 중단되었으며 17.0에서 제거할 예정입니다. 대신 Trivy를 사용하십시오.

여기에 나열된 도구 이외의 보안 스캐너를 GitLab과 통합하려면 보안 스캐너 통합을 참조하세요.

다음 중 하나를 수행하여 컨테이너 스캐닝을 활성화할 수 있습니다:

GitLab은 발견된 취약점을 원본 및 대상 브랜치 간에 비교하고 병합 요청에서 정보를 직접 표시합니다.

컨테이너 스캐닝 위젯

기능

기능 무료 및 프리미엄 얼티메이트
스캐너 구성 가능 가능
설정 사용자화(변수, 재정의, 오프라인 환경 지원 등) 가능 가능
CI 작업 아티팩트로 JSON 보고서 보기 가능 가능
종속성의 JSON 보고서 생성 가능 가능
병합 요청에서 컨테이너 스캐닝을 활성화할 수 있는 기능 가능 가능
UBI 이미지 지원 가능 가능
Trivy 지원 가능 가능
Grype 지원 가능 가능
GitLab 고문 데이터베이스 포함 GitLab 공지-커뮤니티 프로젝트의 시간 지연 콘텐츠로 제한됨 Gemnasium DB의 최신 컨텐츠
병합 요청 및 CI 파이프라인 작업보안 탭에서 보고서 데이터를 표시 불가능 가능
병합 요청 승인과 같은 취약점과 상호 작용 불가능 가능
취약점에 대한 솔루션(자동 복구) 불가능 가능
취약점 허용 목록 지원 불가능 가능
보안 대시보드 페이지에 대한 액세스 불가능 가능
의존성 목록 페이지에 대한 액세스 불가능 가능

Prerequisites

파이프라인에서 컨테이너 스캔을 활성화하려면 다음이 필요합니다.

  • GitLab CI/CD 파이프라인에는 stages 키워드로 재정의되지 않는 한 사용 가능한 test 단계가 포함되어야 합니다.
  • Linux/amd64에 docker 또는 kubernetes 실행자가 있는 GitLab Runner가 있어야 합니다.
  • Docker 18.09.03 이상이 러너와 동일한 컴퓨터에 설치되어 있어야 합니다. GitLab.com에서 인스턴스 러너를 사용하는 경우 이미 설치되어 있습니다.
  • 지원되는 배포와 일치하는 이미지가 필요합니다.
  • 프로젝트의 컨테이너 레지스트리에 Docker 이미지를 빌드하고 푸시해야 합니다.
  • 서드 파티 컨테이너 레지스트리를 사용하는 경우 CS_REGISTRY_USERCS_REGISTRY_PASSWORD 구성 변수를 통해 인증 자격 증명을 제공해야 할 수 있습니다. 이러한 변수를 사용하는 방법에 대한 자세한 내용은 원격 레지스트리에 인증를 참조하세요.

Configuration

컨테이너 스캔을 활성화하려면 .gitlab-ci.yml 파일에 Container-Scanning.gitlab-ci.yml 템플릿을 추가하세요.

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

포함된 템플릿은:

  • CI/CD 파이프라인에서 container_scanning 작업을 생성합니다.
  • 프로젝트의 컨테이너 레지스트리 (자세한 내용은 prerequisites를 참조)에서 빌드된 Docker 이미지를 가져와 가능한 취약점을 스캔합니다.

GitLab은 결과를 컨테이너 스캔 보고서 아티팩트로 저장하여 나중에 다운로드하고 분석할 수 있습니다. 다운로드할 때 항상 최신 아티팩트를 받게 됩니다. 의존성 스캔이 활성화된 경우 의존성 스캔 보고서 아티팩트도 생성됩니다.

다음은 Docker 이미지를 빌드하고 컨테이너 레지스트리에 푸시하고 이미지를 스캔하는 샘플 .gitlab-ci.yml입니다.

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

container_scanning:
  variables:
    CS_DEFAULT_BRANCH_IMAGE: $CI_REGISTRY_IMAGE/$CI_DEFAULT_BRANCH:$CI_COMMIT_SHA

CS_DEFAULT_BRANCH_IMAGE를 설정하면 브랜치 간에 이미지 이름이 다를 때 중복 취약점 결과를 피할 수 있습니다. CS_DEFAULT_BRANCH_IMAGE의 값은 기본 브랜치에 표시되는 스캔된 이미지의 이름을 나타냅니다. 이 중복 방지가 어떻게 달성되는지 자세한 내용은 기본 브랜치 이미지 설정을 참조하세요.

컨테이너 스캔 설정 사용자 정의

GitLab이 컨테이너를 스캔하는 방식을 사용자 정의하려는 경우가 있을 수 있습니다. 예를 들어 더 상세한 출력을 활성화하거나 인증이 필요한 Docker 레지스트리에 액세스하려는 등입니다. 이러한 설정을 변경하려면 .gitlab-ci.yml에서 variables 매개변수를 사용하여 CI/CD 변수를 설정하여 CI/CD 변수를 설정하세요. .gitlab-ci.yml에서 설정하는 변수는 Container-Scanning.gitlab-ci.yml의 변수를 덮어쓰게 됩니다.

다음 예제는 컨테이너 스캔 템플릿을 포함하고 분석기를 위해 상세 출력을 활성화합니다.

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_DEPENDENCY_LIST CI/CD 변수는 스캔이 의존성 목록 보고서를 생성하는지 여부를 제어합니다. 현재 이 변수는 trivy 분석기를 사용할 때만 지원됩니다. 변수의 기본 설정은 "false"로, 스캔이 보고서를 생성하도록 합니다. 보고서를 비활성화하려면 변수를 "true"로 설정하세요.

예시:

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

container_scanning:
  variables:
    CS_DISABLE_DEPENDENCY_LIST: "true"

언어별 발견 보고서

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"

이 기능을 활성화하면 프로젝트에 의존성 스캐닝이 활성화되어 있는 경우 중복된 발견 사항취약점 보고서에 표시될 수 있습니다. 이는 GitLab이 스캐닝 도구 유형 간에 발견을 자동으로 중복 처리할 수 없기 때문에 발생합니다. 어떤 종류의 종속성이 중복될 가능성이 있는지 이해하려면 의존성 스캐닝과 컨테이너 스캐닝 비교를 참조하세요.

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

병합 요청 파이프라인에서 보안 스캐닝 도구 사용을 참조하세요.

사용 가능한 CI/CD 변수

다음 CI/CD 변수를 사용하여 분석기를 구성할 수 있습니다.

경고: GitLab 보안 스캐닝 도구의 모든 사용자 정의는 기본 브랜치로의 병합 전에 병합 요청에서 테스트되어야 합니다. 그렇지 않으면 예기치 않은 결과(예: 대량의 잘못된 양성 결과)가 발생할 수 있습니다.

CI/CD 변수 기본값 설명 스캐너
ADDITIONAL_CA_CERT_BUNDLE "" 신뢰할 CA 인증서 번들입니다. 자세한 내용은 사용자 정의 SSL CA 인증서 권한 사용을 참조하세요. 모두
CI_APPLICATION_REPOSITORY $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG 스캔할 이미지의 Docker 저장소 URL입니다. 모두
CI_APPLICATION_TAG $CI_COMMIT_SHA 스캔할 이미지의 Docker 저장소 태그입니다. 모두
CS_ANALYZER_IMAGE registry.gitlab.com/security-products/container-scanning:6 분석기의 Docker 이미지입니다. 모두
CS_DEFAULT_BRANCH_IMAGE "" 기본 브랜치의 CS_IMAGE 이름입니다. 자세한 내용은 기본 브랜치 이미지 설정을 참조하세요. GitLab 14.5에 도입되었습니다. 모두
CS_DISABLE_DEPENDENCY_LIST "false" 스캔된 이미지에 설치된 패키지를 위한 의존성 스캐닝을 비활성화합니다. GitLab 14.6에 도입되었습니다. 모두
CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN "true" 스캔된 이미지에 설치된 언어별 패키지에 대한 스캔을 비활성화합니다. GitLab 14.6에 도입되었습니다. 모두
CS_DOCKER_INSECURE "false" 인증서를 확인하지 않고 HTTPS를 통해 안전한 Docker 레지스트리에 액세스를 허용합니다. 모두
CS_DOCKERFILE_PATH Dockerfile 수정 사항 생성에 사용할 Dockerfile의 경로입니다. 기본적으로 스캐너는 프로젝트의 루트 디렉토리에 있는 Dockerfile이라는 파일을 찾습니다. Dockerfile이 하위 디렉토리와 같은 비표준 위치에 있는 경우에만 이 변수를 구성해야 합니다. 자세한 내용은 취약점에 대한 솔루션을 참조하세요. 모두
CS_IGNORE_STATUSES1 "" 지정된 상태로 취약점 발견을 무시하도록 분석기를 강제합니다. trivy의 경우 지원되는 값은 unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life입니다. grype의 경우 지원되는 값은 fixed,not-fixed,unknown,wont-fix입니다. 모두
CS_IGNORE_UNFIXED "false" 해결되지 않은 취약점을 무시합니다. 모두

  1. 수정 상태 정보는 소프트웨어 공급자 및 컨테이너 이미지 운영 체제 패키지 메타데이터로부터 정확한 수정 가능성 데이터에 매우 의존적입니다. 또한 각각의 컨테이너 스캐너에서 해석되는 것입니다. 컨테이너 스캐너가 취약점의 수정 가능성을 잘못 보고하는 경우 `CS_IGNORE_STATUSES`를 사용하면 이 설정이 활성화될 때 발견의 잘못된 양성 또는 음성 필터링으로 이어질 수 있습니다.

지원되는 배포

지원은 사용하는 스캐너에 따라 다릅니다.

배포 Grype Trivy
Alma Linux No Yes
Alpine Linux Yes Yes
Amazon Linux Yes Yes
BusyBox Yes No
CentOS Yes Yes
CBL-Mariner No Yes
Debian Yes Yes
Distroless Yes Yes
Oracle Linux Yes Yes
Photon OS No Yes
Red Hat (RHEL) Yes Yes
Rocky Linux No Yes
SUSE No Yes
Ubuntu Yes Yes

FIPS 사용 이미지

GitLab은 컨테이너 스캐닝 이미지의 FIPS 활성화 Red Hat UBI 버전도 제공합니다. 따라서 표준 이미지를 FIPS 활성화 이미지로 대체할 수 있습니다. 이미지를 구성하려면 CS_IMAGE_SUFFIX-fips로 설정하거나 CS_ANALYZER_IMAGE 변수를 표준 태그 및 -fips 확장으로 수정하면 됩니다.

스캐너 이름 CS_ANALYZER_IMAGE
기본 (Trivy) registry.gitlab.com/security-products/container-scanning:6-fips
Grype registry.gitlab.com/security-products/container-scanning/grype:6-fips
Trivy registry.gitlab.com/security-products/container-scanning/trivy:6-fips

참고: GitLab 15.0 이전에는 -ubi 이미지 확장이 사용 가능합니다. GitLab 15.0 이상에서는 -fips만 지원합니다.

GitLab 14.10부터 FIPS 모드가 GitLab 인스턴스에서 활성화되면 CS_ANALYZER_IMAGE에 자동으로 -fips가 추가됩니다.

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

컨테이너 스캐닝을 자동 병합 요청으로 활성화

프로젝트에서 컨테이너 스캐닝을 활성화하려면 보안 구성 페이지에서 병합 요청을 만드세요:

  1. 컨테이너 스캐닝을 활성화하려는 프로젝트에서 Secure > 보안 구성으로 이동합니다.
  2. 컨테이너 스캐닝 행에서 병합 요청으로 구성을 선택합니다.

이렇게 하면 컨테이너 스캐닝을 활성화하기 위한 변경 사항이 포함된 병합 요청이 자동으로 생성됩니다. 구성을 완료하려면이 병합 요청을 검토하고 병합합니다.

구성 도구는 기존의 .gitlab-ci.yml 파일이 없거나 최소한의 구성 파일이 있는 경우에 가장 잘 작동합니다. 복잡한 GitLab 구성 파일이 있는 경우에는 성공적으로 구문 분석되지 않을 수 있으며 오류가 발생할 수 있습니다.

컨테이너 스캐닝 템플릿 덮어쓰기

작업 정의를 덮어쓰려면(예: variables와 같은 속성 변경) 템플릿 포함 후에 작업을 선언하고 덮어쓰기해야 합니다. 그런 다음 추가 키를 지정하면 됩니다.

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

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

container_scanning:
  variables:
    GIT_STRATEGY: fetch

스캐너 변경

CS_ANALYZER_IMAGE 구성 변수의 값에 따라 컨테이너-스캐닝 분석기는 다른 스캐너를 사용할 수 있습니다.

다음 옵션이 가능합니다:

스캐너 이름 CS_ANALYZER_IMAGE
기본 (Trivy) registry.gitlab.com/security-products/container-scanning:6
Grype registry.gitlab.com/security-products/container-scanning/grype:6
Trivy registry.gitlab.com/security-products/container-scanning/trivy:6

경고: 스캐너 이미지 선택시 :latest 태그를 사용하지 마십시오.

기본 브랜치 이미지 설정

기본 설정에 따르면, 컨테이너 스캐닝은 이미지 이름 규칙이 이미지 이름보다는 이미지 태그에 브랜치별 식별자를 저장한다고 가정합니다. 이미지 이름이 기본 브랜치와 기본 브랜치가 아닌 브랜치 사이에서 다를 때, 이전에 감지된 취약점은 병합 요청에서 새롭게 감지된 것으로 표시됩니다.

동일한 이미지가 기본 브랜치와 기본 브랜치가 아닌 브랜치에서 서로 다른 이름을 갖는 경우, 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 파일로, 해당 취약점은 false positives_이거나 _적용되지 않는 경우입니다.

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

  • images 블록을 사용하여 각 컨테이너 이미지에 대해 CVE ID를 지정할 수 있습니다. 일치하는 CVE ID를 가진 지정된 이미지의 모든 취약점은 스캔 보고서에서 제외됩니다. 이미지 이름은 Docker 이미지를 지정하는 데 사용되는 환경 변수 중 하나에서 검색됩니다. 예를 들어 $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)은 선택 사항의 주석 형식입니다. 취약점 처리에 영향을 미치지 않습니다. 취약점을 설명하는 데 주석을 포함할 수 있습니다.

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

컨테이너 스캐닝 분석기가 생성하는 로그를 확인하여 vulnerability-allowlist.yml 파일의 결과 및 정확성을 검증할 수 있습니다.

로그에는 테이블로 발견된 취약점 목록이 포함됩니다. 예를 들어:

+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+
|   상태     |      CVE 심각도         |      패키지 이름         |    패키지 버전        |                             CVE 설명                                   |
+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+
|  승인됨   |   높음 CVE-2019-3462    |          apt            |         1.4.8         | apt 버전 1.4.8 및 이전 버전에서 HTTP 전송 방법의 302 리디렉션 필드의 부적절한 검열이 MITM 공격자에 의해 콘텐츠 주입을 유발 할 수 있으며, 이는 대상 컴퓨터에서 원격 코드 실행으로 이어질 가능성이 있습니다. |
+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+
| 미승인    |  중간 CVE-2020-27350  |          apt            |         1.4.8         | .deb 파일을 구문 분석하는 동안 APT에는 여러 정수 오버플로우와 언더플로우가 있었습니다. GHSL-2020-168 GHSL-2020-169라고도 함. 이 문제는 다음을 포함합니다. 1.2.32ubuntu0.2 이전 apt 1.2.32ubuntu0 버전; 1.6.12ubuntu0.2 이전 apt 1.6.12ubuntu0 버전; 2.0.2ubuntu0.2 이전 apt 2.0.2ubuntu0 버전; 2.1.10ubuntu0.1 이전 apt 2.1.10ubuntu0 버전; |
+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+
| 미승인    |  중간 CVE-2020-3810    |          apt            |         1.4.8         | APT의 ar/tar 구현에서 입력 유효성 검사가 부족했습니다. 2.1.2 버전 이전의 APT는 특수하게 제작된 deb 파일을 처리할 때 서비스 거부로 이어질 수 있습니다.                   |
+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+

로그의 취약점은 해당 CVE ID가 vulnerability-allowlist.yml 파일에 추가되면 승인됨으로 표시됩니다.

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

인터넷을 통한 외부 리소스에 대한 제한적이거나 제한된 또는 간헐적인 액세스가 있는 환경에서 자체 관리형 GitLab 인스턴스를 위해 컨테이너 스캔 작업이 성공적으로 실행되려면 일부 조정이 필요합니다. 자세한 내용은 오프라인 배포를 참조하십시오.

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

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

  • docker 또는 kubernetes executor가 있는 GitLab Runner.
  • 컨테이너 스캔 이미지의 사본이 있는 로컬 Docker 컨테이너 레지스트리를 구성해야 합니다. 이러한 이미지는 각각의 레지스트리에서 찾을 수 있습니다.
GitLab Analyzer 컨테이너 레지스트리
Container-Scanning 컨테이너 스캐닝 컨테이너 레지스트리

GitLab Runner는 기본적으로 항상(pull policy: always) 도커 이미지를 가져오려고 시도하므로, 로컬 사본이 있더라도 GitLab 컨테이너 레지스트리에서 도커 이미지를 가져오려고 합니다. 오프라인 환경에서는 GitLab Runner의 pull policyif-not-present로 설정할 수 있으며, 이를 통해 로컬에서만 사용 가능한 도커 이미지를 선호하는 경우에 사용할 수 있습니다. 그러나 CI/CD 파이프라인에서 업데이트된 스캐너를 사용하려면 오프라인 환경이 아닌 경우에는 항상(pull policy: always)로 설정하는 것이 좋습니다.

사용자 지정 인증 기관 지원

다음 버전에서 사용자 지정 인증 기관 지원이 추가되었습니다:

스캐너 버전
Trivy 4.0.0
Grype 4.3.0

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

컨테이너 스캐닝을 위해 registry.gitlab.com에서 다음 이미지를 로컬 Docker 컨테이너 레지스트리로 가져옵니다:

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

로컬 오프라인 도커 레지스트리로 도커 이미지를 가져오는 프로세스는 귀하의 네트워크 보안 정책에 따라 다릅니다. 외부 리소스에 대한 수락되고 승인된 프로세스를 찾기 위해 귀하의 IT 직원과 상의하십시오. 이러한 스캐너들은 정기적으로 업데이트됩니다, 때때로 자체적으로 업데이트할 수 있을 것입니다.

더 많은 정보는 파이프라인을 사용한 컨테이너 스캐닝 취약점 데이터베이스 업데이트하는 구체적인 단계를 참조하세요.

도커 이미지를 파일로 저장하고 전송하는 방법에 대한 자세한 내용은 도커 문서의 docker save, docker load, docker export, docker import를 참조하세요.

로컬 컨테이너 스캐너 분석기를 사용하도록 container scanning CI/CD 변수 설정

  1. .gitlab-ci.yml 파일에서 로컬 Docker 컨테이너 레지스트리에 호스팅된 도커 이미지를 참조하도록 컨테이너 스캐닝 템플릿을 재정의합니다:

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

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

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

variables:
  SOURCE_IMAGE: registry.gitlab.com/security-products/container-scanning:6
  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 키가 담긴 추가해야 합니다. 또한:

  • 마스크 변수 옵션에 값이 맞지 않을 수 있어 작업 로그에서 값이 노출될 수 있습니다.
  • 보호 변수 옵션을 선택하면 보호되지 않은 특성 브랜치에서 검사가 실행되지 않을 수 있습니다.
  • 옵션을 선택하지 않으면 읽기 전용 권한을 가진 자격 증명을 만들고 주기적으로 회전하는 것이 좋습니다.

FIPS 모드가 활성화된 경우 외부 비공개 레지스트리 이미지 스캔은 지원되지 않습니다.

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

trivy 스캐너를 사용하고 이미지 스캔 중에 jar 파일이 발견되면 trivy는 추가적인 trivy-java-db 취약성 데이터베이스를 다운로드합니다. 기본적으로 trivy-java-db 데이터베이스는 OCI artifactghcr.io/aquasecurity/trivy-java-db:1에 호스팅되어 있습니다. 예를 들어 네트워크 격리된 오프라인 GitLab 인스턴스인 경우, 이 레지스트리에 엑세스할 수 없다면 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 작업의 맥락 안에서 실행하는 것이 아니라 직접 Docker 컨테이너를 대상으로 GitLab 컨테이너 스캐닝 도구를 실행하는 것이 가능합니다. 이미지를 직접 스캔하려면 다음 단계를 따르세요:

  1. Docker Desktop 또는 Docker Machine을 실행합니다.

  2. 원하는 이미지와 태그를 분석하고자 하는 CI_APPLICATION_REPOSITORYCI_APPLICATION_TAG 변수에 전달하여 분석기 Docker 이미지를 실행합니다:

    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 키워드를 통해 인식됩니다.

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

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

더 많은 정보는 보안 스캐너 통합을 참조하세요.

CycloneDX 소프트웨어 자재 목록

  • GitLab 15.11에 도입되었습니다.

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

CycloneDX SBOM은 다른 작업 보관물과 동일한 방식으로 다운로드할 수 있습니다.

보안 대시보드

Security Dashboard는 귀하의 그룹, 프로젝트 및 파이프라인의 모든 보안 취약점에 대한 개요를 보여줍니다.

취약점 데이터베이스

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

이미지는 사용된 스캐너에 따라 상류 통보 데이터베이스의 데이터를 사용합니다:

데이터 소스 Trivy Grype
AlmaLinux 보안 고지 Yes Yes
Amazon Linux 보안 센터 Yes Yes
Arch Linux 보안 추적기 Yes No
SUSE CVRF Yes Yes
CWE 고지 Yes No
Debian 보안 버그 추적기 Yes Yes
GitHub 보안 고지 Yes Yes
Go 취약성 데이터베이스 Yes No
CBL-Mariner 취약성 데이터 Yes No
NVD Yes Yes
OSV Yes No
Red Hat OVAL v2 Yes Yes
Red Hat 보안 데이터 API Yes Yes
Photon 보안 고지 Yes No
Rocky Linux UpdateInfo Yes No
Ubuntu CVE 추적기 (2021년 중반 이후의 데이터 소스만 해당) Yes Yes

이러한 스캐너가 제공하는 소스 외에도 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

이 문제를 해결하려면, CI/CD 변수에 AWS_DEFAULT_REGION을 추가하세요:

variables:
  AWS_DEFAULT_REGION: <AWS_REGION_FOR_ECR>

변경 사항

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