[小ネタ] Splunk マルチアカウントで便利なAWSの分析
AWSのマルチアカウント戦略により、様々なメリットをもたらしますが、その一方で全体的な統制が難しくなったり、リスクや無駄が生じやすくなったりすることがあります。
そういった時に、SIEMなどを使ってログの集中管理をすることで、全体俯瞰した可視性をもたらすのに大いに役立ってくれます。
今回は、AWSのマルチアカウント環境での可視性の向上という観点で、便利な分析についていくつか見ていこうと思います。
分析に使うデータソースと取り込み
Splunk から AWS の各リソースに対して参照系のAPIコールを叩けるようにしてあげて、それらのメタデータを取得し、分析を行います。
リソースのメタデータとは、EC2インスタンスの場合、インスタンスIDやインスタンスタイプ、IPアドレスの情報や稼働状態などです。
AWSのサービスだと、各種リソースのメタデータを確認するにはコンソールにログインしてアカウント毎で確認するか、AWS CLIからスクリプトなどで参照するかになることが多いかと思います。
SIEMからAWSリソースを参照するためのAPIをコールを発行してSIEM内でログとして貯めることで、定常的にアカウントを網羅的に可視化したり、CloudTrailなどの分析結果と同時に見ることが可能になります。
取り込み設定
AWS でIAMユーザーを作成して、アクセスキーを作成します。
ポリシーはドキュメントのこちらで確認することが可能です。
必要な(取得したい)リソースのポリシーのみ設定していただくので問題ございませんが、網羅的に取得したい場合は、以下のポリシーを参考にしていただければと思います。
(各リソースの参照系のアクションの許可ポリシーになります。インラインポリシーで設定した場合は、ポリシーの文字数制限をオーバーするのでアクションをワイルドカードでまとめています。)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"rds:Describe*",
"eks:List*",
"eks:Describe*",
"tag:GetResources",
"elasticloadbalancing:Describe*",
"elasticmapreduce:Describe*",
"elasticmapreduce:List*",
"elasticache:Describe*",
"elasticache:ListTagsForResource",
"tag:GetResources",
"guardduty:ListDetectors",
"guardduty:DescribePublishingDestination",
"guardduty:ListPublishingDestinations",
"iam:List*",
"iam:Get*",
"kinesis:List*",
"kinesis:Describe*",
"firehose:List*",
"firehose:DescribeDeliveryStream",
"lambda:ListFunctions",
"network-firewall:List*",
"network-firewall:Describe*",
"logs:ListLogDeliveries",
"logs:GetLogDelivery",
"route53:List*",
"waf:List*",
"wafv2:List*",
"s3:ListAllMyBuckets",
"s3:Get*",
"s3:GetLifecycleConfiguration"
],
"Resource": [
"*"
]
}
]
}
今回は AWS Secrets Manager に保管して、ここからAPIキーとシークレットを確認するようにしました。
IAMユーザー作成とAWS Secrets Managerへの格納についてはこちらを参考いただくと良いかと思います。
次に Splunk では、Splunk Add on for AWS をインストールし、App内の設定で追加をしていきます。
AWSのIAMユーザーのアクセスキーとシークレットを設定します。
続いて、入力の Create New Input でMetadata を選択します。
AWSアカウントに先ほど設定したアカウント、リージョンを選択します。
リソースも取得したいものにチェックを入れます。
ソースタイプはそのままで問題ありません。インデックスはデフォルトでもいいですし、他のものを選択していただいてもOKです。
分析してみる
停止忘れや無駄なインスタンスがないか、アカウントを横断して一覧表示する
source="*:ec2_instances" sourcetype="aws:metadata"
|dedup InstanceId sortby -_time
|table account_id region InstanceId instance_type image_id ip status
|sort +status
未使用や過剰なキャパシティとなっているEBSボリュームをアカウントを横断して特定する
source="*:ec2_volumes" sourcetype="aws:metadata"
|dedup VolumeId sortby -_time
| rename Attachments{}.InstanceId as InstanceId
|table AccountId AvailabilityZone VolumeId SnapshotId VolumeType Size InstanceId State
|sort -State
◯日間利用/ログインされていない、アクセスキーまたはアカウントをアカウントを横断して特定する
sourcetype="aws:metadata" source="*:iam_users"
| dedup Arn sortby -_time
|spath output=AccessKeys path=AccessKeys{}
|eval AccessKeys=mvfilter(match(AccessKeys,".*\"Status\": \"Active\",*"))
|fields AccountId UserName AccessKeys PasswordLastUsed
|mvexpand AccessKeys
|rex field=AccessKeys ".*LastUsedDate\": \"(?<LastUsedDate>[^\"]*)"
|eval ak_used_day=strptime(LastUsedDate,"%FT%T"), ps_used_day=strptime(PasswordLastUsed,"%FT%T"), recent_used_day=max(ak_used_day,ps_used_day), diff_days=((now() - recent_used_day) / 86400)
|stats min(diff_days) AS no_used_days BY UserName, AccountId
|eval no_used_days=round(no_used_days)
|where (no_used_days > 30)
|eval insight="User unused for extended period of time. (".no_used_days." days since last access)"
|sort - no_used_days
|table AccountId UserName insight
アカウントを横断して、VPCで利用中の割り当てIP Cidrを確認して現状の把握や適切なアーキテクトに活用する
source="*:vpcs" sourcetype="aws:metadata"
|dedup VpcId sortby -_time
|table AccountId Region VpcId CidrBlock State
|sort +state
まとめ
Splunkを使った、マルチアカウント構成で可視性を向上するための分析をいくつか試してみました。
他にも色々なアイデアがあると思いますので、また思いついたらご紹介させていただきたいと思います。