Sumo Logicで社内の基幹AWS環境の情報を可視化してみた(CloudTrail編)

2019.08.30

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

オペレーション部 江口です。

当社では自社のサービスや自社で取り扱っているサービスを自分たちで利用してみる、いわゆるドッグフーディングに取り組んでいます。 その一貫として、当社で扱っているログの管理・分析ツール「Sumo Logic」を、基幹AWSアカウントの監視に利用してみると面白いかもね〜という話が社内で上がり、実際やってみることになりました。

まずはCloudTrailの可視化を行なって、オペ部のSlackで展開しつついろいろ試したので、ちょっと共有してみたいと思います。

当社の基幹AWSアカウントとは

当社の社員のAWSアカウントを管理している共用アカウントです。 当社のエンジニアはそれぞれAWS検証環境を持っていますが、一旦この基幹AWSにログインした後、スイッチロールして自分のAWS検証環境に入る運用となっています。

この基幹AWSアカウントのCloudTrailの情報をSumo Logicを使って可視化することで、アカウント周りの不審な挙動などをより分かりやすく確認・検知できるはずです。

設定

Sumo LogicでCloudTrailの情報を取得する方法については、すでにdevelopers.ioに詳細な記事があるためこちらをご参照ください。

CloudTrailのセキュリティ監視をちょー簡単にやってみた【Sumo Logic】

上記の記事ではIAMユーザのアクセスキーを使った方法が紹介されていますが、Sumo Logicはその後IAMロールを利用したアクセスにも対応しました。 よりセキュアなため現在はこちらの方法がおすすめです(今回もこちらで設定しました)。IAMロールを利用した設定方法もすでに記事がありますのでご参照ください。

Sumo LogicがIAMロールに対応しました

ちなみにCloudTrail用のダッシュボードでどんな情報が取得できるも、前掲のブログ記事で紹介されていますので、詳しくはこちらをご覧ください。

試してみた

設定してダッシュボードで情報が表示されるようになったので、取り急ぎSlackのオペ部のチャンネルで報告。

共有したスクリーンショットは「Console Logins」というログインに関する情報を可視化するダッシュボードでしたが、この時点で、ログインしたアカウントの場所を示すマップ情報で、気になるところがあるという指摘が出てきます。

クラスメソッドはバンクーバやベルリンに支社はありますが、ニューヨークには支社はないはずなのでおかしい、ということですね。

ここでマップをクリックするとドリルダウンしてニューヨークからアクセスしてきたユーザがサクッと確認できる・・・と便利ですが、残念ながらマップをクリックしてもズームするだけです。 ということで自前でクエリを作って情報を出してみました。

モザイクをかけていますが、各アカウントがどの国からログインしてきたのかが分かります。 クエリは以下のような感じです。「Console Logins」にはUS以外からのログインをリストするパネルがあるのですが、そのためのクエリから「US以外」をフィルタする部分を除いただけです。

_sourceCategory = cm-core/cloudtrail  "ConsoleLogin" 
| parse "\"eventName\":\"*\"" as eventName nodrop
| where eventName="ConsoleLogin"
| json "sourceIPAddress"
| parse "\"userName\":\"*\"" as user_name nodrop
| json field=_raw "userIdentity.principalId" as principal_id nodrop
| parse regex field = principal_id ":(?<user_principal>.+)" nodrop
| if (user_name="", user_principal, user_name) as user 
| json field=_raw "responseElements.ConsoleLogin" as loginResult nodrop
| parse "\"MFAUsed\":\"*\"" as mfaUsed nodrop
| count by sourceIPAddress, user, loginresult
| lookup latitude, longitude, country_code, country_name, region, city, postal_code from geo://location on ip = sourceIPAddress
| fields user, country_code, loginresult, _count
| sort by _count, country_code asc, user, loginresult

また、「認証に失敗したアカウントだけ確認したい」というリクエストも出てきたので対応してみました。

これは前掲のクエリの最後の行の前に、コンソールログイン成功/失敗を表すフィールドloginResultの値が失敗(Failure)であった場合、というフィルタを追加しただけです。

_sourceCategory = cm-core/cloudtrail  "ConsoleLogin" 
(略:前掲のクエリと同じ)
| where loginResult == "Failure"
| sort by _count, country_code asc, user, loginresult

また、コンソールログインではなく、オペレーションのアクセスが拒否されたオペレーションの情報も確認できるのですが、興味本位でどんなUserAgentでアクセス拒否されるイベントが多いんだろう・・・と思ってクエリを作ってみると、IntelliJ IDEAからのアクセスの拒否がなんだか滅茶苦茶多いことが分かりました。

※上記では「ログイン失敗」と書いていますが正確にはアクセス拒否です。

クエリは下記のような感じです。シンプルですね・・・AccessDeniedでフィルタして、userAgentフィールドをJSONで抽出、userAgentごとに指定期間内に見つかったイベント数をカウントしています。

_sourceCategory = cm-core/cloudtrail  "\"errorCode\":\"AccessDenied\""
| json "userAgent"
| count by userAgent

エラーメッセージは複数種類あるのだろうか、と思って見てみると一種類。またエラーメッセージにARNも含まれていたので、同一ユーザのIntelliJ IDEAがエラーを発生させているようだ、ということもわかりました。

クエリは下記のような感じです・ (スクリーンショットと少し内容が変わっていますが、下記でも目的の情報は抽出できます)

_sourceCategory = cm-core/cloudtrail  "\"errorCode\":\"AccessDenied\""
| json "userAgent","errorMessage"
| where userAgent contains "IntelliJ"
| count by errorMessage

where節でuserAgentがIntelliJであるもののみフィルタしてエラーメッセージで集計しています。 ユーザ名で集計したいのであれば下記のクエリで対応できます。

_sourceCategory = cm-core/cloudtrail  "\"errorCode\":\"AccessDenied\""
| json "userAgent","errorMessage" | json "userIdentity.userName" as user_name
| where userAgent contains "IntelliJ"
| count by user_name

終わりに

じつはここまで、CloudTrailのダッシュボード作ってから30分くらいの間のやりとりだったりします。 データを可視化してみんなで議論することで、短時間でいろんな分析ができるものだなあ、という感想です。

これ以外にもGuardDutyの可視化も行なってみたりしていますし、今後実際に運用に組み込めないかも社内で検討する、という話も出てきています。 今後もSumo Logicのドッグフーディングについて共有していきたいと思います。

とりあえず今回は以上です。読んでいただいてありがとうございました!