ある研究者の手記

セキュリティとかゲームとかプログラミングとかそのへん

Ubieで一緒にセキュリティをエンジニアリングしていってくれる方を募集中です

TL; DR

  • セキュリティエンジニア(プロダクトおよびコーポレート)絶賛募集中です
  • セキュリティだけを専門でやられていた方だけでなく、サービス開発が中心だったけどセキュリティも少しやっていたみたいな方も大歓迎です

ヘルステックのスタートアップであるUbieで働き始めておよそ2ヶ月ほどたちました。入社する前からなんとなくは知っていましたが、メンバーの熱量の高さや能力の高さに圧倒され続けています。事業についても患者さん向けのユビ―AI受診相談や医師向けのユビーAI問診が中心ではあるものの、その枠に留まらない新しいチャレンジを多角的に取り組んでおり、とても刺激的な日々を過ごしています。自分はセキュリティエンジニアとして入社させてもらい、まだ大きな進捗はないもののUbieで提供するプロダクトやそのプラットフォームのセキュリティを向上させる取り組みをさせてもらっています。

転職した理由として、事業ドメインや成長フェーズの異なる会社に移り、自分の技術や知識、そして考え方が通用するかというのを試したいというものがありました。入社前からいろいろと社内の話はいくらか聞いていましたが、実際に働いてみることで徐々に自分の中で取り組むべき具体的な課題がはっきりしてくるようになりました。同時に、1つ1つがとても重い話で一緒に取り組んでくれる仲間がもっと必要であるということも分かってきました。

そこで、Ubieがこれから取り組みたい課題について言語化してみつつ、どういった方を探しているかについてまとめてみました。興味を持っていただいた方がいたら、ぜひお話させてもらえると嬉しいです。

Ubieにおけるセキュリティのチャレンジ

DevSecOps

バズワードのため定義がはっきりしないDevSecOpsですが、自分の中では以下のように定義しています。

  1. プロダクト開発の各段階で必要なセキュリティの要件を満たしていける
  2. プロダクト開発で継続的に脆弱性が入り込んでいないかのチェックをする

どのサービス事業会社もそうだとは思いますが、Ubieでは特にプロダクトの機能拡張や新しいプロダクトの開発がものすごいスピードで進んでいます。「今度こういう機能を実装する予定なんですよ」 → 「もうできました」みたいな爆速事案をしばしば目撃します。それゆえにプロダクトの変化が激しく、セキュリティ上問題になるような仕組みになっていないか、扱うデータが適切か、脆弱性などが入り込んでいないかなどを常に気にし続けなければなりません。セキュリティを専門に理解している人が張り付くという方法もあるかもしれませんが、スケールしないというのが難点です。

これを解決するアプローチとして仕組み化と自動化を積極的にやっていきたいと考えています。この問題は単にCIにセキュリティチェックを組み込めばいいというわけではなく、どうすれば開発するメンバーの負荷にならないようにセキュリティを向上させられるかを模索していかなければなりません。そのためどちらかといえばプロダクト開発の経験があり、かつセキュリティに対して興味がある、というような方と一緒にチャレンジできると面白そうだなと考えています。

全社共通・横断のプロダクト向けセキュリティ機能の実装

前述したとおり、UbieではユビーAI受診相談およびユビーAI問診という2つのプロダクトを主軸としていますが、それらの拡張だけでなく新しいプロダクトの開発も積極的に取り組んでいます。これら全てのプロダクトは医療に関係するものであり、各々でセキュリティの機能(認証認可、プライバシー保護、監査、リスク分析など)が必要があります。

プロダクトが少ないうちは個別に実装するほうが柔軟に動けるなどのメリットがありますが、プロダクトが多くなってくると実装水準のばらつきや全社的なコントロール、状況把握が難しくなるという課題があります。そこでプロダクトが成長・拡大しようとしているこのタイミングで、全社共通のセキュリティ関連機能を実装したいと考えています。これによって、各プロダクトが必要なセキュリティの水準を満たしつつ、サービス開発者が開発のスピードを上げられるという恩恵も得られるようになると期待されます。

具体的な事例として、認証認可基盤の構築があります。開発するプロダクトが増えることで、認証認可の仕組みをどのように整えていくかという問題と向き合わなければいけません。現代の認証認可の仕組みは単純なID・パスワードの組み合わせを保持すればいいというだけでなく、多要素認証や様々なデバイスからの利用、そしてサービス間の連携を考える必要があります。Ubieが新しいプロダクトや機能を展開していくとなるとその間の認可をどのように制御すればいいかも考える必要があります。

この機能もプロダクトごとに開発すると実装水準にばらつきが出てしまう他、将来的に会社横断で統合するとなると時間が立つほど移行の苦しみが大きくなってきます。今まさにプロダクトが広がっていこうとしている中でこのような仕組みをゼロから設計・実装できるというのは絶妙なチャンスだと考えていますが、自分はこういった仕組みを知識として知っているだけで、実際に大規模な基盤を実装・運用した経験がありません。そういった知識・経験・実装力をもった方にぜひ力を貸していただきたいと考えています。

社内の統合的なセキュリティの向上

Ubieは現在急速にメンバーを増やしつつあり、そのため社内システムや働く環境のセキュリティについても急速に整えていく必要があります。創業したばかりのベンチャーだとよくあることかもしれませんが、Ubieは事業を加速させるために社内のメンバーが自ら各種クラウドサービスを積極的に導入・活用するという文化が根づいています。現状、管理体制として2020年にはISMSを取得し、3省2ガイドラインの準拠を進めるなど、社内体制やシステム側の安全管理を急速に整えてきています。しかし今後世界市場に拡大するためにも、今ある文化を活かしつつ、安全かつスムーズに各種サービスが使えるようなサービス統制や環境整備をさらに進化させる必要があります。

また、各社内システムなどで一定のセキュリティを保つような設定をしているものの、統合した守りの体制を構築していく必要があります。例えば各システムの状況をセキュリティ観点で監視・調査したり、アラートの調査や対応をしたり、セキュリティ関連のエンドポイント製品の導入や運用をしたり…というようなものがあります。これらをバラバラに使うのではなく、それぞれを連携させて機能できるようなグランドデザインをしながら実装・運用をしていく、という試みが必要です。

このような体制を整えていくにあたり、人手を増やすことでスケールさせることも時には必要ですが、近代的なシステムやツールの力を使い、人だけに依存しないような構造を考えていく、というところにエンジニアリングとしてのチャレンジがあるのではないかと思います。そういった取り組みに興味がある人と是非一緒に取り組んでいきたいと考えています。

どういった方に来てもらいたいか

「セキュリティエンジニア」という募集をすると「ずっと情報セキュリティを専門にやってきた方のみを対象にしている」と思われがちですが決してそんなことはありません。特にセキュリティベンダー以外のユーザ向け企業などにおいて、セキュリティの分野というのは業務や開発といった営みに強く関係するものであり、時としてそちらについての知見が必要とされる場合もあります。

もちろん一定のセキュリティに関する知識やエンジニアリングに関する技量は必要となりますが、セキュリティ以外のことについてもいろいろ取り組まれていたり、メインは開発だけど実態としてプロダクトのセキュリティ関連のケアをしてきた、というような人にもぜひ興味を持っていただけると嬉しいです。

meetyのカジュアル面談募集のリンクも以下にありますので、興味を持っていただけた方はぜひお声がけください。お待ちしています!

meety.net

その他関連リンク

recruit.ubie.life

recruit.ubie.life

2021年8月の夏休み

先日ブログに書いたとおり7月末を最終出社として退職し、8月は有給消化期間にした。学生時代以来の長期夏休みを獲得したし、8月上旬にはfully vaccinatedになっていたのでうまくいけば8月下旬にふらっと旅行するぐらい大丈夫なんじゃないかな、とかちょっと期待していたらデルタ株によってご覧の有様である。

そんなわけで折角の機会にも関わらず1ヶ月間は自宅の半径2kmから出ることなく過ごす羽目になってしまい、何もなさすぎて自分でも何をしていたのか忘れてしまいそうなのでブログをしたためておく。

読書

転職先の推薦図書をいくつか読んだ。

Measure What Matters

OKR (Objectives and Key Results) の仕組みや効果についてひたすら書かれている本。OKRというものに触れたのが初めてだったので最初はよくある目標設定とどう違うのかというのがピンときていなかった。今回、自分が読んでなるほどなと思った点は以下の3つだった。

  • 「やるべき重要な取り組み」の優先順位は組織でも個人でもすぐにブレる。なので方向性を揃えたり修正したりするためにOKRが使える。
  • 全社的にOKRというシンプルなプロトコルを使うことで目標管理のコミュニケーションがやりやすくなる。特に全社で定めたOKRが下位のOKRとつながることで、会社としての取り組みに整合性がうまれたりメンバー間の協力がしやすくなる。
  • OKRは「組織にとって価値あることに集中」するための仕組みで、成果をトラックする&必要に応じて柔軟に変更するという運用をやって初めて効果が発揮される。
    • 個人の成績と紐付けてはいけない。なぜなら「組織にとって価値あること」ではなく「OKRを達成すること」が重視されるようになり、間違っていたり環境変化によって効果的ではなくなってしまったOKRでもそれを達成させようとする力学が働くから

How Google Works

おなじみのGoogleが内部でどういう思想でどういう運用をしているかについて書かれた本。全体的に話がちょっと古い(2000年代ぐらいの話が中心)なのと、結果論なのではと思う話が多いきらいはあるものの、 "Googleっぽさ" をいくらか理解できたかなと思う。この本で書かれているような内容も現在においてはすでにいろいろな会社・組織に取り入れられるようになったなと感じており、読んだ率直な感想としてすごい斬新だとは思わなかった。ただ、もともとの根幹の話に触れておくのは大切だし、良い機会だったと思う。

1兆ドルコーチ

シリコンバレーのbig tech企業を中心にコーチングの才を発揮していたビル・キャンベル氏の逸話集。氏の類まれな能力や人格による話なので全てをそのまま実践するのは難しく、体系だてた話でもないのでスッと理解するのも難しい。とはいえ自分に足りない人間力的なところで学ぶべきてきなところや、これからチャレンジしていくべきポイントという意味では学びがあったかなと思う。

開発

個人開発で手を付けたもの。

AlertChain

Security Orchestration, Automation and Response (SOAR) の小さい実装。前職にいたときはAWSのフルサーバレスアーキテクチャDeepAlertというSOARを実装していたが、次の職場ではGCPなので可搬性ゼロで無事終了していた。ということでコンテナベースで動くものを作ろう思い立ったのだが、この機に最初から設計し直すかとなってフルスクラッチしているのがこのAlertChain。

github.com

基本的にはセキュリティアラートを受け取って、1) アラートに対して事前に定めたワークフローを自動的に実行する、2) 追加のワークフローを管理画面から実行できる、という2つだけの機能が主軸。事前に定めたワークフローでは、アラートにでてきたIPアドレスをOSINTしたり、条件に従ってリスク判定したり、どこかに通知したりというようなユースケースを想定している。一方、追加のワークフローというのはもうちょっとアグレッシブ&人間の判断を挟んだほうが良さそうなもので、例えばinstanceをtermianteしたり、ユーザ権限をsuspendさせたり、みたいなのを想定している。下図は対象IPアドレスをBANさせるという追加ワークフローの例。

f:id:mztnex:20210904184210p:plain

前作との違いを少しふれると、以下の3点。

  • 前作は各ワークフローがばらばらになっていてテストがしにくかったのを悔い改め、AlertChainでは全ワークフローを一気通貫でテストできるようにした
  • 1プロセスだけで動くようにして運用やデバッグをやりやすくした
  • AlertChain自体がちゃんとアラートの情報を保持するようにし、管理画面から確認できるようにした

正直、まだ荒削りというレベルにすら達していないが次の職場に導入していきたいと画策していて、運用していく中でブラッシュアップしていきたいと考えている。もうちょっと整ってきたタイミングで解説記事などを改めて書きたい。

zenv

開発などで手元のPCで環境変数を扱う時、envchainを活用しているが、秘匿値以外の環境変数もいい感じに扱えるツールがあると便利だなといろいろ思案した結果、結局envchain + dotenvのようなツールができたというのがこれ。なので既存ツールを組み合わせでどうとでもなる範疇の実装ではあり、人様に強く進めたいというほどのものではない。ただ、 .env ファイルに通常の環境変数だけでなく秘匿値の指定(秘匿値は実際にはkeychain内に保存してある)をしたり、読み込んだ環境変数を元にコマンドライン引数を書き換えたりができるようになっているので、個人的には便利。

github.com

利用イメージとしてはこんな感じ

$ zenv secret write @aws-account AWS_SECRET_ACCESS_KEY 
Value: # コピペなどで入力
$ zenv list @aws-account 
AWS_SECRET_ACCESS_KEY=**************************************** (hidden) # 読み込んだ環境変数を表示。秘匿値は伏せ字にする
$ zenv @aws-account aws s3 ls
(snip) # S3のリスト表示
$ echo "AWS_REGION=ap-northeast-1" > .env
$ zenv list @aws-account
AWS_SECRET_ACCESS_KEY=**************************************** (hidden)
AWS_REGION=ap-northeast-1 # .envファイルからも読み込み

生活

ダイエット

特に意気込んでやっていたわけではないんだけど成果はでていたので、したためておく。運動+なんちゃって糖質制限的なやつを6月末からやっていて、だいたい3kgぐらい減量した。

運動は実は去年からずっとエアロバイク30分程度というのを中心にほぼ毎日やっていたのだが、いまいち減量するにはいたならかった。そこでなんとなく食事量(特に糖質)を減らしてみたところ、徐々に体重が落ち始めたので惰性で続けてみて今に至る。

食事はbase breadとnoshを活用しており、自分ではオートミールをベースにした炒飯とかカレーとかを調理したりしている。あと鶏むね肉やローストビーフをバッチで継続的に低温調理している。糖質はだいたい1日あたり平均して120gぐらいなはず。あとFitbitに食事管理機能があるのだが、定型の食事(それこそbase breadとかnosh)を摂る場合は計測しやすく便利。記入漏れとかもあるからあまり正確ではないが、概ね1日あたり500〜600kcalほどは消費カロリー量が上回っているらしい。

長らく米を食べていないので「たまにはがっつりカツ丼とか食べたい!」と思うことはままあるものの、今のところそこまで辛い気持ちにはなっていないので、無理なく継続してシュッとしていきたい。

ゲーム

MONSTER HUNTER RISE

エアロバイクのお供。毎日30分くらい野良で狩りに行っている。エアロバイクをやっていることを程よく忘れられるくらいの集中力が必要。他のゲームも試してみたが、あんまり没頭できないゲームだと「漕いでいて辛い」という気持ちが続いてしまうのだが、モンハンはいい感じに没頭できる。あと1サイクルが10〜15分くらいなので、2〜3回やっていると運動時間が終わるというのも良い。トータルのプレイ時間はそんなに長くないのでHR200ちょいぐらい。

ただ最近さすがにちょっと飽きは感じ始めているので、代替になりそうなゲーム無いかなとは思い始めている。

Factorio

無人の星に不時着してしまったエンジニアが資源を集めて建物や工場を作り、武装や物流システムを発展させていくゲーム。一応、生産物の一つである「ロケット」を作るとクリアとはされているのだが、マップが無限に広がっておりクリア後も工場を発展させることができる。

このゲーム、去年末くらいにめちゃくちゃハマって300時間くらいプレイし、自分なりの物流システムの最適解に至るまでやりこんだ。ところが、あまりに工場をでかくしすぎて処理負荷が大きくなりゲームがまともに動かなくなってしまったので、それ以降あまりプレイしなくなっていた。で、特に何かあったわけではないんだけど、ふともう一度ゼロから始めるかとなり、異世界転生よろしく2周目の知識を活かして、丁寧かつゆるゆるとしたプレイをしている。

f:id:mztnex:20210905125231p:plain
支配地域を広げすぎてわけわからなくなってしまった図。中心部が工場で、資源採掘ポイントと固定砲台が置かれている軍事拠点が鉄道網で各地に散らばっている

月姫

もう永遠に発売されないんじゃないかと思っていたけど、本当に発売されたよ! ありがとうTYPE-MOON!!

とりあえずの感想として結構演出も凝っているし(「魔法使いの夜」に近い)フルボイスなのでオートモードでプレイしていると実質アニメを見ているのに近く非常に快適。そのため自分の進行はとても遅くまだ序盤も序盤。ただ原作未プレイ勢ではあるものの、結末とか世界設定とかはだいたい知っているのでゆるゆる一月ぐらいかけて楽しんでいくつもり。

転職します(Cookpad → Ubie)

f:id:mztnex:20210731121501p:plain
https://github.com/m-mizutani/m-mizutani/commit/067a421f3e3e8405cba870bb461446c545128a2e

2021年7月30日を最終出社日として現職のCookpadを退職し、9月からUbieという医療系のスタートアップに入社します。

Cookpadでのこれまで

2017年11月に入社したので、在籍期間は4年弱でした。この間、組織変更に伴う部署異動はありましたが、ずっと情報セキュリティに関わる業務をやってきました。

システムのセキュリティ対策

主な業務は「インフラや社内システム、開発サービスに対するセキュリティの機能をエンジニアリングによって向上させること」でした。 製品やサービスをそのまま導入することもありますが、自分たちの必要に応じて既存ツールを拡張したり、全く新しいシステムを自作することもありました。 例えば以下が代表的なやつです。

セキュリティに関する社内の問題を見つけ出してエンジニアリングによってそれを解決していく、という仕事内容は自分の志向とマッチしており仕事はとても楽しかったです。 さらに仕事で取り組んだ結果を発表する機会も各所から多くいただき、これについてもありがたかったです。 USに飛んで英語で撮影するぞという話を突然もらって、七転八倒しながら達成したのも良い思い出です。

ただ調子に乗っていろいろやりすぎてしまった感があり、退職に伴って大量のシステムを引き継ぐことになってしまった点については少し申し訳ないなと感じている次第です。

社内リスク対応

いわゆる社内の情報セキュリティ委員会というやつもやっており、社内で新たに起きる情報セキュリティのリスクをコントロールするということもやっていました。 自分もこの業務に携わるまであまり意識したことがなかったんですが、会社の活動というのは目まぐるしく変化し、それに伴って様々なリスクが発生します。 そういったリスクに対応するため、どんな情報システムを使ったらいいのか、どのように使ったらいいのか、どんなデータを扱っていいのか、という相談をうけたり判断をしたりということもやっていました。

これは単純に社内ルールに準拠するだけでなく、法律や規制などについても配慮し、とりあつかう情報の重要度などから実際のリスクを考え、現実的な落とし所を考える必要があり、最初のうちはかなりハードな業務でした。 自分もそもそも法律などについては素人だったり、(セキュリティの人にありがちですが)過度に安全側に倒して現実的でない方法になってしまうなど四苦八苦していました。 しかし同僚の助けも借りつつ最終的にはある程度の部分をこなせるようになった気がしており、自分としてはなかなか良い経験値になったのではと思います。

その他会社生活全般

組織のカルチャーや雰囲気も自分にとってはかなりマッチしていたと思います。 前職が大手SI企業だったこともあり、そのギャップの衝撃から入社直後にわりとはしゃいでいる記事を書いたりしていました。 さすがに今はもうこの記事のテンションはありませんが、ここで良かったと感じたことは特に変わっていません。

今回の転職直前にオフィスが恵比寿からみなとみらいへ移転するという一大イベントがありましたが、これについても今回の転職とはあまり関係ありません。 個人的にみなとみらいはいろいろ思い出深い土地で気持ちがあったし、WeWorkの無限にビールが飲めるサービスとか楽しみにしていたのですが、情勢によって結局ほとんど恩恵に預かれませんでした。悲しい。

転職のきっかけ

ということで現職に対して特に厳しいことがあったというわけではないのですが、自分の能力の幅を広げるという観点でこの度転職をすることにしました。

セキュリティエンジニアのキャリアパスというのもいろいろあると思うのですが、自分は「システムのセキュリティ対策」というのがやはり最も興味の強い範囲で、 これを継続していった場合にどのようにキャリアを重ねていけばいいのかという点についてはこれまでずっと模索してきました。 社内リスク対応の方はパスとして例えばCISOになるというような話があったりすると思いますが、 どちらかというと現場でエンジニアリングしていたいので、役職を上げるのとはまた違うかなと考えています。

というようなことを長らくもやもやと考えていたのですが、あるきっかけで「違う事業ドメインにチャレンジしてみることで幅を広げるのがいいのでは」と思いつきました。

同じWeb系であっても他社のセキュリティ担当の方と話させてもらうと、やはり会社の事業ごとにリスクであったり守るべき資産の捉え方というのが大きく違うな、というのは以前から感じていました。 そのため現職でうまくいっている事例を話しても「うちとは(環境や背景が)違いますね」という反応になることがあり、自分のやっていることが他の会社や事業ドメインでどのくらい通用するのか?というのが未知なままでした。 そこは確かにやってみないとわからないので「だったら環境を変えてチャレンジすることでより多くの場所で通用することを増やしていこう」と考えるようになりました。

Ubieでのこれから

というわけで冒頭で書いたとおり、Ubieという医療系のスタートアップに転職することにしました。現状では医療機関向け、および患者さん向けのサポートをして患者さんを適切な医療へつないでいく、といったサービスを提供しています。(私もまだ事業の細かいところを知っているわけではないので、詳しくはこちらの資料を見ていただくか、あるいは興味のある方はぜひお声がけください)

ubie.app

Ubieに決めた理由

実は今回の転職では他の会社の選考は受けておらずUbie一本だった*1ため、他社との比較はしていません。普通に考えて転職するときは複数社を受けてオファーを並べて検討するものと思うのですが、1社目で転職しようと考えた決定的な理由は以下の2つでした。

  1. 事業ドメインが今までと大きく違う
  2. セキュリティをエンジニアリングしていくことへの理解

1については転職のきっかけの話の通り、事業ドメインがなるべく違うところが望ましいというのがありました。 特にセキュリティに対しての厳しさでいうと自分の中では医療と金融が最も難しい分野であり、その片方である医療の分野というのは自分の思惑にとてもマッチしていました。 また、事業についても「今あるアナログなビジネスをちゃんとデジタル化していく」という分野は個人的にとても面白く、熱い領域であると考えています。 (流行り言葉を使うといわゆる "DX" になるんだと思います) Ubieの事業が医療機関に関わってくることで自分たちのサービスだけでなく、医療機関でのセキュリティというのも同時に携わっていく必要があり、 それについてもチャレンジングで興味深いと考えています。

自分の中でさらに決定打になったのは2の「セキュリティをエンジニアリングしてくことへの理解」が大きかったです。 これはCookpadへ入社する際の転職活動で感じたことでもあるのですが、 いわゆるセキュリティの問題に対して製品やサービスの導入するだけでなく、 ちゃんと自分たちでエンジニアリングをして問題を解決しようというマインドを持った組織というのは日本だとまだかなり少ない印象です*2。 Ubieのメンバーとカジュアル面談をした際に彼らもその課題感をもっており、しかしまだそこにアプローチするメンバーがいないという話を聞いたときに、 ここで働いてみたいなとう気持ちが強くなったことを覚えています。

この他にもマネジメント的な上下関係がない組織構造(ホラクラシー)や評価のない制度、会社の雰囲気など惹かれた部分はいろいろあります。ただまだ直接働いたわけではなく「良さそう」という印象でしかないので、詳しくはいずれ別の機会にという感じです。

やっていきたいこと

というわけでUbieへの転職後も引き続きセキュリティエンジニアをやっていく予定です。

今回は医療という領域になるため、リスクに対する考え方や対応がよりシビアになっていくのではないかと考えています。 利用してもらう人のために十分な安全性を担保していかなければならないのですが、じゃあどこまでやったら「十分か」ということを常に見極めていく必要があります。 そうしたことを突き詰めていく課程で、最適なセキュリティとはなんなのか?、そもそも最適というものがあるのか? ということを考えていきたいと思っています。

また自分の密かな目標として、サービス運用をソフトウェアエンジニアリングの方法でアプローチするSRE(Site Reliability Engineering)にあやかり、Security Reliability Engineering*3の方法論を探求していきたい、というものがあります。 Site Reliability EngineeringはもともとGoogle社内で運用にまつわる作業や問題をソフトウェア開発の考え方・発想・手法で解決する方法論を体系化して世に出したのが発端という認識です*4。 この着想はセキュリティに関する運用にも適用でき、ソフトウェアエンジニアリングの応用で解決できる問題というのは多くあるのではないかと自分は考えています。 ただSREとは領域や前提がいろいろ違うためそのまま持ってくることはできず、セキュリティ分野ならどうかということを改めて検討しなければなりません。

自分が新しい領域でチャレンジすることでSecurityのReliability Engineeringの方法論を体系化していく足がかりになればと考えており、引き続きやっていきたいと思います。

ということで

各位、引き続きどうぞよろしくお願いいたします。

*1:厳密に言うとUbieに最初に声をかけてもらったので、Ubieの選考がだめだったら他を考えようとしていました

*2:逆に海外のbig tech companyはこのマインドがかなり強い印象で、例えばAWSの事例紹介などでユーザ企業がAWSのサービスを組み合わせてセキュリティの問題を解決しているという話は多くあります

*3:略語がSREともろかぶりなので、この名付けはどうかと思うんですが

*4:なんですが門外漢なので違ったらこっそり教えて下さい

シン・エヴァンゲリオン感想(ネタバレあり)

3月8日の11:00〜の回でシン・エヴァンゲリオンを観劇してきました。基本的ただの雑感のなぐり書きですが、旧劇の「閉塞の拡大」をBGMに聴きながら今のお気持ちをしたためておきます。思春期から拗らせた者の末路なので、その前提でご笑覧ください。

ネタバレしかないので、ご注意ください

全体通して

「まとまった…な…?」みたいな感じ。

アニメーションとしてはめちゃくちゃ動くしすごかったけど、エンターテイメントとしては序や破の方が好きだし、旧劇劇場版のようにバチバチに尖ったところもなかったなという感じ。とはいえこれまでの物語を締めようとしているというのがしっかり見えて「あーこれで終わりなんだな」というのを実感させられた。四半世紀に渡る因縁に対してスパッと決着ついたのかと言われるとちょっとわからないけど、とりあえずこの作品を世に出してくれてありがとうという気持ちです。

その他雑感

序盤〜ヴンダー出撃

  • 小出しにされるコンテンツ見るの嫌い派なので先行映像は一切観なかった、ので冒頭の戦闘シーンは登場する敵含めてちょっと意表をつかれて良かった
  • 村の生活で人間性を獲得していく綾波に対し、どんどん人間性を失っていくシンジがちょっと哀れ
  • シンジ、旧劇ではわりと「そんなことでうじうじしているんじゃない」みたいな感じがあったけど今回の件はまあそりゃ落ち込むよね…、という納得がめちゃくちゃあった
    • とはいえ旧劇劇場版みたいに最後までこのテンションだったらどうするんや…と思っていたけど、ちゃんと復活してくれてよかった
    • アスカにけちょんけちょんに言われてたけど、自分で世界滅ぼしかけて目前で友人殺されてという状況からちゃんと立ち直るの、むしろ強靭メンタルすぎでは?
  • アスカとケンスケがいい仲になっていたのは最初「まじで!?」ってなったけど、個人的にはなんかわりとすんなり受け止められた。一方、一緒に見に行った友人は許せていなそうであった。古のオタクは難しいのだ
  • プラグスーツの電源がなくなる描写、そのまま爆発でもするんじゃないかとヒヤヒヤした

異空間での戦闘〜シンジ覚醒

  • 誘導弾、「完全に無人在来線爆弾じゃねーか」と思わずツッコミ
  • 「ヤマト作戦」とかその他あれこれで、ああ庵野監督は本当に宇宙戦艦ヤマト好きなんだなぁと実感
  • ミサトさんとシンジのコミュニケーションが落ち着いたものでなんか良かった

マイナス宇宙〜終劇

  • 親子プロレス(初号機vs13号機)は、仮想世界での戦いという演出はすごいわかるんだけど、なんかギャグっぽく感じてしまいうーむという印象
    • 「特撮っぽい描写」を演出するために色んな要素をチープにしていたと思うんだけど、あそここそ全力全開最高作画をやってほしかった
    • 異空間とかスケールのデカさからなんかグレンラガンを想起した
  • 旧劇のお家芸、精神世界描写もでてきたり、旧劇のラストに通じるアスカのシーンも会ったりして「あー、ほんとうに過去の因縁を終わらせようとしてくれたんだな」というのを感じた
    • しかしこれ新劇だけ観てた人にはわりと「?」になったりするんじゃないかな
    • 本当は旧劇もこうありたかったということなんじゃないかなー?
  • 旧劇だとゲンドウについてあまり語られなかったけど、今回の深堀りで普通にまるでダメなオヤジだったことがわかりちょっとニッコリした
  • われながらちょろいけど髪下ろしたミサトさんいいよね、、となりました
  • 最後のシンジの相手がマリだったのは、嫌ではないんだけど個人的には納得いかず
    • そもそも君たち本作でやっとちゃんとした面識持ったというぐらいの仲じゃん…。
    • 個人的にはあのポジションはレイだった。アスカはケンスケとよろしくやっているのでヨシ
    • これはなんか過去作に気づいてない伏線とかあるのかもしれないので考察班を待ちます
  • 最後が実写だったのは、監督からの「現実に帰ってこい」的なメッセージを感じましたね
    • 旧劇時代に比べ、監督が結婚して拗れが解消したという説はわりと信憑性があると思う

CLIの環境変数をいい感じに管理するツールを作った

表題のとおりですが altenv というツールを作りました。 Alter environment の略です。

github.com

モチベーション

業務上、大小様々なツールやらシステムやら(これとかこれとか)を開発をすることが多いのですが、あつかうプロジェクトが多くなると開発やデプロイなどに使う設定値の管理がだんだん煩雑化していくという課題を感じていました。特に一部のツールは外部公開もしているので、実装と設定をちゃんと分離しようとすると(特にローカルでの開発に関する設定の場合)数ヶ月たった後に作業をしようとすると「どの設定値を使うんだっけ、、」というのがちょいちょいありました。単純にちゃんと管理しておけという話ではあるものの、そういった設定値を統一的に扱えるものがあると便利だなと思って作ったのがこのツールです。

端的に言うと、オプションや設定ファイルに記載された内容に応じて環境変数を読み込み、その環境変数とともに指定されたコマンドを実行するというだけのツールです。イメージとしては以下の通り。

$ cat test.env
DBNAME=hoge
$ altenv -e test.env npm run server
# running npm server with environment variable DBNAME=hoge

ユースケース

細かい利用方法はレポジトリの方に書いたつもりなので、ざっくりとユースケースごとの使い方を書いておきたいと思います。コマンドラインのオプションでいろいろ指定することもできますが、デフォルトで $HOME/.altenv という設定ファイルを読み込むので、そちらの設定を交えて紹介したいと思います。

プロジェクトのディレクトリごとに環境変数をわける

wordir.xxx というテーブルがあり、これを使って作業ディレクトリごとの環境変数を定義できます。( xxx はただのラベル)

[workdir.proj1]
dirpath = "/Users/mizutani/.ghq/github.com/xxx/project1"
define = ["DB_NAME=mydb1"]

[workdir.proj2]
dirpath = "/Users/mizutani/.ghq/github.com/yyy/project2"
define = ["DB_NAME=mydb2"]

CWDが dirpath 以下にあるとそのテーブル内に記載された設定が有効化されます。具体的には以下のようになります。( -r dryrun で読み込まれた環境変数一覧が表示されます)

$ cd /Users/mizutani/.ghq/github.com/xxx/project1
$ altenv -r dryrun
DB_NAME=mydb1
$ cd ../../yyy/project2
$ altenv -r dryrun
DB_NAME=mydb2

外部のレポジトリやファイル共有サービスから参照する

define環境変数を定義するやり方だと全ての環境変数$HOME/.altenv に書く必要があり、チーム内で共有するのが難しくなってしまいます。なので、外部ファイルを参照することで、gitレポジトリやファイル共有サービス(Google File StreamやDropboxなど)を使って環境変数を共有できます。(ただし、gitレポジトリは自分で最新ファイルをpullしてくることを想定しています)

[workdir.proj1]
dirpath = "/Users/mizutani/.ghq/github.com/xxx/project1"
envfile = ["/Users/mizutani/Google Drive File Stream/Shared drives/MyTeam/config/project1.env"]

[workdir.proj2]
dirpath = "/Users/mizutani/.ghq/github.com/yyy/project2"
envfile = ["/Users/mizutani/.ghq/github.com/yyy/configs/project2.env"]

このように設定することにより、project1 のディレクトリにいる際にはGoogleドライブのShared Drive内にあるファイルが、project2のディレクトリにいるときはconfig管理用レポジトリ内のファイルが参照されるようになります。

Staging / Production などの切り替えをする

例えば同じディレクトリでもステージング環境とプロダクション環境の両方にアクセスする場合、利用する環境変数の切り替えが必要になります。 profile.xxx というテーブルを用意することにより、利用したい設定を都度選択できるようになります。profileにおける xxx はそのままプロファイル名になります。

[profile.proj1-stg]
envfile = ["/path/to/proj1/stg.env"]

[profile.proj1-prd]
envfile = ["/path/to/proj1/prd.env"]

このように設定しておくと、 -p オプションによって読み込まれる環境変数を切り替えることができます。

$ altenv -p proj1-stg ./deploy.sh
# ステージング用の環境変数が読み込まれた上で deploy.sh が実行される

秘匿値を環境変数に使う(macOSのみ)

macOSが提供しているKeychainに環境変数を保存しておくことで、ファイルなどに平文保存するより安全にAPIキーなどの認証情報を管理できます。基本的には envchain の機能をベースに実装しています。

-r update-keychain -w <namespace> というオプションをつけることで、読み込んだ環境変数をKeychainに書き出します。<namespace> は任意の名前空間を指定できます。例えばすでに平文でファイル保存していた場合は以下のようにしてKeychainへの書き出しができます。

$ altenv -e credential.env -r update-keychain -w mycred

あるいはすでに環境変数に読み込まれている場合は以下のようにしてKeychainへ書き出すこともできます。例としてAWSで利用する環境変数 を保存してみます。

$ env | grep -e "^AWS_ " | altenv -i env -r update-keychain -w aws-cli

また、コピー&ペーストにより1つずつ書き出すこともできます。

$ altenv --prompt AWS_SECRET_ACCESS_KEY -r update-keychain -w aws-cli
Enter AWS_SECRET_ACCESS_KEY Value:
# 秘匿値を想定しているため入力した値は表示されない

呼び出すときは -k <namespace> オプションで保存した環境変数を呼び出せます。

$ altenv -k aws-cli -r dryrun
AWS_SECRET_ACCESS_KEY=xxxxxxx
AWS_ACCESS_KEY_ID=xxxx
$ altenv -k aws-cli aws s3 ls
2019-11-21 19:02:20 mybucket-1
2019-11-21 19:02:22 mybucket-2
...

IPアドレスやドメイン名のブラックリストを取得・管理するGo言語のライブラリを作った

だいたいタイトルの通りなのですが、色々なサイトで公開されているブラックリストを取得して、トラフィックログなどとの照合に使うことを目的とした badman というライブラリを作成しました。Blacklisted Address and Dmain name Manager です。

github.com

少し前だとネットワークのセキュリティ監視をするといったら、だいたいsnortのようなネットワーク型IDSを使うことが多かったと思います。しかし近年だと殆どの通信がHTTPS化されているということもあり、現状だとネットワーク型IDSはあまり有効な手法と言えなくなってしましました。代わりにできることの一つとしては、ネットワークのフロー情報(IPアドレス、ポート番号、プロトコルややりとりされたデータサイズなど)やDNSの問合せ+応答のログを蓄積しておいて、マルウェアのCommand & Controlサーバや詐欺サイトとの通信が発生していなかったのかを検証することです。この方法だとWebなどの通信が暗号化されていたとしても、不審な通信があったかを発見できます。ただ、継続的に発生する通信ログの検証をするたびにブラックリスト提供サイトからリストをダウンロードしてくると、提供サイトや自分のネットワークにも負荷をかけてしまいます。そこで一度ダウンロードしたものを中長期的に使い回せるようにと考えて、このライブラリを作成しました。

なお、ライブラリになっているのはログの入力方法やログの内容が環境によって大きく異ると考えられたからです。具体的なアーキテクチャ例は後で説明します。

どう使うものか

Go言語に親しい方だとだいたい以下のコードを見てもらえるとイメージがつくのではと思います。

package main

import (
    "bufio"
    "log"
    "os"

    "github.com/m-mizutani/badman"
    "github.com/m-mizutani/badman/source"
)

func main() {
    man := badman.New()

    if err := man.Download(source.DefaultSet); err != nil {
        log.Fatal("Fail to download:", err)
    }

    // ipaddrs_in_traffic_logs.txt contains IP address line by line
    fd, err := os.Open("ipaddrs_in_traffic_logs.txt")
    if err != nil {
        log.Fatal("Fail to open a file:", err)
    }
    defer fd.Close()

    scanner := bufio.NewScanner(fd)
    for scanner.Scan() {
        entities, err := man.Lookup(scanner.Text())
        if err != nil {
            log.Fatal("Fail to lookup:", err)
        }

        if len(entities) > 0 {
            log.Printf("Matched %s in %s list (reason: %s)\n",
                entities[0].Name, entities[0].Src, entities[0].Reason)
        }
    }
}

このコードでやっていることは以下のとおりです。

  1. ブラックリストを提供しているサイトから複数のリストをダウンロードして自分用のレポジトリを作る
  2. IPアドレスのリストが含まれている ipaddrs_in_traffic_logs.txt を開いて1行(1 IPアドレス)ずつとりだす
  3. とりだしたIPアドレスがレポジトリに含まれていたか検証する

このサンプルだと1.のブラックリストをダウンロードしてくるところは毎回実行されてしまいますが、本来はダウンロードしたものをローカルに一度保存し、それを使い回すということを想定しています。保存する方法は A) シリアライズされたデータをファイルに書き込んで、次回以降はそのファイルを読み込む、 B) 永続性のあるデータストア(現在パッケージに取り込んでいるのはAWSのDynamoDBのみ)をバックエンドに使う、の2通りがあります。詳しい使い方についてはレポジトリの README を御覧ください。

アーキテクチャ

AWSで使うことを前提に、2つのアーキテクチャ例を紹介します。それぞれ badman をライブラリとして使って独自にプログラムを作り、動作させることを想定しています。

サーバレスで使う場合

f:id:mztnex:20200103151337p:plain

このケースでは、2つのLambda関数を利用しています。 1番目(左側)の関数はブラックリストを定期的に取得し、シリアライズされたブラックリストデータをS3に保存します。 2番目(右側)のLambda関数は、トラフィックログファイルがS3にアップロードされた際のObjectCreatedイベントによって呼び出されます。 そしてLambda関数はシリアライズされたブラックリストデータとログファイルの両方をダウンロードし、トラフィックログのIPアドレスブラックリスト内に存在するかどうかを確認します。 存在する場合、ラムダはSlackなどの通信ツールを介して管理者に通知します。

このアーキテクチャの利点はスケーラビリティと価格の柔軟性です。Lambdaは(上限はあるものの)トラフィックログの到着件数の増減に応じてスケールアウト・スケールインするのでログ量に応じてリソースが足りなくなったり、逆に過剰にリソースを割り当てたり、というのを心配する必要がありません。さらに、ログ量が少なければ料金も自動的に少なくなるので、あまりコストをかけたくない小さい規模のネットワークの監視をするなどのケースでおすすめです。

一方で、不利な点は遅延です。ログの流量によりますが、S3にアップロードする前にログをある程度まとめることになるのでそのバッファリングをしている時間は遅延が発生します。経験則だと概ね数分〜十数分になります。もしリアルタイム性が必要なら以下のサーバ型モデルを採用したほうが良いかもしれません。

サーバ上で使う場合

f:id:mztnex:20200103152259p:plain

このアーキテクチャでは常時稼働しているプログラムをホスト上(この例ではAWS EC2)で動かします。主な利点は、リアルタイム性のためのストリーム処理です。 先述したとおり、サーバレスモデルではある程度ログをまとめてからS3にアップロードする必要があるため、ログの発生から処理完了までに数分の遅延が発生します。常時稼働させるサーバプログラムを使ってデータを絶えず流し込むことで、遅延を最小化します。

このプログラムはfluentdのforward用のサービス*1 を動かしている事を想定しており、fluentd経由でトラフィックログを受信します。 その後、badmanを使用して、ブラックリストに含まれているIPアドレストラフィックログを確認します。 ブラックリストは定期的に更新されることを想定しています。プログラムを実行しているホスト(この場合はEC2)がクラッシュしても回復できるように、DynamoDBをデータ保存用のレポジトリとして使用します。

このアーキテクチャの欠点はリソースの割当が難しいことです。おそらくログの流量がボトルネックになるので、その最大値に合わせてホストのリソースを設定する必要があります。さらにトラブルやいつもと違うイベントでログの流量が大幅に増える可能性がある場合は、それについても気をつける必要があります。これを解決するためには自動的なスケーリングなどの仕組みと組み合わせて使う必要があります。

利用してもらうにあたっての注意

ブラックリストを提供しているサイトはそれぞれ異なるポリシーを持っています。そのため、環境や組織によっては利用条件を満たさない可能性があるため注意してください。使えるブラックリスト提供サイトを限定するために、利用者が自分で使うサイトを選択することもできるようになっています。また、自分で badman が提供しているInterfaceを満たす構造体を実装すれば、独自のサイトや非公開のデータストアからデータを取り込むことも可能です。

簡単にですが各サイトのポリシーについてもREADMEにまとめてありますので、そちらもご参照下さい。

ちなみに

昔、似たような mdstore というツールを実は作っていたんですが、今回はGoでえいやと作り直しました。理由としてはLambdaで動かしたかったので、1) Lambda+マネージドサービスだけでよりステートレスに動かす仕組みを作りたかった、 2) 概ねnodejsより速く動くGoにすることで、実行時間を短くして安く済ませたかった、などです。

AWSにおけるお手軽セキュリティ監視運用のはじめかた 2019(Cookpad Tech Bookより)

はじめに

  • この文章は技術書典7で頒布されたCookpad Tech Bookに寄稿させてもらったものの転載になります。基本的に加筆などはしていませんが、一点だけSecurityHubに関する記述に間違いがあった(自動通知の機能がない、という誤った情報を記載していた)のでその点だけ修正しています。
  • 御存知の通り、2019年12月初旬に開催されたAWS re:Invent 2019において色々な新しいサービスが発表されました。なかでもAmazon DetectiveAmazon Fraud Detectionはセキュリティ関連サービスの中で注目すべき存在になっており、今後のAWSセキュリティ監視の中で重要なポジションになる可能性があります。この文書は2019年9月ごろ書かれたものなので当然それらの内容には触れていませんが、それについてはまたいずれ別の形でアウトプットしたいと考えています。

クラウドの時代になってもセキュリティのやっていきは必要です。クラウド上だと多くのマネージドサービスが提供されているためオンプレミスの環境よりもセキュリティの機能を実現しやすい側面はありますが、それでもまだすべてを頼り切ってよいほど進化しているとはいえないのが現状です。やらないといけないセキュリティの機能はさまざまですが、ここではAWS、およびセキュリティ監視(セキュリティ被害の発生の兆候を検知し分析すること)に焦点を当てて、マネージドサービスを活用したセキュリティ監視の小さなはじめかたについて解説したいと思います。また、マネージドサービスの初期設定方法についての解説は世の中に多くありますが、継続的に使っていくためにはどうすればいいか?ということを説明したものはあまりないため、ここではそういった運用に焦点をあてて説明します。

セキュリティ監視

この文章における「セキュリティ監視」とは「自分達が運用しているシステムやサービスに発生しうるインシデントの兆候を検知し、それを分析して監視対象の環境に影響があるかを判断すること」とします。 インシデントとはある人物による作為的な攻撃によって、システムやサービスに何かしら変化が発生し、それによってビジネスや仕事に悪い影響が発生することとします。 わかりやすい例として、業務用PCがマルウェアに感染してしまったり、サービスに侵入されてしまう、という状況を想像してもらえるとよいかと思います。

侵入口を潰したり攻撃そのものを遮断したりする「防御」とは異なり、何かが起きた際にそれを迅速に発見し対応できるようにすることを目的としています。

なぜセキュリティ監視するのか

はじめにそもそもなぜセキュリティ監視が必要なのか?という理由について簡単に説明したいと思います。

  • すべての攻撃を完璧に防ぐのは不可能である: 「監視などするまえにそもそも防いでしまえばいいのでは」という説はありますが、システムに侵入しようとする攻撃の手法やそれをとりまく環境は日々変化し続けており、それに完璧に追従するのは困難です。特に攻撃に利用される脆弱性は次々と新しいものが発見されており、長年使われていたオープンソースのソフトウェアでも例外ではありません。攻撃を防ぐためにはどのような攻撃がくるかということをあらかじめ知っている必要があり、日々状況が更新されていくような環境では防御だけにすべてを頼るのは厳しいといえます。
  • 防御の対策は利便性を阻害しがちである: それでも防御を重要視していこうとすると、今度はユーザーの利便性が阻害されてしまいます。防御とは攻撃と疑われる行為を発見したらそれを止める対策です。防御でなるべく多くの攻撃を止めようとすると、ちょっとでも不審な動きがあればその動きを遮断するような方向に調整しなければなりません。それによって正規のユーザーによる正常な動作も不審とみなされてしまい(これを False Positive と呼びます)システムやサービスへのアクセスを止められてしまいます。極端な例として、パスワードを一度間違えたら1日はアクセスできなくなってしまうサービスを想像してみてください。うかつなパスワードを設定していても突破される可能性は低くなりますが、本来のユーザーによる正規のアクセスも妨げてしまいます。もちろんこのような措置が必要な場合もありますが、多くの場合は利便性とのバランスを考えなければなりません。

以上の理由により、防御となる対策を入れることはもちろん重要なのですが、防御だけですべての攻撃から守ろうとするのはあまり現実的ではありません。監視と併用することによって利便性、安全性、コストのバランスのとれたセキュリティを実現していくことができるようになります。

セキュリティ監視を構成する「検知」と「分析」(と「対応」)

セキュリティ監視というプロセスは主に「検知」と「分析」、そして「対応」という3つのフェイズからなっています。これらはそれぞれがキッチリと分離しているわけではなく、検知と分析が被る部分、分析と対応が被る部分がそれぞれあり、互いに影響しあっていると考えてもらえればと思います。

f:id:mztnex:20191223202935p:plain
aa

セキュリティの製品やサービスでは検知に特化したもの、分析に特化したもの、両方の性質を兼ね備えたものなど、いろいろな種類のものがあります。ただ、今回は特に検知と分析がそれぞれわかれたサービスについて説明します。

用語の定義

  • インシデント : ある人物による作為的な攻撃によって、システムやサービスに何かしら変化が発生し、それによってビジネスや仕事に悪い影響が発生すること
  • イベント : サービスやシステム内で発生する事象を一括にした呼び方。Webサービスへのアクセスからプロセスの起動など、粒度はさまざま
  • アラート : セキュリティ監視のためのプロダクトやサービスが、インシデントの可能性があるイベントを発見し、それについて発報したもの
  • ログ : イベントとして発生した事象の詳細を記録として残したもの

f:id:mztnex:20191223203132p:plain
セキュリティ監視の説明に出てくる要素の関係性。抽象化しているためこのモデルに当てはまらないものもあるが、おおよその関係性ということでご容赦願いたい

検知

監視している対象のサービスやシステム内で発生したイベントの情報から、セキュリティ上問題がある事象をみつけだすことを「検知」とします。たとえばアンチウィルスソフトウェアはディスクに保存されたファイルの内容からマルウェアを検知するというのが分かりやすい事例かと思います。他にもイベントが記録として残ったログを集めて分析し、不審な行動を探し出すSIEM(Security Information and Event Manager)も検知の機能があるといえます。また、機械ではなく人間がログや現在進行中のイベントなどをみて根性で怪しい現象に気づく、というのも検知にあたります(定常的にこれをやるのはあまりお勧めできません)。

しかし、これらはあくまで「可能性」であり実際にサービスやシステムに影響を及ぼしていると断定した形で報告されることは稀です。そこで、発見された事象が本当にインシデントなのかを判断する作業が必要になります。

分析

検知された事象が実際にサービスやシステムに影響を及ぼしたのかを調べるのが「分析」です。検知のためのサービスやプロダクトはインシデントの可能性が高い事象を発見してくれますが、これはあくまで可能性にすぎません。 本来は検知の段階でインシデントであることを確定させてから通知してくれればいいのですが、残念ながら現代のセキュリティ監視のサービスやプロダクトをそのまま使うだけでインシデントを正確に発見するのは困難です。 これはなぜかというと、組織ごとにルールやサービス・システムの運用方法の違い、業務内容の違いがあるからです。

たとえば、AWSのコンソールに普段は見られない国に所属しているIPアドレスからのアクセスがあり、ログインに成功したとします。 後述する Amazon GuardDuty はこういった通常見られない不審なアクセスをアラートとして発報してくれます。 このアラートではIDとパスワードなどの認証情報が盗まれ、第三者が不正にAWSのコンソールにログインした可能性を示唆しています。 では、このアラートがあがった時点でそれをインシデントと断じることができるでしょうか。

ある組織のルールとして「業務は必ずオフィス内で実施すること」と決まっていたとしたら、自国外からのログインはかなりの確度でインシデントとみていいでしょう。 しかし、リモートワークが前提の組織であったとしたらどうでしょうか。スタッフは場合によっては他の国にふらっと旅行にいって、旅先で仕事をしているかもしれません。 そうした場合、通常と違う国からのアクセスが一概に危険とは言い難いです。また、ルールが厳しい前者の組織であってもたまたま出張にでていて例外としてアクセスしていた可能性もあります。 このように組織のルールや内部事情などによって発見された「インシデントの可能性があるもの」が本当にインシデントなのかを、他のデータと突き合わせながら判断するフェーズを「分析」と呼んでいます。

分析では業務内容などに照らし合わせてアラートの判定をする他に、サービスやシステムのログをみてアラートの内容を精査するというアプローチがあります。 さきほどの例から考えると、直接本人に「今、旅行中ですか」と尋ねる方法もありますが、一方で他の社内システムのログを検索することで「しばらく前からいつもと違う国で仕事していたのだな」ということを確認できます。(もちろん、AWSへのアクセスとその社内システムの認証系が別になっていることが前提ですが) 他にも「ある人物による不審な動きが観測された」というようなアラートがあったときに、具体的にどういった動きがあったのかを確認できれば、それが通常の業務の範囲内なのか、それとも逸脱した行為をしているのかということを判断できます。

こういった判断を重ね、発報されたアラートから本当に自組織に対して被害を及ぼすインシデントを発見する、というステップが必要です。実際にインシデントと判断できるものを発見した場合、「対応」のフェーズに移っていきます。

対応(余談)

「対応」は実際に何かしらの被害が発生した際、被害状況をまとめる、被害を軽減する、被害から回復させるといった行動です。 もちろんこれはサービスやシステムを運用する上で重要な対策ではあります。 ただ、やり方がサービスやシステムの構成に大きく依存しており、さらに直接的にこれを支援するAWSのサービスは(今の所)あまりないようなので、今回の解説からは省きます。

ただ今回ひとつ触れておきたいのは、冒頭で述べたとおり分析と対応はきれいに分離されている訳ではない、ということです。 実際の現場では、インシデントと確証はないがかなり怪しいとなったら影響の少ない範囲ですばやく対応を開始する場合も多いです。 これについては筆者もそこまで経験が豊富ではないためあまり多くは語れませんが、発生している事象のリスクと周りに対する影響などを判断しつつ、バランスをとりながら対応することは必ずしも容易ではありません。

セキュリティ監視に使えるAWSサービスとその役割

前置きが長くなりましたが、今回のテーマである「セキュリティ監視を既存(2019年9月現在)のAWSでどうミニマムに実現できるか?」に話を移していきたいと思います。 「AWS セキュリティ」でググってみていただくと分かると思いますが、当然ながらセキュリティは監視だけにあらずで、さまざまなサービスがでてくると思います。 今回はここまで説明した監視だけに絞り、サービスそのものと構成の例について説明したいと思います。 まず次の4つのサービスについて簡単に説明します。各サービスの詳細についてはそれぞれ公式ドキュメントをご覧ください。

  • Amazon GuardDuty
  • AWS Security Hub
  • CloudTrail
  • VPC Flow Logs

検知に役立つAWSサービス

Amazon GuardDuty

Amazon GuardDuty はAWS上で起こる不審な挙動を検出してくれるサービスです。 詳細な動作について細かなアルゴリズムなどは公開されていませんが、一部設定のセキュリティ上の問題をみつけてくれる他、機械学習を利用して通常と異なる動作(EC2インスタンスによる普段と異なる通信、AWSコンソールへの不審なアクセス)を検知してくれます。 具体的な検知内容については https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_finding-types-active.html をご覧ください。

GuardDutyは基本的にはCloudTrailのログ、VPC Flow Logs、そして内部DNSの問い合わせデータを利用して検知をしており、それらのデータから見えないイベントは見ることができないようです。 たとえば、インスタンス内部に悪性プログラムが静かに潜んでいるのを検出するといったようなことはできないはずです。(通信が発生すれば別ですが) そのためAWS内で発生するすべてのインシデントを網羅できるわけではないのですが、 それでもCloudTrailから見えるAWSリソースの操作、 およびVPC内部での通信状況に関しては監視できるため、 AWS利用の中でそれなりに大きな部分をカバーできるといえます。 また、利用料金も全体のAWS利用料のおおよそ1%程度になるといわれており、 一般的な商用セキュリティサービス・プロダクトに比べてかなりリーズナブルになっています。

AWS Security Hub

AWS Security Hub はGuardDutyをはじめとするAWS、あるいはサードパーティのセキュリティ監視検知結果を統合する機能を持っています。 また、AWSのベストプラクティスを元にしたCIS(Center for Internet Security)ベンチマークという機能もあり、AWS上のセキュリティ関連設定の不備について通知してくれます。

AWS Security Hub はそれ自身が検知をする機能を提供しているわけではないのですが、サードパーティのセキュリティ監視サービスやプロダクトからのアラートを統合してくれる点に強みがあります。 セキュリティ監視をするうえで手間がかかることのひとつは複数のサービスやプロダクトを利用する際に、ちゃんと統合して使えるようにすることです。 これはSIEM(Security Information & Event Manager)という製品がより上位の機能を提供しているので、状況によってはSIEMを使ったほうがよいかもしれませんが、Security Hubの方が機能が限定的な代わりに多くの場合SIEMより安価なので、今回は Security Hubを軸として説明します。 仮にGuardDutyしか使っていない状況だったとしても、今後セキュリティ監視に利用するサービス・プロダクトを容易に追加するために最初から導入しておくのがお勧めです。

分析に役立つ(データを蓄積してくれる)AWSサービス

AWS上で分析をするにあたり、なるべく多くのログを保存できたほうがいいのはいうまでもありません。 しかしサービスなどから出力されるログは環境によってまちまちで、一概に説明するのは難しいものです。 そのため、ここでは共通して利用したほうがよいサービスについてのみ解説します。

CloudTrail

CloudTrailはAWS上での操作をAPI単位で記録するサービスです。 AWSではコンソールを含むすべての操作がAPI経由で実行されており、そのログを追うことでどのリソースがいつ作成、変更、削除されたのかを追いかけることができます。

CloudTrailはAWS上でのユーザーの挙動を追跡したり、リソースに関する履歴を調べるのに役立ちます。 アラートの分析をしていると「このユーザーは何をしようとしていたのか」「このリソースはいつ誰が作ったのか」などを確認する必要がたびたびあります。 そのユーザーやリソースについて自分達が記憶していたり、すぐに聞いて分かる状態であればいいのですが、ちょっと前のことになると人は記憶を失ってしまうため、ちゃんとログに頼って検証できる状態にしておくのが望ましいです。 CloudTrailは利用しているアカウントの全リージョンに対し一括有効化できる機能があるため、ひとまず有効化しておいてよいサービスかと思います。

VPC Flow Logs

VPC Flow LogsはVPC内の通信を記録してくれるサービスです。 記録と言ってもその名のとおりフローの情報のみ、つまり送信元IPアドレス、宛先IPアドレス、ポート番号、転送データ量、パケット数、といったような通信の一部の情報のみで、通信の内容については取得されません。 もし通信の内容を取得したい場合は、VPC Traffic Mirroringを利用できます(詳しくは @{Webサービスへのログを取得する} で解説します)

VPC Flow Logsは現状だと一括で有効化する方法は提供されておらず、VPCごとに個別に設定をしていく必要があります。 全VPCで設定を有効化したい場合は、AWS Configを使ってFlow Logsが有効になっていないか探すか、(手前味噌ですが)次のようなツールを使って一気に有効化するというのがよさそうです。

AWSにおけるセキュリティ監視の構成例

では、実際にこれらのサービスをどのように使うかを、検知と分析それぞれの観点から説明したいと思います。 それぞれのサービスを有効化する方法などは公式ドキュメントやWeb上の記事に多く解説がありますので、ここでは触れません。 代わりにどのような構成で使うのがよさそうかという、筆者の視点からみたベストプラクティスについて説明します。

検知のための構成

f:id:mztnex:20191223204328p:plain
検知のための構成

検知をするためのお勧めの最小構成が上記の図です。 Security Hubを中心として、GuardDutyを有効にし、さらに他のセキュリティ監視サービスやプロダクトを使っており、Security Hubとの統合機能が提供されているのであれば、それも統合していきます。 GuardDutyは有効化されていれば自動的に統合されるはずですが、念のためSecurity HubのSummaryページから統合されているか確認してみてください。 これによって検知に関する情報がSecurity Hubに集約され、Security Hubのダッシュボードを見るだけで、対応すべきアラートの一覧を確認できます。 セキュリティ監視サービス・プロダクトが2、3程度だと実感しにくいかもしれませんが、コンソールが別々に分離しているとサービスやプロダクトの数が増えることで作業の手間が指数関数的に煩雑化していきます。 セキュリティ監視の対応(特にアラートの分析まで)は日常のルーチンワークになりがちなので、こういったコストを低減できるうちに取り組んでおくことに価値があります。 Security HubのFinding(本文書でいうところの「アラート」)はCloudWatch Eventsからイベントを発行できるため、Lambdaでそれを受信し各所に通知するなどの自動対応に繋げることができます。

分析のための構成

f:id:mztnex:20191223203527p:plain
分析のための構成

分析のための構成はよりシンプルです。 ここまでで説明したCloudTrail、およびVPC Flow LogsをそれぞれS3 Bucketに保存します。 図中では同じS3 Bucketに保存していますが、監視対象の規模が大きい場合はオブジェクト数が多くなるため別Bucketにするのがよいでしょう。 それぞれ、標準でS3 Bucketに直接ログを出力する機能があるので、それを利用してください。

そして保存したログを検索する方法についてですが、まずはAmazon Athenaを利用することをお勧めします。 詳しい説明は公式ドキュメントなどに譲りますが、簡潔に説明するとS3 Bucket上にあるログデータなどを並列で一気に読み込み、記述したSQLのような命令にしたがって検索、集計、表示をするサービスです。

このサービスが今回のセキュリティ監視に適している理由として、サービスの料金が読み込んだデータ量の従量課金である、ということが挙げられます。 セキュリティ監視における分析は重要なタスクですが、業務時間において四六時中発生している状態は望ましくありません。(もしアラートがひっきりなしに発生している、という状況であれば @{対応するアラートを選別する} をご参照ください) そのため事業内容のデータ分析などと違い、特定の瞬間のみログを検索できるような仕組みのほうがリーズナブルです。 Athenaはこういった要件によくマッチしていることもあり、まずセキュリティ監視の仕組みを作る初期段階にお勧めできます。 具体的な検索の手順などについては次のドキュメントをそれぞれご参照ください。 特に「S3パスの日付を指定して、ある特定の日付からのみ検索する」というテクニックを使うことで、検索範囲を狭め(=読み込むデータ量を減らし=安い料金で)検索結果もより高速に取得することができるようになります。

さらに一歩進んだ監視をしたい場合

今回紹介したのはあくまで最初に取り組む、いわば初期装備とでもいうべき構成となっています。 いずれ何らかの形で改めて紹介したいと考えていますが、セキュリティ監視をより充実させるためにできそうな取り組みのポイントだけ取り上げたいと思います。

また、解説という体になってはいますが、筆者もまだ試行錯誤を続けている段階のものが多くあるため、よい解決方法などをお持ちの方がいたらぜひご教示ください。

Webサービスへのログを取得する

AWSを利用する目的として、かなり多くの方々が「Webサービスの提供」を挙げられるのではないかなと想像しています。 Webサービスを提供している場合「攻撃のための侵入口」としてWebサービスそのものが利用されるのは現代においては自明といってもいいでしょう。 そのため、自分達が提供しているWebサービスまわりのリソースについてのアラートが発報された場合、Webサービスでどのようなことが起こったのか調査できるように、ログを取得・保管しておくことが望ましいです。

通常、セキュリティ監視が目的でなかったとしてもWebサービスに関連するログの一部は取得している場合が多いのではないかと想像しています。 特に次の3点については監査やトラブルシューティングのために何らかの形で保管していることが多いと思われるため、それらをセキュリティ監視の分析でも使えるようにするというのが最初のステップかと考えられます。

  • Reverse Proxy、Load BalancerなどWebアプリの手前の中継機能のログ
  • HTTPサーバなどのミドルウェアのログ(あれば)
  • Webアプリ本体のログ

多くの場合、これらのログは送信元のIPアドレスやリクエストが送信された対象のホスト、URI、一部のクエリなどが含まれており、分析に最低限必要な情報は取得できます。 しかし一方でPOSTリクエストなどに含まれるBodyのデータは見えなかったり、リクエストのヘッダ部分の情報が一部欠落しているケースが多く、そういった部分に攻撃コードが含まれるような場合は追跡が難しくなってしまいます。 (これらの欠落してるデータはデータ量が多い、センシティブなデータが含まれる、というケースがあるので当然といえば当然なのですが) これについては筆者も最適解はまだわかっていませんが、現状AWSサービスで解決するとしたら次の2つを検討します。

  • AWS WAFを使う: AWS WAF(Web Application Firewall)は防御の機能だけでなく、どのようなリクエストが発生してどのルールにマッチしたか・しなかったのか、をログとして残すことができます。ログを残す目的だけ(=トラフィックを止めないの)であればAWS WAFはCloudFront、あるいはALBに関連付けするとすぐ使えるようになるので、既存Webサービスがこれらを使っていた場合は非常に容易に展開ができます。ただし現状(2019年9月現在)はリクエストのBodyの内容は取得できないため、POSTなどによる攻撃の追跡は難しいという欠点があります。
  • VPC Traffic Mirroringを使う: VPC Traffic Mirroring機能はWebサービスに限らずEC2インスタンスなどENI(Elastic Network Interfaces)の通信をパケットレベルですべてコピーし、別のインスタンスなどに送信できるサービスです。完全な通信のコピーを取得できますが、パケット単位で通信が送られてくるため、HTTPリクエストの形に直すためにはツールなどでうまくTCPセッションを復元してあげる必要があります。また通信量も莫大になるため、よりシビアにコスト計算をしたり、運用時のパフォーマンスを考えねばならず、全体的に負荷は高めといえます。

どちらの方法もかなりの量のデータを取り扱うことになるため、どの程度の料金が発生するかなどを事前によく試算してから利用することを強くお勧めします。

その他使えそうなAWSサービス

今回は紹介しませんでしたが、その他セキュリティ監視に利用できそうなサービスをご紹介します。

  • Amazon Macie: S3上に個人情報などセンシティブなデータが保存されていないかをチェックしてくれるサービスです。セキュリティ監視の文脈では有効なサービスではあったのですが、残念ながら2019年9月現在では us-east-1 (バージニア)と us-west-2 (オレゴン)のみでしか利用できないので今回は対象外にしました。
  • Amazon Inspector: EC2インスタンスにインストールされている脆弱なパッケージなどを報告してくれるサービスです。どちらかというと予防の側面が強かったため今回は取り上げませんでしたが、これも利用できると分析時に「この攻撃に対して対象のEC2インスタンスは脆弱だったか?」という検証がしやすくなるため、セキュリティ監視に取り込む検討をしてもよさそうです。

インスタンス内部の情報を取得する

Webサービスに対するリクエスト同様に、今回のセキュリティ監視の構成で取得できていないものとしてインスタンス内部のイベントに関するログがあります。 GuardDutyは「あるインスタンスで不審な活動があった」ということまでは教えてくれますが、インスタンスの中のどのプロセスがその不審な活動をしたか、までは教えてくれません。 (このあたりについて詳しく知りたい場合はAWSの責任共有モデルを調べてみることをお勧めします) そのため、インスタンスの中のイベントのログは自分で取得しないと、どのプロセスが不審な活動をしたのかがわからず、それがインシデントなのか判断できずじまい、ということになりがちです。

これを解決するような製品やOSSは近年増えてきています。 osquery、sysdig、auditbeatなどのOSSも、本格的な運用の話は国内であまり聞こえていませんが、開発も盛んになってきている印象です。 この領域については筆者もいまだ試行錯誤しているため、明確な構成や運用のベストプラクティスなどを語れる立場にありません。 ただ、実際にこのようなログを取り込んだいた場合のアラート分析は著しく捗ることはわかっているため、今後も取り組みを続けたいと考えています。

対応するアラートを選別する

検知の仕組みを入れた後に起こりがちなのが、アラートが大量すぎて対応しきれなくなるというものです。 冒頭でも述べたようにセキュリティ監視は監視する対象のサービス、システム、業務によってやり方が大きく変わってくるため多くの監視サービスやプロダクトは多様なアラートを発報します。 「セキュリティ」というものに取り組んでいると、どうしてもセキュリティ監視サービスやプロダクトが発報したアラートについてひととおり目を通して安全であることを確認しないと気がすまない、という状況に陥りがちです。 確かに些細に見えるアラートが大きなインシデントの兆候を示していた、というケースもありえなくはありません。 しかしそれを理由にすべてのアラートをこと細かに分析してチェックしようとしはじめると現場が疲弊してしまい、本来見るべきだったものを見逃してしまうリスクの方が大きくなります。 これを回避するためには必ずアラートのチューニングをしていく必要があります。 アラートのチューニングにおいて重要になることを2つほど説明させてください。

  1. アラートの内容を機械的に判断して要・不要を判断する: アラートのリスクを判断するときは基本的に人間の直感などに頼らず、判断するための根拠があるはずです。その根拠は同種類の別のアラートにも適用できるはずであり、それをちゃんと言語化しルールとして次のアラートに活かしていかなければなりません。たとえばいつもと違う国からアクセスがあった、というアラートがあってもそれが本人が持っているデバイスからであるという確認がとれれば、それがアメリカからでもイギリスからでも大差はないはずです。(緊張関係にある国だった場合はまた別かもしれませんが、それも言語化すべきルールといえます)このルールをできれば監視のシステム自体に組み込めれば担当者の負荷も劇的に下がると思われますが、それができないシステムも多いので、その場合は基準を作って担当者間で共有するだけでも機械的に対処できることになり、負荷は下げられると考えられます。
  2. 機械的な判断に必要な情報を(なるべく自動的に)揃える: アラートの内容を機械的に判断するためには、ログをはじめとしてアラート外の情報との組み合わせが必要になるケースが多くあります。これらの外部情報の取得作業をいかに簡易化できるかというのも、ある意味チューニングの一部といえます。アラートが発生した際、何を基準に判断するかが明確になっていれば、その判断に必要な情報は何か?という問いの答えも明確になるはずです。何が必要かわかっているなら、あとは機械的(自動的ならなおよし)に取得できるはずで、これによって自動的にアラートの判断ができないまでも、担当者の負荷を下げることにはつながるはずです。

まとめ

AWSをはじめとするクラウドサービスではセキュリティのマネージドサービスが多く提供されており、セキュリティを向上させるための土台はオンプレミス環境より豊富になっていると思います。 しかし一方で、マネージドサービスの個別の使い方についての説明は多く世の中に出回っているものの、運用まで含めた統合的な使い方の説明はあまりないなと常々思っていたため、今回文章にしてみた次第です。 まだ拙い内容なのでわかりにくい部分なども多いと思うのですが、今後もこうした情報発信をしていきたいなと思いますので、ぜひお気持ちのある方々と一緒にやっていければなと思う今日この頃です。