スケーラブルなセキュリティ監視基盤の作り方

水谷正慶氏:それでは、今ご紹介にあずかりました水谷が、クックパッドで現在取り組んでいるセキュリティの監視基盤の作り方に関して、発表させていただきたいと思います。

まず、簡単に自己紹介をさせていただきたいのですが、私は2017年11月にクックパッドに入社いたしました。その前は、研究開発なのでセキュリティ製品の開発であったり、あるいはそのセキュリティの監視をするようなサービスのアナリストとして働いていました。こちらに入ってからは、セキュリティグループに所属しまして、セキュリティの監視を中心に、セキュリティに関連する業務をやらせていただいています。

今回はセキュリティの話なので先におうかがいしてみたいのですが、この中でセキュリティに関する業務を実際やられている方ってどのぐらいいらっしゃいますかね?

(会場挙手)

ありがとうございます。たぶん今回TechConfということでジェネラルな内容が非常に多かったので、とくにセキュリティに特化してる方ってあんまりいないかなと思ったので、まず、セキュリティ監視というものに関して少し簡単に説明させていただきたいと思います。

セキュリティ対策の全体像

セキュリティの対策にはいろいろな種類のものがもちろんあるのですが、大きく分けると、「防御」と「検出」、そして「対応」という3つのフェーズに分けることができます。

「防御」に関しては、例えば、脆弱性をなくすであるとか、あるいは権限の管理をしっかりするといったような部分になります。

そして「検出」というのが、その防御を掻い潜ってきて実際に攻撃を受けたあとに、なにか問題が起きたかどうかを発見するようなフェーズになります。

最後に「対応」というのが、実際に問題が起きたときにそのダメージがどれぐらいあったかを調べたりであるとか、あるいは攻撃によって起きたダメージの回復を行うフェーズです。

基本的にこの3つのフェーズに分かれて対応するというような対策になっています。今日、今回お話しする監視に関しては、基本的にこの検出と対応というところの部分をカバーするようなものになっています。

検出に関しては、例えば、なにかセキュリティ上の問題があったというものの、そういうのを監視するサービスであるとかプロダクトから情報が上がってくるものを検出したりであるとか。

あるいはその対応に関しても、監視をする際にセキュリティに関連したログを収集するので、そのログから「実際にどういうことが起きていたのか?」であるとか、あるいは「実際にどのぐらいのダメージだったか?」をログから推測するようなことを、全体的に引っくるめて「監視」という呼び方をしています。

監視をする理由

そもそもなんで監視をするのかということに関して、「そもそも防御で全部止めちゃえばいいじゃん?」って思う方もいらっしゃるかもしれないのですが、なぜ監視をするのか。そもそも「完全な防御」が存在しないのが1つ大きな理由かなと思います。どうしてもやっぱり、対策をしても、新しく攻撃をする側がそれを乗り越えてくるということもあります。

さらに、検出のほうが、システム自体を使う利用者にとって、コストというか負担が少ないというメリットもあります。

だいたい「防御」というのは「なにかを制限する」であるとか「なにか止める」といったことになりがちなので、そういったものの代わりに、「ここは通すけど、ここでなにか問題があったときにすばやく検出ができるようにしておくと、防御ができなくても、すぐ対応できればセキュリティのリスクを防げるよね」という考え方があるので、そういったものを利用して監視をすることが必要になっています。

セキュリティ監視において消耗してしまうこと

今回のトピックとして「スケーラブルな監視」というタイトルをつけさせていただいたのですが、この「スケーラブル」というのはいったいどういうことかというと、サービスを開発して提供していく会社であったりとすると、サービスのスケールが規模が大きくなっていくのももちろんありますし、あるいは、対応をするべきサービスの種類が増えていくということもあります。

こういったものをひととおり対応していけることを「スケーラブル」という言い方をしているのですが、実際にこれに関してどういったことが問題になってくるかというと、複数サービスと結合したり、そもそもサービスの規模が大きくなって監視するべきものがすごく多くなることももちろん問題としてありえるのですが、今回フォーカスしたいのがこの一番下の部分で、アラートです。

セキュリティの監視をしているときに、「これはなにか問題がありますよ」というような情報が上がってきたときに、それに対応するコストがやっぱりどんどん上がってきてしまうので、これをどうにかしなきゃいけないというところのフォーカスを当ててお話をしたいと思います。

セキュリティ監視をするとき、消耗するようなことがいくつかあります。先ほどのアラート監視の話では、アラートを見たことある方はわかるかもしれないんですけど、誤検知や「これ別に問題じゃないよね」ということをアラートとして報告してくるサービス・プロダクトって、けっこう普通ありえる話なんですね。

これは大きく分けると、誤検知と過剰検知と呼ばれるものに分けることができます。誤検知というのは、そもそも攻撃じゃないんだけど、間違って検出しちゃいましたというパターン。過剰検知は、攻撃ではあったんだけど、実際には被害が起きていなくてちゃんと防げたものを検出してしまったパターンになります。

そういったものが上がってくるたびに、セキュリティの担当の人が逐一全部調べて対応しなきゃいけないとなると、オオカミ少年のような感じになってしまって、対応されないものが山積みになっていき、その中から重要なものが見逃されていくというつらい状況がどうしても出てきてしまうので、こういったものをどうやって防いでいくかが、監視のスケールを上げていく上で重要なポイントになってきます。

上がってくるアラートを減らすために

このような消耗を防ぐためにどうすればいいかというと、話としては非常にシンプルです。アラートとして上がってくるものをなるべく減らす。「そもそもこれは安全だから別に見なくてもいいよね」とか、あるいは「この条件にマッチしていれば、実際には被害が起きていないので、無視してもいい」ということを、実際には人間が調べる段階でそういったことをやっているので、なるべくルールとかそういったものの段階で除外していければいいわけです。

ですが、どうしても問題になるのが、例えばそのルールを調整したときに、「調整したあとにそれをちゃんと検知できるんですか?」ということはやはり検証しなければいけませんし、あるいは「不要だ」という判断のロジックは、サービスやプロダクトによっては柔軟に書けなかったりするので、そういったものをうまくやっていく必要もあります。

あとは、例えばサービスやプロダクトから出てくる完結する情報で「これは必要ないですよ」というのを除外できればいいんですけど、追加の情報を取ってこなければいけないことがあったりすると、そこで対応するのは難しくなってしまいます。

では、我々はどういうアプローチで解決しようとしているかというと、「Security as Code」という考え方があるので、これを利用して解決していければと考えてやっています。

Security as Code

このSecurity as Codeというのは、名前からなんとなく想像できるかもしれないのですが、いわゆるInfrastructure as Codeの派生的な概念と考えていただければと思います。本来のSecurity as Codeってもっと広い概念ではあるんですけど、今回はそのログの収集と分析のところにフォーカスして利用しているような状況です。

例えば、検知に関わる処理をコードとして記述することによって、検知自体をテストをしてからデプロイするといったようなことをできるようになりますし、その記述に関しても、プログラムそのもので書くことによってなるべく高い能力で表現ができるようになります。

あとは、自動的にデータを集めたりして判断するところに関しても、自動化をなるべく差し込んでいくことによって、なにかアラートがきた際も追加でデータを収集できるようにしています。

あとはバージョン管理ですね。誰がどういう意図でこのルールを変更したかも全部管理できるようになることで、全体的にセキュリティ担当の負荷を下げることを目的としています。

アラート処理のパイプライン

実際にどういうシステムを作っているかというところの簡単なご紹介なのですが、基本的には3つのフェーズに分けて実装をしています。

1つがアラートの検出ということで、これは例えばセキュリティのプロダクトであるとかサービスから「怪しいですよ」という情報が飛んでくることもありますし、自分たちでログのデータから怪しい部分を見つけるということもやっています。

次がその関連情報の収集ということで、このなにか怪しい情報が上がってきたときに、じゃあそれに関連するIPアドレスの情報を内部であったり外部であったりとかっていうところからいろいろかき集めてきて、最後のアラートの評価というところで「それは実際にリスクがあったんですか? もしくは無視していいものなんですか?」というところの判定までを、一気通貫で行うような仕組みになっています。

最終的に、PagerDutyとかSlackとかを利用して情報の共有とかを行っているようなかたちになります。

アラートの検出

それぞれ細かく見ていきたいかなと思います。

まずアラートの検出に関しては、ログを収集するところに関しては省かせてもらうのですが、基本的にクックパッドでは現在、ログをすべてS3にデータとして上げるというかたちで管理をしています。

この上がったログを、SNSを通してLambdaを通してといういくつかのパイプラインがあるんですが、最終的には、右側の図にある、アラート検出のためのLambdaを実装して、例えば「本来このアラートは調査をするべきである」とか、あるいは「このアラートに関しては無視するべき」というルールを記述できるようなかたちで実装を行っています。

具体例を簡単にご紹介できればと思います。例えば、これはあるNGFW、つまりファイアウォールでオフィスの通信を監視しているものに関してのアラートです。

ある特定のサイトにアクセスした際に、「OpenSSLのDoSである」という誤判定がされてしまうことがわかっていたので、これを除外するルールを書きたい場合には、例えば通信しているホスト名をルールに記述するであるとか、あるいはドメイン名……検知名ですね。こういう条件の組み合わせで「これは別にアラートではありませんよ」といったように、特定の検知名を無視するルールを記述することができます。

こちらは別の例なんですが、こちらはもう少し複雑です。AWSで動かしているインスタンスから、怪しい不正に利用されているドメインに対して通信が発生したことを検知するアラートです。

不正に取得されたドメイン名に対してクエリを送るのは、本来普通のインスタンスではあまり起こりません。ですがメールサーバなどでは送られてきたメールに対してのドメインの問い合わせをしてしまうことがあるので、そういったものに対して検出されたものを無視したいというのことが起きたときには、同様にルールで記述しています。

今回の場合は、あるインスタンスに対しては「メールサーバとして使われていますよ」というタグがついているので、そのタグの情報をアラートの中から発見したり、ある特定のドメイン名に対しては「これは無視してもいい」というようなことを書くことによって、繰り返し同じようなアラートが上がらないようにというところを記述して、このアラートに対する対応のコストを下げているかたちになります。

アラート関連情報の収集と評価

そのアラートが上がってきたあとにどうするかというと、アラートに関連した情報をかき集めています。

具体的には、外部からの情報としてマルウェア関連情報サイトの「VirusTotal」とか、あるいはサンドボックスのサイトを利用して、関連するIPアドレスとかハッシュ値に関する情報をかき集めてきます。

同様に、内部からの情報もかき集めています。例えば、アラートに出現してきたユーザーが直前にどういう行動をしていたのかサービスの利用のログや、このサービスに対してアクセスしてきたマシンがそもそもどういう種類のマシンだったかというデバイスの情報も、同様に収集をしています。

これらの情報を集めた上で、最終的なアラートの評価を行っています。

アラートの評価に関しては、アラートを、先ほど外部や内部から収集してきた情報をもとに、「このアラートとこの情報の組み合わせがあった場合には問題がありますよ」とか「問題がありませんよ」ということを判定するようなものになっています。

こちらに関して具体的なところをお見せしていければと思います。これはAWSのGuardDutyから上がってきたアラートです。

上がってきたアラートで「ふだんと異なるネットワークネットワークからアクセスがありました」というアラートが上がってきても、例えば「リモートワークをしている社員がそこからアクセスしてきた」というパターンももちろんあったりします。

ですので、実際にアクセスしてきたIPアドレスやデバイスの情報を調べたときに、例えば、実際に自社が持っているデバイスからそのアクセスがあったことがわかれば、「リモートワークをしている人がたまたまどこかのカフェからアクセスしました」みたいなことがわかったりするので、そういったときには「それは問題ない」と判断できます。

こういったことを、実際にルールとしてコードで表現できることによって、セキュリティの担当の人が何度も同じようなアラートに対応しなくても、その対応のコストを下げることができるようになっています。

ということでまとめさせていただきます。

そのサービスの規模とか種類が増えていくにあたって、もちろんその流量自体を捌くことも必要なんですが、その一方でアラート自体の対応も同時に考えていかなければいけません。

今回ご紹介させていただいたのは、その対応をするためにCodenizeや自動化をなるべく行うことによってセキュリティ担当の負担を減らして、監視の幅を広げていくような取り組みをご説明させていただきました。

以上で発表を終わります。ご清聴ありがとうございました

(会場拍手)