皆さん、こんにちは。突然ですが、最近ログ分析という言葉をよく耳にしませんか?
IoTやセキュリティ対策の需要が増える昨今、ログデータから不正アクセスなどを検知し、
被害を最小限に抑えるためには、ログ分析は不可欠なソリューションとなります。
SIEM on Amazon OpenSearch Serviceは、そのソリューションの1つです。
基本的にはSIEM on Amazon OpenSearch Serviceが対応しているログであれば、比較的簡単に取り込むことができますが、 Apacheログなどはデフォルトでは対応していません。
今回は、カスタムで取り込む方法がありますので、共有させていただきたいと思います。
初めて SIEM on Amazon OpenSearch Serviceを利用される方を対象としています。
SIEM on Amazon OpenSearch Serviceについて
SIEM on Amazon OpenSearch Serviceの概要
SIEM on Amazon OpenSearch Serviceはセキュリティインシデントを調査するためのソリューションです。 Amazonのマルチアカウント環境下で、複数のログをSIEM on Amazon OpenSearch Serviceに集約し、下記のようにログ相関分析及び可視化することができます。
ログはAWS S3バケットに集約しておくだけで、自動的にSIEM on OpenSearch Serviceに取り込まれます。デフォルトで対応しているログデータの種類は、下記サイトにてご確認ください。
今回は、デフォルトで対応していないApache(httpd)のアクセスログをSIEM on OpenSearch Serviceに取り込むために、若干のカスタマイズが必要となりました。
本記事で解説する内容
本記事では、EC2上で起動しているWebアプリケーションのApacheアクセスログをSIEM on Amazon OpenSearch Serviceに取り込む手順を記載します。解説する内容は、下記赤い枠部分となります。 水色部分は、SIEM on Amazon OpenSearch Serviceをデプロイした際に自動的に構築される部分です。
データの流れ: EC2アクセスログ⇒Kinesis Data Firehose⇒S3⇒OpenSearch Service
作業手順
1.前提条件
- Amazon Linux EC2上でApacheが動作していること
- ロケーション情報を使用するために、MAXMIND社(https://www.maxmind.com/en/home) から無料ライセンスキーを取得済であること
- EC2やS3バケットの作成経験があること
なお、作業手順はこちらのドキュメントをベースにご説明いたします。 github.com
2.CloudFormationデプロイ用のテンプレートをS3にアップロード
テンプレートアップロードの詳細手順について、上記サイトにてご確認ください。
2-1. AWSコンソール画面からテンプレートを格納するS3バケットを作成します。今回はバケット名を「aes-siem-output」にします。 2-2. S3へファイルをアップロードできる権限をEC2に付与します。 2-3. Tera TermでEC2にログインし、下記を実行します。
sudo yum groups mark install -y "Development Tools" sudo yum install -y amazon-linux-extras sudo amazon-linux-extras enable python3.8 sudo yum install -y python38 python38-devel git jq sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1
2-4.GitHubレポジトリから関連ソースコードをcloneします。
git clone https://github.com/aws-samples/siem-on-amazon-opensearch-service.git
下記のようにテンプレート一式がEC2にcloneされたことを確認できます。
[ec2-user@ip-10-0-0-50 ~]$ ls siem-on-amazon-opensearch-service
2-5.環境変数を設定します。
export TEMPLATE_OUTPUT_BUCKET=aes-siem-output export AWS_REGION=ap-northeast-1
2-6.AWS Lambda 関数のパッケージとテンプレートを作成します。
cd siem-on-amazon-opensearch-service/deployment/cdk-solution-helper chmod +x ./step1-build-lambda-pkg.sh && ./step1-build-lambda-pkg.sh && cd .. chmod +x ./build-s3-dist.sh && ./build-s3-dist.sh $TEMPLATE_OUTPUT_BUCKET
aws s3 cp ./global-s3-assets s3://$TEMPLATE_OUTPUT_BUCKET/ --recursive --acl bucket-owner-full-control aws s3 cp ./regional-s3-assets s3://$TEMPLATE_OUTPUT_BUCKET/ --recursive --acl bucket-owner-full-control
下記の通り、S3へアップされていることを確認できます。
3.SIEM on OpenSearch Serviceのデプロイ
3-1.CloudFormation作成へ移動し、「スタックの作成」をクリックします。 3-2.Amazon S3 URLにテンプレートsiem-on-amazon-opensearch-service.template「https://aes-siem-output.s3.ap-northeast-1.amazonaws.com/siem-on-amazon-opensearch-service.template」(※手順2.7)を記入し、「次へ」をクリックします。 3-3.スタックの名前とパラメータを記入し、「次へ」をクリックします。
項目名 | 説明 |
---|---|
スタックの名前 | aes-siem |
AllowedSourceIpAddresses | アクセスを許可するIPアドレス。複数アドレスはスペース区切り |
GeoLite2LicenseKey | Maxmindのライセンスキー。IP アドレスに国情報を付与 |
ReservedConcurrency | es-loaderの同時実行数の上限値。今回はデフォルト10のまま |
SnSEmail | SIEM on OpenSearch Service で検知したアラートを SNS 経由で送信するメールアドレス |
3-4. スタックオプションの設定は、デフォルトのままで、「次へ」をクリックします。
3-5. 確認画面で特に問題なければ、画面一番下のチェックを入れ、「スタック作成」をクリックします。
大体30分前後で、スタックがcompleteになります。その間に、上記パラメータに記載したSnSEmailの宛先に、下記メールが届きます。メール本文の「Confirm subscription」をクリックすると、SNSのサブスクリプションが作成されます。
▼承認メール
▼作成されたSNS サブスクリプション
▼Completeになったスタック「aes-siem」
スタック「aes-siem」が完成後、計43個リソースが作成されます。そのうち、本記事の解説内容と関連しているリソースは下記の通りです。
▼S3バケット:
ファイル名 | 説明 |
---|---|
aes-siem-アカウントID-geo | GeoIPダウンロード用 S3 バケット名 |
aes-siem-アカウントID-log | ログ用 S3 バケット名 |
aes-siem-アカウントID-snapshot | スナップショット用 S3 バケット名 |
▼Lambda: ▼OpenSearch Service:
4.Kinesis Data Firehoseの作成
4-1. S3バケット「aes-siem-アカウントID-log」(※手順3-5.)配下に、配信先のフォルダー(UserLogs/apache/httpd/)とエラー(error/)フォルダーを作成します。
4-2. Kinesis Data Firehose からS3にアクセスするIAMロール作成します。Kinesis Data Firehoseを作成する際に自動生成されますが、今回は事前にIAMロールを作成します。 ロール名:FirehosetoS3Role ユースケースをEC2で作成した場合、信頼関係のServiceを「ec2.amazonaws.com」から「firehose.amazonaws.com」に編集します。
4-3. Kinesis Data Firehos作成に移動し、「配信ストリームを作成」をクリックします。
4-4. 作成画面で、下記内容を設定します。 それ以外の項目は、デフォルトのままで「Create delivery stream」をクリックします。
項目名 | 記入内容 |
---|---|
Source | Direct PUT |
Destination | Amazon S3 |
Delivery stream name | PUT-S3-test |
S3 bucket | 「Browse」クリックし、aes-siem-アカウントID-logを選択 |
S3 bucket prefix – optional | UserLogs/apache/httpd/ |
S3 bucket error output prefix – optional | error/ |
Permissions | existing IAM roleを選択し、「FirehosetoS3Role」を指定 | |
数分後、配信ストリーム「PUT-S3-test」が作成されていることを確認できます。
5.ログの取り込み
5-1. EC2のIAMロールに、下記権限を付与します。
5-2. Tera TermでEC2にログインし、下記2点を確認します。
▼httpdサービスが起動されていること
もし起動されていなければ、httpdサービスを起動します。
sudo service httpd status
▼ApacheのアクセスログがCombine形式になっていること
grep "access_log" /etc/httpd/conf/httpd.conf
5-3. Kinesisエージェントをインストールします。
sudo yum install –y aws-kinesis-agent
5-4. エージェント設定を編集します。
sudo vi /etc/aws-kinesis/agent.json
初期の状態は下記のようになっていると思います。 編集後:
{ "cloudwatch.emitMetrics": false, "firehose.endpoint": "https://firehose.ap-northeast-1.amazonaws.com", "flows": [ { "filePattern": "/var/log/httpd/access_log", "deliveryStream": "PUT-S3-test" } ] }
項目名 | 記入内容 |
---|---|
Firehose.endpoint | 東京リージョンの場合、「https://firehose.ap-northeast-1.amazonaws.com」 |
filePattern | Apacheアクセスログの対象ファイル |
deliveryStream | PUT-S3-test (※手順4-4.) |
また、logFormatの設定もできますが、今回は元のフォーマットのままにします。
詳細設定は、下記にてご確認ください。
https://docs.aws.amazon.com/ja_jp/firehose/latest/dev/writing-with-agents.html#agent-config-settings
5-5. Kinesisエージェントサービスを起動し、ステータスを確認します。
sudo service aws-kinesis-agent start sudo service aws-kinesis-agent status
5-6. Webからアクセスし、エージェントの実行ログからストリームへ配信状況を確認します。
「*** records sent successfully to destinations」ログが表示されていれば、正常に配信されています。
tail /var/log/aws-kinesis-agent/aws-kinesis-agent.log
数分後に、aes-siem-アカウントID /UserLogs/apache/httpd/配下にyyyy/mm/dd/unique-IDフォルダが作成され、「PUT-S3-test-」から始まるファイルが格納されます。
6.Lambdaにカスタマイズ用のファイルの作成
6-1. Lambdaコンソールを開き、「aes-siem-es-loader」を選択します。
6-2. 新規user.ini を作成します。
オリジナルファイルは下記からコピーできますが、今回は実際の環境に合わせてコードを少し変更しました。
今回デプロイしたコードは、下記となります。
[apache] # S3の保存場所 s3_key = UserLogs/apache/httpd/.*/PUT-S3-test-* # ファイルフォーマット file_format = text # ESのインデックス名 index_name = log-web-apache # 名前付き正規表現でフィールドの抽出 log_pattern = ^(?P<remotehost>[^ ]+) (?P<rfc931>[^ ]+) (?P<authuser>[^ ]+) \[(?P<http_timestamp>[^\[\]]+)\] \"(?P<request_method>[^ ]+) (?P<request_path>.*) (?P<request_version>HTTP/.*)\" (?P<http_status>[^ ]+) (?P<http_bytes>[^ ]+) \"(?P<http_referer>.+)\" \"(?P<http_user_agent>.+)\" # " ログの生成時刻を抽出 timestamp_key = http_timestamp timestamp_format = %d/%b/%Y:%H:%M:%S %z # ECS への正規化 # 正規化後のフィールドを列挙 ecs = source.ip user.name http.request.method url.path http.version http.response.status_code http.response.bytes # 「正規化後 = オリジナルフィールド」 で定義 source.ip = remotehost user.name = authuser http.request.method = request_method url.path = request_path http.version = request_version http.response.status_code = http_status http.response.bytes = http_bytes # GeoIP geoip = source
コード内のS3_keyは取り込み対象ログを定義します。AWSログ以外のログ(例:今回Apacheアクセス)を取り込む場合、対象ファイルを自動的に認識しないため、ファイル名のフォーマットまで指定します。
また、index_nameには、OpenSearch Dashboardsに表示するインデックス名を指定します。
6-3. 「deploy」ボタンをクリックし、Lambdaを更新します。
数分後にアクセスログがSIEMに取り込まれます。 CloudWatchの/aws/lambda/aes-siem-es-loader配下のログから正常処理されるかどうかも確認できます。
▼正常に取り込まれた場合、下記のログ情報が出力されます。
▼取込を失敗した場合、下記のログ情報が出力されます。
7.OpenSearch Service Dashboardsでログの可視化
7-1. OpenSearch Dashboardsにログインします。 CloudFormationの「出力」タブに表示されているURLをクリックし、ユーザー名とパスワードでログインします。
7-2. Indexを作成します。 左ペインのManagementからStack Managementをクリックします。 メニューからIndex Patternsをクリックすると、SIEM on Amazon OpenSearch Serviceがデフォルトで作られたIndex一覧が表示されます。「Create index pattern」をクリックします。 Index作成Step1画面で、「log-web*」を記入し、「log-web-apache-2022-01」(※手順6-2.)が表示されます。「Next step」をクリックします。 Step2画面で、Time fieldで「@timestamp」を選択し、「Create index pattern」をクリックします。 7-3. Discover画面で作成されたindex pattern「log-web*」を選択し、転送されたログが正しく表示されていることを確認できます。 今週のお題「現時点での今年の漢字」
7-4. メニューからVisualizationsを作成します。 下記はVisualizationsサンプルです。 7-5. メニューDashboardsから上記作成したVisualizationsを追加し、ダッシュボードを作成します。
以上、ApacheログをSIEM on Amazon OpenSearch Service で可視化作業が完了しました。
番外編
- クリーンアップ
- CloudFormationからスタックaes-siemを削除します。
- OpenSearch Serviceドメインを削除します。
- Amazon S3バケットを削除します。
- Kinesis 配信ストリーム「PUT-S3-test」を削除します。
- その他、EC2など停止or終了します。
- 再デプロイする予定がある場合、手順2で用意したS3バケット「aes-siem-output」及び中身の一式をそのまま残した方が良いかと思います。そうすると、再デプロイする場合、直接手順3からスタートできます。
- KMSカスタマーマネジメントを削除します、 KMS削除はスケジュール(7~30日)設定でしか削除できないため、すぐに再デプロイする場合、下記コマンドでKMS CMKのエイリアスを削除し、その後、スケジュールを設定すれば問題ありません。
export AWS_DEFAULT_REGION=ap-northeast-1 aws kms delete-alias --alias-name "alias/aes-siem-key"
- エラー対処
エラーメッセージ:Caused by: java.nio.file.AccessDeniedException: /var/log/httpd
対処1:IAMロールの権限付与問題ないか確認
Kinesis関連権限は何種類かありますが、本記事に指定されているのは、
「AmazonKinesisFirehoseFullAccess」です。
対処2:権限変更
sudo chmod 755 /var/log/httpd/ sudo chmod 644 /var/log/httpd/*
最後に
ログ分析について、EC2⇒CloudWatch⇒Lambda⇒OpenSearchや、EC2⇒CloudWatch⇒Kinesis Data Firehose⇒S3などのパターンも検証しましたが、本記事内容の実装は、最も簡単でシンプルだと感じています。 また、AWSサービス以外のログデータを他のログと相関分析する必要がある場合、本記事のように、対象ログを一旦S3に取り込めば、自動的にOpenSearch Serviceに取り込むこともできます。
引き続きデータの活用とログ分析基盤の構築を楽しみつつ、当該ブログにて発信していきますのでよろしくお願いします。
また、もし、AWSおよびデータ・セキュリティ関連でお困り、ご相談がありましたら、弊社JTPまでご連絡いただけますと幸いです。