🦍

CI/CDパイプラインにcfn-nagを統合: GitHub ActionsでCloudFormationをセキュアに

に公開

はじめに

言わずもがなですが、AWSリソースを作成して運用が始まった後に、リソースに脆弱性が見つかった場合、直すのは簡単ではありません。リソース作成時に考慮しておけば、数分から~数時間で修正できるものが、リリース後には必要工数が数倍から数十倍に跳ね上がることも少なくないと思います。例えば、セキュリティグループの設定ミスで外部から不正アクセスが可能になった場合、修正には多大な時間とコストがかかります。
少しでもこういった対応を減らしていくためには、事前予防が大事ですよね。そういった意味でcfn-nagを用いたセキュリティチェックをGitHub ActionsのCI/CDプロセスに組み込んでいこうと思います。

実装

以下のような構成で実装します。

actions
   ├── .github
   │   └── workflows
   │       └── cfn-nag.yaml
   └── cloudformation-templates
       └── create_iam_user.yml

①ワークフローの作成

actions/.github/workflows/cfn-nag.yamlを作成します。

actions/.github/workflows/cfn-nag.yaml
name: CloudFormation Security Check

on: [push, pull_request]

jobs:
  security_check:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.3'

      - name: Install cfn-nag
        run: gem install cfn-nag

      - name: Run cfn-nag
        run: cfn_nag_scan --input-path ./cloudformation-templates/

cfn_nag_scanコマンドを使い、セキュリティチェックを実行します。

②動作確認用のCloudFormationテンプレートを作成

actions/cloudformation-templates/create_iam_user.ymlを作成します。

actions/cloudformation-templates/create_iam_user.yml
Resources:
  MyIAMUser:
    Type: AWS::IAM::User
    Properties:
      UserName: MyUser

テストとして、IAMユーザーを作成するだけのテンプレートを用意しました。

動作検証

①②を作成した上で、GitHubにpushしてみました。するとGitHub Actionsが実行されて以下のようなエラーを吐いてくれました。しっかり実行できているようです!

------------------------------------------------------------
./cloudformation-templates/create_iam_user.yml
------------------------------------------------------------------------------------------------------------------------
| FAIL F2000
|
| Resource: ["MyIAMUser"]
| Line Numbers: [3]
|
| User is not assigned to a group

Failures count: 1
Warnings count: 0

このエラーメッセージは、cfn-nagがCloudFormationテンプレートcreate_iam_user.ymlをチェックした結果、MyIAMUserリソース(IAMユーザー)がIAMグループに割り当てられていないことを検出したことを示しています。
cfn-nagは、IAMユーザーがグループに割り当てられていない場合、セキュリティ上のベストプラクティスに違反していると判断し、エラーとして報告するようです。

ただし、こうしてエラーとして検出されますが、これは開発者としては意図した状態であり、運用上問題ない場合もあるかと思います。次にこれを「抑制」する方法を試したいと思います。今回は別ファイルとして定義ファイルを用意して読み込ませる方針でいきます。

過検知の抑制

今回は/settings/cfn-nag_deny_list.ymlというファイルを作成しました。(ファイルを置く場所やファイル名に特別な制限はありません。)
今回のcfn-nagに指摘されていた「id:F2000」を指定して抑制していきます。

actions/settings/cfn-nag_deny_list.yml
 RulesToSuppress:
   - id: F2000
     reason: "no operational problems"

cfn_nag_scanコマンドに--deny-list-path <抑制の定義が書かれたファイルへのパス>を追加すれば読み込んでくれます。

actions/.github/workflows/cfn-nag.yaml
      - name: Run cfn-nag
        run: cfn_nag_scan --input-path ./cloudformation-templates/ --deny-list-path ./settings/cfn-nag_deny_list.yml

再び実行してみると、以下のように検出されなくなりました。

------------------------------------------------------------
./cloudformation-templates/create_iam_user.yml
------------------------------------------------------------
Failures count: 0
Warnings count: 0

おわりに

cfn-nagをCI/CDパイプラインに組み込むことで、IAMポリシーの過剰な権限や、セキュリティグループの開放設定など、セキュリティリスクの高い設定を未然に防ぎ、安全なインフラ環境を構築できることを期待しています。

Discussion