Network Firewallの マネージドルールグループのルールをルールグループにコピーするLambda関数作成
こんにちは、イムチェジョンです。
アジェンダ
- 背景説明
- マネージドルールグループのコピー
- コピーしたルールグループの自動アップデートする方法
- 結果確認
1. 背景説明
Network Firewallは、ネットワークトラフィックを詳細に制御するファイアウォールルールを定義できるサービスです。
Network Firewallには、AWSが管理するルールグループであるマネージドルールグループ(managed rule group)があります。
マネージドルールグループを使用すると、ユーザーが別にルールグループを作らなくてもAWSに管理してアップデートするルールでネットワークトラフィックを検査できます。
しかし、特定の状況ではマネージドルールグループが使用できない場合があります。
マネージドルールグループが使用できない例は下記のサイトをご参考ください。
どうしてもマネージドルールグループを使用したい場合は、マネージドルールグループを複製してルールグループとして使用することができます。
マネージドルールグループは2つに分かれていますが、ドメインおよびIPルールグループは複製できないため使用できません。 (脅威署名ルールグループのみ可能)
ただし、複製して使用すると、マネージドルールグループがアップデートした時に複製したルールグループまでアップデートしてくれない短所はありません。
この場合はLmabda関数を通じてアップデートすることができるので、ブログでその内容についてまとめます。
2. マネージドルールグループのコピー
まずはマネージドルールグループをコピーします。
VPC ページでネットワークファイアウォールのNetwork Firewall のルールグループに移動します。
Network Firewall のルールグループでルールグループがユーザ定義したルールグループであり、マネージドルールグループがAWSで管理しているルールグループです。
マネージドルールグループのタグをクリックして 「脅威署名ルールグループ」でコピーしたいマネージドルールグループをクリックします。
次に、画面の右上の ルールグループを複製
ボタンをクリックします。
すると、ルールグループの作成ページが出ます。
ここでルール変数やIP セット参照の詳細設定も追加できます。
今回はテストのため名前だけ設定して作成します。
名前はマネージドルールグループと区別するために ThreatSignaturesBotnetActionOrder-copy
で設定しました。
このようにコピーされたルールグループを確認できます。
テストのために複数のマネージドルールグループをコピーしました。
3. コピーしたルールグループの自動アップデートする方法
今回はアップデートを実行してみます。
アップデートの方法は下記になります。
マネージドルールグループがアップデート -> SNSを使用してLambdaに通知 -> Lambda関数の実行 -> ルールグループをアップデート
Lambda関数作成
まず、Lambda関数を作成します。
関数名は任意で作成して、ランタイムはPython 3.9
を選択します。
すると、画面のようにLambda関数が作成されます。
関数の ARN
が必要なので、どこかにコピーをしておきます。
SNSを使用してLambdaに通知
次にはマネージドルールグループがアップデートされた時に通知をもらうためにSNSサブスクリプションを作成します。
注意)マネージドルールグループのアップデートの通知はバージニア北部(us-east-1)
リージョンに移動する設定する必要があります。
VPCのNetwork Firewall のルールグループでマネージドルールグループ(脅威署名ルールグループ)の中で一つをクリックします。
マネージドルールグループの Amazon SNS トピック
の ARN
をコピーしておきます。
そして ARN をクリックしてサブスクリプションの作成ページに移動します。
上でコピーしておいた情報を入力します。
トピック ARN : 上でコピーした Amazon SNS トピック
の ARN
プロトコル : AWS Lambda
エンドポイント : 上でコピーした Lambda関数の ARN
入力できたらサブスクリプションを作成します。
すると、画面のようにSNSサブスクリプションが作成されたのを確認できます。
Lambda関数でもトリガーとしてSNSが追加されたのを確認できます。
サブスクリプションの作成が完了されたら、既存のリージョンに戻ります。
Lambda関数の実行
まず、コードを作成する前に必要な権限などの設定を行います。
まず、 設定
の アクセス権限
タグで実行ロールの ロール名
をクリックします。
すると、Lambda関数に割り当てたIAMロールのページが出ます。
ここで許可を追加
を押してポリシーをアタッチ
をクリックします。
追加する役割が下記になります。
追加する権限はIAMポリシーで作成しておきました。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "network-firewall:UpdateRuleGroup", "network-firewall:DescribeRuleGroup" ], "Resource": [ "arn:aws:network-firewall:ap-northeast-1:111111111111:stateful-rulegroup/*" ] } ] }
次には設定
の一般設定
タグで編集
をクリックします。
タイムアウトを 8秒で設定して保存します。
今からLambda関数コードを修正します。
import json import boto3 client = boto3.client('network-firewall') def lambda_handler(event, context): ## 入ってくる SNS イベントを確認 print(event) ## アップデートされたマネージドルールグループを確認 ManegerdRuleArn = event["Records"][0]["Sns"]["MessageAttributes"]["managed_arn"]["Value"].split('/') ManegerdRuleName = ManegerdRuleArn[1] print(ManegerdRuleName) ManegerdRuleRes = client.describe_rule_group( RuleGroupArn='arn:aws:network-firewall:ap-northeast-1:aws-managed:stateful-rulegroup/' + ManegerdRuleName, Type='STATEFUL' ) MyRuleName = ManegerdRuleName + '-copy' ## アップデートするルールグループの情報取得 ## もし、対象のルールグループがない場合にはアップデートをしないまま Skip を表示 try: MyRuleRes = client.describe_rule_group( RuleGroupName=MyRuleName, Type='STATEFUL' ) except: print("Skip") return "Skip Updates" RuleGroupName = MyRuleRes['RuleGroupResponse']['RuleGroupName'] RulesString = ManegerdRuleRes["RuleGroup"]["RulesSource"]["RulesString"] UpdateToken = MyRuleRes["UpdateToken"] RuleGroupArn = MyRuleRes["RuleGroupResponse"]["RuleGroupArn"] ## アップデート実行 ## 成功すれば True / 失敗すれば False result = update(RuleGroupName, RulesString, UpdateToken, RuleGroupArn) return result def update(RuleGroupName, RulesString, UpdateToken, RuleGroupArn): try: response = client.update_rule_group( UpdateToken=UpdateToken, RuleGroupArn=RuleGroupArn, RuleGroupName=RuleGroupName, RuleGroup={ 'RulesSource': { 'RulesString': '#test4\n' + RulesString } } ) print("Success") return True except: return False
Deploy
をします。
4. 結果確認
最後に結果を確認してみます。
モニタリング
タグで View CloudWatch logs
ボタンをクリックします。
ログストリームが出ますが、その中で結果をクリックして確認してみます。
成功した場合
成功した場合にはSNSから来るイベントを出力してそこでアップデートされたマネージドルールグループの名前を取得します。
今回のマネージドルールグループはルールグループとしてコピーされているので、アップデートを実行します。
結果的に成功した Success
をログで出力してLambda関数を終了します。
スキップした場合
スキップする場合、イベントを出力して対象のマネージドルールグループの名前を取得します。
今回のマネージドルールグループはルールグループとしてコピーされてないので、アップデートを実行する必要がありません。
なので、ログに Skip
を出力してLambda関数を終了します。