正式なドキュメントは英語版であり、この日本語訳はAI支援翻訳により作成された参考用のものです。日本語訳の一部の内容は人間によるレビューがまだ行われていないため、翻訳のタイミングにより英語版との間に差異が生じることがあります。最新かつ正確な情報については、英語版をご参照ください。

コンテナスキャン

  • プラン: Free、Premium、Ultimate
  • 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated

コンテナイメージのセキュリティの脆弱性は、アプリケーションライフサイクル全体にリスクをもたらします。コンテナスキャンは、これらのリスクを、本番環境に到達する前に早期に検出します。脆弱性がベースイメージまたはオペレーティングシステムのパッケージに現れた場合、コンテナスキャンはそれらを特定し、可能な場合は修正パスを提供します。

コンテナスキャンは、多くの場合、ソフトウェアコンポジション解析(SCA)の一部と見なされます。SCAには、コードで使用するアイテムの検査の側面が含まれる場合があります。これらのアイテムには通常、アプリケーションやシステムの依存関係が含まれており、ほとんどの場合、これらはユーザーが記述したアイテムからではなく外部ソースからインポートされます。

GitLabは、これらすべての依存タイプのカバレッジを確保するために、コンテナスキャンと依存関係スキャンの両方を提供しています。リスク領域を可能な限り網羅するには、すべてのセキュリティスキャナーを使用してください。これらの機能の比較については、依存関係スキャンとコンテナスキャンの比較を参照してください。

GitLabは、Trivyセキュリティスキャナーと統合して、コンテナ内の脆弱性の静的な解析を実行します。

機能

機能FreeとPremiumUltimate
設定のカスタマイズ(変数オーバーライドオフライン環境のサポートなど)check-smcheck-sm
CIジョブアーティファクトとしてJSONレポートを表示check-smcheck-sm
CIジョブアーティファクトとしてCycloneDX SBOM JSONレポートを生成check-smcheck-sm
GitLab UIのMR経由でコンテナスキャンを有効にする機能check-smcheck-sm
UBIイメージのサポートcheck-smcheck-sm
Trivyのサポートcheck-smcheck-sm
エンドオブライフオペレーティングシステムの検出check-smcheck-sm
GitLabアドバイザリデータベースの包含GitLab advisories-communitiesプロジェクトからの時間差コンテンツに限定可 - Gemnasium DBからのすべての最新コンテンツ
CIパイプラインジョブのマージリクエストタブとセキュリティタブでのレポートデータの表示Nocheck-sm
脆弱性のソリューション(自動修正)Nocheck-sm
脆弱性許可リストのサポートNocheck-sm
依存関係リストへのアクセスNocheck-sm

はじめに

CI/CDパイプラインでコンテナスキャンアナライザーを有効にします。パイプラインが実行されると、アプリケーションが依存するイメージの脆弱性がスキャンされます。CI/CD変数を使用して、コンテナスキャンをカスタマイズできます。

前提条件:

  • .gitlab-ci.ymlファイルにはTestステージが必要です。
  • セルフマネージドRunnerを使用する場合は、Linux/amd64上でdockerまたはkubernetes executorを備えたRunnerが必要です。GitLab.comのインスタンスRunnerを使用している場合、これはデフォルトで有効になっています。
  • サポートされているディストリビューションに一致するイメージ。
  • プロジェクトのコンテナレジストリに対して、Dockerイメージをビルドしてプッシュしていること。
  • サードパーティのコンテナレジストリを使用している場合は、CI/CD変数CS_REGISTRY_USERCS_REGISTRY_PASSWORDを使用して認証情報を指定する必要がある場合があります。これらの変数の使用方法の詳細については、プライベートな外部レジストリへの認証を参照してください。

ユーザーおよびプロジェクト固有の要件については、以下の詳細を参照してください。

アナライザーを有効にするには、次のいずれかの方法を使用します。

  • Auto DevOpsを有効にします。これには、依存関係スキャンが含まれます。
  • 事前設定されたマージリクエストを使用します。
  • コンテナスキャンを強制するスキャン実行ポリシーを作成します。
  • .gitlab-ci.ymlファイルを手動で編集します。

事前設定されたマージリクエストを使用する

この方法では、.gitlab-ci.ymlファイルにコンテナスキャンテンプレートを含むマージリクエストが自動的に準備されます。次に、マージリクエストをマージして、コンテナスキャンを有効にします。

コンテナスキャンを有効にするには:

  1. 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
  2. セキュリティ > セキュリティ設定を選択します。
  3. コンテナスキャン行で、マージリクエスト経由で設定を選択します。
  4. マージリクエストの作成を選択します。
  5. マージリクエストをレビューして、マージを選択します。

これで、パイプラインにコンテナスキャンジョブが含まれるようになりました。

.gitlab-ci.ymlファイルを手動で編集する

この方法では、既存の.gitlab-ci.ymlファイルを手動で編集する必要があります。複雑なGitLab設定ファイルがある場合、またはデフォルト以外のオプションを使用する必要がある場合は、この方法を使用してください。

コンテナスキャンを有効にするには:

  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. 標準のワークフローに従ってマージリクエストをレビューおよび編集し、パイプラインが成功するまで待ってからマージを選択します。

これで、パイプラインにコンテナスキャンジョブが含まれるようになりました。

結果について理解する

パイプラインの脆弱性を確認できます。

  1. 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
  2. 左側のサイドバーで、ビルド > パイプラインを選択します。
  3. パイプラインを選択します。
  4. セキュリティタブを選択します。
  5. 脆弱性を選択して、次の詳細を表示します。
    • 説明: 脆弱性の原因、潜在的な影響、推奨される修正手順について説明しています。
    • ステータス: 脆弱性がトリアージされたか、解決されたかを示します。
    • 重大度: 影響に基づいて6つのレベルに分類されます。重大度レベルの詳細はこちらをご覧ください
    • CVSSスコア: 重大度にマップする数値を指定します。
    • EPSS: 脆弱性が実際に悪用される可能性を示します。
    • 既知の悪用された脆弱性(KEV): 特定の脆弱性がすでに悪用されていることを示します。
    • プロジェクト: 脆弱性が特定されたプロジェクトを強調表示します。
    • レポートの種類: 出力の種類を説明します。
    • スキャナー: 脆弱性を検出したアナライザーを示します。
    • イメージ: 脆弱性に紐付けられたイメージを提供します。
    • ネームスペース: 脆弱性に紐付けられたワークスペースを示します。
    • リンク: さまざまなアドバイザリーデータベースに登録されている脆弱性の証拠です。
    • 識別子: CVE識別子など、脆弱性の分類に使用される参照の一覧です。

詳細については、パイプラインセキュリティレポートを参照してください。

コンテナスキャン結果を表示する追加の方法:

最適化

GitLabは、コンテナスキャンに2つのアプローチを提供します:

  • 標準コンテナスキャン: ジョブごとに1つのコンテナイメージをスキャンします。シンプルで分散されたワークフローに最適です。
  • マルチコンテナスキャン: 単一の設定ファイルを使用して、複数のイメージを並行してスキャンします。複数のイメージを効率的にスキャンする場合に最適です。

ロールアウトする

単一のプロジェクトのコンテナスキャン結果に自信がある場合は、その実装を他のプロジェクトに拡張できます:

  • 強制スキャン実行を使用して、コンテナスキャンの設定をグループ全体に適用します。
  • 固有の要件がある場合は、オフライン環境でコンテナスキャンを実行できます。

サポートされているディストリビューション

次の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モードが有効になっている場合、認証済みレジストリのイメージのコンテナスキャンはサポートされません。CI_GITLAB_FIPS_MODE"true"で、CS_REGISTRY_USERまたはCS_REGISTRY_PASSWORDが設定されている場合、アナライザーはエラーで終了し、スキャンを実行しません。

設定

アナライザーの動作をカスタマイズする

コンテナスキャンをカスタマイズするには、CI/CD変数を使用します。

冗長な出力を有効にする

たとえば、トラブルシューティングを行う場合など、依存関係スキャンジョブが何を行うかを詳細に確認する必要がある場合は、詳細出力を有効にします。

次の例では、コンテナスキャンテンプレートが含まれており、詳細出力が有効になっています。

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

variables:
    SECURE_LOG_LEVEL: 'debug'

言語固有の検出結果をレポートする

CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN CI/CD変数は、スキャンでプログラミング言語に関連する検出結果をレポートするかどうかを制御します。サポートされている言語の詳細については、Trivyドキュメントの言語固有のパッケージを参照してください。

デフォルトでは、レポートにはオペレーティングシステム(OS)パッケージマネージャー(yumaptapktdnfなど)によって管理されるパッケージのみが含まれます。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変数を使用します。次の表に、コンテナスキャンに固有のCI/CD変数を示します。定義済みCI/CD変数も使用できます。

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_IMAGEregistry.gitlab.com/security-products/container-scanning:8アナライザーのDockerイメージ。GitLabが提供するアナライザーイメージで:latestタグを使用しないでください。
CS_DEFAULT_BRANCH_IMAGE""デフォルトブランチのCS_IMAGEの名前。詳細については、デフォルトブランチイメージを設定するを参照してください。
CS_DISABLE_DEPENDENCY_LIST"false"warning GitLab 17.0で**削除**されました。
CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN"true"スキャンされたイメージにインストールされている言語固有パッケージのスキャンを無効にします。
CS_DOCKER_INSECURE"false"証明書を検証せずに、HTTPSを使用してセキュアなDockerレジストリへのアクセスを許可します。
CS_DOCKERFILE_PATHDockerfile修正の生成に使用する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_life1
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-enabledイメージがスキャンに使用されます。詳細については、FIPS対応イメージを参照してください。
CS_QUIET""設定した場合、この変数はジョブログの脆弱性テーブルの出力を無効にします。
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に関係なく常に報告されます。サポートされているレベルは、UNKNOWNLOWMEDIUMHIGHCRITICALです。
CS_SEVERITY_THRESHOLDUNKNOWN重大度レベルのしきい値。スキャナーは、このしきい値以上の重大度レベルの脆弱性を出力します。サポートされているレベルは、UNKNOWNLOWMEDIUMHIGHCRITICALです。
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_LEVELinfo最小ログ生成レベルを設定します。このログ生成レベル以上のメッセージが出力されます。ログ生成レベルは重大度の高いものから順に、fatalerrorwarninfodebugです。
TRIVY_TIMEOUT5m0sスキャンのタイムアウトを設定します。
TRIVY_PLATFORMlinux/amd64イメージがマルチプラットフォーム対応の場合は、os/arch形式でプラットフォームを設定します。

脚注:

  1. 修正ステータスの情報は、ソフトウェアベンダーからの修正プログラムの提供状況に関する正確なデータと、コンテナイメージのオペレーティングシステムパッケージのメタデータに大きく依存します。また、個々のコンテナスキャナーによる解釈の影響も受けます。コンテナスキャナーが、脆弱性に対して修正されたパッケージの提供状況を誤って報告した場合、CS_IGNORE_STATUSESを使用すると、この設定が有効になっているときに検出結果のフィルタリングで誤検出や検出漏れにつながる可能性があります。

コンテナスキャンテンプレートをオーバーライドする

ジョブ定義をオーバーライドする場合(variablesのようなプロパティを変更する場合など)、テンプレートを含めた後でジョブを宣言してオーバーライドし、追加のキーを指定する必要があります。

この例では、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_USERおよびCS_REGISTRY_PASSWORD CI/CD変数を使用して、認証情報を提供します。

たとえば、Googleコンテナレジストリでイメージをスキャンするには:

  1. Google Cloud Platformコンテナレジストリドキュメントで説明されているように、JSONキーを含むGCP_CREDENTIALSのCI/CD変数を追加します。

    • 変数の値がマスク変数オプションのマスク要件に適合しない場合があるため、値がジョブログに公開される可能性があります。
    • 変数保護オプションを選択した場合、保護されていないフィーチャーブランチでスキャンが実行されない場合があります。
    • これらのオプションを選択しない場合は、読み取り専用の権限で認証情報を作成し、定期的にローテーションすることを検討してください。
  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 Amazon 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:1OCIアーティファクトとしてホストされます。このレジストリにアクセスできない場合、または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

デフォルトブランチイメージを設定する

デフォルトでは、コンテナスキャンは、イメージの命名規則が、ブランチ固有の識別子をイメージ名ではなくイメージタグに格納することを想定しています。イメージ名がデフォルトブランチと非デフォルトブランチで異なる場合、以前に検出された脆弱性は、マージリクエストで新しく検出されたものとして表示されます。

デフォルトブランチと非デフォルトブランチで同じイメージに異なる名前が付けられている場合は、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値は、証明書へのパスが必要なfileとして、または証明書のテキスト表現が必要な変数として、UIでカスタム変数として構成することもできます。

マルチアーチイメージをスキャンする

TRIVY_PLATFORM CI/CD変数を使用して、特定のオペレーティングシステムとアーキテクチャに対して実行するようにコンテナスキャンを設定できます。たとえば、.gitlab-ci.ymlファイルでこの値を設定するには、以下のように記述します。

container_scanning:
  # Use an arm64 SaaS runner to scan this natively
  tags: ["saas-linux-small-arm64"]
  variables:
    TRIVY_PLATFORM: "linux/arm64"

脆弱性の許可リスト

  • プラン: Ultimate
  • 提供形態: GitLab.com、GitLab 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 ID CVE-2019-8696CVE-2014-8166CVE-2017-18248を持つすべての脆弱性
  2. registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256コンテナイメージで見つかった、CVE ID CVE-2018-4180を持つすべての脆弱性
  3. your.private.registry:5000/centosコンテナで見つかった、CVE ID CVE-2015-1419CVE-2015-1447を持つすべての脆弱性
ファイル形式
  • generalallowlistブロックを使用すると、CVE IDをグローバルに指定できます。一致するCVE IDを持つすべての脆弱性は、スキャンレポートから除外されます。

  • imagesブロックを使用すると、コンテナイメージごとにCVE IDを個別に指定できます。指定されたイメージ内で一致するCVE IDを持つすべての脆弱性は、スキャンレポートから除外されます。イメージ名は、スキャン対象のDockerイメージを指定するために使用される環境変数($CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAGCS_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
コンテナスキャンのジョブログ形式

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としてマークされます。

オフライン環境

  • プラン: Free、Premium、Ultimate
  • 提供形態: GitLab Self-Managed

オフライン環境でコンテナスキャンを実行するには、初期設定を行い、継続的なメンテナンスを実行する必要があります。

初期設定:

継続的なメンテナンス:

  • 新しいバージョンがリリースされたら、ローカルコンテナスキャンイメージを更新します。

Runnerを構成する

Runnerを構成します(dockerまたはkubernetes executorが使用可能であることを確認します)。詳細については、はじめにを参照してください。

デフォルトでは、Runnerは、ローカルコピーが利用可能な場合でも、GitLabコンテナレジストリからコンテナイメージをプルします。ローカルコンテナイメージのみを使用する場合は、pull_policyif-not-presentに設定できます。ただし、変更する正当な理由がない限り、pull_policy設定はデフォルトのままにしておく必要があります。

コンテナイメージをコピーする

GitLab.comコンテナレジストリからローカルコンテナレジストリに、次のイメージをインポートします。このイメージは、オフラインのGitLabインスタンスからアクセスできる必要があります。

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

ローカルコンテナレジストリへのイメージのインポートプロセスは、ネットワークセキュリティポリシーによって異なります。IT部門に相談して、外部リソースをインポートまたは一時的にアクセスするための承認済みプロセスを確認してください。

各プロジェクトのCI/CDを構成する

コンテナスキャンを使用するすべてのプロジェクトについて、適用されるすべての場所で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:
    # Container scanning-specific 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_USERおよびCI_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.tar.gz)をサポートしています。このようなイメージは、たとえば、docker savedocker buildx buildを使用して作成できます。

アーカイブファイルをスキャンするには、環境変数CS_IMAGEarchive://path/to/archive形式に設定します。

  • archive://スキームプレフィックスは、アナライザーにアーカイブをスキャンするよう指示します。
  • path/to/archiveは、スキャン対象のアーカイブのパスを、絶対パスまたは相対パスのいずれかで指定します。

コンテナスキャンは、Dockerイメージ仕様に準拠したtarイメージファイルをサポートしています。OCI tarballはサポートされていません。サポートされている形式の詳細については、Trivy tarファイルのサポートを参照してください。

サポートされているtarファイルをビルドする

コンテナスキャンは、イメージの名前付けのためにtarファイルのメタデータを使用します。tarイメージファイルをビルドするときは、必ずイメージにタグを付けてください。

# Pull or build an image with a name and a tag
docker pull image:latest
# OR
docker build . -t image:latest
# Then export to tar using docker save
docker save image:latest -o image-latest.tar

# Or build an image with a tag using 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

# With podman
podman build -t image:latest .
podman save -o image-latest.tar image:latest

イメージ名

コンテナスキャンは、最初にアーカイブのmanifest.jsonを評価し、RepoTagsの最初の項目を使用して、イメージ名を決定します。これが見つからない場合、index.jsonを使用してio.containerd.image.nameアノテーションをフェッチします。これも見つからない場合、代わりにアーカイブのファイル名を使用します。

以前のジョブでビルドされたアーカイブをスキャンする

CI/CDジョブでビルドされたアーカイブをスキャンするには、ビルドジョブからコンテナスキャンジョブにアーカイブアーティファクトを渡す必要があります。artifacts:pathsおよびdependenciesキーワードを使用して、あるジョブから次のジョブにアーティファクトを渡します。

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ジョブでGIT_STRATEGYキーワードをcloneまたはfetchのいずれかに設定します。デフォルトではnoneに設定されているためです。

container_scanning:
  variables:
    GIT_STRATEGY: fetch

スタンドアロンのコンテナスキャンツールを実行する

GitLabコンテナスキャンツールをDockerコンテナに対して実行できます。CIジョブのコンテキスト内で実行する必要はありません。イメージを直接スキャンするには、次の手順に従います。

  1. Docker DesktopまたはDocker Machineを実行します。

  2. アナライザーのDockerイメージを実行し、CI_APPLICATION_REPOSITORYおよびCI_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/CD設定ファイル内のartifacts:reportsキーワードを介して認識するJSONレポートを出力します。

CI/CDジョブアーティファクトが完了すると、RunnerはこれらのレポートをGitLabにアップロードします。これは、CI/CDジョブアーティファクトで使用できるようになります。GitLab GitLab Ultimateでは、これらのレポートを対応するパイプラインと脆弱性レポートで表示できます。

これらのレポートは、コンテナスキャンレポートスキーマに準拠している必要があります。

コンテナスキャンレポートの例

CycloneDXソフトウェア部品表

JSONレポートファイルに加えて、コンテナスキャンツールは、スキャンされたイメージのCycloneDXソフトウェア部品表(SBOM)を出力します。このCycloneDX SBOMはgl-sbom-report.cdx.jsonという名前で、JSON report fileと同じディレクトリに保存されます。この機能は、Trivyアナライザーを使用する場合にのみサポートされます。

このレポートは、依存関係リストで表示できます。

CycloneDX SBOMは、他のジョブアーティファクトと同じ方法でダウンロードできます。

CycloneDXレポートのライセンス情報

コンテナスキャンでは、CycloneDXレポートにライセンス情報を含めることができます。この機能は、下位互換性を維持するためにデフォルトで無効になっています。

コンテナスキャンの結果でライセンススキャンを有効にするには、次のようにします。

  • .gitlab-ci.ymlファイルでCS_INCLUDE_LICENSES変数を設定します。
container_scanning:
  variables:
    CS_INCLUDE_LICENSES: "true"
  • この機能を有効にすると、生成されたCycloneDXレポートには、コンテナイメージで検出されたコンポーネントのライセンス情報が含まれます。

  • このライセンス情報は、依存関係リストページで表示することも、ダウンロード可能なCycloneDXジョブアーティファクトの一部として表示することもできます。

SPDXライセンスのみがサポートされていることに注意してください。ただし、SPDXに準拠していないライセンスも、ユーザーにエラーを表示せずにインジェストされます。

エンドオブライフオペレーティングシステムの検出

コンテナスキャンには、コンテナイメージがエンドオブライフ(EOL)に達したオペレーティングシステムを使用している場合に、それを検出して報告する機能があります。EOLに達したオペレーティングシステムはセキュリティアップデートが提供されなくなり、新たに発見されたセキュリティ上の問題に対して脆弱な状態のままになります。

EOL検出機能は、Trivyを使用して、それぞれのディストリビューションでサポートが終了したオペレーティングシステムを特定します。EOLのオペレーティングシステムが検出されると、他のセキュリティ検出結果とともに、コンテナスキャンレポートで脆弱性として報告されます。

EOL検出を有効にするには、CS_REPORT_OS_EOL"true"に設定します。

レジストリのコンテナスキャン

  • プラン: Ultimate
  • 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated

コンテナイメージがlatestタグ付きでプッシュされると、セキュリティポリシーボットによって、デフォルトブランチに対して新しいパイプラインでコンテナスキャンジョブが自動的にトリガーされます。

通常のコンテナスキャンとは異なり、スキャン結果にセキュリティレポートは含まれません。代わりに、レジストリのコンテナスキャンは、継続的脆弱性スキャンを利用して、スキャンによって検出されたコンポーネントを検査します。

セキュリティ検出結果が特定されると、GitLabはこれらの検出結果を脆弱性レポートに入力します。脆弱性は、脆弱性レポートページのコンテナレジストリの脆弱性タブで確認できます。

レジストリのコンテナスキャンは、新しい勧告がGitLabアドバイザリデータベースに公開された場合にのみ、脆弱性レポートを設定します。新しく検出されたデータだけでなく、存在するすべてのアドバイザリーデータを脆弱性レポートに入力するためのサポートは、エピック11219で提案されています。

前提条件

  • レジストリのコンテナスキャンを有効にするには、プロジェクトでメンテナー以上のロールを持っている必要があります。
  • 使用するプロジェクトが空であってはなりません。コンテナイメージの保存のみを目的として空のプロジェクトを利用している場合、この機能は意図したとおりに機能しません。回避策として、プロジェクトにデフォルトブランチへの最初のコミットが含まれていることを確認してください。
  • デフォルトでは、1日あたり1プロジェクトにつき50回のスキャンに制限されています。
  • コンテナレジストリ通知を設定する必要があります。
  • パッケージメタデータデータベースを構成する必要があります。これは、GitLab.comでデフォルトで構成されています。

レジストリのコンテナスキャンを有効にする

GitLabコンテナレジストリのコンテナスキャンを有効にするには:

  1. 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
  2. セキュリティ > セキュリティ設定を選択します。
  3. レジストリのコンテナのスキャンセクションまでスクロールし、切替をオンにします。

オフラインまたはインターネット未接続(エアギャップ)環境で使用する

オフラインまたはエアギャップ環境でレジストリのコンテナスキャンを使用するには、コンテナスキャンアナライザーイメージのローカルコピーを使用する必要があります。この機能はGitLabセキュリティポリシーボットによって管理されるため、.gitlab-ci.ymlファイルを編集してアナライザーイメージを設定することはできません。

代わりに、GitLab UIでCS_ANALYZER_IMAGE CI/CD変数を設定して、デフォルトのスキャナーイメージをオーバーライドする必要があります。動的に作成されたスキャンジョブは、UIで定義された変数を継承します。プロジェクト、グループ、またはインスタンスのCI/CD変数を使用できます。

カスタムスキャナーイメージを設定するには:

  1. 上部のバーで、検索または移動先を選択して、プロジェクトまたはグループを見つけます。
  2. 設定 > CI/CDを選択します。
  3. 変数セクションを展開します。
  4. 変数を追加を選択し、詳細を入力します。
    • キー: CS_ANALYZER_IMAGE
    • 値: ミラーリングされたコンテナスキャンイメージの完全なURL。例: my.local.registry:5000/analyzers/container-scanning:7
  5. 変数を追加を選択します。

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 tierでは、GitLabアドバイザリデータベースからのデータがマージされ、外部ソースからのデータが拡張されます。GitLab PremiumおよびFreeでは、GitLabアドバイザリデータベース(Open Source Edition)からのデータがマージされ、外部ソースからのデータが拡張されます。この拡張は、Trivyスキャナーのアナライザーイメージにのみ適用されます。

他のアナライザーのデータベース更新情報については、メンテナンステーブルを参照してください。

脆弱性のソリューション(自動修正)

  • プラン: Ultimate
  • 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated

GitLabが自動的に生成するソリューションを適用することで、一部の脆弱性を修正できます。

修正のサポートを有効にするには、スキャンツールがCI/CD変数CS_DOCKERFILE_PATHで指定されたDockerfileにアクセスできる必要があります。スキャンツールがこのファイルにアクセスできるようにするには、このドキュメントのコンテナスキャンテンプレートをオーバーライドするセクションの説明に従って、.gitlab-ci.ymlファイルでGIT_STRATEGY: fetchを設定する必要があります。

詳細については、脆弱性のソリューションを参照してください。