Skip to main content

CI/CD環境は安全だと思っていますか?

著者

Anita Buehrle

2019年2月21日

0 分で読めます

WeaveworksとSnykが共同執筆したこの記事では、GitOpsの継続的インテグレーション(CI)/継続的デリバリー(CD)パイプラインと適切なセキュリティ対策を組み合わせることで、Kubernetes向け開発ワークフロー全体のセキュリティをどのように強化できるかを解説します。

一般的なCI/CDパイプライン

皆さんのCI/CDパイプラインも、以下の簡略化したモデルによく似ているかもしれません。フローは左端から始まり、開発者のマシン上にあるコードがGitHubなどのコードリポジトリにプッシュされます。次にCIツールがコードを取得し、テストを実行して、コンテナイメージなどの成果物をビルドします。そのイメージがイメージリポジトリにプッシュされ、Kubernetesなどのオープンソースのオーケストレーターや同様のシステムにデプロイされます。

DevからCode Repo、CI、Image Repoを経てKubernetesに至るワークフロー図。

しかし、見落とされがちなのは、一般的なCI/CDのプッシュモデルが安全かどうかという点です。次の2つの質問について考えてみましょう。

  • CI環境からコンテナイメージリポジトリに直接アクセスできますか?

  • CI環境から本番クラスターに直接アクセスできますか?

もう一度パイプラインを見てみましょう。今度は、どのステージが互いにアクセスできるかに注目します。以下の図では、RWは読み取り/書き込みアクセス、ROは読み取り専用アクセスを表しています。予想以上に赤い線が多いのではないでしょうか。この単純なパイプラインは、Open Web Application Security Project(OWASP)のセキュリティ原則のうち、最小権限の原則や職務分掌などに違反しています。たとえば、開発者はコードリポジトリとクラスターに対して読み取り/書き込みアクセス権を持っています。

開発者がイメージリポジトリやクラスターに直接アクセスできないようにすることで、攻撃対象領域を縮小し、特権アクセスを最小限に抑え、職務を分離できます。

Dev、コードリポジトリ、CI、イメージリポジトリ、クラスターが読み書きおよび読み取り専用の矢印でつながったワークフロー図。

GitOpsの登場

GitOpsは、クラウドネイティブアプリケーションの継続的デリバリーを実現する方法です。Gitを宣言型インフラストラクチャとアプリケーションの信頼できる唯一の情報源として利用します。Gitに変更が加えられると、デリバリーパイプラインがインフラストラクチャに変更を自動で反映します。さらに、実際の本番環境の状態を確認し、ソースと実環境が一致しない場合に通知するツールも使用します。

GitOpsでは、クラスター内でリコンシリエーションオペレーターを実行し、安全でないパイプラインの問題に対処します。オペレーターは、別々の認証情報を使って構成用のGitリポジトリを操作します。Gitリポジトリに保存されたマニフェストファイルに記述された望ましい状態と、クラスターの実際の状態を比較し、両者を一致させます。

開発者、コードリポジトリ、CI、イメージリポジトリ、クラスターオペレーター、構成リポジトリが、読み取り/書き込みおよび読み取り専用のフローで接続されたワークフロー図

これにより、境界を越えて認証情報が漏えいすることはありません。CIシステムはターゲットクラスターとは異なるセキュリティ「ゾーン」で動作できます。各パイプラインコンポーネントに必要なのは、1つの読み取り/書き込み認証情報だけです。クラスターの認証情報がクラスターの外に出ることはないため、「秘密情報は手元に置く」ことができます。

もうセキュリティを心配する必要はない?

このアプローチを採用すると、最小権限の原則や職務分掌に関する問題などを解消し、セキュリティリスクを軽減できます。もちろん、セキュリティ上の懸念がすべて解決するわけではありません。むしろ、コードリポジトリのセキュリティを確保することが、これまで以上に重要になります。

GitSecOpsの登場

わかりました。業界にはすでに流行語があふれているので、これ以上増やすのはやめましょう。とはいえ、James Governorこと@monkchipsの言うことは、遅かれ早かれ現実になることが多いものです。アイデアをありがとう、James。この記事を気に入ってもらえるとうれしいです!

コードリポジトリをより安全にするためのヒントをご紹介します。

プルリクエストにセキュリティテストを追加する

主要なコードリポジトリには、イベント駆動型の強力なフックフレームワークが備わっています。イベント発生時に、任意のサービスへHTTP POSTリクエストを送信できます。対応できるイベントは数多くありますが、段階的なコード変更をテストするうえで特に有用なのがpull_requestイベントです。

フックに対応した静的コード解析ツールは数多くあります。プルリクエストが作成されるとHTTP POSTが送信され、最新の更新をテストできます。また、コードや構成の変更がセキュリティ要件に沿っているかを確認する絶好の機会でもあります。

Snykでリポジトリを静的解析

Snykはリポジトリを静的解析し、使用している可能性のある脆弱な依存関係を検出して、修正を支援します。SnykのUIでリポジトリをテストして問題を見つけられるだけでなく、プルリクエストをテストすることで、ユーザーが新たな脆弱なライブラリを追加するのを防ぐこともできます。新たな脆弱性が持ち込まれた場合は、テストを失敗させることも可能です。

ステータスパネルには、依存関係のセキュリティチェックが1件失敗し、新たな問題が2件あることが表示されています。一方、ブランチにマージコンフリクトはありません。

GitHub、GitLab、Bitbucketとの便利なインテグレーションに加え、プルリクエストは「ビルドを失敗させる」方法よりも優れています。実際、デフォルトでは情報提供を目的としているため、マージをブロックする必要もありません。テストでは全体の結果ではなく変更点だけを確認し、変更前から存在していた脆弱性ではなく、新たな脆弱なライブラリを持ち込んだ場合にのみ失敗します。

認証情報をコードや構成ファイルに保存しない

GitHubで簡単に検索するだけでも、リポジトリにパスワードが保存されている問題がいかに広範囲に及んでいるかがわかります。この単純な検索で返された35万件のコミットには、コミットメッセージから簡単には見つけられないものや、履歴を削除して痕跡を隠そうとしたものは含まれていません。

git-secretsなどのツールを使って、コードや構成ファイルで機密情報が見つかったときにビルドを強制的に失敗させることもできます。チーム全体でこのような事態を防ぐルールを設ければ、既存の開発ワークフローにおける不適切な行為を抑止できます。

そもそもリポジトリに認証情報を入れない方法は数多くあります。できる限り多くの方法を導入するべきですが、それでも機密情報が紛れ込む可能性は常にあります。リポジトリを定期的に監査することも検討し、GitRobやtruffleHogなどのツールを活用しましょう。これらのツールはコードベースをスキャンし、パターンマッチングで機密情報を探します。

コードリポジトリに機密データを保存していた場合は、復旧のために次の対応が必要です。

  1. 公開されていたトークンやパスワードを無効にする必要があります。

  2. 秘密情報がインターネット上で公開されたら、攻撃者の手に渡ったと想定し、それに応じて対処してください。

  3. コードや監査履歴に痕跡が残らないよう、秘密情報に関する履歴をすべて削除します。

アクセスを厳格に管理する

コントリビューターに、次の基本的な対策を徹底させましょう。

  • すべてのコントリビューターに、GitHubアカウントで2要素認証を必須にする。

  • ユーザー間でアカウントやパスワードを共有させない。

  • ソースコードにアクセスできるノートパソコンやデバイスを適切に保護する。

  • 個人アカウントは、ユーザーが会社を離れても自動的に無効にならないことがよくあります。すでに一緒に働いていないユーザーのアクセス権は、確実に取り消してください。

  • リポジトリ管理者は、データへのチームアクセスを管理する必要があります。コントリビューターには、業務に必要なデータへのアクセス権だけを付与してください。

SECURITY.mdファイルを追加する

ほとんどのプロジェクトオーナーやメンテナーが、リポジトリにREADME.mdを追加するのは自然なことです。実際、READMEがないと批判されることも珍しくありません。同様に、プロジェクトのセキュリティ関連情報をまとめたSECURITY.mdファイルを追加することも、ますます一般的になっています。このファイルがあれば、ユーザーに重要なセキュリティ情報を提供できるだけでなく、メンテナー自身も脆弱性の開示や更新、一般的なセキュリティ対策への対応方法を考えることになります。SECURITY.mdファイルの優れた例は、Apache StormとTensorFlowのリポジトリで確認できます。

まとめ

CIサーバーは、メインラインへのマージ、ビルド、テストといった開発プロセスを十分にオーケストレーションできます。しかし、CIサーバーが継続的デリバリーの処理を始めると、追加のセキュリティ上の考慮事項が生じます。GitOpsでは、Kubernetesまたはクラスターが内部でトランクの更新に基づいてデプロイを管理します。これはCDの「プル」モデルとも呼ばれます。

コードだけでなく、構成や関連するスタックにとっても、Gitが唯一の信頼できる情報源になります。そのため、Gitのセキュリティはより重要になります。コードリポジトリで基本的な衛生管理を徹底すれば、さまざまな対策が可能です。たとえば、すべてのプルリクエストでSnykなどのテストツールを自動実行する、実施するセキュリティ手順を記載したSECURITY.mdファイルを作成する、秘密情報をコードに保存せずボルトを使用する、といった方法があります。

GitワークフローやCI/CDパイプラインにセキュリティを組み込むには、Snykを無料でお試しください!また、Snykの実際の動作をご覧になりたい方は、チームとの個別デモをご予約ください。