Amazon Web Services ブログ

AWS Systems Manager カスタムインベントリを使ったマネージドノード上の Log4j ファイル検索

※このブログは、2022年1月31日に公開された Use AWS Systems Manager custom Inventory to locate Log4j files on managed nodes を翻訳したものです。原⽂はこちらを参照して下さい。

このブログでは、最近公開された Log4j の脆弱性の対応に役立つガイダンスを紹介します。具体的には、AWS Systems Manager の機能の一つである Inventory を使用して、Linux 及び Windows Server の Amazon Elastic Compute Cloud(EC2) インスタンスとハイブリッドマネージドノードから Log4j JAR ファイルを見つける方法をご紹介していきます。ハイブリッドマネージドノードには、他のクラウド環境の VM を含む AWS Systems Manager 用に設定されたオンプレミスサーバー、エッジデバイス、仮想マシン (VM) が含まれます。

このブログでは、カスタムインベントリデータの型を利用して、Windows および Amazon Linux EC2 インスタンスとハイブリッドマネージドノードで Log4j JAR ファイルを見つける方法を紹介します。PowerShell スクリプトを使用して Windows マネージドノードからメタデータを収集し、シェルスクリプトを使用して Amazon Linux マネージドノードからメタデータを収集します。シェルコマンドを適切に変更することで、他の Linux オペレーティングシステムにも拡張できます。

Log4j は、バンドルまたはシェーディングライブラリとして他のファイルにも存在する場合があることに注意してください。AWS では log4j-core-*.jar ファイル以外にも広範な検索を行うことを推奨しています。

Log4j の脆弱性(CVE-2021-44228CVE-2021-45046)は、ユビキタスロギングプラットフォームの Apache Log4j における重大な脆弱性(CVSS 3.1 基本スコア 10.0)です。この脆弱性により、攻撃者はこの脆弱性を悪用してリモートからコードを実行する可能性があります。Version 2.0-beta-9 から 2.15.0 までの Log4j が影響を受けます。

即座に行うべき対応としては、こちらのブログに従って、Log4j 2.0 以降を使用している JVM にホットパッチを適用するためのツールを使用してください。AWS の最高情報セキュリティ責任者である Steve Schmidt も、このホットパッチについて自身のブログにて述べています。Log4j の脆弱性に関連して AWS セキュリティサービスを使用する方法の詳細については、「Log4j 脆弱性に対する AWS セキュリティサービスを利用した保護、検知、対応」を参照してください。

AWS Systems Manager Inventory について

AWS Systems Manager の機能の一つである Inventory は、システム、アプリケーション、インスタンスのメタデータを一元的に収集及び検索することができます。リソースデータの同期機能を使用すると、このメタデータを Amazon Simple Storage Service (Amazon S3) に同期できます。Amazon S3 では、異なる AWS リージョンやアカウントからもメタデータを集約できます。このインベントリデータを Amazon S3 に同期すると、Amazon AthenaAmazon QuickSight を使用してさまざまなデータを可視化できます。

この機能により、すべてのサーバーとインスタンスをスキャンし、レポート用のデータを一元化管理できます。これにより、パッチを適用または更新する必要があるサーバを迅速に特定できます。複数のアカウントとリージョンにまたがるマネージドノードへのパッチ適用の詳細については、「AWS Systems Manager Automation によるマルチアカウント、マルチリージョンでの一元的にスケジューリングされたパッチ適用」を参照してください。

前提条件

Amazon Elastic Compute Cloud (EC2) インスタンス、AWS Internet of Things (IoT) Greengrass コアデバイス、オンプレミスサーバー、エッジデバイス、VM は、Systems Manager のマネージドノードとして管理されており、インベントリメタデータが収集されている必要があります。つまり、ノードは前提条件を満たし、AWS Systems Manager Agent (SSM Agent) が設定されている必要があります。詳細については、「AWS Systems Manager のセットアップ」を参照してください。

カスタムインベントリドキュメントを作成する

デフォルトでは、AWS-GatherSoftwareInventory ドキュメントを使用してインベントリデータを収集できます。今回のユースケースでは、PowerShell スクリプトを実行するカスタムドキュメントを作成し、インベントリ収集前にLog4j JAR ファイルを検索できるようにします。

AWS CloudFormation を使用してカスタムインベントリドキュメントを作成するには、このブログの「CloudFormation StackSets を使用してドキュメントと関連付けを AWS アカウントとリージョン全体にデプロイする」セクションを参照してください。

以下の GitHub のページを開き、customInventoryLog4jDocument.ymlをダウンロードしてください。

https://github.com/aws-samples/aws-systems-manager-custom-inventory-log4j-example/blob/main/customInventoryLog4jDocument.yml

オプション1: AWS マネージメントコンソールでドキュメントを作成する

AWS Systems Manager のコンソールに移動し、ナビゲーションペインからドキュメントを選択してください。

  1. ドキュメントのページにて、Create document を押下し、Command or Session を選択してください
  2. 名前には、customInventoryLog4j のような名前を入力してください
  3. コンテンツでは、YAML を選択し、サンプルコンテンツを消してから、GitHub からダウンロードしたcustomInventoryLog4jDocument.yml の中身を貼り付けて、ドキュメントの作成を選択してください

オプション2: AWS Command Line Interface(AWS CLI) でドキュメントを作成する

以下のコマンドでドキュメントを作成します。

aws ssm create-document --content file://path to your file/customInventoryLog4jDocument.yml --name "customInventoryLog4j" --document-type Command --document-format YAML

以下のコマンドで、ドキュメントのステータスを確認します。

aws ssm list-documents --document-filter-list key=Name,value=customInventoryLog4j

以下は、コマンド実行結果の例です。

{
    "DocumentIdentifiers": [
        {
            "Name": "customInventoryLog4j",
            "CreatedDate": "2021-12-20T17:52:38.328000+00:00",
            "Owner": "012345678901",
            "PlatformTypes": [
                "Windows",
                "Linux",
                "MacOS"
            ],
            "DocumentVersion": "1",
            "DocumentType": "Command",
            "SchemaVersion": "2.2",
            "DocumentFormat": "YAML",
            "Tags": []
        }
    ]
}

customInventoryLog4jドキュメントを使用して関連付けを作成する

CloudFormation を使用して AWS Systems Manager State Manager の関連付けを作成するには、このブログの「CloudFormation StackSets を使用してドキュメントと関連付けを AWS アカウントとリージョン全体にデプロイする」セクションを参照してください。

1つ前のセクションで Inventory で利用するポリシードキュメントを作成したので、ここからは State Manager の関連付けを作成して、このポリシードキュメントをターゲットインスタンスに関連付けていきます。

  1. AWS Systems Manager のコンソールを開いてください
  2. ナビゲーションペインからステートマネージャーを選択してください
  3. 関連付けの作成を選択してください
  4. 名前には、customInventory_Log4j のような名前を入力してください
  5. ドキュメントの設定では、ドキュメント名プレフィックス:Equals:customInventoryLog4j でフィルタリングを行い、前のセクションで作成したカスタムドキュメントを選択してください

次に、以下のスクリーンショットのように、PowerShellスクリプトとLinuxシェルスクリプトを対応するパラメータにそれぞれ貼り付けてください。

これらのスクリプトは、Inventory のプラグインが呼び出される前に実行されます。Windows インスタンスでは aws: runPowerShellScript 、Linux インスタンスでは aws: runShellScript というドキュメント内のプラグインによって実行されます。

以下の GitHub のページを開き、customInventoryLog4jPowerShell.ps1 と customInventoryLog4jShell.sh をダウンロードしてください。

PowerShell Script:

https://github.com/aws-samples/aws-systems-manager-custom-inventory-log4j-example/blob/main/customInventoryLog4jPowerShell.ps1

Shell Script:

https://github.com/aws-samples/aws-systems-manager-custom-inventory-log4j-example/blob/main/customInventoryLog4jShell.sh

これらのスクリプトは、ターゲットとなるマネージドノード上のファイルシステムをスキャンして、バージョンに関係なく Log4j JAR ファイルを見つけます。スクリプトは、マネージドノード上のカスタムインベントリ用ディレクトリに作成されたJSON ファイルにファイル名とパスを記録します。その後、インベントリデータ収集プロセスによって JSON ファイルが収集され Systems Manager に連携されます。

Windows:

%SystemDrive%\ProgramData\Amazon\SSM\InstanceData\node-id\inventory\custom

Linux:

/var/lib/amazon/ssm/node-id/inventory/custom

このステップでは、関連付けを行うターゲットインスタンスを選択する必要があります。また、インベントリ収集のスケジュールを設定しましょう。必要に応じて、この関連付けのコンプライアンス重要度を指定できます。

ターゲットインスタンスとスケジュールの設定を行ったら、関連付けの作成を選択してください。以上で、関連付けの作成作業は完了です。設定したカスタムドキュメントが実行されると、Log4j JAR ファイルのパスが収集され、Systems Manager Inventory にレポートされます。

Fleet Manager に移動し、ターゲットのインスタンスのインベントリタブを開きましょう。以下のスクリーンショットは、Windows EC2 インスタンスの例で、新しいカスタムインベントリデータタイプが存在することが確認できます。

インベントリに結果がない場合は、一致するファイルが見つからないことが原因と考えられます。確認するには、State Manager の関連付けのステータスを確認します。関連付けのステータスが成功している場合は、該当するファイルが見つからなかったことになります。関連付けのステータスが失敗の場合は、関連付けの名前の横にあるラジオボタンを選択し、詳細を表示を選択して詳細を確認しましょう。

GetInventory API を使用して、マネージドノードのリストをフィルタリングできます。例えば、次の AWS CLI コマンドを実行すると、Log4j ファイルがあるマネージドノードのリストを出力できます。

aws ssm get-inventory --filters Key=Custom:Log4J.Filename,Values="log4j",Type="BeginWith" --query 'Entities[*].Data."AWS:InstanceInformation".Content[].InstanceId'
[
    "i-1234567890abcdef0",
    "i-021345abcdef6789",
    "mi-1234567890abcdef0"
]

また、リソースデータの同期を使用することで、複数の AWS アカウントやリージョンにまたがるインベントリデータを一つのAmazon S3 バケットに集約できます。集約されたデータは JSON ファイルとして扱えるため、必要に応じてクエリが実行できます。

 
       
Amazon S3 上のデータは、 Amazon Athena を使用してインスタンスのインベントリデータに対するクエリを実行できます。必要に応じて、 Amazon QuickSight を使用してインスタンスのインベントリデータを可視化できます。例えば、次のクエリを使用して、アカウントとリージョンにまたがって、log4j JAR ファイルがあるマネージドノードのリストを返すことができます。
 
SELECT
 resourceid,accountid,filename,path
FROM
 custom_log4j

CloudFormation StackSets を使用してドキュメントと関連付けを AWS アカウントとリージョン全体にデプロイする

上記の手順では、特定の AWS アカウントとリージョン内で Systems Manager ドキュメントと State Manager の関連付けを作成する方法を詳しく説明してきました。AWS CloudFormation StackSets を使用すると、複数アカウント、複数リージョンに対して、Systems Manager ドキュメントと State Manager の関連付けを行うことができます。

管理アカウントとターゲットアカウントに、これらのスタックの実行に必要な権限が設定されていることを確認しましょう。詳細については、AWS CloudFormation ドキュメントのスタックセットオペレーションの前提条件を確認してください。この設定がない場合、または StackSets の使用を避けたい場合は、各ターゲットアカウントで個別に CloudFormation スタックを使用してください。

以下の GitHub ページを開き、customInventoryLog4jCloudFormationTemplate.ymlをダウンロードしてください。

https://github.com/aws-samples/aws-systems-manager-custom-inventory-log4j-example/blob/main/customInventoryLog4jCloudFormationTemplate.yml

このテンプレートは、Systems Manager のカスタムインベントリ用のドキュメントと State Manager の関連付けをターゲットアカウントに作成します。

  1. 管理アカウントにて、AWS CloudFormation のコンソールを開き、左側のナビゲーションペインから StackSets を選び、StackSets の作成を選択してください。
  2. テンプレートの選択画面で、以下の手順に沿って設定を行ってください
    1. 権限セクションの設定は、AWS Organizations を有効にしているかどうかによって異なります
      1. AWS Organizations を有効にしていない場合は、セルフサービスのアクセス許可を選択し、次へを選択してください
      2. AWS Organizations を有効にしている場合は、サービスマネージドアクセス許可を選択して、StackSets を組織または OU に適用できます。手動でアクセス許可をコントロールしたい場合は、セルフサービスのアクセス許可を選択し、アカウントのリストをターゲットとして追加してください
    2. 前提条件 – テンプレートの準備では、デフォルトのテンプレートの準備完了のままにしてください
    3. テンプレートの指定テンプレートファイルをアップロードを選択し、ファイルの選択を押下して、customInventoryLog4jCloudFormationTemplate.yml を選び、次へを選択してください。
  3. StackSet の詳細を指定ページにて、以下の手順に沿って設定をしてください
    1. StackSet 名は、customInventoryBlog のような名前を入力してください
    2. tagKey には、カスタムインベントリを収集するマネージドノードのタグキーを入力してください
    3. tagValue には、カスタムインベントリメタデータを収集するマネージドノードのタグ値を入力してください
    4. 次ヘを選択してください

  1. StackSet オプション設定画面では、 実行設定はデフォルト値のままとして次へを選択してください
  2. デプロイオプションの設定画面では、以下の手順で設定をしてください
    1. デプロイターゲットでは、AWS 組織全体にデプロイするか、特定の AWS 組織単位 (OU) にデプロイするかを選択してください
    2. リージョンの指定では、マネージドノードがあるリージョンを選択してください
    3. 次へを選択してください

  1. 次のページでは、選択したオプションとパラメータを確認し、送信を選択してください

ページが更新されると、StackSet が表示されます。作成後、ステータスは SUCCEEDED に変わります。

クリーンアップ

このブログの手順で作成した関連付けを削除するには、State Manager のコンソールに移動し、作成した関連付けを選択して関連付けの削除を選択してください。

カスタムドキュメントを削除するには、Systems Manager のドキュメントページに移動し、自己所有タブを開き、作成したカスタムドキュメントを選択し、アクションからドキュメントを削除するを選択してください。

カスタムインベントリスキーマとそのすべてのデータを削除するには、以下のコマンドを実行してください。

aws ssm delete-inventory --type-name "Custom:Log4J" --schema-delete-option "DeleteSchema"

CloudFormation StackSet を削除するには、管理アカウントの AWS CloudFormation コンソールに移動します。左側のナビゲーションペインで StackSets を開き、作成した StackSet を選択してください。アクションから StackSet からスタックを削除を選択し、AWS OU ID を入力し、すべてのリージョンを追加を押下し、次へを選択し、送信を選択してください。すべてのスタックインスタンスを削除したら、アクションから、StackSet の削除を選択してください。

まとめ

このブログでは、Systems Manager のカスタムインベントリを使用して、マネージドノードのファイルシステム上にある Log4j JAR ファイルを見つけ、ファイル名とパスをカスタムインベントリオブジェクトとしてレポートする方法を説明しました。これにより、インベントリポリシーが実行されるたびに、インスタンスからカスタムインベントリデータを収集して送信できます。その後、インスタンス全体または、インスタンス単位に対してクエリを実行できます。

また、CloudFormation StackSets を使用して、複数の AWS アカウントとリージョンに、このカスタムインベントリドキュメントと State Manager の関連付けをプロビジョニングする方法についても説明しました。

リソースデータの同期を利用することで、パッチ適用、コンプライアンス、インベントリのデータを 1 か所に集約できます。これにより、一元管理用の S3 バケットにデータが同期されます。詳細については、「インベントリのリソースデータの同期の設定」を参照してください。

リソースデータの同期を作成したら、Amazon Athenaと Amazon QuickSight を設定して、パッチ適用とインベントリ関連データを可視化できます。詳しくは、「複数のリージョンとアカウントからのインベントリデータをクエリする」をご覧ください。

著者について

Erik Weber

Erik Weber は、AWS Cloud Oerations services におけるワールドワイドスペシャリストソリューションアーキテクトです。AWS Systems Manager、AWS Config、AWS CloudTrail、AWS Audit Manager を専門としています。仕事以外では、ハイキング、料理、サイクリングに情熱を注いでいます。

翻訳は、ソリューションアーキテクトの上野が担当しました。