GitLab CI/CDにおけるイメージスキャン

By 清水 孝郎 - OCTOBER 12, 2022

SHARE:

本文の内容は、2022年10月12日にEduardo Mínguezが投稿したブログ(https://sysdig.com/blog/gitlab-ci-cd-image-scanning/)を元に日本語に翻訳・再構成した内容となっております。

Sysdig Secureを使ってGitLab CI/CDでコンテナ・イメージの脆弱性や設定ミスをスキャンするのは、簡単な作業です。この記事では、その方法をステップバイステップで説明していきます。



以下のPoCでは、GitLab CI/CDで sysdig-cli-scanner を活用する方法を紹介しました。可能ではありますが、この手順はSysdigによって公式にサポートされていないため、ドキュメントを確認して、これらの手順を自分の環境に適合させることをお勧めします。

このブログ記事は、2022年4月以降に利用できる脆弱性スキャナーに焦点を合わせています。レガシースキャナーを使用している場合は、その詳細について公式ドキュメントを参照してください。

こちらからパイプラインの定義に直接行けます。

Sysdig Secureによるイメージ脆弱性スキャン

イメージスキャンにより、DevOpsチームは、コンテナが本番環境にデプロイされる前、またはイメージが任意のコンテナ・レジストリにプッシュされる前に、パイプラインの初期段階で既知の脆弱性を検出し、コンテナのビルド構成を検証することにより、セキュリティをシフトレフトさせることができます。これにより、問題の迅速な検出と修正、本番環境での脆弱性の回避、クレデンシャル漏洩の回避、本番環境へのデリバリー時間の短縮が可能になり、そのすべてがより安全な方法で行われます。

Sysdigイメージスキャンのプロセスは、ImageConfigのチェック(機密情報の漏洩など)や、OSパッケージ(rpm、debなど)だけでなく、言語固有のパッケージやライブラリ(java、pythonなど)のチェックなど、さまざまなルールを含むようにカスタマイズできるポリシーに基づいて行われます。

Sysdigの脆弱性スキャンは、スキャン手順を実行する場所によって、イメージの分類が異なります。

  • Pipeline: sysdig-cli-scannerツールによって実行される実行段階の前(開発者のワークステーション内、CI/CDパイプライン内など)。
  • Runtime: 実行ノードでイメージが実行され、Sysdigエージェントによってスキャンが実行されるとき。



今回は、GitLab CI/CDを利用してパイプラインのステップでスキャンを実行する方法を、採用すべきベストプラクティスとして取り上げます。

コンテナイメージに対してスキャナを実行するのは、 sysdig-cli-scanner ツールに以下のようないくつかのフラグ(詳細は公式ドキュメントを参照)を付けて実行するだけで、簡単にできます:

SECURE_API_TOKEN=<your-api-token> ./sysdig-cli-scanner --apiurl <sysdig-api-url> <image-name> --policy <my-policy>

イメージはツールを実行するホスト、ラップトップ、またはパイプラインを実行するコンテナ上でローカルでスキャンされ、スキャン結果のみがSysdig Secureのバックエンドに送信されます。

GitLab CI/CDにおける脆弱性スキャン

GitLab CI/CDは、GitLabソフトウェア開発およびコラボレーションプラットフォームと統合された、オープンソースの継続的インテグレーションおよび配信サーバーです。

あなたのリポジトリにGitLab CI/CDを設定すると、開発者が追跡されたリポジトリブランチにコミットをプッシュするたびに、パイプラインスクリプトが自動的にトリガーされるようになります。

これらのパイプラインを使用して、多くのプロセスを自動化することができます。一般的なタスクとしては、QAテスト、ソフトウェア配布アーティファクト(コンテナイメージやLinuxパッケージなど)のビルド、設定の検証、脆弱性の検証、コンプライアンスなどがあります。

イメージスキャンは、開発プロセスの早い段階でセキュリティを導入することで、CI/CDワークフローにおいて重要なステップとなっています(セキュリティ・シフト・レフト)。このワークフローでは、コンテナイメージをビルドし、sysdig-cli-scanner ツールを使ってローカルでイメージをスキャンします。スキャン結果はSysdigに送信されます。スキャン評価に失敗した場合、ワークフローは中断され、レジストリにイメージがアップロードされるのを阻止します。そうでない場合は、コンテナイメージはGitLabコンテナレジストリにプッシュされます。


GitLabのCI/CDパイプラインを作成する

この例で使用するバージョンは、以下のとおりです:

  • Runner: 15.4.0~beta.5.gdefc7017   ruby:2.5 イメージで Docker 実行形式を使用します
  • Sysdig-cli-scanner バージョン  1.2.9-rc, commit: e716ba6
レガシースキャナーを使用している場合、パイプラインの定義が異なります。sysdiglabs/secure-inline-scan-example リポジトリで提供されている例を参照してください。

前提条件

Sysdig Image Scanningを稼働させるための要件は簡単です。

  • GitLab リポジトリ(管理者権限付き)。
  • スキャン結果を収集するための Sysdig Secure アカウント。もし持っていない場合は、無料トライアルをリクエストすることができます。
  • ビルドする準備が整ったコンテナDockerfile。この例をフォークして使用することもできますが、独自のコンテナを使用する方がより楽しいでしょう!

準備ができたら、次に進みましょう!

リポジトリにGitLab CI/CDを設定する

GitLab CI/CDは、デフォルトですべての新しいプロジェクトで有効になっていますが、もしあなたのリポジトリでGitLab CI/CDを有効にしていないなら、最初のステップは、それが有効になっていることを確認することです。リポジトリの設定、CI/CDセクション(https://gitlab.com/<user>/<repository>/edit)に移動し、“Visibility, project features, permissions” セクションを展開し、“CI/CD”トグルがアクティブであることを確認します:



コンテナイメージの保存にも使用するので、 “Container registry”のトグルが有効になっていることを確認します。

マスクされた変数

レジストリのパスワードやAPIトークンなどの機密データについては、repository Settings -> CI/CD -> Variables -> “Add variable”で、代わりにマスクされた変数を作成することが推奨されます。



この例では、SYSDIG_SECURE_TOKENを追加して、Sysdig APIへのクエリーとスキャン結果の送信に必要なSysdig APIトークンを格納します。取得方法の詳細については、Sysdigの公式ドキュメントを参照してください。

なお、セキュリティ上の問題や情報漏えいの可能性を避けるため、この変数はマスクする必要があることを明記しておきます。詳細については、公式ドキュメントを参照してください。


コンテナレジストリ

スキャンが正常に完了したら、GitLabのコンテナレジストリを活用してコンテナイメージを保存します。

コンテナレジストリを利用するための特別なCI/CD変数(CI_REGISTRY*)がいくつかあり、それらはGitLabによって自動的に入力されるので、利用したい場合はパイプラインで指定する必要はありません。Cool!

GitLabの公式ドキュメントで詳しく説明されていますが、以下は自動的に入力された後の変数の内容の例です。

  • CI_REGISTRY="registry.example.com"
  • CI_REGISTRY_IMAGE="registry.example.com/gitlab-org/gitlab-foss"
  • CI_REGISTRY_USER="gitlab-ci-token"
  • CI_REGISTRY_PASSWORD="[masked]"

イメージスキャンのGitLab CI/CDパイプラインを設定する

GitLab CI/CDパイプラインは、デフォルトではリポジトリ内の.gitlab-ci.ymlファイル内のYAMLファイルによって定義されます。パイプラインは変数を持ち、異なるステップに分けることができ、それぞれが異なるプロパティを持ち、複数のコマンド/スクリプトを実行することができます。

パイプラインの編集は、GitLab UI のパイプラインエディターを使うか、リポジトリ内の .gitlab-ci.yml ファイルに変更をコミットするだけで行うことができます。

それでは、パイプラインの定義を詳しく見ていきましょう:

変数とステージの定義


variables: SYSDIG_SECURE_ENDPOINT: "https://eu1.app.sysdig.com" CI_IMAGE_TAG: "my-tag" stages: - build - scan - push

いくつかの変数を使って、Sysdig API のエンドポイントと、ビルドするコンテナイメージに使用するコンテナイメージタグを保存します。また、コンテナイメージのビルド、スキャン、プッシュに使用するステージを定義しています。

ビルドステージ

image:build:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  script:
    - /kaniko/executor --dockerfile Dockerfile --destination $CI_REGISTRY_IMAGE:$CI_IMAGE_TAG --no-push --oci-layout-path $(pwd)/build/ --tarPath $(pwd)/build/$CI_IMAGE_TAG.tar
  artifacts:
    paths:
      - build/
    expire_in: 1 days


イメージビルドステップでは、Kanikoプロジェクトを利用して、Dockerfileの指示によりコンテナイメージをビルドし、次のステップでスキャンする新しいローカルイメージを $(pwd)/build/$CI_IMAGE_TAG.tar ファイルに生成します。


スキャンステージ

image:scan:
  stage: scan
  before_script:
    - export SECURE_API_TOKEN=$SYSDIG_SECURE_TOKEN
  script:
    - curl -LO https://download.sysdig.com/scanning/bin/sysdig-cli-scanner/$(curl -L -s https://download.sysdig.com/scanning/sysdig-cli-scanner/latest_version.txt)/linux/amd64/sysdig-cli-scanner
    - chmod +x ./sysdig-cli-scanner
    - ./sysdig-cli-scanner --console-log  --apiurl $SYSDIG_SECURE_ENDPOINT file://$(pwd)/build/$CI_IMAGE_TAG.tar
  artifacts:
    paths:
      - build/
    expire_in: 1 days
    when: always
  needs:
    - image:build
この段階では、イメージの脆弱性をスキャンして設定を検証し、その結果をSysdigのバックエンドに保存しています。Sysdigのローカルスキャン手法の利点の1つは、スキャンするためにイメージをレジストリにプッシュしたり、外部に公開する必要がないため、イメージの制御を失わないということです。スキャンはランナー内部で行われ、その結果のみがSysdig Secureに送信されます。

スキャン処理は、バイナリファイルをダウンロードし、いくつかのパラメータ(前に作成した SYSDIG_SECURE_TOKEN 変数から SECURE_API_TOKEN 環境変数を含む)を付けて、前にビルドしたコンテナイメージに対して実行するだけというシンプルさです。

Sysdig Secureは、イメージにポリシーで設定した停止条件(致命的な脆弱性など)のいずれかが含まれている場合、このステージでエラーコードを返します。パイプラインを停止することで、脆弱なイメージをコンテナイメージレジストリにプッシュすることができなくなります。


プッシュステージ


image:push: stage: push image: name: gcr.io/go-containerregistry/crane:debug entrypoint: [""] script: - crane auth login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - crane push build/$CI_IMAGE_TAG.tar $CI_REGISTRY_IMAGE:$CI_IMAGE_TAG needs: - image:scan


最後のステップは、イメージスキャンステップが成功した場合にのみ、craneを使用してコンテナイメージを認証し、プッシュします。

GitLab におけるイメージスキャン

リポジトリに Dockerfile があり、有効な Secure API トークンがあれば、先ほど作成したパイプラインのコミットで実行が始まり、イメージがビルドされ、スキャンされるはずです。

レポの CI/CD -> Pipelines セクションに移動して、実行結果を見ることができます:



また、実行の各ステップをクリックすると、詳細なビューが表示されます。


分析結果は、Sysdig SecureアカウントのVulnerability -> Pipelineに掲載されます。



成功! 脆弱性は見つからず、イメージはレジストリにプッシュして公開され、アセットは次の実行のためにキャッシュに自動的に保存され、時間の節約と不要なダウンロードの回避になります。

このスキャン例では、デフォルトの “Sysdig Best Practices” ポリシーを使用しましたが(ログで確認できます)、脆弱性ポリシーだけでなく、イメージのベストプラクティスなど、チェックしたいポリシーを作成し、カスタマイズすることも可能です。

ポリシーが原因でスキャンが失敗した場合、ワークフローは停止し、イメージはレジストリにプッシュされません(これは良いアイデアです)このように表示されます。



この例では脆弱性は発見されませんでしたが(やった!)、https://github.com/sysdiglabs/dummy-vuln-app のような別のアプリケーションを見ると、いくつか発見されていることがわかります。





すでに修正されているもの、および/または、悪用可能なものをフィルタリングし、修正または更新が最も急がれるものに焦点を当てることができます:



脆弱性だけでなく、ベストプラクティスでないものも見ることができます:



まとめ

このように、GitLab CI/CDは、GitLabリポジトリ上で直接CI/CDパイプラインを自動化するための強力なツールです。Sysdig Secure Inline Scanをワークフローに組み込むことは簡単で、イメージの脆弱性をスキャンし、ビルド時にベストプラクティスを実施し、レジストリ内の旧来のイ メージスキャンと比較していくつかの利点を提供することができるようになりました。

  • CI/CDパイプラインにイメージスキャンを導入することで、脆弱性や設定ミスが発見された場合、そのイメージが公開されるのを一切防ぐことができます。
  • 解析はランナー内でインライン(ローカル)に行われるため、ビルドされた環境の外を含め、イメージがどこかに送信されることはありません。解析中は、イメージからメタデータ情報のみを抽出し、実際のコンテンツは抽出されません。
  • Sysdig Secureは、様々なコンテナのコンプライアンス基準(NIST 800-190PCIなど)を実施・遵守するためのポリシーをすぐに利用できるように提供します。

Sysdig Secure Image Scanningは、ほとんどのCI/CDパイプラインツールとシームレスに統合することができます。

まだSysdig Secureをイメージ・スキャンに利用していない方は、今すぐデモをご依頼ください。