第 16日目は、SOC アナリスト 野岡弘幸の記事です。SOC の業務改善を促進するためのライブラリと基盤の開発について紹介します。

---

SOC アナリストの野岡です。セキュリティインシデントは状況に応じて適切に対応しなければならないため、その都度大量のログを扱って正確な分析を行う必要があります。しかし、アナリストが日々多数のお客様のログを分析していると、どこか似たようなインシデントが発生しては同じような分析結果のレポートを提出する、というようなことがよくあります。その他にも分析業務に関わる付随的な作業も数多くあります。このような「あまり頭を使わない作業」は以下の理由によりアナリストの好むところではありません。

  • 技術力が発揮されない
  • 思考停止に繋がりミスを誘発する
  • 稼働だけでなく思考も奪われ、付加価値の高い業務に使うべきリソースが削られる

このような不幸を積み重ねるとアナリストの 燃え尽き症候群 や離職などに繋がってしまうため、チームとして何らかの対策を打たなければいけません。

そこで、生産性の向上や分析のさらなる高度化、アナリストの従業員満足度の向上を目指して、私たちは「定型業務の自動化」における課題を本質的に解決することに挑戦しました。

共通ライブラリの作成

これまでも長年、分析業務や定型作業の自動化・効率化という課題に対して日常的に取り組んでいました。ところが、やはり自動化が進むにつれて多くの組織で経験するような次の問題が出てくるようになりました。ボトムアップに自動化を進めたときにありがちな「システムの乱立」「開発の重複」「作った人しか分からない」「依存システムの仕様変更に伴う大量の修正(と修正漏れ)」というものです。

そこで、我々はボトムアップの自動化の取り組みを継続しつつも、これまでの課題を解決し、より一層の自動化を促進するための方法を模索しました。そこで登場したのが、今まで開発してきた関連システムやツール群をフレームワーク化するというアイデアです。つまり、関連システムにアクセスするための処理を Python ライブラリとして共通化し、アナリストはプログラムやコマンドラインから各種機能を呼び出すという発想です。システム側の変更はライブラリで吸収することで、自動化スクリプト開発者はシステムの構成に左右されず自動化ロジックに集中することができます。また、自動化スクリプトの実装量が減るので、他のアナリストが書いたコードを引き継いでも(比較的)実装意図を読み取りやすくなります。

ライブラリ経由で各種システムにアクセスする場合は、Python スクリプトの先頭に

import lhk

と記述します。LHK とはこのプロジェクトのコードネームで、「L3(アナリスト)チームの働き方改革」を意味します。単に処理が共通化できるだけでなく、日ごろの作業においても気軽にスクリプトを作成することができるようになり、山ほどある GUI システムのボタンをポチポチと押して作業するよりも、ハッカーマインド溢れるクールな仕組みと言えるのではないでしょうか。

ライブラリの詳細な実装については利用するシステムに強く依存するため割愛しますが、実装の際に感じた自動化へのポイントを書いておきます。

入出力データの構造化

データをプログラムで扱う際の必須とも言っていい要件として、データが扱いやすく構造化されていることが挙げられます。巷でいう ネ申エクセル のようなデータを処理しようとすると、非常に複雑な処理が要求されバグの温床にもなるので、この部分が整理できていない場合は自動化以前に手を付ける必要があります。

プログラム的に操作可能なシステム

ライブラリを作成していて感じた障壁の 1つが、利用しているシステムの一部が人間による操作(のみ)を前提としていることでした。フォームに値を入力して Submit をクリックしているようなシステムでは自動化の恩恵を十分に受けることができません。これを解決するためにシステムへのリクエストをリバースエンジニアリングして操作に必要なリクエストを発行できるメソッドを開発しましたが、やはりなかなか実装していて辛いものがあったので、システムを作る際は自動化を念頭において API を整備することを強く推奨します。

ドキュメント

アナリストがライブラリの詳細な実装を気にしないといけないならば、ライブラリ化のメリットが大きく損なわれます。それを防ぐためにはコンポーネントにはどのようなメソッドがあり、メソッドにはどのような入出力が想定されているのかといった部分をきちんとドキュメントで残していくことが必要です。また、アナリストが読みやすいように用語の定義はきちんと統一される必要があり、また実装と乖離しないよう継続的にメンテナンスされる必要があります。

私たちは実装に取り掛かる前に用語集を作成して意思統一し、ソースコードにクラスやメソッドの説明をコメントで入れる(ドキュメントは pydoc で出力する)開発ルールを設けることで実装との乖離をなくすようにしています。

アーキテクチャとデザイン

各システムの連携を担うコンポーネントをどのように実装するかには様々な流儀があります。REST vs SOAP のような設計思想レベルから、クラスやメソッドの命名規則のようなレベル、さらに、アナリストがどのようにライブラリを利用するのかというユースケースまで考えて実装を決めていかないと、結局アナリストにとって使いにくいものとなってしまいます。(紆余曲折ありましたが)私たちは今のところ大まかに下記のような要件でライブラリを開発しています。

  • ライブラリ、スクリプトともに実装は Python 3 で行う。
  • アナリストは各システムを操作するクラスのインスタンスを作り、インスタンスのメソッドでシステムを操作する。
  • 各コンポーネントではシステムの機能に準ずるメソッドと、アナリストが実業務で行うような操作を模倣するメソッドを実装していく。
    • 例:フリーワードでのログ検索と、特定フィールドを指定したログ検索

Ver. 2 からが本番

どんなに入念に検討しても、いざリリースしてみるとどうしても改善点が出てきます。そういったものを一通り出しきると、気が付けば最初のリリースを丸ごと作り直したような Version 2 が出来上がることもあります。ただ、改めて見直すとその Version 2 はやはり様々な面で洗練されたものになっているので、1回リリースして終わりではなくライブラリ自身も継続的な改善の対象に組み込んでいくことが重要です。

FaaS によるスクリプトの実行

ライブラリを作成したら、次はそれらを用いたユースケースを充実させていくフェーズに入ります。このフェーズではアナリストがどのようにユースケースをリリースし、何をトリガーとするのかがカギとなります。私たちのチームの分析基盤は Kubernetes を使って構築しているので、リリース時は作成したユースケースが動作する Pod を展開することになります。Web GUI があるような、ある程度作りこみをしたアプリケーションはともかく、小さな toil を削減するちょっとしたスクリプトをリリースするために適切なイメージファイルの作成、Pod や Cronjob、Ingress などの Manifest 作成といった操作を要求することは場合によってはスクリプト本体の作成よりも手間となり、それがユースケース展開の障壁となりえます。この問題を解決するために、私たちは Kubeless をベースとした FaaS を分析基盤上に構築することにしました。Kubeless の選定理由としては下記 2点です。

  • 実装が比較的シンプルで既存の構成を変更する必要がない
  • HTTP(アナリスト任意のタイミングで実行)と Cronjob(定期実行)それぞれをトリガーとして利用できる

Kubeless 選定時に公式で提供されていた GUI は Cronjob をトリガーで設定できなかったり、誰がスクリプトを投入したかといった管理機能が少し弱かったので、GUI を自分達で内製して補いました。これにより、アナリストはスクリプト本体と、Cronjob を使う場合は実行周期を入力するだけでリリースすることができるようになりました。

何が自動化できたのか

上記のような取り組みを経て、私たちはこれまで手が付けづらかった様々な処理の自動化を実現することができるようになりました。以下はほんの一例です。

  • 定型的だが自動化しづらかったレポートの作成
  • エンドポイント分析のための初動データ収集
  • 分析ログを絞り込むためのフィルタのメンテナンス

最後に

本記事では SOC の継続的な改善として、分析自動化の取り組みを紹介しました。NTT セキュリティ・ジャパンではアナリスト自身がこれからも楽しくハッピーに分析サービスを提供し続けられるよう多くの施策を行っています。

SOCではこれらの取り組みに共感してくれる仲間を募集しています ので、興味を持っていただいた方はぜひご応募を検討ください。