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
を作成します。
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
を作成します。
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」を指定して抑制していきます。
RulesToSuppress:
- id: F2000
reason: "no operational problems"
cfn_nag_scan
コマンドに--deny-list-path <抑制の定義が書かれたファイルへのパス>
を追加すれば読み込んでくれます。
- 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