おい、ちょっと手を止めてこっちを向いてくれ。
クラウド移行を進める現場で、こんな会話をよく耳にする。「Terraformで綺麗にインフラをコード化したから、インフラの品質は担保されている」「CloudFormationのテンプレートがあるからレビューもバッチリだ」――。
甘い。実務の現場をいくつも修羅場をくぐり抜けてきた俺から言わせれば、その「コード化されたインフラ」こそが、攻撃者にとっての黄金の扉になっているケースが多々ある。人間が書く以上、IAMの権限設定ミスや、S3バケットの公開設定のうっかりミス(Public Read)は必ず紛れ込む。しかも、それが一瞬でクラウド全体にデプロイされてしまうのがIaCの恐ろしさだ。
今回は、デプロイボタンを押してから冷や汗をかくような失態を犯さないために、CI/CDパイプラインに静的解析(Checkov等)を組み込み、「本番環境にゴミや爆弾を絶対に到達させない」ための実践的アプローチを叩き込む。
—
なぜ、IaCのレビューだけでは防げないのか?
GitHubのPull Requestでコードレビューをしているから大丈夫? 残念ながら、人間の目は「S3バケットのポリシーの細部」や「セキュリティグループの 0.0.0.0/0 からの全開放」をいとも簡単に見落とす。疲弊した金曜日の夕方、急ぎのリリースプルリクエストならなおさらだ。
攻撃者はそこを突く。彼らは脆弱なTerraformテンプレートが誤ってリポジトリにプッシュされた瞬間を狙っている。例えば、以下のような設定が混入していたとする。
# 【危険なアンチパターン】すべてを許可してしまったIAMポリシー
resource "aws_iam_policy" "dangerous_policy" {
name = "over_permissive_policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "*"
Effect = "Allow"
Resource = "*"
}
]
})
}
こんなコードがmainブランチにマージされ、適用されたが最後、クラウド環境全体が乗っ取られる。これを手動や目視で見つけるのは、広大な砂漠で針を探すようなものだ。だからこそ、機械(静的解析ツール)に強制的にチェックさせ、基準を満たさないコードはビルドすらさせない仕組みが必要になる。
—
Checkovを用いたCI/CDパイプラインへの静警備の導入
ここで登場するのが、オープンソースのIaC静的解析ツール Checkov だ。Terraform、CloudFormation、Kubernetesマニフェストなど、あらゆるIaCフォーマットをスキャンし、CISベンチマークやAWSウェルアーキテクテッドに基づいたセキュリティ違反を検知してくれる。
日々の開発フローを止めることなく、GitHub Actions等のCI/CDパイプラインにこれを組み込む具体的な設定を見ていこう。
1. GitHub Actionsワークフローの設定例
以下のワークフローを .github/workflows/iac-security.yml としてリポジトリに配置する。これにより、PRが作成された段階で自動的にIaCのセキュリティスキャンが走り、重大な脆弱性(HIGHやCRITICAL)が見つかればビルドを即座に失敗させる。
name: IaC Security Scan (Checkov)
# プルリクエスト作成時またはmainブランチへのプッシュ時に実行
on:
pull_request:
branches:
- main
push:
branches:
- main
jobs:
checkov-scan:
runs-on: ubuntu-latest
name: Run Checkov Static Analysis
steps:
# リポジトリのコードをチェックアウト
- name: Checkout Code
uses: actions/checkout@v3
# Python環境のセットアップ
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
# Checkovのインストール
- name: Install Checkov
run: |
pip install --upgrade pip
pip install checkov
# Terraformコードに対してCheckovを実行
# --soft-fail をあえて外すことで、脆弱性検知時にCIを失敗(FAIL)させる
- name: Run Checkov on Terraform
run: |
checkov -d ./terraform --framework terraform --output cli
この設定のミソは、--soft-fail をつけていない点だ。セキュリティ要件を満たさないコードが含まれている場合、Exitコードが非ゼロになり、GitHub上で「Merge Button」が赤くロックされる。開発者はマージする前にコードを修正せざるを得なくなるというわけだ。
—
現場で即効性のあるセキュアなTerraform実装サンプル
では、先ほど挙げた危険なIAMポリシーをどう修正すべきか。最小権限の原則(Principle of Least Privilege)に基づき、必要なリソースとアクションだけに絞ったセキュアなTerraformコードの書き方を共有する。
以下のコードは、特定のS3バケットに対する読み取り権限のみを許可する、Checkovのチェックも一発でクリアするセキュアな実装例だ。
# 【セキュアな実装例】最小権限の原則に基づいたIAMポリシー
data "aws_iam_policy_document" "secure_s3_read_doc" {
statement {
sid = "AllowSpecificS3ReadAccess"
effect = "Allow"
# ワイルドカード「*」を避け、必要なアクションのみを定義
actions = [
"s3:GetObject",
"s3:ListBucket"
]
# リソースも対象のバケットとその配下に限定する
resources = [
"arn:aws:s3:::my-secure-app-bucket",
"arn:aws:s3:::my-secure-app-bucket/*"
]
}
}
resource "aws_iam_policy" "secure_policy" {
name = "secure_s3_read_policy"
description = "最小権限に基づいた安全なS3読み取りポリシー"
policy = data.aws_iam_policy_document.secure_s3_read_doc.json
}
このように、Action = "*" や Resource = "*" といった怠惰な記述を排除し、具体的なスコープを定義する。これを静的解析ツールが常時監視することで、セキュリティインシデントの芽をデプロイ前に完全に摘み取ることができるのだ。
—
セキュリティチーフからの現場の心得
ツールを導入すれば、それで万全というわけではない。セキュリティは「ツール+プロセス+人間の意識」の三位一体で初めて機能する。
もしチームメンバーから「Checkovの警告がうるさくて開発スピードが落ちる」という不満が出たら、それはチャンスだ。なぜその警告が出ているのか、その裏にあるリスク(例えば、S3のパブリックアクセスが万が一許可された場合のデータ漏洩リスク)をチームで共通言語として持てるようにリードしてほしい。
ルールを厳しくしすぎても開発が止まる。だが、ガバナンスを緩めればいつか会社が傾くようなインシデントを踏む。その絶妙なバランスを取りながら、自動化されたガードレールを敷き続けるのが、我々プロフェッショナルなエンジニアの仕事だ。
さあ、今すぐ手元のリポジトリのCIパイプラインを確認してくれ。あなたのクラウド環境を守れるのは、他の誰でもなく、今このコードを書いているあなた自身なのだから。
コメント