Help us understand the problem. What is going on with this article?

CloudFormationテンプレートのセキュリティ的な問題を開発プロセスの初期段階から警告しよう

CloudFormation を使用することで、AWS のリソースを素早くプロビジョニングできます。また、yaml 形式のテンプレートファイルで記述することにより、インフラ開発者はどのリソースが作成されるのかを宣言的に管理できます。
開発者は AWS リソースをすばやく簡単に作成できますが、安全でないリソースもすばやく作成できてしまいます。「安全でない」とは、TCP ポートを世界中に公開したり、特定の IAM ユーザーにフル権限を与えてしまうことでセキュリティ的に問題があるリソースを作り出してしまうことを意味しています。

以前、CircleCI MeetUp で CloudFormation を静的構文解析する話をしました。
CloudFormation を静的構文解析することにより、セキュリティ的に問題があったり、命名規則に従っていないリソースに対して警告できます。このようにポリシー違反を検知する仕組みを作ることで、AWS リソースを構築する前にセキュリティ的な問題を対応できるようになります。

ただしルールを全て自作したり、セキュリティ的に問題がある箇所を洗い出す作業は非常に面倒です。

今回はそんなケースに有効な cfn-nag というツールを紹介します。

cfn-nag はセキュリティ的に問題がある CloudFormation のテンプレートを警告できるツールです。cfn-Python-lint と並んで CI のプロセスに組み込むことができます。

cfn-nag のインストール

cfn-nag は Ruby 製のツールです。Gem としてインストールしましょう。

gem install cfn-nag

cfn-nag の使用方法

以下のようなテンプレートを例に取り上げます。
外部から 80 番ポートで TCP 通信することを許可するセキュリティグループを作成しようとしています。

template.yaml
  SecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      VpcId: !Ref VpcId
      GroupDescription: security group
      SecurityGroupIngress:
        - IpProtocol: "TCP"
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
          Description: "All"

このテンプレートに対して cfn-nag を実行してみましょう。

$ cfn_nag template.yaml
------------------------------------------------------------
template.yaml
------------------------------------------------------------------------------------------------------------------------
| WARN W9
|
| Resources: ["SecurityGroup"]
| Line Numbers: [9]
|
| Security Groups found with ingress cidr that is not /32
------------------------------------------------------------
| WARN W2
|
| Resources: ["SecurityGroup"]
| Line Numbers: [9]
|
| Security Groups found with cidr open to world on ingress.  This should never be true on instance.  Permissible on ELB
------------------------------------------------------------
| FAIL F1000
|
| Resources: ["SecurityGroup"]
| Line Numbers: [9]
|
| Missing egress rule means all traffic is allowed outbound.  Make this explicit if it is desired configuration

Failures count: 1
Warnings count: 2

2つの Warnings, 1 つの Failure, 合計 3 つの警告がでました。

  • Warnings: ingress ルールで/32 からのアクセスを許可していること
  • Warnings: ingress ルールが全世界に向けて全開放していること
  • Failures: egress ルールがついていないこと

cfn-nag のルールを許容する

cfn-nag の警告を確認すると確かにセキュリティ的にはあまりよくないルールになっていますね。

ただし、実際にこのようなセキュリティグループを使用することはよくあります。たとえばチームとして egress ルールは全許可にしていても良いなどのルールを決めている。あるいはパブリックユーザ向けの Web サービスの場合、特定のポート番号(例えば 443)で ingress ルールを全世界に向けて全開放することは一般的です。

このような場合は、許容するルールを Metadata に記載しておきましょう。

template.yaml
  SecurityGroup:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      VpcId: !Ref VpcId
      GroupDescription: security group
      SecurityGroupIngress:
        - IpProtocol: "TCP"
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
          Description: "All"
    Metadata:
      cfn_nag:
        rules_to_suppress:
          - id: W9
            reason: "このセキュリティグループはEC2には付与しない。ELBに付与して使用する"
          - id: W2
            reason: "このセキュリティグループはEC2には付与しない。ELBに付与して使用する"
          - id: F1000
            reason: "egressルールには制限を課しません"

このようにしておくことで警告を無視できます。

$ cfn_nag template.yaml
------------------------------------------------------------
template.yaml
------------------------------------------------------------
Failures count: 0
Warnings count: 0

開発環境に組み込む(VSCode の場合)

VSCode には cfn-nag の拡張機能(プラグイン)が提供されています。
こちらからインストールしておきましょう。

Format On Save の項目にチェックを入れておくと、ファイルを保存した時に自動的に cfn-nag が実行されます。

image.png

このようにすることで早い段階でセキュリティ的に問題があるテンプレートを見つけることができるようになりました。

image.png

CI に組み込む(CircleCI の場合)

さらにCIのプロセスにも組み込んでおくと安心です。CircleCI の場合は以下のような感じでしょうか。
実際のユースケースに合わせて bundler で管理することもあるかと思います。

circleci/config.yml
version: 2
jobs:
  build:
    docker:
      - image: circleci/ruby:2.6.0-node-browsers-legacy
    working_directory: ~/repo
    steps:
      - checkout
      - run: gem install cfn-nag
      - run: cfn_nag template.yaml
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away