Snykインテグレーションを使ったAWSの脆弱性スキャン
2021年2月10日
0 分で読めますAWSのKubernetes関連ツール群をお使いなら、Amazon Elastic Container Registry(ECR)とAmazon Elastic Kubernetes Service(EKS)のインテグレーションを通じて、Snykでワークフローに直接スキャンを組み込めます。さっそく始めましょう!
この記事では、Snykのテスト用アプリケーションを使ってアプリケーションをビルド、デプロイします。コードはこちらから入手できます。また、次の依存ツールをインストールしておく必要があります。
さっそく始めましょう
準備が整ったところで、始めましょう!
まず、Snykがリポジトリにアクセスできるよう、ECRを設定します。そのために、AWS Identity and Access Managementでポリシーとロールを割り当てます。これにより、Snykのバックエンドに適切な権限を付与し、ECRリポジトリ内のイメージの一覧表示や取得などを行えるようにします。
インテグレーションの設定手順はSnykのドキュメントにすべて記載されていますが、必要な設定情報はSnykのUIから直接確認できます。Settings/Integrations/ECR/Edit Settingsに移動し、まずUIに表示されるJSONを使ってポリシーを設定します。
- oriこの設定により、JSONのActionセクションで定義された権限が、ECRアカウント内で指定したすべてのリポジトリとイメージに対してSnykに付与されます。これは、リポジトリとイメージの一覧表示、およびリポジトリからのイメージ取得に必要な最小限の権限です。手順に従って、このJSONをAWSのIAMポリシー設定に追加してください。
次に、ロールを追加し、手順に記載されているポリシーをそのロールに割り当てます。

また、ロールを利用できるSnyk組織IDを指定して、ロールの適用範囲を設定する必要があります。新しく作成したロールの信頼関係を、ドキュメントに記載されたJSONで編集します。sts:ExternalIdの文字列にはSnyk組織IDを指定します。このJSONスニペットは、指定されたExternalIdがSnyk組織IDと一致する場合に、AWSプリンシパルがロールを引き受けられるようにするものです。
手順に記載されているように、このポリシーに複数のSnyk組織を追加する場合は、角括弧で囲んだJSON配列として追加します。
Snyk組織IDは、Settings > Generalに移動すると確認できます。
![組織名、APIキー、組織IDの各フィールドが表示された、[一般]タブの設定ページ。](https://res.cloudinary.com/snyk/image/upload/f_auto,w_1240,q_auto/v1630414078/wordpress-sync/blog-snyk-organization-id.png)
最後に、SnykのUIでこのロールを使ってECRに接続するよう設定します。Settings/Integrations/ECR/Edit Settingsに戻り、ECRを設定したリージョンと、先ほど作成したロールを入力します。

これでECRインテグレーションの設定は完了です。次に、動作を確認しましょう。
まず、AWS CLIを使ってECRにリポジトリを作成します。
ECRにリポジトリができたので、そこにプッシュできるようDockerを設定しましょう。
このコマンドはログインパスワードを出力し、それをDocker CLIに渡してAWS ECRレジストリに対して認証します。ECRを有効にしたAWSリージョンを正しく指定してください。
次に、テスト用アプリケーションを確認します。これは多くの脆弱性を含むシンプルなNode.jsアプリケーションで、DockerでのビルドとKubernetesへのデプロイに必要な設定も含まれています。
まず、Dockerを使ってアプリケーションをビルドします。
イメージのビルドが完了すると、ローカルのDockerリポジトリに表示されます。
上流のECRリポジトリにプッシュする前に、タグを付けます。リポジトリ名は、先ほどECRで設定したものに置き換えてください。
これでECRにプッシュできます。
プッシュが完了したら、ECRリポジトリでプッシュしたイメージを確認できます。
イメージがECRに格納されたら、Snykでスキャンするよう設定できます。SnykのUIでAdd Projectを選択し、ECRアイコンに移動します。

ECRの設定が正しければ、ECRで利用可能なすべてのリポジトリと、それぞれに含まれるイメージが表示されます。

先ほど作成したgoofリポジトリが表示され、その中にイメージタグが1つあります。イメージを選択し、Add selected repositoriesボタンをクリックします。SnykがECRからリポジトリをインポートし、スキャンとモニタリングを開始します。
インポートが完了すると、SnykのProjectsページに表示されます。

Snykはイメージ自体に加えて、イメージ内にデプロイされたNodeアプリケーションが使用するpackage.jsonも検出し、それぞれのプロジェクトを作成しています。
イメージ自体は古く脆弱なベースイメージを使用しています。Snykは多数の脆弱性を検出し、脆弱性の総数を減らせるベースイメージを推奨します。

package.jsonには、アプリケーションに含まれるNodeパッケージが定義されています。package.jsonファイルで指定されている直接依存パッケージと、依存関係を通じて含まれる間接依存パッケージの両方が対象です。Snykはこれらすべてのパッケージの依存関係ツリーを作成し、脆弱性データベースを照会して、使用されている特定のバージョンに存在する脆弱性を検出します。このアプリケーションは脆弱なバージョンを使うよう設計されているため、多数の脆弱性が表示されます。

個々の脆弱性に関する情報や、修正のためにアップグレードすべきパッケージについてのアドバイスも確認できます。SnykのUIで提供される情報をぜひ詳しくご覧ください。
EKSとのSnykインテグレーションを設定する
次に、Elastic Kubernetes ServiceとのSnykインテグレーションを設定します。Kubernetesインテグレーションは有料プランで提供されるため、設定にはSnykのいずれかのスタンダードプランの無料トライアルが必要です。
そのために、EKSを使ってKubernetesクラスターを作成しましょう。方法はいくつかありますが、最も簡単な方法の1つはeksctlツールを使うことです。
まずAWS CLIを使って、必要に応じてクラスターのノードにSSH接続するためのキーペアを作成します。
次にeksctlを使って、us-west-2リージョンにmattjarvis-skoというクラスターを作成します。Linuxノードのマネージドノードグループを使用し、キーペアを追加します。
% eksctl create cluster --name mattjarvis-sko --region us-west-2 --with-oidc --ssh-access --ssh-public-key SKO_demo --managed
このコマンドの完了には時間がかかりますが、完了するとEKSクラスターが利用可能になり、kubectlもクラスターと通信できるように設定されます。
EKSクラスターが稼働したら、アプリケーションをデプロイするためのKubernetes設定を確認しましょう。goofアプリケーションのGitチェックアウトにはmanifestsディレクトリがあり、2つのKubernetes YAMLファイルが含まれています。
goof-deployment.yamlでは、goofアプリケーションと、依存関係として必要なmongodbポッドを定義しています。imageセクションは、先ほど設定したECRリポジトリを使うように変更してください。
goof-service.yamlでは、mongodbサービスを定義し、ポート27017でmongodbポッドに接続できるようにします。これにより、goofアプリケーションがデータベースに接続します。また、実行中のアプリケーションへの外部接続を可能にする、外部向けのLoadBalancerサービスも定義しています。LoadBalancerの実装はクラスターをデプロイするプラットフォームによって異なります。AWSではElastic Load Balancerがプロビジョニングされ、外部ポート80からgoofポッドのポート3001(Node.jsアプリケーションが動作するポート)に接続します。
それでは、アプリケーションをクラスターにデプロイしましょう。
EXTERNAL-IPフィールドのURLは、LoadBalancerサービスの一部としてプロビジョニングされたELBから提供されます。このURLを使って、実行中のアプリケーションを表示できます。ブラウザーでアクセスすると、goofアプリケーションが動作していることを確認できます。

これでアプリケーションはEKSクラスターにデプロイされ、実行されています。最後に、SnykとEKSクラスターを連携させ、本番環境で稼働するワークロードをスキャンできるようにします。SnykのKubernetesインテグレーションは、Kubernetesの単一ポッドで動作するオペレーターで構成されます。Kubernetes APIに問い合わせて、クラスター内のコンテナイメージをスキャンし、Snykのバックエンドと通信します。
CloudFormationでEKSクラスターをデプロイする場合は、SnykインテグレーションをデプロイするためのAWSクイックスタートを利用できます。今回はデモでeksctlを使うため、手動でインストールする手順を見ていきましょう。
最初に、Snyk Kubernetes MonitorをデプロイするHelmチャートを含むHelmリポジトリを追加します。
次に、Snyk Monitor用の独立した名前空間を作成します。Kubernetesでは、アプリケーションごとに名前空間を分けるのが一般的なベストプラクティスです。権限をより細かく制御できるためです。
次に、SnykのintegrationIDを含むシークレットをKubernetesに作成します。これは、Snyk Monitorのプロセスが上流のSnyk APIと通信し、クラスター内で稼働するポッドの情報をSnykに送るために使われます。イメージの取得時にログインが必要なプライベートレジストリを使う場合は、認証情報もdockercfg.jsonセクションに渡す必要があります。詳しくはSnyk Monitorのドキュメントをご覧ください。
シークレットを作成したら、Helmを使ってsnyk-monitor名前空間にSnyk Monitorをインストールします。
Helmチャートの処理が完了すると、クラスターのsnyk-monitor名前空間でsnyk-monitorポッドが実行されていることを確認できます。
ログを表示して、snyk-monitorからSnykにデータが送信されていることも確認できます。
MonitorからSnykにデータが送信されるまで、ワークロードがSnykのUIに表示されるまで少し時間がかかることがあります。1分ほど経つと、Add Project/Kubernetesに移動して、クラスター内で稼働しているワークロードを確認できます。

稼働中のワークロードが表示されます。追加するには、チェックボックスを選択してSnykにインポート、テストさせるだけです。

プロジェクトをインポートしたら、Projectsページに移動して、インポートしたプロジェクトの詳細を確認できます。まず注目したいのは、Snykがワークロードの実行時設定を検出し、その設定にセキュリティ上の問題がないかチェックしていることです。ここでは、root権限で実行されていることやCPU制限が設定されていないことなど、複数のセキュリティテストに失敗しています。

ワークロード自体を確認すると、Snykがベースイメージとそのイメージに含まれるすべての脆弱性を検出し、脆弱性への露出が少ない代替ベースイメージを推奨していることが分かります。

まとめ
このデモでは、ソフトウェア開発ライフサイクル全体にセキュリティテストを組み込み始める方法を紹介しました。これは、クラウドネイティブ環境でワークロードとインフラストラクチャのセキュリティを維持するための重要な戦略です。
Snykはさまざまな統合開発環境、ソースコード管理ツール、CI/CDシステムとも連携できるため、デプロイパイプライン全体をカバーできます。
AmazonのコンテナおよびKubernetesサービスをお使いの場合、ECRとEKSの両方にSnykを簡単に連携できます。CloudFormationテンプレートを使ってすべてをデプロイするためのAWSクイックスタートも用意されています。Snykの無料アカウントに登録して、ぜひお試しください!
Capture the Flagを始めよう
オンデマンドのバーチャル入門ワークショップを見て、Capture the Flagの課題の解き方を学びましょう。



