3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Lambdaでセキュリティグループを自動更新する(CloudFront用)

Last updated at Posted at 2019-09-03

CloudFrontのIPがよく変更されるので、自動でセキュリティグループを変更してくれるバッチを作成しました。
CloudFrontのIPレンジはAWSがjson形式で公開しているので、これをベースに作成します。
※CloudFrontはエッジロケーションとリージョナルエッジキャッシュの2つがあります。

#CloudFront+ALBのアクセス制御方法
たくさんあるのでこちらにわかりやすくまとまってます。
よくあるパターン

  1. ALBにWAFを入れてアクセス制御
  2. CloudFrontにカスタムヘッダ付与+ALBのルールでアクセス制御
  3. セキュリティグループで制限

今回は3つめのCloudFrontからのアクセスをセキュリティグループで制御してみます。

こちらに私が改修したプログラムがあるのでそれを使います。

#SecurityGroupによるアクセス制御方法
##実行環境
LambdaとSNSを使います。
SNSをトリガーとし、lambdaを動かし、実行結果をSNSのメールとして通知します。

##事前準備
###セキュリティグループの作成とタグ付け
以下のセキュリティグループを4つ作成して、下記のタグをつけます。
Name:cfnt_global_http, cfnt_global_https, cfnt_region_http, cfnt_region_https
AutoUpdate:true
Protocol:http or https
※ルールは空で大丈夫です

###IAMポリシー
Lambda用ロールを作成し、ポリシーをアタッチ

Policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:RevokeSecurityGroupIngress"
            ],
            "Resource": "arn:aws:ec2:[region]:[account-id]:security-group/*"
        },
        {
            "Effect": "Allow",
            "Action": "ec2:DescribeSecurityGroups",
            "Resource": "*"
        },
        {
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": "sns:Publish",
            "Resource": "*"
        }
    ]
}

##実行環境作成
###Lambda
実行環境:Python2.7
ソースはGithubで公開しています。
https://github.com/ytatsuya-private/update-cloudfront-sg
インスタンスは一番小さいものを選択。
タイムアウトは30秒程度あれば十分です。
作成したロールをアタッチ
GitHubから落としてきたプログラムのTOPIC_ARN定数にSNS完了通知用のARNを記載する。

###SNS
・完了通知用
通知用としてトピックを作成し、サブスクリプションで通知先アドレスを入力

・トリガー用
トリガーにSNSを選択し、下記ARNを指定して追加を実行する。
arn:aws:sns:us-east-1:806199016981:AmazonIpSpaceChanged

##テスト準備
lambdaで仮にAWSからの通知が来た場合を想定して実行してみましょう。

Lambda関数の「テスト」をクリックし、下記ポリシーを貼り付け、作成をクリック

テストコード
{
  "Records": [
    {
      "EventVersion": "1.0",
      "EventSubscriptionArn": "arn:aws:sns:EXAMPLE",
      "EventSource": "aws:sns",
      "Sns": {
        "SignatureVersion": "1",
        "Timestamp": "1970-01-01T00:00:00.000Z",
        "Signature": "EXAMPLE",
        "SigningCertUrl": "EXAMPLE",
        "MessageId": "00a95725138f2348131821c6987b5966",
        "Message": "{\"create-time\": \"yyyy-mm-ddThh:mm:ss+00:00\", \"synctoken\": \"0123456789\", \"md5\": \"00a95725138f2348131821c6987b5966\", \"url\": \"https://ip-ranges.amazonaws.com/ip-ranges.json\"}",
        "Type": "Notification",
        "UnsubscribeUrl": "EXAMPLE",
        "TopicArn": "arn:aws:sns:EXAMPLE",
        "Subject": "TestInvoke"
      }
    }
  ]
}

##テスト実行
このテストコードで初回実行した際に、MessageIDが異なります、という形でエラーが起きるので、テストコードのMessageIdとMessageにある文字を書き換えます。
上のコードでいう「00a95725138f2348131821c6987b5966」にあたります。

書き換え後、保存して再度テスト実行すると上手く動くようになります。

update-sg01.png

メール通知も来ています
update-sg02.png

#注意点
トリガーとなるAmazonIpSpaceChangedですが、こちらはAWS全てのリソースのIPの変化を通知するので、プログラムを書き換えて使う方は注意してください。
またテスト時は設定するインバウンドルールを1つ以上削除し、ルールが更新される状態に変更してからテストを実施してください。セキュリティグループの更新が無い場合は、メールを通知しない仕組みにしているためです。

参考
https://github.com/aws-samples/aws-cloudfront-samples/tree/master/update_security_groups_lambda

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?