近年、エンジニア界隈でクラウド インフラストラクチャのデプロイを高速化、効率化する手段の需要が高まっていることから、Infrastructure as Code (IaC) の導入が急速に広まっています。IaC とは、インフラストラクチャの管理とプロビジョニングを、非効率な手作業ではなく、コンピューターで処理可能な言語 (つまりコード) で行うテクノロジーやプロセスを指す言葉です。たとえば Terraform や Pulumi のように、インフラストラクチャのコード化言語を統一し、異なる環境やプロバイダーにまたがって素早くクラウド オーケストレーションを実施できる言語やフレームワークがあります。また、AWS CloudFormation や Azure Resource Manager (ARM) など、毎回手作業が必要であったプロビジョニング プロセスを拡張と繰り返しが可能で一貫性のあるプロセスに転換するネイティブ IaC フレームワークも、クラウド プロバイダーから提供されています。

IaC でクラウド セキュリティを開発に組み込む

IaC はインフラストラクチャのデプロイを開発段階に組み込む手法であり、従来とは異なり、クラウド環境の自動化、スケール、保護が可能になります。

IaC 以前の手法では、クラウドのセキュリティは事後対応にならざるを得ませんでした。その方法は、実行中にポリシー違反がないかどうかリソースを監視するというものでした。こうしたアプローチでは、たとえ自動化を導入したとしてもエンジニアは問題が起きてから特定しなければならず、時間と労力がかかってしまいます。しかし、コード化したクラウド インフラストラクチャを開発ライフサイクルに組み込めば、クラウド上のセキュリティに対して予防措置を講じられるようになります。

IaC の導入により、コンテナや依存関係のスキャン、SAST、DAST などと合わせてセキュリティのベスト プラクティスを適用できます。ただし、IaC のセキュリティの効果を真に発揮するには、自動 CI パイプラインに組み込まなければなりません。

CI/CD のセキュリティのベスト プラクティスについては、「CI/CD のセキュリティと DevSecOps の完全ガイド」(英語) をご覧ください。

IaC にセキュリティを適用するには

さて、AWS や Google Cloud、Azure、Kubernetes などのリソースのビルドに使用するインフラストラクチャについて、ポリシー違反や構成ミスを検出するにはどうすればよいのでしょうか。その答えは、”IoT セキュリティ検査ツールを CI パイプラインに組み込む” です。たとえば、Bridgecrew なら、インフラストラクチャを継続的にスキャンして既知のセキュリティの脆弱性を特定し、脆弱性の修復用コードを提供します。例として、見落とされがちな次のポリシーを考えてみましょう。

  • S3 バケットに保存する全データは、保存中は確実に暗号化する
  • いずれのセキュリティ グループでも、0.0.0.0:0 からポート 22 への出力を許可しない
  • 起動設定の EBS ボリュームに保存する全データを確実に暗号化する

ローカルで IaC のスキャンを行い、これらのポリシーに違反がないか調べるために、ビルド環境に適した Bridgecrew をインストールしてみましょう。

## Standard installation
pip install bridgecrew

## Installation on Linux / Mac distros where `python` references python2
## (this is usually the case - run `python --version` to verify)
pip3 install bridgecrew

## Installation on Alpine
pip3 install --upgrade pip && pip3 install --upgrade setuptools\npip3 install bridgecrew

## Installation using homebrew (MacOS only)
brew tap bridgecrewio/bridgecrew https://github.com/bridgecrewio/bridgecrew\nbrew update\nbrew install bridgecrew

## Installation on Windows (ensure you add the cmd file to your path)
pip install bridgecrew\n
echo %PATH%\n
cd C:\\Users\\<my_username>\\AppData\\Local\\Microsoft\\WindowsApps\n
curl -o bridgecrew.cmd https://raw.githubusercontent.com/bridgecrewio/bridgecrew/master/bin/bridgecrew.cmd

次に、Bridgecrew の無料アカウントに登録して、一意の API トークンを取得してから、ローカルのディレクトリまたはファイルをスキャンします。

##directory
- bridgecrew -d <directory> --bc-api-key <key> --repo-id <repo_id> --branch <branch>

##file
- bridgecrew -f <file_1> <file_2> ... <file_n> --bc-api-key <key> --repo-id <repo_id> --branch <branch>

Bridgecrew からコマンド ラインに次の結果が返され、それぞれのポリシーに合格したかどうかが示されます。

_          _     _                                    
| |__  _ __(_) __| | __ _  ___  ___ _ __ _____      __ 
| '_ \| '__| |/ _` |/ _` |/ _ \/ __| '__/ _ \ \ /\ / / 
| |_) | |  | | (_| | (_| |  __/ (__| | |  __/\ V  V /  
|_.__/|_|  |_|\__,_|\__, |\___|\___|_|  \___| \_/\_/   
                     |___/                              
                                      
by bridgecrew.io | version: 1.0.455

terraform scan results:

Passed checks: 2, Failed checks: 1, Skipped checks: 0

Check: "Ensure all data stored in the S3 bucket is securely encrypted at rest"
PASSED for resource: aws_s3_bucket.foo-bucket
File: /example.tf:1-25

Check: "Ensure the S3 bucket has access logging enabled"
PASSED for resource: aws_s3_bucket.foo-bucket
File: /example.tf:1-25

Check: "S3 Bucket has an ACL defined which allows public access."
FAILED for resource: aws_s3_bucket.foo-bucket
File: /example.tf:1-25

1 | resource "aws_s3_bucket" "foo-bucket" {
2 | region = var.region
3 | bucket = local.bucket_name
4 | force_destroy = true
5 |
6 | tags = {
7 | Name = "foo-${data.aws_caller_identity.current.account_id}"
8 | }
9 | versioning {
10 | enabled = true
11 | }
12 | logging {
13 | target_bucket = "${aws_s3_bucket.log_bucket.id}"
14 | target_prefix = "log/"
15 | }
16 | server_side_encryption_configuration {
17 | rule {
18 | apply_server_side_encryption_by_default {
19 | kms_master_key_id = "${aws_kms_key.mykey.arn}"
20 | sse_algorithm = "aws:kms"
21 | }
22 | }
23 | }
24 | acl = "public-read"
25 | }

上記出力では、2 つの検査に合格していますが、”S3 Bucket has an ACL defined which allows public access” の検査は不合格となっています。今回は、検査をローカル環境において手動で行いました。しかし、業界におけるセキュリティのベスト プラクティスやコンプライアンスのベンチマークをすべて網羅するには、IaC でセキュリティのスキャンを自動化するしかありません。

Bridgecrew で IaC のセキュリティ検査を自動化する

IaC セキュリティ検査を効率的かつ行動に役立つものにするには、一貫性のあるフィードバックが得られるようにする必要があります。このような一貫性を確保する一番の方法は、IaC セキュリティ検査を自動 CI パイプラインに組み込むことです。

たとえば、Bridgecrew orb を使用すると、CircleCI に Bridgecrew を組み込むことができます。CircleCI 環境変数 BC_API_KEY を新しく追加し、先ほど取得した API トークンを設定します。そして、ビルドのたびに Bridgecrew のスキャンをトリガーするように、CircleCI ワークフローを設定します。完成した .circleci/config.yml は、次のようになります。

version: 2.1
orbs:
    bridgecrew: bridgecrew/bridgecrew@1.0.3
jobs:
    build:
      executor: bridgecrew/default
      steps:
        - checkout
        - bridgecrew/scan:
            directory: ‘.’
            api-key-variable: BC_API_KEY

設定ファイルに Bridgecrew orb を追加すると、指定した IaC ディレクトリに対して、コンプライアンス ポリシー数百個について違反がないかどうかの検査が行われます。 オプションとして、ポリシー違反が検出されると CircleCI のビルドが失敗するように設定することもできます。

さらに、Bridgecrew プラットフォームにアクセスすれば、重大度やカテゴリ、コンプライアンス ベンチマーク別にインシデントを詳しく調べることも可能です。このプラットフォームでは、問題を分析してその影響度や関係するリソースを確認し、調査結果に応じてコードを修正できます。

プル リクエストを統合すれば、修正したコードを即座に VCS へプッシュし、マージしてビルドをやり直すことができます。プロビジョニング済みのクラウド リソースに不適切な構成がデプロイされないようにするには、このように継続的なワークフローを用意することが最適です。 🙌

まとめ

IaC は非常に強力なツールであり、クラウドネイティブ型のチームに導入すれば、今あるインフラストラクチャに別次元のスピードやスケーラビリティ、コスト節約、そしてセキュリティが加わります。IaC の本質は不変性にあります。IaC セキュリティ検査を自動化することで、この性質を活かし、時間を節約しながらクラウド セキュリティ対策を強固にすることができます。