ブログ

Docker イメージとコード依存関係のセキュリティ スキャン インフラ

フィリップ・ピトゥローン サムネイル
フィリップ・ピトゥローン
2020年9月21日公開
彗星のサムネイル
彗星
2020年9月21日公開
ssi1

今年初め、私たちのチームは、PCI-DSS および SOC-2 コンプライアンスのために既存のセキュリティ ツールとソフトウェア開発 + テスト プラクティスを強化するように依頼されました。 私たちが強化しなければならなかった重要な領域の 1 つは、K8s ベースのマイクロサービスといくつかのモノリシック サービスの脆弱性スキャンでした。 その結果、当社の DevOps チームは、ソフトウェアの脆弱性スキャンを実装するために、いくつかの商用ツールとオープンソース ソリューションの中から選択する必要がありました。 これらのツールはすべて非常に似た機能を実行します。依存関係 (プロジェクト ライブラリまたは OS パッケージ) をスキャンし、脆弱性データベース (NIST の NVD など) と比較します。

ビルド対 買う?

独自の脆弱性スキャン ソリューションを構築するために使用できるオープン ソース ツールがいくつかあります。また、基本的なスキャンにさらに機能を追加して作業を容易にする商用製品を使用することもできます。 例: 

  • プロジェクトの脆弱性を素早く把握できる便利なダッシュボード 
  • 通知(メール、Slack など) 
  • Git リポジトリ (GitHub、GitLab) との統合 
  • 他のサービスとの統合(Docker レジストリ、Kubernetes) 
  • プロジェクト管理(Jira など)との統合 
  • 脆弱な依存関係を修正するための自動マージリクエスト作成 
  • チーム、プロジェクト、RBAC のサポート

ほとんどの商用ソリューションは、公開されている脆弱性データベースを独自の脆弱性データベースで補強し、誤検知/誤検知を排除して、より関連性の高い結果を提供します。 とはいえ、開発者の数が増えるにつれて、これらの商用ツールはすべて非常に高価になります。 したがって、既存のオープンソース ツールを使用して独自のソリューションを購入するか、構築するかのどちらが「良い」のかを検討する必要があります。

当初、私たちは時間的な制約を考慮すると、商用ツールが私たちのニーズに最も適していると判断しました。 しかし、業界をリードする商用製品の導入とテストに 3 か月を費やした後、Golang のサポートが限られている、依存関係が誤って選択されて正常に終了しない、ゼロから構築されたコンテナとベースイメージを使用して構築されたコンテナで問題が発生するなど、多くの課題に直面しました。 その結果、私たちはそれをあきらめ、利用可能なオープンソース技術を使用して独自のツールを構築することに切り替えることにしました。

この投稿では、オープンソースを選択する場合に、最初に取り組むべき強固な基盤を提供します。 さらに、投稿の最後には、すぐに使い始めることができるオープンソース リポジトリへのリンクがあります。

何をスキャンしますか?

基本的に、脆弱性をスキャンする必要があるのは 2 つあります。 

  1. プロジェクトのコード依存関係 (yarn.lock、Gopkg.lock など)
  2. Docker イメージ内の OS 依存関係 (Debian パッケージ、Alpine パッケージなど)

将来的には、ライセンス チェックや静的コード分析などの機能を追加することも可能ですが、それはこの記事の範囲外です。

いつスキャンしますか?

まず、コードや Docker イメージの変更によって新たな脆弱性が導入されないようにする必要があります。そのため、マージする前にすべてのマージ リクエストをスキャンすることをお勧めします。

しかし、時間の経過とともに新たな脆弱性が出現する可能性があるため、定期的にスキャンする必要もあります。 また、重大度は変化する可能性があります。最初は無視していた重大度が低いものでも、新しい攻撃ベクトルやエクスプロイトが見つかると、時間の経過とともに重大になる可能性があります。 商用ツールは最後のスキャンを記憶し、新しい脆弱性が見つかった場合に通知しますが、当社のオープンソース ソリューションでは、プロジェクトのマスター ブランチ上でスキャンを繰り返すだけです。

ツールの選択

利用できるオープンソース ツールは多数ありますが、私たちが選んだのは Trivy です。使いやすく、活発に開発されており、複数のプロジェクトや OS タイプをスキャンできるからです。

Trivy は、コンテナやその他の成果物に対するシンプルで包括的な脆弱性スキャナーです。 ソフトウェアの脆弱性とは、ソフトウェアまたはオペレーティング システムに存在する不具合、欠陥、または弱点のことです。 Trivy は、OS パッケージ (Alpine、RHEL、CentOS など) とアプリケーション依存関係 (Bundler、Composer、npm、yarn など) の脆弱性を検出します。 Trivy は使い方が簡単です。バイナリをインストールするだけでスキャンの準備が整います。 スキャンに必要なのは、コンテナのイメージ名などのターゲットを指定することだけです。

ビルドされた Docker イメージまたはプロジェクトのルートに対してローカルに簡単にインストールして実行できます。 また、JSON やテーブル出力など、複数の出力もサポートしています。

ssi2

残念ながら、Trivy がスキャンできないプロジェクト (Golang など) があり、多くのコードが golang で記述されているため、 OWASP Dependency-Checkに頼らざるを得ませんでした。

Dependency-Check は、プロジェクトの依存関係内に含まれる公開された脆弱性を検出しようとするソフトウェア構成分析 (SCA) ツールです。 これは、特定の依存関係に Common Platform Enumeration (CPE) 識別子があるかどうかを判断することによって行われます。 見つかった場合は、関連する CVE エントリにリンクするレポートが生成されます。

レポート、JUnit、JSON 出力 (およびその他) を含む HTML ページを生成できます。

レポートとダッシュボード

今、私たちはもっと面白いものに近づいています😊

当社では DevOps チームと SRE チームですでにElasticsearch + Kibana + Fluentd を使用しているため、既存のインフラストラクチャを使用してセキュリティ スキャンの JSON 出力を分析するのは自然な流れでした。

信頼できないインフラストラクチャ (CI ランナー) から安全な Elasticsearch にデータを送信する方法を見つけるだけで済みました。 この目的のために、中間にメッセージ キューを配置することにしました。 Fluentd には Amazon SQS からメッセージを読み取るための in_sqs プラグインがあり、使い方も簡単なので、最終的なアーキテクチャは次のようになります。

ssi3
セキュリティスキャンアーキテクチャ

データが Elasticsearch に到達すると、Kibana を使用していくつかのダッシュボードを作成したり、Discover を使用して必要に応じてすべての詳細を含む脆弱性をクエリしたりすることが簡単になります。

ssi4
脆弱性の概要
ssi5
重大な脆弱性の探索

脆弱性への対処

スキャンと便利なダッシュボードができました。次は何をするのでしょうか? 開発者がこれらのダッシュボードを定期的に監視することは期待できません。 代わりに、重大度の高い問題またはそれ以上の問題が見つかり、修正プログラムが利用可能な場合は CI を失敗させることに決めました。これにより、責任が開発者とプロジェクト所有者に移されます。

当然、一部の CVE をホワイトリストに登録したり、プロジェクトごとにこのデフォルトの動作を上書きしたりするオプションが必要でした。 そこで、Trivy の実行をラップし、その動作と出力を処理するスキャン ツールによって使用されるセキュリティ スキャン プロファイルを含むリポジトリを作成しました。

これで、どの開発者もこのリポジトリに対してマージ リクエストを送信し、例外を要求することができます。 Kibanaプロジェクトのプロファイル例:

ssi6

今後の改善

このセキュリティ スキャンの実装は、当初のユースケースを超えて拡張できる強固な基盤です。 例えば: 

  • Slack 通知を追加し、セキュリティ プロファイルを使用してプロジェクトごとのチャネルとオプションを指定します 
  • Gitlab Issues、Jira、その他のチケットシステムとの統合を追加する
  • Kubernetes クラスターにデプロイされたイメージのスキャンを実行するためのシンプルなサービスまたはサイドカーを作成する

フォークして使ってみよう

Dockerfile とツールは、公開 Gitlab リポジトリで見つかります: https://gitlab.com/volterra.io/security-scanning

Jakub Pavlíkに感謝します。