CloudWatch メトリクスフィルターを利用して SSH の不正ログイン試行を監視してみた

CloudWatch メトリクスフィルターを利用して SSH の不正ログイン試行を監視してみた

Clock Icon2024.12.16

こんにちは。テクニカルサポートチームのShiinaです。

はじめに

EC2 インスタンスへの SSH アクセスを利用している場合、不正なアクセスを防ぐためにログ監視が重要です。
CloudWatch メトリクスフィルターを活用して、/var/log/secureのログ監視をやってみました。
不正なログイン試行や認証失敗を検知するアラートを設定することで、攻撃の早期発見と迅速な対応が可能になります。

前提

  • /var/log/secureに次の記録を示すログメッセージが繰り返し行われている場合にアラートを検知させます
    ・存在しないユーザー名でのログイン試行
    ・パスワード認証失敗
    ・不正な秘密鍵でのログイン試行
  • EC2 インスタンスに CloudWatch エージェントがインストールされていること
  • EC2 インスタンスロールには、CloudWatch エージェントがログ書き込みに必要な IAM ポリシーが付与されていること

設定の流れ

CloudWatch エージェントを使用して /var/log/secure のログを収集するための設定と ACL によるログファイルの読み取り権限を付与します。
その後、メトリクスフィルターを設定して不正なログイン試行を検知します。
アラームを設定して、特定の条件下で通知を受け取れるようにします。

1.CloudWatch エージェント設定

CloudWatch エージェントを利用して/var/log/secureのログを収集する設定を行います。
以下の設定ファイルを利用しました。

confg.json
{
        "agent": {
                "metrics_collection_interval": 60,
                "run_as_user": "cwagent"
        },
        "logs": {
                "logs_collected": {
                        "files": {
                                "collect_list": [
                                        {
                                                "file_path": "/var/log/secure",
                                                "log_group_class": "STANDARD",
                                                "log_group_name": "secure",
                                                "log_stream_name": "{instance_id}",
                                                "retention_in_days": -1
                                        }
                                ]
                        }
                }
        }
}

設定ファイルの反映を行います。

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json

2.ACL 設定

/var/log/secureは機密性の高いログファイルであり、CloudWatch エージェントユーザである cwagent に読み取り権限はありません。
ACL を利用することで、cwagent ユーザーに必要最低限の読み取り権限を付与できます。
他のユーザーやプロセスに不要な権限を与えるリスクを避けられます。

sudo setfacl -m u:cwagent:r /var/log/secure

設定後は getfacl コマンドで cwagent に読み取り権限が付与されていることを確認します。

getfacl /var/log/secure

getfacl: Removing leading '/' from absolute path names
# file: var/log/secure
# owner: root
# group: root
user::rw-
user:cwagent:r--
group::---
mask::r--
other::---

3.CloudWatch Logs のロググループ確認

CloudWatch エージェントによりログが収集され、CloudWatch Logs のロググループに出力されていることを確認します。
CloudWatch メニューのロググループを選択します。
ロググループ一覧を確認します。
上記の設定ファイルを利用した場合、ロググループ名はインスタンス ID となります。
ロググループ確認

4.メトリクスフィルター設定

各パターンごとにメトリクスフィルターを設定します。
AWS CLI で設定を行う場合は記載のコマンドを利用してください。

存在しないユーザー名でのログイン試行

CloudWatch メニューのロググループを選択します。
メトリクスフィルタータブより[メトリクスフィルターを作成]を選択します。
以下の値を入力し、メトリクスフィルターの作成を行います。

  • フィルタパターン
    [Mon, day, timestamp, ip, id, status = Invalid, ...]
  • フィルターパターンテスト用ログデータ
    Dec 9 05:20:36 ip-10-0-0-215 sshd[3742]: Invalid user admin from XXX.XXX.XXX.XXX port 29294
  • フィルター名:SSHInvalidUserFilter
  • メトリクス名前空間:SSH
  • メトリック:InvalidUserMetrics
  • メトリクス値:1
    invaliuser

invaliuser2

・AWS CLI コマンド
YOUR_LOG_GROUP_NAME はロググループ名を指定してください。

aws logs put-metric-filter \
    --log-group-name YOUR_LOG_GROUP_NAME \
    --filter-name "SSHInvalidUserFilter" \
    --filter-pattern "[Mon, day, timestamp, ip, id, status = Invalid, ...]" \
    --metric-transformations '[{
        "metricName": "InvalidUserMetrics",
        "metricNamespace": "SSH",
        "metricValue": "1"
    }]'

パスワード認証失敗

CloudWatch メニューのロググループを選択します。
メトリクスフィルタータブより[メトリクスフィルターを作成]を選択します。
以下の値を入力し、メトリクスフィルターの作成を行います。

  • フィルタパターン
    [Mon, day, timestamp, ip, id, msg1= Failed, msg2 = password, ...]
  • フィルターパターンテスト用ログデータ
    Dec 9 06:15:06 ip-10-0-0-215 sshd[5811]: Failed password for invalid user admin from XXX.XXX.XXX.XXX port 29292 ssh2
  • フィルター名:SSHFailedPasswordFilter
  • メトリクス名前空間:SSH
  • メトリック:FailedPasswordMetrics
  • メトリクス値:1

password1

password2

・AWS CLI コマンド
YOUR_LOG_GROUP_NAME はロググループ名を指定してください。

aws logs put-metric-filter \
    --log-group-name YOUR_LOG_GROUP_NAME \
    --filter-name "SSHFailedPasswordFilter" \
    --filter-pattern "[Mon, day, timestamp, ip, id, msg1= Failed, msg2 = password, ...]" \
    --metric-transformations '[{
        "metricName": "FailedPasswordMetrics",
        "metricNamespace": "SSH",
        "metricValue": "1"
    }]'

不正な秘密鍵でのログイン試行

CloudWatch メニューのロググループを選択します。
メトリクスフィルタータブより[メトリクスフィルターを作成]を選択します。
以下の値を入力し、メトリクスフィルターの作成を行います。

  • フィルタパターン
    [Mon, day, timestamp, ip, id, msg1= Connection, msg2 = closed, ...]
  • フィルターパターンテスト用ログデータ
    Dec 9 05:17:29 ip-10-0-0-215 sshd[3612]: Connection closed by XXX.XXX.XXX.XXX port 29678 [preauth]
  • フィルター名:SSHClosedConnectionFilter
  • メトリクス名前空間:SSH
  • メトリック:ClosedConnectionMetrics
  • メトリクス値:1

key1

key2

・AWS CLI コマンド
YOUR_LOG_GROUP_NAME はロググループ名を指定してください。

aws logs put-metric-filter \
    --log-group-name YOUR_LOG_GROUP_NAME \
    --filter-name "SSHClosedConnectionFilter" \
    --filter-pattern "[Mon, day, timestamp, ip, id, msg1= Connection, msg2 = closed, ...]" \
    --metric-transformations '[{
        "metricName": "ClosedConnectionMetrics",
        "metricNamespace": "SSH",
        "metricValue": "1"
    }]'

5.アラーム設定

メトリクスフィルターによって記録されるメトリクスに対してアラームを設定します。
メトリクスと条件、通知設定の上、それぞれのメトリクスに対してアラームを設定します。
1分間で5回以上、不審な SSH アクセス試行が記録された場合を条件としてみました。

CloudWatch メニューのすべてのアラームを選択します。
[アラームの作成]を選択します。
以下の値を入力し、アラームの作成を行います。

  • メトリクス名:FailedPasswordMetrics
  • 統計:合計
  • 期間:1分
  • 条件:> 5
  • 通知:アラーム状態トリガーに SNS トピックに通知
  • アラーム名:任意の名前
  • アラームの説明 - オプション :任意の値

同様に InvalidUserMetrics、ClosedConnectionMetrics メトリクスに対してアラームを設定します。

アラーム作成1

アラーム作成2

・AWS CLI コマンド
YOUR_DESCRIPTION、YOUR_TOPIC_ARN は適切なものを指定してください。

aws cloudwatch put-metric-alarm \
    --alarm-name 'FailedPasswordMetricsAlarm' \
    --alarm-description 'YOUR_DESCRIPTION' \
    --actions-enabled \
    --alarm-actions 'YOUR_TOPIC_ARN' \
    --metric-name 'FailedPasswordMetrics' \
    --namespace 'SSH' \
    --statistic 'Sum' \
    --period 60 \
    --evaluation-periods 1 \
    --datapoints-to-alarm 1 \
    --threshold 5 \
    --comparison-operator 'GreaterThanThreshold' \
    --treat-missing-data 'missing'
aws cloudwatch put-metric-alarm \
    --alarm-name 'InvalidUserMetricsAlarm' \
    --alarm-description 'YOUR_DESCRIPTION' \
    --actions-enabled \
    --alarm-actions 'YOUR_TOPIC_ARN' \
    --metric-name 'InvalidUserMetrics' \
    --namespace 'SSH' \
    --statistic 'Sum' \
    --period 60 \
    --evaluation-periods 1 \
    --datapoints-to-alarm 1 \
    --threshold 5 \
    --comparison-operator 'GreaterThanThreshold' \
    --treat-missing-data 'missing'
aws cloudwatch put-metric-alarm \
    --alarm-name 'ClosedConnectionMetricsAlarm' \
    --alarm-description 'YOUR_DESCRIPTION' \
    --actions-enabled \
    --alarm-actions 'YOUR_TOPIC_ARN' \
    --metric-name 'ClosedConnectionMetrics' \
    --namespace 'SSH' \
    --statistic 'Sum' \
    --period 60 \
    --evaluation-periods 1 \
    --datapoints-to-alarm 1 \
    --threshold 5 \
    --comparison-operator 'GreaterThanThreshold' \
    --treat-missing-data 'missing'

やってみた

不審な SSH アクセス試行を何回か試行し、メトリクスとアラームの状態を確認してみます。

メトリクス

それぞれメトリクス値が記録されていることが確認できます。
メトリクス確認

アラームの状態

FailedPasswordMetrics のアラームがアラーム状態となっていることが確認できます。
アラーム状態

通知

SNSトピックのサブスクリプションしているメールアドレス宛に通知が届きました。
通知メール

まとめ

SSH はログイン試行の記録が残るため、ブルートフォース攻撃などの不正アクセスの早期発見につながります。
セキュリティ対策の一つとしてメトリクスフィルターを利用した監視を活用してみてください。

本記事が誰かのお役に立てれば幸いです。

参考

https://aws.amazon.com/jp/blogs/security/how-to-monitor-and-visualize-failed-ssh-access-attempts-to-amazon-ec2-linux-instances/

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.