InfoGrab Docs

컨테이너 스캔

요약

컨테이너 이미지의 보안 취약점은 애플리케이션 라이프사이클 전반에 걸쳐 위험을 초래합니다. 컨테이너 스캔은 소프트웨어 컴포지션 분석(SCA)의 일부로 간주되는 경우가 많습니다. GitLab은 이러한 모든 의존성 유형을 포괄하기 위해 컨테이너 스캔과 의존성 스캔을 모두 제공합니다.

컨테이너 이미지의 보안 취약점은 애플리케이션 라이프사이클 전반에 걸쳐 위험을 초래합니다. 컨테이너 스캔은 이러한 위험을 프로덕션 환경에 도달하기 전, 조기에 감지합니다. 베이스 이미지나 운영 체제 패키지에 취약점이 발견되면, 컨테이너 스캔은 이를 식별하고 가능한 취약점에 대한 해결 방법을 제공합니다.

컨테이너 스캔은 소프트웨어 컴포지션 분석(SCA)의 일부로 간주되는 경우가 많습니다. SCA는 코드가 사용하는 항목을 검사하는 측면을 포함할 수 있습니다. 이러한 항목에는 일반적으로 애플리케이션 및 시스템 의존성이 포함되며, 이는 거의 항상 외부 소스에서 가져오고 직접 작성한 항목이 아닙니다.

GitLab은 이러한 모든 의존성 유형을 포괄하기 위해 컨테이너 스캔과 의존성 스캔을 모두 제공합니다. 위험 영역을 최대한 포괄하려면 모든 보안 스캐너를 사용하세요. 이러한 기능의 비교를 위해서는 의존성 스캔과 컨테이너 스캔 비교를 참조하세요.

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

Warning

Grype 분석기는 GitLab 지원 정책에 설명된 제한적인 수정을 제외하고 더 이상 유지 관리되지 않습니다. Grype 분석기 이미지의 현재 주요 버전은 GitLab 19.0까지 최신 어드바이저리 데이터베이스 및 운영 체제 패키지로 계속 업데이트되며, 그 이후에는 분석기가 작동을 멈춥니다.

기능#

기능 Free 및 Premium Ultimate
설정 커스터마이즈 (변수, 오버라이딩, 오프라인 환경 지원 등)
CI job 아티팩트로 JSON 보고서 보기
CI job 아티팩트로 CycloneDX SBOM JSON 보고서 생성
GitLab UI에서 MR을 통해 컨테이너 스캔 활성화
UBI 이미지 지원
Trivy 지원
수명 종료 운영 체제 감지
GitLab 어드바이저리 데이터베이스 포함 GitLab advisories-communities 프로젝트의 시간 지연 콘텐츠로 제한 예 - Gemnasium DB의 모든 최신 콘텐츠
머지 리퀘스트 및 CI 파이프라인 job의 Security 탭에서 보고서 데이터 표시
취약점 솔루션 (자동 해결)
취약점 허용 목록 지원
의존성 목록 페이지 접근

시작하기#

CI/CD 파이프라인에서 컨테이너 스캔 분석기를 활성화하세요. 파이프라인이 실행되면, 애플리케이션이 의존하는 이미지에서 취약점이 스캔됩니다. CI/CD 변수를 사용하여 컨테이너 스캔을 커스터마이즈할 수 있습니다.

전제 조건:

  • .gitlab-ci.yml 파일에 test 스테이지가 필요합니다.
  • 셀프 매니지드 러너를 사용하는 경우 Linux/amd64에서 docker 또는 kubernetes executor가 있는 러너가 필요합니다. GitLab.com의 인스턴스 러너를 사용하는 경우 기본적으로 활성화됩니다.
  • 지원되는 배포판과 일치하는 이미지.
  • Docker 이미지를 프로젝트의 컨테이너 레지스트리에 빌드하고 푸시합니다.
  • 서드파티 컨테이너 레지스트리를 사용하는 경우, CI/CD 변수 CS_REGISTRY_USERCS_REGISTRY_PASSWORD를 사용하여 인증 자격증명을 제공해야 할 수 있습니다. 이 변수 사용 방법에 대한 자세한 내용은 프라이빗 외부 레지스트리 인증을 참조하세요.

사용자 및 프로젝트별 요구사항에 대한 자세한 내용을 아래에서 확인하세요.

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

  • 의존성 스캔을 포함하는 Auto DevOps를 활성화합니다.
  • 사전 구성된 머지 리퀘스트를 사용합니다.
  • 컨테이너 스캔을 적용하는 스캔 실행 정책을 생성합니다.
  • .gitlab-ci.yml 파일을 수동으로 편집합니다.

사전 구성된 머지 리퀘스트 사용#

이 방법은 .gitlab-ci.yml 파일에 컨테이너 스캔 템플릿을 포함하는 머지 리퀘스트를 자동으로 준비합니다. 그런 다음 머지 리퀘스트를 머지하여 컨테이너 스캔을 활성화합니다.

Note

이 방법은 기존 .gitlab-ci.yml 파일이 없거나 최소한의 구성 파일이 있는 경우에 가장 잘 작동합니다. 복잡한 GitLab 구성 파일이 있는 경우 성공적으로 파싱되지 않을 수 있으며 오류가 발생할 수 있습니다. 이 경우 수동 방법을 사용하세요.

전제 조건:

  • 프로젝트에 대한 Developer, Maintainer 또는 Owner 역할.
  • .gitlab-ci.yml 파일에 test 스테이지가 있어야 합니다.
  • 셀프 매니지드 러너를 사용하는 경우 Linux/amd64에서 docker 또는 kubernetes executor가 있는 러너. GitLab.com의 인스턴스 러너를 사용하는 경우 기본적으로 활성화됩니다.
  • 지원되는 배포판과 일치하는 이미지.
  • Docker 이미지가 프로젝트의 컨테이너 레지스트리에 빌드되고 푸시되어 있어야 합니다.
  • 서드파티 컨테이너 레지스트리를 사용하는 경우, CI/CD 변수 CS_REGISTRY_USERCS_REGISTRY_PASSWORD를 사용하여 인증 자격증명을 제공해야 할 수 있습니다. 자세한 내용은 프라이빗 외부 레지스트리 인증을 참조하세요.

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

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
  2. 왼쪽 사이드바에서 Secure > Security configuration을 선택합니다.
  3. Container Scanning 행에서 Configure with a merge request를 선택합니다.
  4. Create merge request를 선택합니다.
  5. 머지 리퀘스트를 검토한 다음 Merge를 선택합니다.

이제 파이프라인에 컨테이너 스캔 job이 포함됩니다.

.gitlab-ci.yml 파일 수동 편집#

이 방법을 사용하면 기존 .gitlab-ci.yml 파일을 수동으로 편집해야 합니다. 복잡한 GitLab 구성 파일이 있거나 기본값이 아닌 옵션을 사용해야 하는 경우 이 방법을 사용하세요.

전제 조건:

  • 프로젝트에 대한 Developer, Maintainer 또는 Owner 역할.
  • .gitlab-ci.yml 파일에 test 스테이지가 있어야 합니다.
  • 셀프 매니지드 러너를 사용하는 경우 Linux/amd64에서 docker 또는 kubernetes executor가 있는 러너. GitLab.com의 인스턴스 러너를 사용하는 경우 기본적으로 활성화됩니다.
  • 지원되는 배포판과 일치하는 이미지.
  • Docker 이미지가 프로젝트의 컨테이너 레지스트리에 빌드되고 푸시되어 있어야 합니다.
  • 서드파티 컨테이너 레지스트리를 사용하는 경우, CI/CD 변수 CS_REGISTRY_USERCS_REGISTRY_PASSWORD를 사용하여 인증 자격증명을 제공해야 할 수 있습니다. 자세한 내용은 프라이빗 외부 레지스트리 인증을 참조하세요.

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

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.

  2. 왼쪽 사이드바에서 Build > Pipeline editor를 선택합니다.

  3. .gitlab-ci.yml 파일이 없는 경우 Configure pipeline을 선택한 다음 예제 내용을 삭제합니다.

  4. 다음을 복사하여 .gitlab-ci.yml 파일 하단에 붙여넣습니다. include 줄이 이미 있는 경우 그 아래에 template 줄만 추가합니다.

    include:
      - template: Jobs/Container-Scanning.gitlab-ci.yml
    
  5. Validate 탭을 선택한 다음 Validate pipeline을 선택합니다.

    Simulation completed successfully 메시지가 파일이 유효함을 확인합니다.

  6. Edit 탭을 선택합니다.

  7. 필드를 완성합니다. Branch 필드에 기본 브랜치를 사용하지 마세요.

  8. Start a new merge request with these changes 체크박스를 선택한 다음 Commit changes를 선택합니다.

  9. 표준 워크플로우에 따라 필드를 완성한 다음 Create merge request를 선택합니다.

  10. 표준 워크플로우에 따라 머지 리퀘스트를 검토하고 편집하고 파이프라인이 통과할 때까지 기다린 다음 Merge를 선택합니다.

이제 파이프라인에 컨테이너 스캔 job이 포함됩니다.

결과 이해하기#

전제 조건:

  • 프로젝트에 대한 Security Manager, Developer, Maintainer 또는 Owner 역할.

파이프라인에서 취약점을 검토할 수 있습니다:

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
  2. 왼쪽 사이드바에서 Build > Pipelines를 선택합니다.
  3. 파이프라인을 선택합니다.
  4. Security 탭을 선택합니다.
  5. 취약점을 선택하여 다음을 포함한 세부 정보를 봅니다:
    • 설명: 취약점의 원인, 잠재적인 영향 및 권장 해결 단계를 설명합니다.
    • 상태: 취약점이 트리아지되거나 해결되었는지 여부를 나타냅니다.
    • 심각도: 영향에 따라 6가지 수준으로 분류됩니다. 심각도 수준에 대해 자세히 알아보기.
    • CVSS 점수: 심각도에 매핑되는 숫자 값을 제공합니다.
    • EPSS: 야생에서 취약점이 악용될 가능성을 보여줍니다.
    • 알려진 악용 사례(KEV): 특정 취약점이 악용된 것을 나타냅니다.
    • 프로젝트: 취약점이 식별된 프로젝트를 강조 표시합니다.
    • 보고서 유형: 출력 유형을 설명합니다.
    • 스캐너: 취약점을 감지한 분석기를 식별합니다.
    • 이미지: 취약점에 귀속된 이미지를 제공합니다.
    • 네임스페이스: 취약점에 귀속된 작업 영역을 식별합니다.
    • 링크: 다양한 어드바이저리 데이터베이스에 취약점이 카탈로그화된 증거.
    • 식별자: CVE 식별자와 같이 취약점을 분류하는 데 사용되는 참조 목록.

자세한 내용은 파이프라인 보안 보고서를 참조하세요.

컨테이너 스캔 결과를 볼 수 있는 추가 방법:

최적화#

GitLab은 컨테이너 스캔을 위한 두 가지 방법을 제공합니다:

  • 표준 컨테이너 스캔: job당 단일 컨테이너 이미지를 스캔합니다. 단순하고 분산된 워크플로우에 적합합니다.
  • 멀티 컨테이너 스캔: 단일 구성 파일을 사용하여 여러 이미지를 병렬로 스캔합니다. 여러 이미지를 효율적으로 스캔하는 데 적합합니다.

롤아웃#

단일 프로젝트에 대한 컨테이너 스캔 결과에 확신이 생긴 후, 추가 프로젝트로 구현을 확장할 수 있습니다:

  • 강제 스캔 실행을 사용하여 그룹 전체에 컨테이너 스캔 설정을 적용합니다.
  • 고유한 요구사항이 있는 경우 컨테이너 스캔을 오프라인 환경에서 실행할 수 있습니다.

지원되는 배포판#

다음 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 확장을 추가한 값으로 수정하세요.

Note

GitLab 인스턴스에서 FIPS 모드가 활성화된 경우 -fips 플래그가 CS_ANALYZER_IMAGE에 자동으로 추가됩니다.

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

구성#

분석기 동작 커스터마이즈#

컨테이너 스캔을 커스터마이즈하려면 CI/CD 변수를 사용하세요.

상세 출력 활성화#

예를 들어 문제 해결 시 의존성 스캔 job이 수행하는 작업을 자세히 볼 필요가 있을 때 상세 출력을 활성화합니다.

다음 예제에서는 컨테이너 스캔 템플릿이 포함되고 상세 출력이 활성화됩니다.

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

variables:
    SECURE_LOG_LEVEL: 'debug'

언어별 결과 보고#

CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN CI/CD 변수는 스캔이 프로그래밍 언어와 관련된 결과를 보고할지 여부를 제어합니다. 지원되는 언어에 대한 자세한 내용은 Trivy 문서의 언어별 패키지를 참조하세요.

기본적으로 보고서에는 운영 체제(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이 서로 다른 유형의 스캔 도구에서 결과를 자동으로 중복 제거할 수 없기 때문입니다. 중복될 가능성이 있는 의존성 유형을 이해하려면 의존성 스캔과 컨테이너 스캔 비교를 참조하세요.

머지 리퀘스트 파이프라인에서 job 실행#

머지 리퀘스트 파이프라인과 함께 보안 스캔 도구 사용을 참조하세요.

사용 가능한 CI/CD 변수#

컨테이너 스캔을 커스터마이즈하려면 CI/CD 변수를 사용하세요. 다음 표에는 컨테이너 스캔에 특화된 CI/CD 변수가 나열되어 있습니다. 미리 정의된 CI/CD 변수도 사용할 수 있습니다.

Warning

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:8 분석기의 Docker 이미지. GitLab에서 제공하는 분석기 이미지에 :latest 태그를 사용하지 마세요.
CS_DEFAULT_BRANCH_IMAGE "" 기본 브랜치의 CS_IMAGE 이름. 자세한 내용은 기본 브랜치 이미지 설정을 참조하세요.
CS_DISABLE_DEPENDENCY_LIST "false" ⚠️ GitLab 17.0에서 제거됨.
CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN "true" 스캔된 이미지에 설치된 언어별 패키지 스캔을 비활성화합니다.
CS_DOCKER_INSECURE "false" 인증서 유효성 검사 없이 HTTPS를 사용하는 보안 Docker 레지스트리 접근을 허용합니다.
CS_DOCKERFILE_PATH Dockerfile 해결책을 생성하는 데 사용할 Dockerfile 경로. 기본적으로 스캐너는 프로젝트의 루트 디렉토리에서 Dockerfile이라는 파일을 찾습니다. Dockerfile이 하위 디렉토리와 같이 비표준 위치에 있는 경우에만 이 변수를 구성해야 합니다. 자세한 내용은 취약점 솔루션을 참조하세요.
CS_INCLUDE_LICENSES "" 설정된 경우 각 컴포넌트에 대한 라이선스를 포함합니다. cyclonedx 보고서에만 적용 가능하며 해당 라이선스는 trivy에서 제공됩니다.
CS_IGNORE_STATUSES "" 쉼표로 구분된 목록에서 지정된 상태의 결과를 무시하도록 분석기를 강제합니다. 허용되는 값: unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life. 1
CS_IGNORE_UNFIXED "false" 수정되지 않은 결과를 무시합니다. 무시된 결과는 보고서에 포함되지 않습니다.
CS_IMAGE $CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG 스캔할 Docker 이미지. 설정된 경우 이 변수는 $CI_APPLICATION_REPOSITORY$CI_APPLICATION_TAG 변수를 재정의합니다.
CS_IMAGE_SUFFIX "" CS_ANALYZER_IMAGE에 추가되는 접미사. -fips로 설정하면 스캔에 FIPS 활성화 이미지가 사용됩니다. 자세한 내용은 FIPS 활성화 이미지를 참조하세요.
CS_QUIET "" 설정된 경우 job 로그의 취약점 테이블 출력을 비활성화합니다.
CS_REGISTRY_INSECURE "false" 안전하지 않은 레지스트리(HTTP만 해당) 접근을 허용합니다. 로컬에서 이미지를 테스트할 때만 true로 설정해야 합니다. 모든 스캐너에서 작동하지만 Trivy가 작동하려면 레지스트리가 포트 80/tcp에서 수신 대기해야 합니다.
CS_REGISTRY_PASSWORD $CI_REGISTRY_PASSWORD 인증이 필요한 Docker 레지스트리에 접근하기 위한 비밀번호. 기본값은 $CS_IMAGE$CI_REGISTRY에 있는 경우에만 설정됩니다. FIPS 모드가 활성화된 경우 지원되지 않습니다.
CS_REGISTRY_USER $CI_REGISTRY_USER 인증이 필요한 Docker 레지스트리에 접근하기 위한 사용자 이름. 기본값은 $CS_IMAGE$CI_REGISTRY에 있는 경우에만 설정됩니다. FIPS 모드가 활성화된 경우 지원되지 않습니다.
CS_REPORT_OS_EOL "false" EOL 감지 활성화
CS_REPORT_OS_EOL_SEVERITY "Medium" CS_REPORT_OS_EOL이 활성화된 경우 EOL OS 결과에 할당된 심각도 수준. EOL 결과는 CS_SEVERITY_THRESHOLD에 관계없이 항상 보고됩니다. 지원되는 수준: UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL.
CS_SEVERITY_THRESHOLD UNKNOWN 심각도 수준 임계값. 스캐너는 이 임계값보다 높거나 같은 심각도 수준의 취약점을 출력합니다. 지원되는 수준: UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL.
CS_TRIVY_JAVA_DB "registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-java-db" trivy-java-db 취약점 데이터베이스의 대체 위치를 지정합니다.
CS_TRIVY_DETECTION_PRIORITY "precise" 정의된 Trivy 감지 우선순위를 사용하여 스캔합니다. 허용되는 값: precise 또는 comprehensive.
SECURE_LOG_LEVEL info 최소 로깅 수준을 설정합니다. 이 로깅 수준 이상의 메시지가 출력됩니다. 가장 높은 수준에서 낮은 수준 순서로: fatal, error, warn, info, debug.
TRIVY_TIMEOUT 5m0s 스캔 타임아웃을 설정합니다.
TRIVY_PLATFORM linux/amd64 이미지가 멀티 플랫폼인 경우 os/arch 형식으로 플랫폼을 설정합니다.

각주:

  1. 수정 상태 정보는 소프트웨어 공급업체 및 컨테이너 이미지 운영 체제 패키지 메타데이터의 정확한 수정 가용성 데이터에 크게 의존합니다. 또한 개별 컨테이너 스캐너에 의한 해석의 영향을 받습니다. 컨테이너 스캐너가 취약점에 대한 수정된 패키지의 가용성을 잘못 보고하는 경우, 이 설정이 활성화된 경우 CS_IGNORE_STATUSES를 사용하면 결과 필터링에서 거짓 양성 또는 거짓 음성이 발생할 수 있습니다.

기본 환경 변수로 Trivy 직접 구성#

위에 나열된 GitLab 특화 CS_* 변수 외에도, container_scanning job에서 기본 환경 변수를 설정하여 Trivy를 직접 구성할 수 있습니다. GitLab 컨테이너 스캔 분석기는 모든 환경 변수를 자동으로 Trivy에 전달합니다.

예를 들어, Trivy가 자동 감지할 수 없는 컨테이너 이미지(예: 커스터마이즈된 베이스 이미지)에 대해 OS 배포판을 수동으로 지정하려면:

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

container_scanning:
  variables:
    GIT_STRATEGY: fetch
    TRIVY_DISTRO: "alma/10"
Note

TRIVY_DISTRO에서 사용하는 --distro 플래그는 Trivy에서 실험적입니다. 결과는 Trivy 버전 및 지정된 배포판에 따라 달라질 수 있습니다.

GitLab 래퍼에서 관리하는 변수#

다음 TRIVY_* 변수는 GitLab 컨테이너 스캔 분석기에 의해 내부적으로 설정됩니다. 해당 GitLab CI/CD 변수로 제어되며 직접 재정의할 수 없습니다:

Trivy 변수 GitLab CI/CD 변수
TRIVY_CACHE_DIR (내부, 노출되지 않음)
TRIVY_USERNAME CS_REGISTRY_USER
TRIVY_PASSWORD CS_REGISTRY_PASSWORD
TRIVY_DEBUG SECURE_LOG_LEVEL
TRIVY_INSECURE CS_DOCKER_INSECURE
TRIVY_NON_SSL CS_REGISTRY_INSECURE
TRIVY_DB_REPOSITORY 관련 알려진 문제#

TRIVY_DB_REPOSITORY를 커스텀 취약점 데이터베이스로 지정하도록 설정해도 효과가 없습니다. GitLab 컨테이너 스캔 분석기는 취약점 데이터베이스를 분석기 이미지 내부에 번들로 포함하고 런타임에 Trivy에 --skip-db-update를 전달하므로, 이 변수에 관계없이 Trivy는 데이터베이스를 다운로드하지 않습니다. 커스텀 데이터베이스 위치를 사용하려면 Java 데이터베이스의 경우 Trivy Java 데이터베이스 미러 사용을, 일반 오프라인 설정의 경우 오프라인 환경을 참조하세요.

컨테이너 스캔 템플릿 오버라이딩#

job 정의를 오버라이딩하려면(예: variables와 같은 속성 변경), 템플릿 포함 후 job을 선언하고 오버라이딩한 다음 추가 키를 지정해야 합니다.

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

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

container_scanning:
  variables:
    GIT_STRATEGY: fetch

외부 레지스트리의 이미지 스캔#

기본적으로 컨테이너 스캔은 GitLab 컨테이너 레지스트리의 이미지를 스캔합니다. 외부 레지스트리의 이미지도 스캔할 수 있습니다.

외부 레지스트리의 이미지를 스캔하려면 이미지의 전체 경로를 사용하여 CS_IMAGE 변수를 구성합니다.

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

container_scanning:
  variables:
    CS_IMAGE: <example.com>/<user>/<image>:<tag>

프라이빗 외부 레지스트리 인증#

외부 레지스트리가 인증을 필요로 하는 경우 CS_REGISTRY_USERCS_REGISTRY_PASSWORD CI/CD 변수를 사용하여 자격증명을 제공하세요.

Note

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

예를 들어, Google Container Registry의 이미지를 스캔하려면:

  1. Google Cloud Platform Container Registry 문서에 설명된 대로 JSON 키를 포함하는 GCP_CREDENTIALS CI/CD 변수를 추가합니다.

    • 변수 값이 마스크 변수 옵션의 마스킹 요구사항을 충족하지 않을 수 있으므로 job 로그에 값이 노출될 수 있습니다.
    • 보호 변수 옵션을 선택하면 보호되지 않은 기능 브랜치에서는 스캔이 실행되지 않을 수 있습니다.
    • 이 옵션을 선택하지 않는 경우 읽기 전용 권한을 가진 자격증명을 생성하고 정기적으로 교체하는 것을 고려하세요.
  2. .gitlab-ci.yml 파일에 다음을 추가합니다.

    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-your-registry>/<image>:<tag>"
    

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

  • .gitlab-ci.yml 파일에 다음을 추가합니다:

    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
        - 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>
    

Trivy Java 데이터베이스 미러 사용#

trivy 스캐너가 사용되고 스캔 중인 컨테이너 이미지에서 jar 파일이 발견되면, trivy는 추가 trivy-java-db 취약점 데이터베이스를 다운로드합니다. 기본적으로 trivy-java-db 데이터베이스는 ghcr.io/aquasecurity/trivy-java-db:1에서 OCI 아티팩트로 호스팅됩니다. 이 레지스트리에 접근할 수 없거나 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인 경우, 컨테이너 스캔 job을 다음과 같이 구성해야 합니다. 끝에 :1 태그를 추가하지 마세요. trivy에 의해 추가됩니다:

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

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

기본 브랜치 이미지 설정#

기본적으로 컨테이너 스캔은 이미지 명명 규칙이 이미지 이름이 아닌 이미지 태그에 브랜치별 식별자를 저장한다고 가정합니다. 기본 브랜치와 비기본 브랜치 사이에 이미지 이름이 다른 경우, 이전에 감지된 취약점이 머지 리퀘스트에서 새로 감지된 것으로 표시됩니다.

동일한 이미지가 기본 브랜치와 비기본 브랜치에서 서로 다른 이름을 가지는 경우, 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_DEFAULT_BRANCH_IMAGE는 주어진 CS_IMAGE에 대해 동일하게 유지되어야 합니다. 변경되면 중복 취약점 세트가 생성되며, 이를 수동으로 해제해야 합니다.

Auto DevOps를 사용하는 경우 CS_DEFAULT_BRANCH_IMAGE는 자동으로 $CI_REGISTRY_IMAGE/$CI_DEFAULT_BRANCH:$CI_APPLICATION_TAG로 설정됩니다.

커스텀 SSL CA 인증 기관 사용#

ADDITIONAL_CA_CERT_BUNDLE CI/CD 변수를 사용하여 커스텀 SSL CA 인증 기관을 구성할 수 있으며, 이는 HTTPS를 사용하는 레지스트리에서 Docker 이미지를 가져올 때 피어를 검증하는 데 사용됩니다. 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로 또는 인증서의 텍스트 표현이 필요한 변수로 설정할 수 있습니다.

멀티 아키텍처 이미지 스캔#

TRIVY_PLATFORM CI/CD 변수를 사용하여 특정 운영 체제와 아키텍처에 대해 컨테이너 스캔을 실행하도록 구성할 수 있습니다. 예를 들어, .gitlab-ci.yml 파일에서 이 값을 구성하려면 다음을 사용하세요:

container_scanning:
  # arm64 SaaS 러너를 사용하여 기본적으로 스캔
  tags: ["saas-linux-small-arm64"]
  variables:
    TRIVY_PLATFORM: "linux/arm64"

취약점 허용 목록#

전제 조건:

  • 프로젝트에 대한 Developer, Maintainer 또는 Owner 역할.

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

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

vulnerability-allowlist.yml 데이터 형식#

vulnerability-allowlist.yml 파일은 거짓 양성이거나 적용 불가능하기 때문에 존재가 허용되는 취약점의 CVE ID 목록을 지정하는 YAML 파일입니다.

vulnerability-allowlist.yml 파일에서 일치하는 항목이 발견되면 다음과 같이 됩니다:

  • 분석기가 gl-container-scanning-report.json 파일을 생성할 때 취약점이 포함되지 않습니다.
  • 파이프라인의 Security 탭에 취약점이 표시되지 않습니다. JSON 파일은 Security 탭의 정보 소스이므로 포함되지 않습니다.

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-4180registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256 컨테이너 이미지에서 발견된 모든 취약점.
  3. CVE ID가 CVE-2015-1419, CVE-2015-1447your.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).
Note

CVE ID 뒤의 문자열(이전 예의 cupslibxml2)은 선택적인 주석 형식입니다. 취약점 처리에 영향을 미치지 않습니다. 취약점을 설명하는 주석을 포함할 수 있습니다.

컨테이너 스캔 job 로그 형식#

container_scanning job 세부 정보에서 컨테이너 스캔 분석기가 생성한 로그를 확인하여 스캔 결과와 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로 표시됩니다.

오프라인 환경#

오프라인 환경에서 컨테이너 스캔을 실행하려면 초기 설정을 수행하고 지속적인 유지 관리를 해야 합니다.

초기 설정:

지속적인 유지 관리:

  • 새 버전이 출시되면 로컬 컨테이너 스캔 이미지를 업데이트합니다.

러너 구성#

러너를 구성합니다(docker 또는 kubernetes executor가 사용 가능한지 확인합니다). 자세한 내용은 시작하기를 참조하세요.

기본적으로 러너는 로컬 복사본이 있더라도 GitLab 컨테이너 레지스트리에서 컨테이너 이미지를 가져옵니다. 로컬 컨테이너 이미지만 사용하려면 pull_policyif-not-present로 설정할 수 있습니다. 그러나 변경해야 할 충분한 이유가 없는 한 pull_policy 설정을 기본값으로 유지해야 합니다.

컨테이너 이미지 복사#

GitLab.com 컨테이너 레지스트리에서 로컬 컨테이너 레지스트리로 다음 이미지를 가져옵니다. 이 이미지는 오프라인 GitLab 인스턴스에서 접근 가능해야 합니다.

registry.gitlab.com/security-products/container-scanning:8

이미지를 로컬 컨테이너 레지스트리로 가져오는 프로세스는 네트워크 보안 정책에 따라 다릅니다. IT 직원에게 문의하여 외부 리소스를 가져오거나 임시로 접근할 수 있는 수용 가능하고 승인된 프로세스를 찾으세요.

각 프로젝트에 대한 CI/CD 구성#

Note

이러한 구성 변경 사항은 .gitlab-ci.yml 파일을 참조하지 않기 때문에 레지스트리에 대한 컨테이너 스캔에는 적용되지 않습니다. 오프라인 환경에서 레지스트리에 대한 자동 컨테이너 스캔을 구성하려면 대신 GitLab UI에서 CS_ANALYZER_IMAGE 변수를 정의하세요.

컨테이너 스캔을 사용하는 모든 프로젝트에 대해 적용되는 모든 위치에서 CI/CD 구성을 편집합니다. 여기에는 다음이 포함될 수 있습니다:

  • 개별 프로젝트 .gitlab-ci.yml 파일
  • 파이프라인 실행 정책
  • 스캔 실행 정책

컨테이너 스캔 구성을 다음 변수로 업데이트합니다:

  1. 선택 사항. 컨테이너 스캔 템플릿이 아직 포함되지 않은 경우 추가합니다.
  2. 로컬 컨테이너 레지스트리의 컨테이너 스캔 이미지로 CS_ANALYZER_IMAGE를 설정합니다.
  3. 선택 사항. GitLab이 아닌 컨테이너 레지스트리를 사용하는 경우 로컬 레지스트리 자격증명과 일치하도록 CS_REGISTRY_USERCS_REGISTRY_PASSWORD를 설정합니다.
  4. 선택 사항. 로컬 컨테이너 레지스트리에 자체 서명 인증서를 사용하는 경우 CS_DOCKER_INSECURE: "true"를 설정합니다.

오프라인 환경의 .gitlab-ci.yml 구성 예제:

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

container_scanning:
  variables:
    # 컨테이너 스캔 관련 변수
    CS_ANALYZER_IMAGE: <hostname>:<port>/analyzers/container-scanning:8
    CS_REGISTRY_USER: <username>
    CS_REGISTRY_PASSWORD: <password>
    CS_DOCKER_INSECURE: "true"

로컬 컨테이너 이미지 업데이트#

컨테이너 스캔 이미지는 주기적으로 업데이트되어 GitLab.com 레지스트리에 푸시됩니다. 오프라인 환경에서는 자동(권장) 또는 수동으로 로컬 컨테이너 레지스트리의 컨테이너 스캔 이미지를 업데이트해야 합니다.

  • 수동 방법: 네트워크를 통해 GitLab.com 레지스트리에 접근할 수 없는 경우 로컬 레지스트리에서 컨테이너 스캔 이미지를 수동으로 업데이트합니다. 초기 설정을 위해 이미지를 복사할 때 사용한 것과 동일한 방법을 사용하세요.
  • 자동 방법: 오프라인 GitLab 인스턴스가 GitLab.com에 대한 읽기 접근 권한이 있는 경우, 미리 설정된 일정에 따라 이미지를 자동으로 업데이트하는 예약된 파이프라인을 설정합니다.
자동 이미지 업데이트 방법#

다음 .gitlab-ci.yml 추출본은 로컬 레지스트리에서 컨테이너 스캔 이미지를 자동으로 업데이트하는 방법을 보여줍니다. 이 방법은 소스 이미지와 대상 이미지에 대한 변수를 정의한 다음 Docker CLI를 사용하여 GitLab.com 레지스트리에서 이미지를 가져와 로컬 레지스트리에 푸시합니다.

GitLab이 아닌 레지스트리를 사용하는 경우 CI_REGISTRY 값을 업데이트하고 로컬 레지스트리 자격증명과 일치하도록 CI_REGISTRY_USERCI_REGISTRY_PASSWORD 변수를 설정하여 인증을 구성합니다.

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

image: docker:cli

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

아카이브 형식 스캔#

히스토리
  • tar 파일 스캔이 GitLab 18.0에서 도입됨.

컨테이너 스캔은 아카이브 형식(.tar, .tar.gz)의 이미지를 지원합니다. 이러한 이미지는 예를 들어 docker save 또는 docker buildx build를 사용하여 생성할 수 있습니다.

아카이브 파일을 스캔하려면 환경 변수 CS_IMAGEarchive://path/to/archive 형식으로 설정합니다:

  • archive:// 스킴 접두사는 분석기가 아카이브를 스캔하도록 지정합니다.
  • path/to/archive는 절대 경로 또는 상대 경로로 스캔할 아카이브의 경로를 지정합니다.

컨테이너 스캔은 Docker Image Specification을 따르는 tar 이미지 파일을 지원합니다. OCI tar볼은 지원되지 않습니다. 지원되는 형식에 대한 자세한 내용은 Trivy tar 파일 지원을 참조하세요.

지원되는 tar 파일 빌드#

컨테이너 스캔은 이미지 명명을 위해 tar 파일의 메타데이터를 사용합니다. tar 이미지 파일을 빌드할 때 이미지에 태그가 지정되어 있는지 확인합니다:

# 이름과 태그로 이미지를 가져오거나 빌드
docker pull image:latest
# 또는
docker build . -t image:latest
# 그런 다음 docker save를 사용하여 tar로 내보내기
docker save image:latest -o image-latest.tar

# 또는 buildx build를 사용하여 태그로 이미지 빌드
docker buildx create --name container --driver=docker-container
docker buildx build -t image:latest --builder=container -o type=docker,dest=- . > image-latest.tar

# podman 사용 시
podman build -t image:latest .
podman save -o image-latest.tar image:latest

이미지 이름#

컨테이너 스캔은 먼저 아카이브의 manifest.json을 평가하고 RepoTags의 첫 번째 항목을 사용하여 이미지 이름을 결정합니다. 발견되지 않으면 index.json을 사용하여 io.containerd.image.name 어노테이션을 가져옵니다. 발견되지 않으면 아카이브 파일 이름이 대신 사용됩니다.

이전 job에서 빌드된 아카이브 스캔#

CI/CD job에서 빌드된 아카이브를 스캔하려면 빌드 job에서 컨테이너 스캔 job으로 아카이브 아티팩트를 전달해야 합니다. artifacts:pathsdependencies 키워드를 사용하여 한 job에서 다음 job으로 아티팩트를 전달합니다:

build_job:
  script:
    - docker build . -t image:latest
    - docker save image:latest -o image-latest.tar
  artifacts:
    paths:
      - "image-latest.tar"

container_scanning:
  variables:
    CS_IMAGE: "archive://image-latest.tar"
  dependencies:
    - build_job

프로젝트 리포지터리의 아카이브 스캔#

프로젝트 리포지터리에 있는 아카이브를 스캔하려면 Git 전략이 리포지터리에 대한 접근을 활성화하는지 확인합니다. container_scanning job에서 GIT_STRATEGY 키워드를 clone 또는 fetch로 설정합니다. 기본적으로 none으로 설정되어 있습니다.

container_scanning:
  variables:
    GIT_STRATEGY: fetch

독립형 컨테이너 스캔 도구 실행#

CI job의 컨텍스트 내에서 실행하지 않고 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/CD 구성 파일의 artifacts:reports 키워드를 통해 인식하는 JSON 보고서를 생성합니다.

CI/CD job이 완료되면 러너는 이러한 보고서를 GitLab에 업로드하며, 이는 CI/CD job 아티팩트에서 사용할 수 있습니다. GitLab Ultimate에서 이러한 보고서는 해당 파이프라인 및 취약점 보고서에서 볼 수 있습니다.

이러한 보고서는 컨테이너 스캔 보고서 스키마를 준수해야 합니다.

컨테이너 스캔 보고서 예제.

CycloneDX 소프트웨어 자재명세서#

JSON 보고서 파일 외에도, 컨테이너 스캔 도구는 스캔된 이미지에 대한 CycloneDX 소프트웨어 자재명세서(SBOM)를 출력합니다. 이 CycloneDX SBOM의 이름은 gl-sbom-report.cdx.json이며 JSON 보고서 파일과 동일한 디렉토리에 저장됩니다. 이 기능은 Trivy 분析기를 사용하는 경우에만 지원됩니다.

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

CycloneDX SBOM을 다른 job 아티팩트와 동일한 방식으로 다운로드할 수 있습니다.

CycloneDX 보고서의 라이선스 정보#

히스토리

컨테이너 스캔은 CycloneDX 보고서에 라이선스 정보를 포함할 수 있습니다. 이 기능은 이전 버전과의 호환성을 유지하기 위해 기본적으로 비활성화되어 있습니다.

컨테이너 스캔 결과에서 라이선스 스캔을 활성화하려면:

  • .gitlab-ci.yml 파일에서 CS_INCLUDE_LICENSES 변수를 설정합니다:
container_scanning:
  variables:
    CS_INCLUDE_LICENSES: "true"
  • 이 기능을 활성화한 후 생성된 CycloneDX 보고서에는 컨테이너 이미지에서 감지된 컴포넌트에 대한 라이선스 정보가 포함됩니다.
  • 의존성 목록 페이지에서 또는 다운로드 가능한 CycloneDX job 아티팩트의 일부로 이 라이선스 정보를 볼 수 있습니다.

SPDX 라이선스만 지원된다는 점을 언급하는 것이 중요합니다. 그러나 SPDX와 호환되지 않는 라이선스도 사용자에게 오류 없이 수집됩니다.

수명 종료 운영 체제 감지#

컨테이너 스캔에는 컨테이너 이미지가 수명 종료(EOL)에 도달한 운영 체제를 사용하는 경우 감지하고 보고하는 기능이 포함되어 있습니다. EOL에 도달한 운영 체제는 더 이상 보안 업데이트를 받지 않아 새로 발견된 보안 문제에 취약합니다.

EOL 감지 기능은 Trivy를 사용하여 해당 배포판에서 더 이상 지원되지 않는 운영 체제를 식별합니다. EOL 운영 체제가 감지되면 컨테이너 스캔 보고서에 다른 보안 결과와 함께 취약점으로 보고됩니다.

EOL 감지를 활성화하려면 CS_REPORT_OS_EOL"true"로 설정합니다.

레지스트리를 위한 컨테이너 스캔#

히스토리

latest 태그가 있는 컨테이너 이미지가 푸시되면, 보안 정책 봇에 의해 기본 브랜치에 대한 새 파이프라인에서 컨테이너 스캔 job이 자동으로 트리거됩니다.

일반 컨테이너 스캔과 달리 스캔 결과에는 보안 보고서가 포함되지 않습니다. 대신 레지스트리를 위한 컨테이너 스캔은 지속적 취약점 스캔을 사용하여 스캔에서 감지된 컴포넌트를 검사합니다.

보안 결과가 식별되면 GitLab은 이러한 결과로 취약점 보고서를 채웁니다. 취약점은 취약점 보고서 페이지의 Container registry vulnerabilities 탭에서 볼 수 있습니다.

레지스트리를 위한 컨테이너 스캔은 새 어드바이저리가 GitLab 어드바이저리 데이터베이스에 게시될 때만 취약점 보고서를 채웁니다. 새로 감지된 데이터만이 아닌 현재 어드바이저리 데이터 모두로 취약점 보고서를 채우는 지원은 에픽 11219에서 제안됩니다.

Warning

레지스트리를 위한 컨테이너 스캔에서 감지된 취약점은 취약한 컴포넌트를 업데이트하거나 제거할 때 자동으로 해결됨으로 표시될 수 없습니다. 이 기능은 취약점 해결에 필요한 보안 보고서가 아닌 SBOM만 생성하기 때문에 이러한 취약점은 무기한 표시됩니다.

레지스트리에 대한 컨테이너 스캔 켜기#

전제 조건:

  • 프로젝트에 대한 Security Manager, Maintainer 또는 Owner 역할.
  • 사용 중인 프로젝트는 비어 있으면 안 됩니다. 컨테이너 이미지 저장만을 위한 빈 프로젝트를 사용하는 경우 이 기능이 의도한 대로 작동하지 않습니다. 해결책으로 프로젝트의 기본 브랜치에 초기 커밋이 포함되어 있는지 확인합니다.
  • 기본적으로 프로젝트당 하루에 50회 스캔 제한이 있습니다.
  • 컨테이너 레지스트리 알림을 구성해야 합니다.
  • 패키지 메타데이터 데이터베이스를 구성해야 합니다. GitLab.com에서는 기본적으로 구성됩니다.

GitLab 컨테이너 레지스트리에 대한 컨테이너 스캔을 켜려면:

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
  2. 왼쪽 사이드바에서 Secure > Security configuration을 선택합니다.
  3. Container Scanning For Registry 섹션으로 스크롤하고 토글을 켭니다.

오프라인 또는 에어갭 환경에서 사용#

오프라인 또는 에어갭 환경에서 레지스트리에 대한 컨테이너 스캔을 사용하려면, 컨테이너 스캔 분析기 이미지의 로컬 복사본을 사용해야 합니다. 이 기능은 GitLab 보안 정책 봇이 관리하기 때문에, 분析기 이미지를 .gitlab-ci.yml 파일을 편집하여 구성할 수 없습니다.

대신 GitLab UI에서 CS_ANALYZER_IMAGE CI/CD 변수를 설정하여 기본 스캐너 이미지를 재정의해야 합니다. 동적으로 생성된 스캔 job은 UI에 정의된 변수를 상속합니다. 프로젝트, 그룹 또는 인스턴스 CI/CD 변수를 사용할 수 있습니다.

전제 조건:

  • 프로젝트 또는 그룹에 대한 Maintainer 또는 Owner 역할.

커스텀 스캐너 이미지를 구성하려면:

  1. 상단 바에서 Search or go to를 선택하고 프로젝트 또는 그룹을 찾습니다.
  2. 왼쪽 사이드바에서 Settings > CI/CD를 선택합니다.
  3. Variables 섹션을 펼칩니다.
  4. Add variable을 선택하고 세부 정보를 입력합니다:
    • Key: CS_ANALYZER_IMAGE
    • Value: 미러링된 컨테이너 스캔 이미지의 전체 URL. 예: my.local.registry:5000/analyzers/container-scanning:7.
  5. Add variable을 선택합니다.

GitLab 보안 정책 봇은 스캔을 트리거할 때 지정된 이미지를 사용합니다.

취약점 데이터베이스#

모든 분析기 이미지는 매일 업데이트됩니다.

이미지는 업스트림 어드바이저리 데이터베이스의 데이터를 사용합니다:

  • AlmaLinux Security Advisory
  • Amazon Linux Security Center
  • Arch Linux Security Tracker
  • SUSE CVRF
  • CWE Advisories
  • Debian Security Bug Tracker
  • GitHub Security Advisory
  • Go Vulnerability Database
  • CBL-Mariner Vulnerability Data
  • NVD
  • OSV
  • Red Hat OVAL v2
  • Red Hat Security Data API
  • Photon Security Advisories
  • Rocky Linux UpdateInfo
  • Ubuntu CVE Tracker (2021년 중반 이후의 데이터 소스만)

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

GitLab Ultimate 티어에서는 GitLab 어드바이저리 데이터베이스의 데이터가 외부 소스의 데이터를 보완하기 위해 병합됩니다. GitLab Premium 및 Free 티어에서는 GitLab 어드바이저리 데이터베이스(오픈 소스 에디션)의 데이터가 외부 소스의 데이터를 보완하기 위해 병합됩니다. 이 보완은 Trivy 스캐너의 분析기 이미지에만 적용됩니다.

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

취약점 솔루션 (자동 해결)#

일부 취약점은 GitLab이 자동으로 생성하는 솔루션을 적용하여 수정할 수 있습니다.

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

취약점 솔루션에 대해 자세히 읽어보세요.

컨테이너 스캔

Tier: Ultimate
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
원문 보기
요약

컨테이너 이미지의 보안 취약점은 애플리케이션 라이프사이클 전반에 걸쳐 위험을 초래합니다. 컨테이너 스캔은 소프트웨어 컴포지션 분석(SCA)의 일부로 간주되는 경우가 많습니다. GitLab은 이러한 모든 의존성 유형을 포괄하기 위해 컨테이너 스캔과 의존성 스캔을 모두 제공합니다.

컨테이너 이미지의 보안 취약점은 애플리케이션 라이프사이클 전반에 걸쳐 위험을 초래합니다. 컨테이너 스캔은 이러한 위험을 프로덕션 환경에 도달하기 전, 조기에 감지합니다. 베이스 이미지나 운영 체제 패키지에 취약점이 발견되면, 컨테이너 스캔은 이를 식별하고 가능한 취약점에 대한 해결 방법을 제공합니다.

컨테이너 스캔은 소프트웨어 컴포지션 분석(SCA)의 일부로 간주되는 경우가 많습니다. SCA는 코드가 사용하는 항목을 검사하는 측면을 포함할 수 있습니다. 이러한 항목에는 일반적으로 애플리케이션 및 시스템 의존성이 포함되며, 이는 거의 항상 외부 소스에서 가져오고 직접 작성한 항목이 아닙니다.

GitLab은 이러한 모든 의존성 유형을 포괄하기 위해 컨테이너 스캔과 의존성 스캔을 모두 제공합니다. 위험 영역을 최대한 포괄하려면 모든 보안 스캐너를 사용하세요. 이러한 기능의 비교를 위해서는 의존성 스캔과 컨테이너 스캔 비교를 참조하세요.

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

Warning

Grype 분석기는 GitLab 지원 정책에 설명된 제한적인 수정을 제외하고 더 이상 유지 관리되지 않습니다. Grype 분석기 이미지의 현재 주요 버전은 GitLab 19.0까지 최신 어드바이저리 데이터베이스 및 운영 체제 패키지로 계속 업데이트되며, 그 이후에는 분석기가 작동을 멈춥니다.

기능#

기능 Free 및 Premium Ultimate
설정 커스터마이즈 (변수, 오버라이딩, 오프라인 환경 지원 등)
CI job 아티팩트로 JSON 보고서 보기
CI job 아티팩트로 CycloneDX SBOM JSON 보고서 생성
GitLab UI에서 MR을 통해 컨테이너 스캔 활성화
UBI 이미지 지원
Trivy 지원
수명 종료 운영 체제 감지
GitLab 어드바이저리 데이터베이스 포함 GitLab advisories-communities 프로젝트의 시간 지연 콘텐츠로 제한 예 - Gemnasium DB의 모든 최신 콘텐츠
머지 리퀘스트 및 CI 파이프라인 job의 Security 탭에서 보고서 데이터 표시
취약점 솔루션 (자동 해결)
취약점 허용 목록 지원
의존성 목록 페이지 접근

시작하기#

CI/CD 파이프라인에서 컨테이너 스캔 분석기를 활성화하세요. 파이프라인이 실행되면, 애플리케이션이 의존하는 이미지에서 취약점이 스캔됩니다. CI/CD 변수를 사용하여 컨테이너 스캔을 커스터마이즈할 수 있습니다.

전제 조건:

  • .gitlab-ci.yml 파일에 test 스테이지가 필요합니다.
  • 셀프 매니지드 러너를 사용하는 경우 Linux/amd64에서 docker 또는 kubernetes executor가 있는 러너가 필요합니다. GitLab.com의 인스턴스 러너를 사용하는 경우 기본적으로 활성화됩니다.
  • 지원되는 배포판과 일치하는 이미지.
  • Docker 이미지를 프로젝트의 컨테이너 레지스트리에 빌드하고 푸시합니다.
  • 서드파티 컨테이너 레지스트리를 사용하는 경우, CI/CD 변수 CS_REGISTRY_USERCS_REGISTRY_PASSWORD를 사용하여 인증 자격증명을 제공해야 할 수 있습니다. 이 변수 사용 방법에 대한 자세한 내용은 프라이빗 외부 레지스트리 인증을 참조하세요.

사용자 및 프로젝트별 요구사항에 대한 자세한 내용을 아래에서 확인하세요.

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

  • 의존성 스캔을 포함하는 Auto DevOps를 활성화합니다.
  • 사전 구성된 머지 리퀘스트를 사용합니다.
  • 컨테이너 스캔을 적용하는 스캔 실행 정책을 생성합니다.
  • .gitlab-ci.yml 파일을 수동으로 편집합니다.

사전 구성된 머지 리퀘스트 사용#

이 방법은 .gitlab-ci.yml 파일에 컨테이너 스캔 템플릿을 포함하는 머지 리퀘스트를 자동으로 준비합니다. 그런 다음 머지 리퀘스트를 머지하여 컨테이너 스캔을 활성화합니다.

Note

이 방법은 기존 .gitlab-ci.yml 파일이 없거나 최소한의 구성 파일이 있는 경우에 가장 잘 작동합니다. 복잡한 GitLab 구성 파일이 있는 경우 성공적으로 파싱되지 않을 수 있으며 오류가 발생할 수 있습니다. 이 경우 수동 방법을 사용하세요.

전제 조건:

  • 프로젝트에 대한 Developer, Maintainer 또는 Owner 역할.
  • .gitlab-ci.yml 파일에 test 스테이지가 있어야 합니다.
  • 셀프 매니지드 러너를 사용하는 경우 Linux/amd64에서 docker 또는 kubernetes executor가 있는 러너. GitLab.com의 인스턴스 러너를 사용하는 경우 기본적으로 활성화됩니다.
  • 지원되는 배포판과 일치하는 이미지.
  • Docker 이미지가 프로젝트의 컨테이너 레지스트리에 빌드되고 푸시되어 있어야 합니다.
  • 서드파티 컨테이너 레지스트리를 사용하는 경우, CI/CD 변수 CS_REGISTRY_USERCS_REGISTRY_PASSWORD를 사용하여 인증 자격증명을 제공해야 할 수 있습니다. 자세한 내용은 프라이빗 외부 레지스트리 인증을 참조하세요.

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

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
  2. 왼쪽 사이드바에서 Secure > Security configuration을 선택합니다.
  3. Container Scanning 행에서 Configure with a merge request를 선택합니다.
  4. Create merge request를 선택합니다.
  5. 머지 리퀘스트를 검토한 다음 Merge를 선택합니다.

이제 파이프라인에 컨테이너 스캔 job이 포함됩니다.

.gitlab-ci.yml 파일 수동 편집#

이 방법을 사용하면 기존 .gitlab-ci.yml 파일을 수동으로 편집해야 합니다. 복잡한 GitLab 구성 파일이 있거나 기본값이 아닌 옵션을 사용해야 하는 경우 이 방법을 사용하세요.

전제 조건:

  • 프로젝트에 대한 Developer, Maintainer 또는 Owner 역할.
  • .gitlab-ci.yml 파일에 test 스테이지가 있어야 합니다.
  • 셀프 매니지드 러너를 사용하는 경우 Linux/amd64에서 docker 또는 kubernetes executor가 있는 러너. GitLab.com의 인스턴스 러너를 사용하는 경우 기본적으로 활성화됩니다.
  • 지원되는 배포판과 일치하는 이미지.
  • Docker 이미지가 프로젝트의 컨테이너 레지스트리에 빌드되고 푸시되어 있어야 합니다.
  • 서드파티 컨테이너 레지스트리를 사용하는 경우, CI/CD 변수 CS_REGISTRY_USERCS_REGISTRY_PASSWORD를 사용하여 인증 자격증명을 제공해야 할 수 있습니다. 자세한 내용은 프라이빗 외부 레지스트리 인증을 참조하세요.

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

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.

  2. 왼쪽 사이드바에서 Build > Pipeline editor를 선택합니다.

  3. .gitlab-ci.yml 파일이 없는 경우 Configure pipeline을 선택한 다음 예제 내용을 삭제합니다.

  4. 다음을 복사하여 .gitlab-ci.yml 파일 하단에 붙여넣습니다. include 줄이 이미 있는 경우 그 아래에 template 줄만 추가합니다.

    include:
      - template: Jobs/Container-Scanning.gitlab-ci.yml
    
  5. Validate 탭을 선택한 다음 Validate pipeline을 선택합니다.

    Simulation completed successfully 메시지가 파일이 유효함을 확인합니다.

  6. Edit 탭을 선택합니다.

  7. 필드를 완성합니다. Branch 필드에 기본 브랜치를 사용하지 마세요.

  8. Start a new merge request with these changes 체크박스를 선택한 다음 Commit changes를 선택합니다.

  9. 표준 워크플로우에 따라 필드를 완성한 다음 Create merge request를 선택합니다.

  10. 표준 워크플로우에 따라 머지 리퀘스트를 검토하고 편집하고 파이프라인이 통과할 때까지 기다린 다음 Merge를 선택합니다.

이제 파이프라인에 컨테이너 스캔 job이 포함됩니다.

결과 이해하기#

전제 조건:

  • 프로젝트에 대한 Security Manager, Developer, Maintainer 또는 Owner 역할.

파이프라인에서 취약점을 검토할 수 있습니다:

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
  2. 왼쪽 사이드바에서 Build > Pipelines를 선택합니다.
  3. 파이프라인을 선택합니다.
  4. Security 탭을 선택합니다.
  5. 취약점을 선택하여 다음을 포함한 세부 정보를 봅니다:
    • 설명: 취약점의 원인, 잠재적인 영향 및 권장 해결 단계를 설명합니다.
    • 상태: 취약점이 트리아지되거나 해결되었는지 여부를 나타냅니다.
    • 심각도: 영향에 따라 6가지 수준으로 분류됩니다. 심각도 수준에 대해 자세히 알아보기.
    • CVSS 점수: 심각도에 매핑되는 숫자 값을 제공합니다.
    • EPSS: 야생에서 취약점이 악용될 가능성을 보여줍니다.
    • 알려진 악용 사례(KEV): 특정 취약점이 악용된 것을 나타냅니다.
    • 프로젝트: 취약점이 식별된 프로젝트를 강조 표시합니다.
    • 보고서 유형: 출력 유형을 설명합니다.
    • 스캐너: 취약점을 감지한 분석기를 식별합니다.
    • 이미지: 취약점에 귀속된 이미지를 제공합니다.
    • 네임스페이스: 취약점에 귀속된 작업 영역을 식별합니다.
    • 링크: 다양한 어드바이저리 데이터베이스에 취약점이 카탈로그화된 증거.
    • 식별자: CVE 식별자와 같이 취약점을 분류하는 데 사용되는 참조 목록.

자세한 내용은 파이프라인 보안 보고서를 참조하세요.

컨테이너 스캔 결과를 볼 수 있는 추가 방법:

최적화#

GitLab은 컨테이너 스캔을 위한 두 가지 방법을 제공합니다:

  • 표준 컨테이너 스캔: job당 단일 컨테이너 이미지를 스캔합니다. 단순하고 분산된 워크플로우에 적합합니다.
  • 멀티 컨테이너 스캔: 단일 구성 파일을 사용하여 여러 이미지를 병렬로 스캔합니다. 여러 이미지를 효율적으로 스캔하는 데 적합합니다.

롤아웃#

단일 프로젝트에 대한 컨테이너 스캔 결과에 확신이 생긴 후, 추가 프로젝트로 구현을 확장할 수 있습니다:

  • 강제 스캔 실행을 사용하여 그룹 전체에 컨테이너 스캔 설정을 적용합니다.
  • 고유한 요구사항이 있는 경우 컨테이너 스캔을 오프라인 환경에서 실행할 수 있습니다.

지원되는 배포판#

다음 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 확장을 추가한 값으로 수정하세요.

Note

GitLab 인스턴스에서 FIPS 모드가 활성화된 경우 -fips 플래그가 CS_ANALYZER_IMAGE에 자동으로 추가됩니다.

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

구성#

분석기 동작 커스터마이즈#

컨테이너 스캔을 커스터마이즈하려면 CI/CD 변수를 사용하세요.

상세 출력 활성화#

예를 들어 문제 해결 시 의존성 스캔 job이 수행하는 작업을 자세히 볼 필요가 있을 때 상세 출력을 활성화합니다.

다음 예제에서는 컨테이너 스캔 템플릿이 포함되고 상세 출력이 활성화됩니다.

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

variables:
    SECURE_LOG_LEVEL: 'debug'

언어별 결과 보고#

CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN CI/CD 변수는 스캔이 프로그래밍 언어와 관련된 결과를 보고할지 여부를 제어합니다. 지원되는 언어에 대한 자세한 내용은 Trivy 문서의 언어별 패키지를 참조하세요.

기본적으로 보고서에는 운영 체제(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이 서로 다른 유형의 스캔 도구에서 결과를 자동으로 중복 제거할 수 없기 때문입니다. 중복될 가능성이 있는 의존성 유형을 이해하려면 의존성 스캔과 컨테이너 스캔 비교를 참조하세요.

머지 리퀘스트 파이프라인에서 job 실행#

머지 리퀘스트 파이프라인과 함께 보안 스캔 도구 사용을 참조하세요.

사용 가능한 CI/CD 변수#

컨테이너 스캔을 커스터마이즈하려면 CI/CD 변수를 사용하세요. 다음 표에는 컨테이너 스캔에 특화된 CI/CD 변수가 나열되어 있습니다. 미리 정의된 CI/CD 변수도 사용할 수 있습니다.

Warning

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:8 분석기의 Docker 이미지. GitLab에서 제공하는 분석기 이미지에 :latest 태그를 사용하지 마세요.
CS_DEFAULT_BRANCH_IMAGE "" 기본 브랜치의 CS_IMAGE 이름. 자세한 내용은 기본 브랜치 이미지 설정을 참조하세요.
CS_DISABLE_DEPENDENCY_LIST "false" ⚠️ GitLab 17.0에서 제거됨.
CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN "true" 스캔된 이미지에 설치된 언어별 패키지 스캔을 비활성화합니다.
CS_DOCKER_INSECURE "false" 인증서 유효성 검사 없이 HTTPS를 사용하는 보안 Docker 레지스트리 접근을 허용합니다.
CS_DOCKERFILE_PATH Dockerfile 해결책을 생성하는 데 사용할 Dockerfile 경로. 기본적으로 스캐너는 프로젝트의 루트 디렉토리에서 Dockerfile이라는 파일을 찾습니다. Dockerfile이 하위 디렉토리와 같이 비표준 위치에 있는 경우에만 이 변수를 구성해야 합니다. 자세한 내용은 취약점 솔루션을 참조하세요.
CS_INCLUDE_LICENSES "" 설정된 경우 각 컴포넌트에 대한 라이선스를 포함합니다. cyclonedx 보고서에만 적용 가능하며 해당 라이선스는 trivy에서 제공됩니다.
CS_IGNORE_STATUSES "" 쉼표로 구분된 목록에서 지정된 상태의 결과를 무시하도록 분석기를 강제합니다. 허용되는 값: unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life. 1
CS_IGNORE_UNFIXED "false" 수정되지 않은 결과를 무시합니다. 무시된 결과는 보고서에 포함되지 않습니다.
CS_IMAGE $CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG 스캔할 Docker 이미지. 설정된 경우 이 변수는 $CI_APPLICATION_REPOSITORY$CI_APPLICATION_TAG 변수를 재정의합니다.
CS_IMAGE_SUFFIX "" CS_ANALYZER_IMAGE에 추가되는 접미사. -fips로 설정하면 스캔에 FIPS 활성화 이미지가 사용됩니다. 자세한 내용은 FIPS 활성화 이미지를 참조하세요.
CS_QUIET "" 설정된 경우 job 로그의 취약점 테이블 출력을 비활성화합니다.
CS_REGISTRY_INSECURE "false" 안전하지 않은 레지스트리(HTTP만 해당) 접근을 허용합니다. 로컬에서 이미지를 테스트할 때만 true로 설정해야 합니다. 모든 스캐너에서 작동하지만 Trivy가 작동하려면 레지스트리가 포트 80/tcp에서 수신 대기해야 합니다.
CS_REGISTRY_PASSWORD $CI_REGISTRY_PASSWORD 인증이 필요한 Docker 레지스트리에 접근하기 위한 비밀번호. 기본값은 $CS_IMAGE$CI_REGISTRY에 있는 경우에만 설정됩니다. FIPS 모드가 활성화된 경우 지원되지 않습니다.
CS_REGISTRY_USER $CI_REGISTRY_USER 인증이 필요한 Docker 레지스트리에 접근하기 위한 사용자 이름. 기본값은 $CS_IMAGE$CI_REGISTRY에 있는 경우에만 설정됩니다. FIPS 모드가 활성화된 경우 지원되지 않습니다.
CS_REPORT_OS_EOL "false" EOL 감지 활성화
CS_REPORT_OS_EOL_SEVERITY "Medium" CS_REPORT_OS_EOL이 활성화된 경우 EOL OS 결과에 할당된 심각도 수준. EOL 결과는 CS_SEVERITY_THRESHOLD에 관계없이 항상 보고됩니다. 지원되는 수준: UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL.
CS_SEVERITY_THRESHOLD UNKNOWN 심각도 수준 임계값. 스캐너는 이 임계값보다 높거나 같은 심각도 수준의 취약점을 출력합니다. 지원되는 수준: UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL.
CS_TRIVY_JAVA_DB "registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-java-db" trivy-java-db 취약점 데이터베이스의 대체 위치를 지정합니다.
CS_TRIVY_DETECTION_PRIORITY "precise" 정의된 Trivy 감지 우선순위를 사용하여 스캔합니다. 허용되는 값: precise 또는 comprehensive.
SECURE_LOG_LEVEL info 최소 로깅 수준을 설정합니다. 이 로깅 수준 이상의 메시지가 출력됩니다. 가장 높은 수준에서 낮은 수준 순서로: fatal, error, warn, info, debug.
TRIVY_TIMEOUT 5m0s 스캔 타임아웃을 설정합니다.
TRIVY_PLATFORM linux/amd64 이미지가 멀티 플랫폼인 경우 os/arch 형식으로 플랫폼을 설정합니다.

각주:

  1. 수정 상태 정보는 소프트웨어 공급업체 및 컨테이너 이미지 운영 체제 패키지 메타데이터의 정확한 수정 가용성 데이터에 크게 의존합니다. 또한 개별 컨테이너 스캐너에 의한 해석의 영향을 받습니다. 컨테이너 스캐너가 취약점에 대한 수정된 패키지의 가용성을 잘못 보고하는 경우, 이 설정이 활성화된 경우 CS_IGNORE_STATUSES를 사용하면 결과 필터링에서 거짓 양성 또는 거짓 음성이 발생할 수 있습니다.

기본 환경 변수로 Trivy 직접 구성#

위에 나열된 GitLab 특화 CS_* 변수 외에도, container_scanning job에서 기본 환경 변수를 설정하여 Trivy를 직접 구성할 수 있습니다. GitLab 컨테이너 스캔 분석기는 모든 환경 변수를 자동으로 Trivy에 전달합니다.

예를 들어, Trivy가 자동 감지할 수 없는 컨테이너 이미지(예: 커스터마이즈된 베이스 이미지)에 대해 OS 배포판을 수동으로 지정하려면:

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

container_scanning:
  variables:
    GIT_STRATEGY: fetch
    TRIVY_DISTRO: "alma/10"
Note

TRIVY_DISTRO에서 사용하는 --distro 플래그는 Trivy에서 실험적입니다. 결과는 Trivy 버전 및 지정된 배포판에 따라 달라질 수 있습니다.

GitLab 래퍼에서 관리하는 변수#

다음 TRIVY_* 변수는 GitLab 컨테이너 스캔 분석기에 의해 내부적으로 설정됩니다. 해당 GitLab CI/CD 변수로 제어되며 직접 재정의할 수 없습니다:

Trivy 변수 GitLab CI/CD 변수
TRIVY_CACHE_DIR (내부, 노출되지 않음)
TRIVY_USERNAME CS_REGISTRY_USER
TRIVY_PASSWORD CS_REGISTRY_PASSWORD
TRIVY_DEBUG SECURE_LOG_LEVEL
TRIVY_INSECURE CS_DOCKER_INSECURE
TRIVY_NON_SSL CS_REGISTRY_INSECURE
TRIVY_DB_REPOSITORY 관련 알려진 문제#

TRIVY_DB_REPOSITORY를 커스텀 취약점 데이터베이스로 지정하도록 설정해도 효과가 없습니다. GitLab 컨테이너 스캔 분석기는 취약점 데이터베이스를 분석기 이미지 내부에 번들로 포함하고 런타임에 Trivy에 --skip-db-update를 전달하므로, 이 변수에 관계없이 Trivy는 데이터베이스를 다운로드하지 않습니다. 커스텀 데이터베이스 위치를 사용하려면 Java 데이터베이스의 경우 Trivy Java 데이터베이스 미러 사용을, 일반 오프라인 설정의 경우 오프라인 환경을 참조하세요.

컨테이너 스캔 템플릿 오버라이딩#

job 정의를 오버라이딩하려면(예: variables와 같은 속성 변경), 템플릿 포함 후 job을 선언하고 오버라이딩한 다음 추가 키를 지정해야 합니다.

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

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

container_scanning:
  variables:
    GIT_STRATEGY: fetch

외부 레지스트리의 이미지 스캔#

기본적으로 컨테이너 스캔은 GitLab 컨테이너 레지스트리의 이미지를 스캔합니다. 외부 레지스트리의 이미지도 스캔할 수 있습니다.

외부 레지스트리의 이미지를 스캔하려면 이미지의 전체 경로를 사용하여 CS_IMAGE 변수를 구성합니다.

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

container_scanning:
  variables:
    CS_IMAGE: <example.com>/<user>/<image>:<tag>

프라이빗 외부 레지스트리 인증#

외부 레지스트리가 인증을 필요로 하는 경우 CS_REGISTRY_USERCS_REGISTRY_PASSWORD CI/CD 변수를 사용하여 자격증명을 제공하세요.

Note

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

예를 들어, Google Container Registry의 이미지를 스캔하려면:

  1. Google Cloud Platform Container Registry 문서에 설명된 대로 JSON 키를 포함하는 GCP_CREDENTIALS CI/CD 변수를 추가합니다.

    • 변수 값이 마스크 변수 옵션의 마스킹 요구사항을 충족하지 않을 수 있으므로 job 로그에 값이 노출될 수 있습니다.
    • 보호 변수 옵션을 선택하면 보호되지 않은 기능 브랜치에서는 스캔이 실행되지 않을 수 있습니다.
    • 이 옵션을 선택하지 않는 경우 읽기 전용 권한을 가진 자격증명을 생성하고 정기적으로 교체하는 것을 고려하세요.
  2. .gitlab-ci.yml 파일에 다음을 추가합니다.

    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-your-registry>/<image>:<tag>"
    

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

  • .gitlab-ci.yml 파일에 다음을 추가합니다:

    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
        - 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>
    

Trivy Java 데이터베이스 미러 사용#

trivy 스캐너가 사용되고 스캔 중인 컨테이너 이미지에서 jar 파일이 발견되면, trivy는 추가 trivy-java-db 취약점 데이터베이스를 다운로드합니다. 기본적으로 trivy-java-db 데이터베이스는 ghcr.io/aquasecurity/trivy-java-db:1에서 OCI 아티팩트로 호스팅됩니다. 이 레지스트리에 접근할 수 없거나 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인 경우, 컨테이너 스캔 job을 다음과 같이 구성해야 합니다. 끝에 :1 태그를 추가하지 마세요. trivy에 의해 추가됩니다:

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

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

기본 브랜치 이미지 설정#

기본적으로 컨테이너 스캔은 이미지 명명 규칙이 이미지 이름이 아닌 이미지 태그에 브랜치별 식별자를 저장한다고 가정합니다. 기본 브랜치와 비기본 브랜치 사이에 이미지 이름이 다른 경우, 이전에 감지된 취약점이 머지 리퀘스트에서 새로 감지된 것으로 표시됩니다.

동일한 이미지가 기본 브랜치와 비기본 브랜치에서 서로 다른 이름을 가지는 경우, 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_DEFAULT_BRANCH_IMAGE는 주어진 CS_IMAGE에 대해 동일하게 유지되어야 합니다. 변경되면 중복 취약점 세트가 생성되며, 이를 수동으로 해제해야 합니다.

Auto DevOps를 사용하는 경우 CS_DEFAULT_BRANCH_IMAGE는 자동으로 $CI_REGISTRY_IMAGE/$CI_DEFAULT_BRANCH:$CI_APPLICATION_TAG로 설정됩니다.

커스텀 SSL CA 인증 기관 사용#

ADDITIONAL_CA_CERT_BUNDLE CI/CD 변수를 사용하여 커스텀 SSL CA 인증 기관을 구성할 수 있으며, 이는 HTTPS를 사용하는 레지스트리에서 Docker 이미지를 가져올 때 피어를 검증하는 데 사용됩니다. 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로 또는 인증서의 텍스트 표현이 필요한 변수로 설정할 수 있습니다.

멀티 아키텍처 이미지 스캔#

TRIVY_PLATFORM CI/CD 변수를 사용하여 특정 운영 체제와 아키텍처에 대해 컨테이너 스캔을 실행하도록 구성할 수 있습니다. 예를 들어, .gitlab-ci.yml 파일에서 이 값을 구성하려면 다음을 사용하세요:

container_scanning:
  # arm64 SaaS 러너를 사용하여 기본적으로 스캔
  tags: ["saas-linux-small-arm64"]
  variables:
    TRIVY_PLATFORM: "linux/arm64"

취약점 허용 목록#

전제 조건:

  • 프로젝트에 대한 Developer, Maintainer 또는 Owner 역할.

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

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

vulnerability-allowlist.yml 데이터 형식#

vulnerability-allowlist.yml 파일은 거짓 양성이거나 적용 불가능하기 때문에 존재가 허용되는 취약점의 CVE ID 목록을 지정하는 YAML 파일입니다.

vulnerability-allowlist.yml 파일에서 일치하는 항목이 발견되면 다음과 같이 됩니다:

  • 분석기가 gl-container-scanning-report.json 파일을 생성할 때 취약점이 포함되지 않습니다.
  • 파이프라인의 Security 탭에 취약점이 표시되지 않습니다. JSON 파일은 Security 탭의 정보 소스이므로 포함되지 않습니다.

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-4180registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256 컨테이너 이미지에서 발견된 모든 취약점.
  3. CVE ID가 CVE-2015-1419, CVE-2015-1447your.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).
Note

CVE ID 뒤의 문자열(이전 예의 cupslibxml2)은 선택적인 주석 형식입니다. 취약점 처리에 영향을 미치지 않습니다. 취약점을 설명하는 주석을 포함할 수 있습니다.

컨테이너 스캔 job 로그 형식#

container_scanning job 세부 정보에서 컨테이너 스캔 분석기가 생성한 로그를 확인하여 스캔 결과와 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로 표시됩니다.

오프라인 환경#

오프라인 환경에서 컨테이너 스캔을 실행하려면 초기 설정을 수행하고 지속적인 유지 관리를 해야 합니다.

초기 설정:

지속적인 유지 관리:

  • 새 버전이 출시되면 로컬 컨테이너 스캔 이미지를 업데이트합니다.

러너 구성#

러너를 구성합니다(docker 또는 kubernetes executor가 사용 가능한지 확인합니다). 자세한 내용은 시작하기를 참조하세요.

기본적으로 러너는 로컬 복사본이 있더라도 GitLab 컨테이너 레지스트리에서 컨테이너 이미지를 가져옵니다. 로컬 컨테이너 이미지만 사용하려면 pull_policyif-not-present로 설정할 수 있습니다. 그러나 변경해야 할 충분한 이유가 없는 한 pull_policy 설정을 기본값으로 유지해야 합니다.

컨테이너 이미지 복사#

GitLab.com 컨테이너 레지스트리에서 로컬 컨테이너 레지스트리로 다음 이미지를 가져옵니다. 이 이미지는 오프라인 GitLab 인스턴스에서 접근 가능해야 합니다.

registry.gitlab.com/security-products/container-scanning:8

이미지를 로컬 컨테이너 레지스트리로 가져오는 프로세스는 네트워크 보안 정책에 따라 다릅니다. IT 직원에게 문의하여 외부 리소스를 가져오거나 임시로 접근할 수 있는 수용 가능하고 승인된 프로세스를 찾으세요.

각 프로젝트에 대한 CI/CD 구성#

Note

이러한 구성 변경 사항은 .gitlab-ci.yml 파일을 참조하지 않기 때문에 레지스트리에 대한 컨테이너 스캔에는 적용되지 않습니다. 오프라인 환경에서 레지스트리에 대한 자동 컨테이너 스캔을 구성하려면 대신 GitLab UI에서 CS_ANALYZER_IMAGE 변수를 정의하세요.

컨테이너 스캔을 사용하는 모든 프로젝트에 대해 적용되는 모든 위치에서 CI/CD 구성을 편집합니다. 여기에는 다음이 포함될 수 있습니다:

  • 개별 프로젝트 .gitlab-ci.yml 파일
  • 파이프라인 실행 정책
  • 스캔 실행 정책

컨테이너 스캔 구성을 다음 변수로 업데이트합니다:

  1. 선택 사항. 컨테이너 스캔 템플릿이 아직 포함되지 않은 경우 추가합니다.
  2. 로컬 컨테이너 레지스트리의 컨테이너 스캔 이미지로 CS_ANALYZER_IMAGE를 설정합니다.
  3. 선택 사항. GitLab이 아닌 컨테이너 레지스트리를 사용하는 경우 로컬 레지스트리 자격증명과 일치하도록 CS_REGISTRY_USERCS_REGISTRY_PASSWORD를 설정합니다.
  4. 선택 사항. 로컬 컨테이너 레지스트리에 자체 서명 인증서를 사용하는 경우 CS_DOCKER_INSECURE: "true"를 설정합니다.

오프라인 환경의 .gitlab-ci.yml 구성 예제:

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

container_scanning:
  variables:
    # 컨테이너 스캔 관련 변수
    CS_ANALYZER_IMAGE: <hostname>:<port>/analyzers/container-scanning:8
    CS_REGISTRY_USER: <username>
    CS_REGISTRY_PASSWORD: <password>
    CS_DOCKER_INSECURE: "true"

로컬 컨테이너 이미지 업데이트#

컨테이너 스캔 이미지는 주기적으로 업데이트되어 GitLab.com 레지스트리에 푸시됩니다. 오프라인 환경에서는 자동(권장) 또는 수동으로 로컬 컨테이너 레지스트리의 컨테이너 스캔 이미지를 업데이트해야 합니다.

  • 수동 방법: 네트워크를 통해 GitLab.com 레지스트리에 접근할 수 없는 경우 로컬 레지스트리에서 컨테이너 스캔 이미지를 수동으로 업데이트합니다. 초기 설정을 위해 이미지를 복사할 때 사용한 것과 동일한 방법을 사용하세요.
  • 자동 방법: 오프라인 GitLab 인스턴스가 GitLab.com에 대한 읽기 접근 권한이 있는 경우, 미리 설정된 일정에 따라 이미지를 자동으로 업데이트하는 예약된 파이프라인을 설정합니다.
자동 이미지 업데이트 방법#

다음 .gitlab-ci.yml 추출본은 로컬 레지스트리에서 컨테이너 스캔 이미지를 자동으로 업데이트하는 방법을 보여줍니다. 이 방법은 소스 이미지와 대상 이미지에 대한 변수를 정의한 다음 Docker CLI를 사용하여 GitLab.com 레지스트리에서 이미지를 가져와 로컬 레지스트리에 푸시합니다.

GitLab이 아닌 레지스트리를 사용하는 경우 CI_REGISTRY 값을 업데이트하고 로컬 레지스트리 자격증명과 일치하도록 CI_REGISTRY_USERCI_REGISTRY_PASSWORD 변수를 설정하여 인증을 구성합니다.

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

image: docker:cli

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

아카이브 형식 스캔#

히스토리
  • tar 파일 스캔이 GitLab 18.0에서 도입됨.

컨테이너 스캔은 아카이브 형식(.tar, .tar.gz)의 이미지를 지원합니다. 이러한 이미지는 예를 들어 docker save 또는 docker buildx build를 사용하여 생성할 수 있습니다.

아카이브 파일을 스캔하려면 환경 변수 CS_IMAGEarchive://path/to/archive 형식으로 설정합니다:

  • archive:// 스킴 접두사는 분석기가 아카이브를 스캔하도록 지정합니다.
  • path/to/archive는 절대 경로 또는 상대 경로로 스캔할 아카이브의 경로를 지정합니다.

컨테이너 스캔은 Docker Image Specification을 따르는 tar 이미지 파일을 지원합니다. OCI tar볼은 지원되지 않습니다. 지원되는 형식에 대한 자세한 내용은 Trivy tar 파일 지원을 참조하세요.

지원되는 tar 파일 빌드#

컨테이너 스캔은 이미지 명명을 위해 tar 파일의 메타데이터를 사용합니다. tar 이미지 파일을 빌드할 때 이미지에 태그가 지정되어 있는지 확인합니다:

# 이름과 태그로 이미지를 가져오거나 빌드
docker pull image:latest
# 또는
docker build . -t image:latest
# 그런 다음 docker save를 사용하여 tar로 내보내기
docker save image:latest -o image-latest.tar

# 또는 buildx build를 사용하여 태그로 이미지 빌드
docker buildx create --name container --driver=docker-container
docker buildx build -t image:latest --builder=container -o type=docker,dest=- . > image-latest.tar

# podman 사용 시
podman build -t image:latest .
podman save -o image-latest.tar image:latest

이미지 이름#

컨테이너 스캔은 먼저 아카이브의 manifest.json을 평가하고 RepoTags의 첫 번째 항목을 사용하여 이미지 이름을 결정합니다. 발견되지 않으면 index.json을 사용하여 io.containerd.image.name 어노테이션을 가져옵니다. 발견되지 않으면 아카이브 파일 이름이 대신 사용됩니다.

이전 job에서 빌드된 아카이브 스캔#

CI/CD job에서 빌드된 아카이브를 스캔하려면 빌드 job에서 컨테이너 스캔 job으로 아카이브 아티팩트를 전달해야 합니다. artifacts:pathsdependencies 키워드를 사용하여 한 job에서 다음 job으로 아티팩트를 전달합니다:

build_job:
  script:
    - docker build . -t image:latest
    - docker save image:latest -o image-latest.tar
  artifacts:
    paths:
      - "image-latest.tar"

container_scanning:
  variables:
    CS_IMAGE: "archive://image-latest.tar"
  dependencies:
    - build_job

프로젝트 리포지터리의 아카이브 스캔#

프로젝트 리포지터리에 있는 아카이브를 스캔하려면 Git 전략이 리포지터리에 대한 접근을 활성화하는지 확인합니다. container_scanning job에서 GIT_STRATEGY 키워드를 clone 또는 fetch로 설정합니다. 기본적으로 none으로 설정되어 있습니다.

container_scanning:
  variables:
    GIT_STRATEGY: fetch

독립형 컨테이너 스캔 도구 실행#

CI job의 컨텍스트 내에서 실행하지 않고 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/CD 구성 파일의 artifacts:reports 키워드를 통해 인식하는 JSON 보고서를 생성합니다.

CI/CD job이 완료되면 러너는 이러한 보고서를 GitLab에 업로드하며, 이는 CI/CD job 아티팩트에서 사용할 수 있습니다. GitLab Ultimate에서 이러한 보고서는 해당 파이프라인 및 취약점 보고서에서 볼 수 있습니다.

이러한 보고서는 컨테이너 스캔 보고서 스키마를 준수해야 합니다.

컨테이너 스캔 보고서 예제.

CycloneDX 소프트웨어 자재명세서#

JSON 보고서 파일 외에도, 컨테이너 스캔 도구는 스캔된 이미지에 대한 CycloneDX 소프트웨어 자재명세서(SBOM)를 출력합니다. 이 CycloneDX SBOM의 이름은 gl-sbom-report.cdx.json이며 JSON 보고서 파일과 동일한 디렉토리에 저장됩니다. 이 기능은 Trivy 분析기를 사용하는 경우에만 지원됩니다.

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

CycloneDX SBOM을 다른 job 아티팩트와 동일한 방식으로 다운로드할 수 있습니다.

CycloneDX 보고서의 라이선스 정보#

히스토리

컨테이너 스캔은 CycloneDX 보고서에 라이선스 정보를 포함할 수 있습니다. 이 기능은 이전 버전과의 호환성을 유지하기 위해 기본적으로 비활성화되어 있습니다.

컨테이너 스캔 결과에서 라이선스 스캔을 활성화하려면:

  • .gitlab-ci.yml 파일에서 CS_INCLUDE_LICENSES 변수를 설정합니다:
container_scanning:
  variables:
    CS_INCLUDE_LICENSES: "true"
  • 이 기능을 활성화한 후 생성된 CycloneDX 보고서에는 컨테이너 이미지에서 감지된 컴포넌트에 대한 라이선스 정보가 포함됩니다.
  • 의존성 목록 페이지에서 또는 다운로드 가능한 CycloneDX job 아티팩트의 일부로 이 라이선스 정보를 볼 수 있습니다.

SPDX 라이선스만 지원된다는 점을 언급하는 것이 중요합니다. 그러나 SPDX와 호환되지 않는 라이선스도 사용자에게 오류 없이 수집됩니다.

수명 종료 운영 체제 감지#

컨테이너 스캔에는 컨테이너 이미지가 수명 종료(EOL)에 도달한 운영 체제를 사용하는 경우 감지하고 보고하는 기능이 포함되어 있습니다. EOL에 도달한 운영 체제는 더 이상 보안 업데이트를 받지 않아 새로 발견된 보안 문제에 취약합니다.

EOL 감지 기능은 Trivy를 사용하여 해당 배포판에서 더 이상 지원되지 않는 운영 체제를 식별합니다. EOL 운영 체제가 감지되면 컨테이너 스캔 보고서에 다른 보안 결과와 함께 취약점으로 보고됩니다.

EOL 감지를 활성화하려면 CS_REPORT_OS_EOL"true"로 설정합니다.

레지스트리를 위한 컨테이너 스캔#

히스토리

latest 태그가 있는 컨테이너 이미지가 푸시되면, 보안 정책 봇에 의해 기본 브랜치에 대한 새 파이프라인에서 컨테이너 스캔 job이 자동으로 트리거됩니다.

일반 컨테이너 스캔과 달리 스캔 결과에는 보안 보고서가 포함되지 않습니다. 대신 레지스트리를 위한 컨테이너 스캔은 지속적 취약점 스캔을 사용하여 스캔에서 감지된 컴포넌트를 검사합니다.

보안 결과가 식별되면 GitLab은 이러한 결과로 취약점 보고서를 채웁니다. 취약점은 취약점 보고서 페이지의 Container registry vulnerabilities 탭에서 볼 수 있습니다.

레지스트리를 위한 컨테이너 스캔은 새 어드바이저리가 GitLab 어드바이저리 데이터베이스에 게시될 때만 취약점 보고서를 채웁니다. 새로 감지된 데이터만이 아닌 현재 어드바이저리 데이터 모두로 취약점 보고서를 채우는 지원은 에픽 11219에서 제안됩니다.

Warning

레지스트리를 위한 컨테이너 스캔에서 감지된 취약점은 취약한 컴포넌트를 업데이트하거나 제거할 때 자동으로 해결됨으로 표시될 수 없습니다. 이 기능은 취약점 해결에 필요한 보안 보고서가 아닌 SBOM만 생성하기 때문에 이러한 취약점은 무기한 표시됩니다.

레지스트리에 대한 컨테이너 스캔 켜기#

전제 조건:

  • 프로젝트에 대한 Security Manager, Maintainer 또는 Owner 역할.
  • 사용 중인 프로젝트는 비어 있으면 안 됩니다. 컨테이너 이미지 저장만을 위한 빈 프로젝트를 사용하는 경우 이 기능이 의도한 대로 작동하지 않습니다. 해결책으로 프로젝트의 기본 브랜치에 초기 커밋이 포함되어 있는지 확인합니다.
  • 기본적으로 프로젝트당 하루에 50회 스캔 제한이 있습니다.
  • 컨테이너 레지스트리 알림을 구성해야 합니다.
  • 패키지 메타데이터 데이터베이스를 구성해야 합니다. GitLab.com에서는 기본적으로 구성됩니다.

GitLab 컨테이너 레지스트리에 대한 컨테이너 스캔을 켜려면:

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
  2. 왼쪽 사이드바에서 Secure > Security configuration을 선택합니다.
  3. Container Scanning For Registry 섹션으로 스크롤하고 토글을 켭니다.

오프라인 또는 에어갭 환경에서 사용#

오프라인 또는 에어갭 환경에서 레지스트리에 대한 컨테이너 스캔을 사용하려면, 컨테이너 스캔 분析기 이미지의 로컬 복사본을 사용해야 합니다. 이 기능은 GitLab 보안 정책 봇이 관리하기 때문에, 분析기 이미지를 .gitlab-ci.yml 파일을 편집하여 구성할 수 없습니다.

대신 GitLab UI에서 CS_ANALYZER_IMAGE CI/CD 변수를 설정하여 기본 스캐너 이미지를 재정의해야 합니다. 동적으로 생성된 스캔 job은 UI에 정의된 변수를 상속합니다. 프로젝트, 그룹 또는 인스턴스 CI/CD 변수를 사용할 수 있습니다.

전제 조건:

  • 프로젝트 또는 그룹에 대한 Maintainer 또는 Owner 역할.

커스텀 스캐너 이미지를 구성하려면:

  1. 상단 바에서 Search or go to를 선택하고 프로젝트 또는 그룹을 찾습니다.
  2. 왼쪽 사이드바에서 Settings > CI/CD를 선택합니다.
  3. Variables 섹션을 펼칩니다.
  4. Add variable을 선택하고 세부 정보를 입력합니다:
    • Key: CS_ANALYZER_IMAGE
    • Value: 미러링된 컨테이너 스캔 이미지의 전체 URL. 예: my.local.registry:5000/analyzers/container-scanning:7.
  5. Add variable을 선택합니다.

GitLab 보안 정책 봇은 스캔을 트리거할 때 지정된 이미지를 사용합니다.

취약점 데이터베이스#

모든 분析기 이미지는 매일 업데이트됩니다.

이미지는 업스트림 어드바이저리 데이터베이스의 데이터를 사용합니다:

  • AlmaLinux Security Advisory
  • Amazon Linux Security Center
  • Arch Linux Security Tracker
  • SUSE CVRF
  • CWE Advisories
  • Debian Security Bug Tracker
  • GitHub Security Advisory
  • Go Vulnerability Database
  • CBL-Mariner Vulnerability Data
  • NVD
  • OSV
  • Red Hat OVAL v2
  • Red Hat Security Data API
  • Photon Security Advisories
  • Rocky Linux UpdateInfo
  • Ubuntu CVE Tracker (2021년 중반 이후의 데이터 소스만)

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

GitLab Ultimate 티어에서는 GitLab 어드바이저리 데이터베이스의 데이터가 외부 소스의 데이터를 보완하기 위해 병합됩니다. GitLab Premium 및 Free 티어에서는 GitLab 어드바이저리 데이터베이스(오픈 소스 에디션)의 데이터가 외부 소스의 데이터를 보완하기 위해 병합됩니다. 이 보완은 Trivy 스캐너의 분析기 이미지에만 적용됩니다.

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

취약점 솔루션 (자동 해결)#

일부 취약점은 GitLab이 자동으로 생성하는 솔루션을 적용하여 수정할 수 있습니다.

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

취약점 솔루션에 대해 자세히 읽어보세요.