🚀

【AWS】Inspector v2/Lambdaで 脆弱性件数を通知する

2022/07/20に公開


はじめに

ご覧いただきありがとうございます。阿河です。

AWSには様々なセキュリティに関わるサービスが用意されています。

Amazon Inspectorは、EC2が抱える潜在的な問題点について「自動検出」および「継続的なスキャン」を行います。
今回は検知した脆弱性を重要度別に分類し、ユーザーに通知を行います。

対象者

  • AWSを運用中
  • AWSのセキュリティ系サービスについて学びたい

概要

  1. Inspector v2のセットアップ
  2. EC2インスタンスをInspectorの診断対象とする
  3. Lambda関数の作成

今回はAmazon Inspectorの現行バージョンであるv2を使用します。

検知した脆弱性のうち、重要度が"Critical","High","Medium"のものをそれぞれピックアップして、それぞれの件数をユーザーに通知します。

1. Inspector v2のセットアップ

Amazon Inspector v2の機能について

Amazon Inspector v2のサービス概要については、公式ドキュメントのFAQページに分かりやすく情報がまとまっています。

以下は抜粋です。

  • Amazon Inspector は、自動化された脆弱性管理サービスであり、Amazon Elastic Compute Cloud (EC2) とコンテナのワークロードを継続的にスキャンして、ソフトウェアの脆弱性と意図しないネットワークのエクスポージャーを検出します。

  • エージェントとしてAWS Systems Manager Agent (SSM Agent) を使用。

  • 新しく起動されたすべての Amazon EC2 インスタンスと Amazon ECR にプッシュされた適格なコンテナイメージを自動的に検出し、ソフトウェアの脆弱性と意図しないネットワークのエクスポージャーを即座にスキャンします。

  • 新しい脆弱性をもたらす可能性のあるイベントが発生すると、関連するリソースが自動的に再スキャンされます。リソースの再スキャンを開始するイベントには、EC2 インスタンスへの新しいパッケージのインストール、パッチのインストール、およびリソースに影響を与える新しい一般的な脆弱性と暴露 (CVE) がパブリッシュされた際などがあります。

Inspector v2の有効化

Amazon Inspectorのページを開くと、上記の画面が表示されます。
「使用を開始する」をクリック。

有効化します。

Inspectorの画面が表示されました。
次のセクションで実際にInspectorを機能させていきます。

2. EC2インスタンスをInspectorの診断対象とする

ロールの作成

必要な権限を付与するIAMロールを作成します。

  • 信頼されたエンティティタイプ: AWSのサービス
  • 一般的なユースケース: EC2
  • ポリシー: AmazonSSMManagedInstanceCore
  • ロール名: ※任意の名前をつけてください

対象のEC2の作成

スキャンの対象とするEC2インスタンスを作成します。

  • AMI: Amazon Linux2
  • VPC: ※任意のVPC
  • サブネット: ※任意のサブネット
  • パブリックIPの自動割り当て: 有効化
  • セキュリティグループ: ※必要に応じてアクセスを許可してください

EC2インスタンスは、想定される使用状況に合わせて作成してください。

EC2をInspectorの診断対象にする

EC2ページの「アクション」から、ロールの割り当てができます。
先程作成した「AmazonSSMManagedInstanceCore」が付与されたIAMロールを、対象EC2インスタンスに割り当てます。

次にSystems Managerのページに移動して、サイドバーから「FleetManager」をクリックします。

IAMロールを付与して一定時間が経てば、対象EC2インスタンスがマネージドインスタンスとして登録されます。

なお一定時間経過してもマネージドインスタンスとして認識されなければ、別要因で認識されていない可能性があるのでこちらを参照ください。

Inspector側の確認

Inspector側で認識されているかを確認します。

Inspectorのダッシュボードの環境カバレッジを見ると、Inspectorで有効になっているインスタンスとして3台が認識されているのが分かります。
私の環境では起動中のマネージドインスタンスが3台あるので、特に矛盾はありません。


「検出結果」⇒「インスタンス別」から、EC2インスタンス別に検出結果の確認ができます。

分かりやすい参考情報として、Inspectorテスト用として1か月前に作成したEC2インスタンスの脆弱性情報を表示しています。
重要度別("Critical",""High","Medium")に検知結果が表示されています。
どういった脆弱性が検知されたかを全件個別に確認することができます。

「Active(解決されていない)」な脆弱性が何件あるかが、一目で分かります。

パッチをあてる

EC2インスタンスに接続します。

$ sudo yum update --cve CVE-2022-1160
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
amzn2-core
・・・・・(省略)

Updated:
  vim-common.x86_64 2:8.2.4857-1.amzn2.0.1          vim-data.noarch 2:8.2.4857-1.amzn2.0.1             
  vim-enhanced.x86_64 2:8.2.4857-1.amzn2.0.1        vim-filesystem.noarch 2:8.2.4857-1.amzn2.0.1       
  vim-minimal.x86_64 2:8.2.4857-1.amzn2.0.1        

Complete!

cvesの後に、検出された該当CVEを指定します。
何件かのアップデートが走りました。

Inspectorの画面を確認すると、脆弱性が減少していることが分かります。
※関連した脆弱性含めて。

アップデートについては、アプリケーションへの影響を考慮して、パッチを適用するか/しないかを判断してください。

3. Lambda関数の作成

SNSトピックの作成

Amazon SNSのページに移動して、「トピックの作成」を行います。

  • タイプ: スタンダード
  • 名前: ※任意の名前

続いて、サブスクリプションの作成を行います。

  • プロトコル: Eメール
  • エンドポイント: ※通知を送りたいEメールアドレス

サブスクリプションを作成すると、指定したEメールアドレスに確認メールが届きます。
承認してください。

Lambda用のIAMロール作成

  • 信頼されたエンティティタイプ: AWSのサービス
  • 一般的なユースケース: Lambda
  • ポリシー: AWSLambdaBasicExecutionRole/AmazonSNSFullAccess/AmazonInspector2FullAccess
  • ロール名: ※任意の名前をつけてください

Lambda関数の作成

  • オプション: 一から作成
  • 関数名: ※任意の名前
  • ランタイム: Python3.8
  • アーキテクチャ: x86_64
  • アクセス制限: ※Lambda用のロールを付与

関数作成後、設定タブからタイムアウトの秒数を10秒に変更。

コードを作成します。

※「topic_arn」と「instance_id」を環境に合わせて修正してください。

import boto3

inspector2 = boto3.client("inspector2")
sns_client = boto3.client('sns')
topic_arn = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
instance_id = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

def lambda_handler(event, context):
    
    critical_finding = inspector2.list_findings(filterCriteria={
        
                'findingStatus': [
                    {
                        'comparison': 'EQUALS',
                        'value': 'ACTIVE'
                    },
                ],
                'resourceId': [
                    {
                        'comparison': 'EQUALS',
                        'value': instance_id
                    },
                ],
                'severity': [
                    {
                        'comparison': 'EQUALS',
                        'value': 'CRITICAL'
                    }
                ]
            }
        )
            
    high_finding = inspector2.list_findings(filterCriteria={
        
                'findingStatus': [
                    {
                        'comparison': 'EQUALS',
                        'value': 'ACTIVE'
                    },
                ],
                'resourceId': [
                    {
                        'comparison': 'EQUALS',
                        'value': instance_id
                    },
                ],
                'severity': [
                    {
                        'comparison': 'EQUALS',
                        'value': 'HIGH'
                    }
                ]
            }
        )
        
        
    medium_finding = inspector2.list_findings(filterCriteria={
        
                'findingStatus': [
                    {
                        'comparison': 'EQUALS',
                        'value': 'ACTIVE'
                    },
                ],
                'resourceId': [
                    {
                        'comparison': 'EQUALS',
                        'value': instance_id
                    },
                ],
                'severity': [
                    {
                        'comparison': 'EQUALS',
                        'value': 'MEDIUM'
                    }
                ]
            }
        )
        
    c_num = len(critical_finding['findings'])
    h_num = len(high_finding['findings'])
    m_num = len(medium_finding['findings'])
    
    mail_title = "Inspector v2 Alert"
    message = f"脆弱性を検知しました。内容をご確認ください。\nCRITICAL: {c_num}\nHITH: {h_num}\nMEDIUM: {m_num}"
    mail = sns_client.publish(
        
            TopicArn=topic_arn,
            Subject=mail_title,    
            Message=message
            )
        
        
    return 0

boto3のAPIリファレンスでInspector v2のページを確認したところ、「list_findings」(ご使用の環境の調査結果を一覧表示します)が使えそうです。

"インスタンスID"や"重要度"による絞り込みができます。
戻り値としてfindingsが返ってくるので、件数だけ洗い出します。

"CRITICAL","HIGH","MEDIUM"ごとに件数が確認できたら、SNSで通知を送ります。

テストの実施

ではテストを実施します。
AWSコンソール上では、以下の件数の脆弱性が確認されています。

Lambdaのテストタブから、テストを実行します。

想定していた通りに、メール通知が送られました。

さいごに

以上 Amazon Inspector v2の脆弱性検知結果を、重要度別にメール通知しました。
Lambdaを実行するトリガーは別途ご用意ください。

御覧いただき ありがとうございました!!

MEGAZONE株式会社 Tech Blog

Discussion