task4233のめも

書きたいことをつらつらと

SecHack365 2020 研究駆動コース参加記録

はじめに

こんにちは。task4233です。

この度は、SecHack365 研究駆動コースのトレーニーとして1年間研究をさせていただきました。そのまとめとして、本エントリを書くことにしました。

なぜSecHack365に申し込んだのか

一言で言うと、大学にセキュリティ系の研究室が無かったためです。私がセキュリティ系の研究に興味を持ったのは昨年度のセキュリティ・キャンプ全国大会でした。そこで、マルウェアの検知手法に意外と単純なシグネチャ比較が用いられていることを知り、「これなら私でも手を出せるのでは?」と思い始めたのがきっかけでした。しかし、残念ながら私の所属している大学にはセキュリティ系の研究室がありませんでした。そのため、研究室がないなら外部で研究できるところを探そう!と思い、SecHack365の研究駆動コースに応募しました。その結果、合格しました。

SecHack365で何をしたのか

SecHack365では、マルウェア検知システムの提案と一部実装を行い、ポスター発表を行いました。

github.com

ポスター: https://sechack365.nict.go.jp/achievement/2020/pdf/2020_32.pdf

全体のスケジューリングについては、他のトレーニーの参加記録に書かれていると思うので割愛します。

blog.sechack365.com

一方で、他のトレーニーが書いていないであろう「オンライン開催」の感想を書こうと思います。
正直なところ、研究駆動コースにおいては「オンライン開催」は正解だったと考えています。なぜなら、定期的にオンラインでゼミを実施することが出来たためです。これは他のコースでも行われていたかもしれませんが、現状で何が出来ていて、何が出来ていないのか、そして次は何をすれば良いのかが明確になるため、日々の開発、研究の振り返りをすることはとても大切だと考えています。

逆に、「オンライン開催」で残念だったのは、旅行に行けなかった日本各地で対面でのお話が出来なかったことです。実は対m......おっと誰か来たようです。

挑戦と挫折の繰り返し

私はマルウェア検知システムに、CFG(Control Flow Graph)というプログラムの遷移状態を持つデータ構造を利用したのですが、その生成と利用に関して色々な角度から挑戦しては何度も挫折を繰り返しました。

ja.wikipedia.org

ざっくり話すと、最初はCFGの生成にLLDBというデバッガのC++APIを用いていたのですが、3カ月ほどかけて実装が難しいことに気づきました。そのため、比較的遅めなGDBPython APIを用いてなんとか実装し、最終的にCFGの生成部を実装することが出来ました。LLDBからGDBを用いた手法に変えるのに、3カ月も要してしまった理由はLLDBは高速なC++ APIを用いていたのに対して、GDBは遅めのPython APIを用いていたためです。今思うと、動くモノが出来ていないにも関わらず、最初から速さを意識して実装に取り組んでいたのは勿体なかったと思います。そのため、ここに時間をかけずに、もっと短いスパンで様々な手法を試すことが重要だったのかなと今思っています。

SecHack365では何が得られるのか

SecHack365全体では、イノベーティブな友人関係が得られます。多くの方は、SecHack365に対して「1年間で圧倒的成長」や「セキュリティつよつよになって帰ってくる」といったイメージを持っているのかもしれません。それは事実なのですが、それ以上にイノベーティブな友人関係が出来るのは大きいと私は考えています。なぜなら、SecHack365は事実上期限がありますが、友人関係は消えることがないためです。実際に、SecHack365を修了した今でも交友関係は続いていますし、今後も消えることは無いと思います。SecHack365を通して、この関係が作れたのは本当にありがたかったです。

また、習慣化が根付いてくるのも特徴の一つだと思います。SecHack365のトレーナーには習慣化のプロがおり、そのトレーナーから習慣化のコツや取り組み方を教えてもらうことが出来ます。しかし、ただ話を聞いているだけでは習慣化を続けていくことは難しいと思います。この習慣化を定着させるためには、そのトレーナーの助言を聴くだけでなく、実践することが肝要だと感じました。

実際に、私はSecHack365に参加して、本当に忙しい時以外は日報を書くようにすることで、その日の振り返りを習慣化できました。日報が書けないくらい忙しいときでも、最近は風呂の中で振り返りを行っています。その結果、寝る前にあまり進捗が出ていない日でも、「今日はここまでできたからえらい」とか「今日は出来なかったけど、明日はこれをやってみよう」とかいうことを考えることが習慣化できるようになってきました。その甲斐あってか、最終的に習慣化大賞をいただきました🎉

大賞の景品としていただいた一口羊羹焼肉

研究駆動コースでは何が得られるのか

研究駆動コースでは、研究的思考を実践しながら学ぶことのサポートが得られます。これは以下のSecHack365における、研究駆動コースの概要文にも書かれていることです。

SecHack365「研究駆動コース」においては、いわゆる成果主義ではなくアイデア発想とその着想理由を大切にしていることから、いわゆる研究の基本的スタイルに合わせることをそれほど重要視しません。その代わりに研究プロセスをしっかり明確にさせるための特訓を行います。これにより、アイデアの着想に至った過程の重要さに気づいてもらい、研究へのモチベーションを高める支援を行います。 具体的には、アイデアの創出から始まり、その研究が誰に対してどのような効果や利点があるのか、何故それを実施してみたいのか、どうしてもやってみたいのか等々はっきりさせることが大切であり、トレーニーに求めることは今まで経験してきたようなドリルの問題を単に解くような「問題解決」スタイルではなく、自ら「課題設定」ができる能力を伸ばしてみたいという意欲を自身で持つ、ということが重要です。もう1点、単なる思いつきでは世界には勝てないということに気づいてもらいたいということです。よって、諦めない強い心を作り上げること、これがトレーナーたちが本コースを運営する上で最も重要視している点です。人によっては少し厳しい感じを受けたかもしれませんが、私たちは皆様のチャレンジを全力で受け入れられるよう身体を暖めながらお待ちしております。

sechack365.nict.go.jp

研究的思考、とは様々な側面がありますが、これは文面ではなく実践を通して学ぶものだと思います。そのため、興味が湧いた方は、ぜひ来年度以降の研究駆動コースに応募してみてください!

sechack365.nict.go.jp

おわりに

最後になりますが、トレーナーの皆さん、スタッフの皆さん、アシスタントの皆さん、そしてトレーニーの皆さんに支えていただいたことに対して深く感謝申し上げます。皆さんの存在は、私1人で出てくるアイデアを大きく膨らませる手助けになってくれました。私1人では、SecHack365での研究を形にしてポスターとして発表するのは難しかったと思います。その点で、アイデアや情報提供をしてくださった皆さんには本当に感謝しています。ありがとうございました。

最後に、いただいた修了証受理ツイートをもって締めさせていただきます。最後までお読みいただき、ありがとうございました!

2020年の振り返りと2021年の目標を述べてみる

はじめに

こんにちは。task4233と申します。

この記事は, 僕の2020年の振り返りと2021年の目標を述べることを目的として書かれたポエムです。
昨年のポストに引き続き, 書いてみました。昨年は思っていた以上に某ウイルスにダメージを受けて色々と大変な年でした。
これは皆さんが感じていることだと思うので, 上手く付き合っていくしかないのかなと思います。
昨年で得られた知見をいくつかに分けて書いたので, 少しでもお役に立てれば幸いです。

もくじ

2020年の振り返り

今年の目標は以下の5つでした。

  • [x] SecHack365に応募する
    • 2020年 SecHack365 研究駆動コース
  • [ ] セキュリティ・キャンプ全国大会2020のチューターに応募する
    • SecHack365, 教育実習に専念したかったので応募を断念
  • [ ] 高度情報技術者試験かセキュリティ資格試験AC
    • 某ウイルスで断念
    • 今年は受験予定
  • [ ] CTFの本番で正答率10~20%の問題を通す
    • WaniCTF SQL Challenge 2(26.7%)
  • [ ] セキュリティに関するOSSツール(拡張)を作る
    • SecHackで作成中
    • 今年公開予定

以上のうち, チェック([x])がついているものを達成しました。

全然達成していませんね。もちろん努力はしていたのですが, 予想通りには行かないものです。
引き続き精進します。

院進学と将来

色々な方々に相談にのっていただき, 結局そのまま同じ研究室で続投することに決めました。
この場をお借りして感謝申し上げます。本当にありがとうございました!

理由はいくつかあるのですが, 決め手となった2つの要素は, 来年弊学にネットワーク系の教授が配属されることと, 僕の研究分野において他大に行くメリットがそこまでなかったことです。

僕の研究分野は簡単にいうとお金にならない(?)ので全国の大学の研究室を探しても完全に合致する研究室はありませんでした。微妙に被っている研究室が筑波大にあり, 受け入れていただく流れになっていたのですが, 色々な方々に相談させていただき総合的に判断した結果, そのまま他大に行かずに院進することに決めました。詳しく書くと色々と問題がありそうなので, 他大の院に行くかどうか迷っている方がいれば, 内々で相談にのれるかもしれません。DMを飛ばしてください。

また, 将来的にはやはりエンジニアの方面に進みそうな気がしています。
研究者も悪くはないのですが, 現状で研究の楽しさよりも求められた要件をクールに解決するコードを書く楽しさの方が勝っているので, そちらの方面に進みそうです。
そのために, 会社(業界)を知り, 優れた仲間を見つけ, スキルアップするために, 今年は積極的にインターンに応募するつもりです。おススメのインターン等ありましたらお教えください。

エンジニア種別としては, バックエンドエンジニアになりそうですが, バックエンドだけに限らずフルスタックを目指して精進していきたいと思います。

誕生日CTFの反省

今年も12月5日に誕生日CTFを開催しましたが, 結論から言うと, 下記の謎問題たちを出題してしまい, あまり芳しくないCTFとなってしまいました。

  • パラメータを変えずに連続アクセスすると得られるWeb問
  • アクセス権限不備で想定解以外でも得られるWeb問
  • 論理性が欠如したOSINT問

これらの対策は下記の通りです

  • 環境構築も含めた問題管理
  • 事前の難易度確認と調整

さて, 謎問題たちは僕の手で生み出してしまった訳ですが, これらのうち上2つはサーバの設定不備により問題環境が蒸発したために生まれてしまいました。もちろん問題はGitで管理していたのですが, 本番環境のアクセスコントロールはnginxで行っていたため, GKEのインスタンスがおしゃかになってしまったときに対応できなくなってしまいました。 対策として, KosenXmasCTFのように, 各問題それぞれをDockerfileで切り離す手法が取れそうです。そうすることで, docker-composeかk8sで一括管理できるので, 来年はそうするつもりです。

OSINT問に関しては, ヒントになるオブジェクトを置くなどするべきでした。正直, 難易度は理不尽級に高かったものの「どうせ解かれるでしょ」と思っていたら1人にしか解かれていなかったので*1やってしまったなと後悔しました。逆に, もう一方の問題は, ヒントとなるオブジェクトがあったためか, 6割程度の方が解けていました。 そのため, OSINT問題は事前に友人に出題してみて, 特定できるかを確認してから出題するのが良いと思いました。

一方で, Grass FlagCaesar Cipher Translatorの二問はまぁまぁ面白い問題だったと自負しているので, そこは良かったと思います。 実際にアンケートでも面白かったというコメントをいくつもいただけたので良かったです。

来年はこれらの謎問題を含まないようなCTFにするので, もしよければ来年は参加してみてください。

Goが楽しい

昨年はGoを一番使いましたし, 今後のメイン言語をGoにしようと思うほどGoを書いた年でした。 ここまでハマるきっかけとなったのは, 一昨年2月ごろに開催されたMercariさんのStep up goでした。ここで, 毎週Goについて実践的に学ぶことが出来たので, 自信が付いてゴリゴリ書くようになりました。

Goの良さは色々ありますが, 私が最初に惹かれたのはエラーハンドリングでした。
他の言語ではtry-catch-finally形式の例外処理機構を用いるものもありますが, 私はこれがあまり好きでないです。 別に悪くはないのですが, とりあえずExceptionなら弾くのが気持ち悪い, とか, スコープが異なるので事前にインスタンスを宣言しておく書き方が気持ち悪い, とか, そういった理由で好きではないです。その点, Goは標準的にエラーを戻り値として取得する週間がありますし, finally句の代用としてdefer句を使用することで絶対に処理したい部分を簡素に書くことが出来ます。

他にも, 平行処理に対するサポートや実行効率が良く, 静的解析しやすいところも良いところでしょう。実際に, 先日のSpecification輪読会で, 「interfaceのアドレスはいつ確保されるのか」という話が出た時に, 気軽にバイナリを解析できました。

このような流れで, 来年もGoを積極的に使っていくことになると思います。 最近はGo Language Specification輪読会でSpecificationを読んでいるのですが, 知らなかった仕様に驚き学ぶ日々を送っています。新年は1/13に開催するので興味のある方は参加してみてはいかがでしょうか。

Rustも良いらしいですが, 沼に落としてくれる人がいなかったので, そういった方が出てきてくれればぜひぜひ沼に引きずりこんで欲しいところです。よろしくお願いします。

研究が大変

これが一番苦労した(している)ところです。 その原因は, 問題設定とその解決法の2つにあると考えています。

まず, 問題設定に関して。 今までは問題が既に設定されていて, それを解決するという道筋でした。 学校で出題される問題や, 競プロ, CTF, 技術検証でもこれは同じです。そのため, これらは情報収集をすることで外堀を埋めて地道に理解していけば解決できることが多いと考えています。

しかし, 研究では問題を定義するところから始まります。この問題設定が確実に正しいかは分かりません。例えば, 設定した問題を解決する手法が時間計算量的に渋かったり, そもそも別部門で議論されていたりすることはよくあるのです。そのため, お偉い教授に相談してから問題設定がマズいと指摘されることがありました。この原因は, 一言で言えば僕の情報不足によるものなのだと思います。この情報不足に対して, クリティカルに効く文献などは無いので, ひとまず有識者に相談することがベストだと思っています。とはいえ, 有識者もヒマではないのでここで作業を続けた結果, 出戻りが発生することが多かったです。もっと良い対処法があればご教授いただきたいです。

次に, 解決法に関して。 解決(できる可能性のある手)法はたくさんあります。その全てに取り組むことは時間的に厳しいので, 最初にある程度調査を行った上で解決法を試す必要があると思います。 が, 僕は引き際を見誤り, 解決できそうな手法をひたすら試してしまい, 時間を棒に振ってしまいました。今思えば良くなかったと思いますが, 当時はもう少しで出来ると本気で思っていたので悲しいです。これに関する対処法は時間を決めて取り組むことなのか, 単に僕の能力が低かったのかよく分かりません。

教育実習で得られたもの

今年の10月中旬から11月上旬にかけて, 母校にて3週間だけ数学の授業を32時間分実習させていただきました。 昨年の介護等体験では, どのような相手に対しても等しく対応することの重要性を再確認したと書きました。

今回の教育実習でも多くのことを学ばせていただきました。その中で, 1つ挙げるとすれば時間の管理方法だと思います。端的に言うと, 期限がギリギリである程度の質を求められた時にどう対処するか, を実践を通して学ばせていただきました。

僕なりの答えとしては, 自分で時間的な期限を決め, その7割を超えた時点で収束に持ち込むという方法がしっくりきました。 これは授業においても, 授業外に関してもそうでした。

きっかけは, 授業用の指導案と実際に行う授業の進行がズレてしまい, 時間通りに終わらせるためのアドバイスを先生方からいただいたことでした。
その内容をざっくり書くと下記の通りです。

  • 指導案はあくまで目安に過ぎない
    • 教育実習の建前として作らせているだけ
  • 実際の授業では残り15分を境に教える範囲を進めるか復習するか決めている

これを受けて実践してみると, 意外と上手く行きました。残り時間が少なくなった時は授業の復習時間に充てることで生徒の理解度向上にも寄与した気がしますし, 何より指導案通りにいかない可能性を視野に入れて授業を出来たので, 最初の35分間をのびのびと使うことが出来ました。

さらに, 授業外でもこれが使えることが分かりました。というのも, 私の実習では32時間分担当するということを, 実習初日に知らされ, 初回授業が実習3日目だったものですから, 全ての資料作成が当然間に合いませんでした。 そのため, 次の授業の資料作成を前の日にやるというのを繰り返した結果, 初週の平均睡眠時間が1.5hという結果になってしまいました。 このままだと2,3週目にぶっ倒れると思い, 対策を考えていた矢先, 先ほどの「残り15分を境に決める」という言葉をふと思い出しました。 50分授業で残り15分というと, 開始から35分後なので全体の7割にあたります。 これを, 翌日の資料作成においても実践してみると睡眠時間を最低限確保した上で資料作成に取り組むことができるのではないかと考えました。 結果として, これにのっとり, 2,3週目は安定した睡眠時間を確保した上でそこそこの授業を実施出来たと思います。

これは僕だけかもしれませんが, 完璧主義寄りの人は睡眠時間を犠牲にしてまで何かに取り組みがちだと思っています。 その結果, 体調を崩したり課題ごとの質がバラバラだったりすることがあるのではないでしょうか。 しかし, それを改善しなくてはいけないとわかっていても対策が分かっていない方もいると思うので, 参考になれば幸いです。

他にも, 先生方を観察していると, 不器用にも全力でやっている先生方もいらっしゃいましたが, 上手いこと手を抜けるところは抜いて職務にあたっている方もいらっしゃいました。 もちろん良し悪しは付けられませんが, 出来れば僕は後者でありたいなと強く思ったそんな教育実習でした。

他にもエピソードはあるのですが, 全部書いてしまうとつまらないので, 対面でお会いしたときにでも機会があればお話しましょう。

SecHack365の途中経過

SecHack365は, セキュリティ・キャンプで存在を知り応募しました。

僕は研究駆動コースだったので, 下記の3点を鮮明にして応募要項を埋めました。

  • どんな研究を志望するのか
  • SecHack365がなぜ必要なのか
  • 研究のために何を今しているのか

現状で, 周りのプロたちよりは成果が出ていませんが, そもそもこの環境にいられたこと, そしてトレイニー同士のつながりを作れたのが大きな成果です。
セキュリティ・キャンプやインターンでもそうなのですが, 一緒に課題に取り組む方々って良い人ばかりなんですよね。 先述したCTFでサーバをHackしてバースデーメッセージを載せてくる人や, 他のトレイニーが取り組んでいる課題に対してアドバイスや意見を飛ばしてくださる人, ギークな話題で語りあえる人などなど, 尊敬できる一面を数多く備えている気がします。 こういった環境で切磋琢磨できて僕は本当に幸せだと思います。

しかし, 現実では僕の進捗は微妙なところなので, 残りの2週間で計画と実践をやっていき, なんとか形にしたいと思います。
SecHackは終わりではなく始まりなので, 今後の研究において大きな転機となったのは間違いないです。

2021年の目標

  • 積極的にインターンに申し込む
  • 査読付き論文を1本通す
  • 朝活を継続する

この3つが, 今年達成したい3つの目標です。昨年は5つにしていたのですが, 今年は変化がありそうな年なので余裕を持たせて3つにしました。

おわりに

以上が, 2020年の振り返りと2021年の目標でした。

2020年は予想とは異なる年になってしまいましたが, 今年は着実に一歩一歩進んでいくつもりです。

長くなってしまいましたが, ここまでお読みいただきありがとうございました。少しでもためになる部分があれば幸いです。 では, 今年も1年よろしくお願いします。

*1:1人解いていた人は朝の4時ごろまでずっとやっていたようです......一体どこのOOtokiさんなんだ......

Hardening 2020 H3DXに参加してチーム優勝してきた

はじめに

2020年11月13日(金)から14日(土)にかけて開催されたHardening 2020 H3DXに参加し, チームおにぎりまみれの一員として優勝してきました。

f:id:task4233:20201126194720p:plain

本競技での私の役割は技術部門の「なんでも屋」だった気がします。その辺りの話も含めながら, 本イベントの概要, 競技までの流れと事前準備, 競技中の様子, 全体の感想を書きます。

参考までに, 他のメンバーの参加記のリンクを貼っておきます。本記事よりもクオリティが高いので, 次回以降参加する方はぜひチェックしてみてください!

nomizooon.hateblo.jp kiryuanzu.hatenablog.com sirabete-manabu.hatenablog.com

目次

Hardening 2020 H3DXとは?

ざっくり言うと, 外部からの攻撃を防御しつつ, 売り上げを最大化する競技です。 公式の説明は下記の通りです。

Hardening競技会は、基本的に、チームに託されたウェブサイト(例えばEコマースサイト)を、ビジネス目的を踏まえ、降りかかるあらゆる障害や攻撃に対して、考えうる手だてを尽くしてセキュリティ対応を実施しつつ、ビジネス成果が最大化するよう調整する力を競うものです。 ref: https://wasforum.jp/hardening-project/hardening-2020-h3dx/

そして, H3DXは下記の3要項を指します。

  • Deep Trans-organization
  • Digital Transformation
  • Dependence Excercise

意味をお尋ねしたところ, 「あまり深く考えなくて良いよ」とのことでした。

競技までの流れと事前準備

競技までの流れは, 応募->チーム確定->役職決定->競技準備->競技本番でした。 10月14日にチーム確定メールが来たので, 11月13日の本番までの約1か月間が準備期間でした。私は運悪く, 急遽確定した教育実習と事前準備の期間が丸被りしていたので, 事前ミーティングには殆ど参加できませんでした。その分, 競技前日のミーティングで出来ることを精一杯やろうと決めていました。

結果として事前準備で貢献できたのは, パスワード変更用のシェルスクリプト作成くらいだと思います。このスクリプトUbuntu, CentOSサーバ内のbash_historyにも履歴が残らないので採用しました。特に不具合報告もなかったので, 無事動いてくれたと思います(たぶん)。

それと, 使われたのか知りませんが, 1分くらいで意外と上手く書けた目玉商品の紹介画像があるので, ここで供養しておきます。

f:id:task4233:20201126200924j:plain:w300
サブスク『諸刃の刃』

他に, チームとしてやったことや事前に用意したものは, のみぞーさんや, ばばさんが, 詳細にまとめてくださったので, そちらをご参照ください。

nomizooon.hateblo.jp sirabete-manabu.hatenablog.com

これらの記事でも少し触れられていますが, 各メンバーが率先して何かをこなそうとしていたこと各メンバーが提案を快く受け入れていたことが非常に印象的でした。 例えば, チーム用Slackの作成やミーティングの提案, スキルチェックシートの作成, Discord, Trelloといったサービス利用はメンバー各自の提案であり, その全てがメンバーに受け入れられ実現していきました。私はあまり関われずに指を咥えて見ているばかりでしたが, こういった心強いメンバーと同じチームになれたのは本当に幸運でした。

後にのみぞーさんやあんずさんの記事で, リアクションを徹底していたことを知り, 次のイベントでは私もこのようなアクションを取ろうと思いました。思い返すと, 発言が虚空に消えそうな雰囲気を感じたときにコメントを拾ってくださったことが多く, 不安が払拭されていったのを実感がありました。

競技中の様子

Hardening Day

外部からの攻撃を防御しつつ, 売り上げを最大化する競技の日でした。この日を技術面とコミュニケーション面に分けて振り返ります。

技術面について

技術面において, 私は「何でも屋」として振舞っていたつもりです。

事前に決めていた私の役割はWebページのhttps化だったのですが, 今回のECサイトはデフォルトでhttps化されていました。そのため, 私の仕事はパスワード変更くらいでした。それが終了したときには, 他のメンバーの方々はそれぞれの仕事を始めていたため, 他のメンバーのサポートに入ろうと思い, 「何かやることがありませんか?」と逐次聞くようにしていました。 その結果, WordPressの管理, Webページの情報差し替え, 文書用のスクリーンショット準備, EDRのインストール, SSL証明書の期限切れ報告といったことをする何でも屋として動いていました。今回の競技の目的は売り上げを最大化することだったので, 地道にミッションをこなすことでほんの少しはチームに貢献できたのかなと思っています。

これは余談ですが, メンバーから「アンダーバー入力できる人はEDRのインストールお願いします!」というお願いがきて私が対応した際に, クライアントのGuacamoleの仕様で表示されていないだけというのは泣けました。直接/etc/vconsole.confを編集しても改善されなかったときは🤔となったのをよく覚えています。

コミュニケーション面について

コミュニケーションは, テキストベースのSlackと音声ベースのDiscordにて行っていました。ここで私が意識していたことは, テキストベースで発言した上で, 反応がなければ音声ベースで発言するという, 2段階の発言を行っていたことです。よく考えれば普通なのかもしれませんが, テキストベースでの発言を1度挟むことで, Discordの帯域を邪魔することが少なかった気がしています(気のせいかもしれません)。

また, この2段階の発言を行うことで, 発言の取りこぼしも減ったと考えています。とはいえ, 実際はチームメンバーの意識付けのおかげだったのかもしれません。

Softening Day

Hardening Dayの振り返りや, 攻撃者のkuromame6*1による講評等が行われた日でした。

急遽CEOのさんごさんが発表できなくなったため*2, 発表はのみぞーさんが行ってくださいました。結果として, 時間ピッタリで素晴らしい発表をしてくださったので, 非常に心強かったです。

全チームの発表を聞いていると, チーム内でのメンバ同士のやり取りが円滑に出来たか否かで大きく結果が変わったように感じました。これは, 競技後に他のチームの方にお聞きしても同意されていたので, やはりそういうことだと思います。

講評

講評を大きく2つに分けると, インシデントについてと親会社への報告についてでした。

インシデントについては, 自分たちで起こしていることが多いとのことでした。本競技では, kuromame6はDNSに全く触れていなかったそうなので, DNSの障害は完全に自己責任ということでした。また, フィッシングメールに返信してしまったり, FWで操作用のポートまで閉じてしまったりしたチームもあったようなので, わざわざインシデントを作ってお金を払っていたチームもあったようです。 その他に, 事前にタスクスケジューラに埋め込まれたPowerShellスクリプトや, DB情報をダンプするcronも設定されていたようなので, 攻撃されていないからといって安心するのは危ないそうです。これらの布石は, 事前に配布された競技背景にヒントとして埋め込まれていたそうです。

親会社への報告は, 資料を用意するか否かという問題のみならず, 情報が洩れているのか漏れていないのかが不明瞭な点, 売り上げに対して情報漏洩がどのような作用をもたらすのかを考慮していなかった点も問題点として指摘されました。

全体の感想

結果として, つよつよチームメンバーのおかげでグランプリをいただけましたが, グランプリをいただけたことよりもチームでワイワイしながら競技に参加できたことが良かったです。

また, 準備不足だったと思うことは報告書のテンプレート作成でした。 今回は怒られイベントが発生したために強く感じたのかもしれませんが, 情報漏えいが確認できた時点で資料作成のテンプレートがあると良かったかなと思います。 怒られイベントで「え?君たち報告会に資料もなしに来たの?」などと言われているのを聞いて, 胃痛がしたのをよく覚えています。

事前に情報漏洩時の対応についても決めていたので, 生かしきれなかったのも残念でした(作ってくださったさんごさん申し訳ないです)

これは余談ですが, 情報セキュリティインシデント報告書を調べたところ、JUCE(私立大学情報教育協会)から公開されているものがこちらにありました。参考までに。

おわりに

今回の競技は事前準備も含め, かなり長丁場のイベントだったと感じています。その分, メンバーの強い協力もあって本番中はワイワイしながら競技に取り組めたのかなと考えています。そのため, また競技に参加できることがあれば, リアクションを徹底することを強く心に留めておきます。

最後になりますが, 運営メンバーの皆様, そして参加者の皆様, 非常に面白いイベントにしていただき本当にありがとうございました!
またこのようなイベントは開催されると思うので, 興味のある方は参加してみてはいかがでしょうか?

*1:攻撃者で構成されたチームのことです

*2:グランプリのCEOは現地に招集されたため

NTT Performance Tuning Challenge 2020 参加記

はじめに

2020年9月11日(金)に開催されたNTT Performance Tuning ChallengeにチームКошкаとしてはなかずさんと2人で参加しました。 終了2時間前くらいには結構上位に食い込めていたのですが、最終的にその状態に復元することが出来ず、結果正の得点を取ったチームの中で下から2番目となってしまいました。

とはいえ、今回のイベントにおいて学べたことが多かったので、ここに記すことにしました。

学べたこと

Slow Queryの探し方

Slow Queryを探すためにはpt-query-digestを使います。このツールはデータベースのSlow Queryログを解析するツールです。 Slow Queryは下記の記述をmysqldのconfファイルに追記することで出力できます。

slow_query_log       = 1
slow_query_log_file = /tmp/slow-query.log
long_query_time = 0.1

ここで出力されたログをpt-query-digestに渡すことで、下記のようにSlow Queryをまとめて出力してくれます。

$ pt-query-digest /tmp/slow-query.log
# (snip)
# Query 1: 2.41 QPS, 0.19x concurrency, ID 0xB09A20EF29F18029 at byte 84332154
# Scores: V/M = 0.07
# Time range: 2020-09-11T04:23:45 to 2020-09-11T04:25:04
# Attribute    pct   total     min     max     avg     95%  stddev  median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count          1     190
# Exec time     51     15s    74us   327ms    78ms   266ms    76ms    48ms
# Lock time      3     8ms    14us   381us    42us    98us    37us    31us
# Rows sent      0     188       0       1    0.99    0.99    0.10    0.99
# Rows examine   0     188       0       1    0.99    0.99    0.10    0.99
# Query size     0   8.11k      41      46   43.71   42.48    0.54   42.48
# String:
# Databases    app
# Hosts        competition-068.c.sys0098096-1-80305617.inte...
# Users        ptc-user
# Query_time distribution
#   1us
#  10us  #
# 100us  ####
#   1ms  ####
#  10ms  ################################################################
# 100ms  ######################
#    1s
#  10s+
# Tables
#    SHOW TABLE STATUS FROM `app` LIKE 'events'\G
#    SHOW CREATE TABLE `app`.`events`\G
# EXPLAIN /*!50100 PARTITIONS*/
SELECT image FROM `events` WHERE `id` = 3128\G

この出力から、SELECT image FROM events WHERE id = 3128に、最長で100[ms]単位を要していることが分かります。

更に、Slow Queryに関連して、カーネルパラメータやコネクション数の調整のような普段は触らない部分を知るきっかけになりました。

遅いエンドポイントの探し方

遅いエンドポイントを探すためには、kataribeが使えます。このツールは、httpサーバのログを解析するツールです。httpサーバのログはNginx等で出力できます。

このツールは、下記の通りtoml形式でフォーマットを指定することでアクセスログをまとめてくれます。

$ sudo cat /tmp/access.log | kataribe -f ./kataribe.toml
Top 20 Sort By Total
Count   Total     Mean   Stddev     Min   P50.0   P90.0   P95.0   P99.0     Max  2xx  3xx  4xx  5xx  TotalBytes   MinBytes  MeanBytes   MaxBytes  Request
  154  52.263   0.3394   0.4680   0.000   0.245   0.261   0.513   2.890   3.148   11    0  143    0       10662         31         69        399  POST /api/events HTTP/1.1
  145  34.146   0.2355   0.0536   0.001   0.242   0.256   0.261   0.440   0.500    0    0  145    0        6920         31         47         55  PUT /api/events/1 HTTP/1.1
    1  24.126  24.1260   0.0000  24.126  24.126  24.126  24.126  24.126  24.126    1    0    0    0        4718       4718       4718       4718  GET /api/events?limit=12&offset=889 HTTP/1.1
    1  23.876  23.8760   0.0000  23.876  23.876  23.876  23.876  23.876  23.876    1    0    0    0        4791       4791       4791       4791  GET /api/events?limit=12&offset=1028 HTTP/1.1
    1  23.483  23.4830   0.0000  23.483  23.483  23.483  23.483  23.483  23.483    1    0    0    0        4492       4492       4492       4492  GET /api/events?limit=12&offset=341 HTTP/1.1
    1  23.412  23.4120   0.0000  23.412  23.412  23.412  23.412  23.412  23.412    1    0    0    0        4628       4628       4628       4628  GET /api/events?limit=12&offset=46 HTTP/1.1
    1  23.408  23.4080   0.0000  23.408  23.408  23.408  23.408  23.408  23.408    1    0    0    0        4412       4412       4412       4412  GET /api/events?limit=12&offset=1584 HTTP/1.1
   37  23.210   0.6273   0.6186   0.001   0.270   1.770   2.035   2.398   2.398   27    0   10    0         291          0          7         35  POST /api/logout HTTP/1.1
(snip)

このログから、GET /api/events?limit=12&offset=889 HTTP/1.1は1回しか呼ばれていないのに、24[ms]もかかっているので、ボトルネックになっている可能性があるなどのことが分かります。

このツールは、出力のどの部分を見れば良いのかよく分からないツールでした。実際に何度か使うと使い方がわかってくると思いますが、最初はこれを見ても見方や使い方がよく分かりませんでした。参考になる資料などありましたら教えていただきたいです。

N+1クエリ

N+1クエリとは、一覧の取得に1回、関連データの取得にN回、計N+1回のクエリを発行する際に起きる性能問題のことです。 これは、先述したkataribeのログを見て、極端に遅いエンドポイントのハンドラに含まれていることが多いです。

N+1クエリとは、下記のようなものです。なお、長くなるのでエラーハンドリングは割愛しています。脳内補完してください。

type Item struct {
  Name     string
  UserName string
}

var items []Item{}

itemRows, _ := dbc.Query("SELECT user_id, name FROM items")
defer itemRows.Close()
for itemRows.Next() {
  // idとnameをmap
  var userID int
  var item Item
  itemRows.Scan(&userID, &item.Name);
  
  userRows, _ =  dbc.Query("SELECT username FROM users WHERE id=?", userID)
  for userRows.Next() {
    // UserNameをmap
    userRows.Scan(&item.UserName)
    items = append(items, resItem)
  }
}
  

ここで、最初のクエリでitemsテーブルから得たrow1行ごとに、usersテーブルにクエリを実行していることが分かります。 このようにrow1行に対して別テーブルに呼び出しを行うことで、テーブルのレコード数が大きければ大きいほど実行時間が長くなるクエリがN+1クエリです。

そして、その改善方法のひとつとして、SQLの問い合わせは全部SQLに任せる、というものがあります。 今回の例でいえば、下記のようにテーブルへの問い合わせを別々に行わず、まとめて問い合わせることになります。

var items []Item{}

itemRows, _ := dbc.Query("SELECT u.name, i.name FROM items i INNER JOIN users u ON i.user_id=i.id")
defer itemRows.Close()
for itemRows.Next() {
  // UserNameとnameをmap
   var item Item
  itemRows.Scan(&item.UserName, &item.Name);
  
  userRows, _ =  dbc.Query("SELECT username FROM users WHERE id=?", userID)
  for userRows.Next() {
    // UserNameをmap
    userRows.Scan(&item.UserName)
    items = append(items, resItem)
  }
}

このように、INNER JOIN句を用いて内部結合を行うことで、各テーブルへの問い合わせをソースコードを介さずに行うことが出来ます。 そのため、直感的に早くなりそうだということが分かるはずです。

今回のイベントでの反省点

一言でいえば、変更点をメモしていなかったことです。 最初にも書いた通り、ちょこちょこ変更を加えている間にベンチに失敗するようになってしまいました。 小さな変更を加えるごとにベンチを回すのが理想だったのかもしれませんが、ベンチが回りきるまでに3分程度かかるので新しい機能の追加に応じてベンチを回すようにしていました。 その結果、新しい機能を追加したらベンチが正常終了しなくなり、元の状態に復帰できなくなってしまいました。

当初は、変更点くらいならGitのコミットで管理すれば良いかなと考えていたのですが、このイベントではソースコードのみならずDBやインフラのように複数変更する部分があります。 Git上では、stable version(1270)というコミットがあったのですが、このコミットにロールバックしてもインフラやDBの状態までは復元できませんでした :cry: 。 そのため、Gitのコミットのみでなく、何時ごろに何をしたかをざっくりとメモしておけばよかったと考えています。もっといい方法があれば教えていただきたいです。

ベンチマーカについて

今回のベンチマーカは、PythonTevernを使っていたようです。 しかし、テストに失敗したときにそれっぽいログは出力されていましたが、あまり見たことのないフォーマットだったのでどの部分が原因で落ちたのかが分かりにくかったです。 例えば、logoutの機構に関して、ブラウザでは正しく実行できているのにローカルでのベンチでは落ちているというケースも散見されました。 本番中は焦っていたので、ExpectedとAcctualの部分からソースコードのどこがおかしいかをざっくり探していたのですが、今思うと危なかったかな、とも思います。

おわりに

こういうイベント系は、参加記を書くまでがイベントな感じがするので参加記を書きました。 イベント全体を通して、6時間半という長丁場でしたが、ドキュメントや初期設定等に1時間、想定していた3台構成にするまでに1時間、ベンチを回している時間をまとめると30分程度、椅子を温めている時間が1時間と、効果的に手を動かせていたのは1時間程度と、濃い時間だったように思います。とはいえ、その間もソースコードを見ながら雑にインデックスを貼ったくらいで、ドキュメントの情報は殆ど使えていなかったように思います。 その点で言えば、まだまだISUCON初心者だと思うので、また別の機会があればこういったイベントに参加してみたいです。

明日はISUCON10の予選ですが、私は参加権が得られなかったので次回のISUCON11や他のチューニング系イベントで再チャレンジしたいと考えています。 ISUCON11では誰か一緒に出てほしいです。お茶くみくらいならやります。

最後になりますが、運営メンバーの方々、面白いイベントを開催していただき、ありがとうございました。 またこのイベントを開催する可能性があるらしいので、興味のある方は参加してみてはいかがでしょうか。

参考にした資料

SBテクノロジーでSOCアナリストとして2か月の就業型インターンをしてきた話

もくじ

はじめに

2月から2ヵ月にわたり、SBテクノロジーのMSS(Managed Security Service)に携わるSOCアナリストとして就業型インターンをしてきました。 このエントリは、節目としてエントリを残しておきたいという思いと、今後SBテクノロジーインターンを志望する方の参考になればという思いで書かれました。

SBテクノロジーis何?

一言でいうと、ICTサービス事業としてクラウドに特化して環境および運用を提供する会社です。事業内容はこちらをご覧ください

クラウドの環境および運用を提供するということは、そのセキュリティ監視も当然存在します。その一部に、私が従事した、SOCとして24時間365日セキュリティ監視を行うMSSがあります。

SBテクノロジーインターンに応募した理由

SOCとして従事するMSSに応募した理由は、以下の3点でした。

  • クラウドのセキュリティに特化しているという部分に興味を持ったため
  • 実業務としてSOCの経験をできるインターンが無かったため
  • 自分のセキュリティに関する知識・経験がどれだけ通用するのか知りたかったため

そもそも、SOCはその存在自体が隠蔽される性質を持つので、SOCのインターンは非常に珍しく感じました。それに加え、セキュリティ・キャンプで「クラウドのセキュリティに特化しています」と紹介していたため、「クラウドのセキュリティとは:thinking_face:」と気になっていたこともきっかけの1つです。

以上の理由から、将来SOCになるか否かは別として、SOCがどのような場所であり、そこで私に何ができるのかを知るためにインターンに応募しました。

SBテクノロジーでしたこと

定常業務

SOCの業務の中で私に課されたのは下記の3つの定常業務でした。

  • お客様の製品が正しく運用されているかの監視
  • 脆弱性情報の配信
  • お客様へのログから読み取れる攻撃傾向のご報告

これらの定常業務は、全ての業務を含めて3・4時間もあれば終わってしまうので、業務時間中に手があくこともしばしばありました。そのような時には、レポートのダブルチェックを行ったり、システム構成に関する会議に同席したりすることもありました。

半自動化による業務改善

それでも時間は余ってしまうもので、業務改善として「お客様の製品が正しく運用されているかの監視」を半自動化しました。半自動化に際して、アナリストのご意見をお聞きしながら試行錯誤を重ね、最終的に業務用ツールとして認められたので達成感がありました。

その過程で、「技術にこだわった開発」ではなく「需要に応じた開発」ができました。

趣味の開発では、面白そうならとりあえずインストールして動かしていましたが、実務ではリスクを増やさないために許可なく新しいソフトウェアを入れることは禁止されていました。

特に印象的だったのは、「このツールを入れたいんですが、良いですか?」とお聞きしたときの「そのツールを入れると、どんなメリットとリスクがあるの?」という返しです。業務に従事している方からすると当然なのかもしれませんが、こういった発想に至らなかった部分が私の未熟な部分なのだと感じました。

結果として、既に業務用ツールの一部で使用されていたPythonを選定することになったのですが、私はPythonを積極的に使ったことはなかったため、開発の過程でDocstringやclassにおけるgetter、setterの記法といったPythonの独特な表現を知ることができました。

また、下記のように、アナリストの方にツールを見せて意見をお聞きして、改善できたのも良かったです。

ア「初めて使う人にも分かりやすいように手順書があると良いかもね」 私『画像やQ&A付きの手順書制作しました!』

ア「Pythonがインストールできない時はどうするの?」 私『pyinstallerでexe化しました!』 私『ついでにexe化および必要な依存パッケージインストールのためのバッチファイルの用意しました!』

このように、実際に使う人の意見を聞きながら制作する経験ができたのは本インターンの良い副作用でした。

おわりに

業務的に秘匿にするべき部分が多く、なんとも抽象的な記述が多くなってしまいましたが、(おそらく)要点は伝えられたと思います。

インターンは就業型のインターンなので、現職のアナリストの業務のうち対応できそうなものを業務として与えられます。しかし、SOCが扱うシステムは複雑であるため、いくらスキルがあろうとも対応方法を知るために幾ばくかの時間を要します。そのため、全ての業務が与えられる訳ではなく、自分から仕事を探せる人間でないとかなり暇になると思います。

一方で、SOCの実業務を経験して雰囲気を知ることができる良い機会であるとも言えます。冒頭にも書きましたが、SOCのインターンは少なく、それもSOC見学のように短期間で終わるものが多いと考えています。そんな中、SBテクノロジーでは長期に及びインターンを実施してくださるので、その経験を積みたい方にはオススメだと考えています。

以上が、本インターンのエントリになります。 最後になりますが、SOCアナリストとして様々なことを学ぶことができて感謝しています。ありがとうございました。

NTTコミュニケーションズ SREエンジニア体験 参加記

はじめに

2020年2月15日(土)にNTTコミュニケーションズにて開催された「SREエンジニア体験」に参加しました。

午前中にSREエンジニアに関する座学を, 午後にGCPを用いたハンズオンを行いました。

ここで, SREについてかなりの知見が得られたので, 参加記としてまとめることとしました。

午前 - 座学

SREとは

SRE(Site Realiability Engineering)とは, システムの信頼性を担保するエンジニアリングのことです。

SREは, 品質の維持かつ高速なリリースサイクルの実現を目的とします。具体的には, アプリケーション基盤の構築および運用やリリースプロセスの整備(共通化)が挙げられます。

SREについては, 以下の本がおすすめです。

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

用語: SLI, SLO, SLAについて

SLOのすすめによると, それぞれの要素について以下のように書かれています。

SLI(Service Level Indicator)とは, サービスレベルの指標のことです。具体的には「リクエストの成功率」や「月間利用可能率」などが挙げられます。

SLO(Service Level Objective)とは, サービスレベルの目標のことです。具体的には「各四半期中の全リクエストの成功率は99.99%以上とする」が挙げられます。
この値は, 定期的にクライアントにヒアリングをしながら定期的に見直す必要があります。例えば, 満足度を指標としている場合は, 満足度を計る狩野モデルを用いて, 満足度が低い場合はSLOを引き上げるといった変更が必要になります。

SLA(Service Level Agreement)とは, サービスレベルに関する合意のことです。具体的には「SLOが満たされなかった場合, 利用料の50%を返金する」といったものが挙げられます。

従来の運用

従来の運用では, Dev*1Ops*2がチームとして分離しています。この運用では, Devは新機能や修正のためにシステムの変更を望むのに対し, Opsはシステム安定のためにシステムの変更を望みません。

システムの変更は必要なので, レビュープロセスやリリースプロセスを厳格化することで障害を減らそうとします。この結果, システムの規模が大きくなればなるほど, 運用コストも比例して増加します

また, SLAに違反しないようサービスの停止を極端に嫌い, 過度に慎重になります。

以上の要因により, サービスのリリースが遅くなる訳です。

SREによる運用

SREによる運用では, システムの規模に比例して運用コストが増加しません。なぜなら, リリースに応じた正常性確認を自動化するためです。システムの規模に応じて時間がかかる理由は, 正常性確認を手動で行っているためなので, 自動化は運用コストの膨張防止に大きく貢献します。

そして, 障害発生を0にするのは誤りであると考え, 障害発生時には影響を最小化する運用を行います*3。そのため, SLAに基づいたサービス品質を目指して, 早急にシステム障害から復旧できる仕組みを実装します。

また, SLOに違反しない限りはサービス断を許容し, 余った時間*4で新機能のリリースといった挑戦的なことを行います。

SLO違反を防ぐ仕組み

余った時間を用いると言えど, SLOに違反しては問題です。
そこで, SLO違反を検知する機構としてCanary Releaseが適用できます。

Canary Releaseとは, 新しいバージョンに流すトラフィックを制限することで, 新しいバージョンに問題があっても全体のSLOを担保するリリース手法です。例えば, 新しいバージョンに流すトラフィックを全体のトラフィックの1%に留めれば, 新しいバージョンが100%機能しなくとも全体へのダメージは1%を超えることはありません。

Canary Releaseには, OSSツールのIstioが利用できます。

CI/CD

CI(Continuous Integration)およびCD(Continuous Delivery)のことです。

CI(Continuous Integration)

リリースまでのパイプラインで言えば, Test/Buildの自動化がCIに該当します。

CIによる恩恵は, 品質の保証と開発者への情報提供です。 前者は, deployされたコードがtestを通っていることが保証されているので, 最低限の品質は保証されているという意味です。後者は, エンジニアがpushしたコードのフィードバックを即時にもらえるという意味です。

具体的なワークフローとしては以下の3つが挙げられます。

  • Run test localy
    • ローカル環境で動かないものは基本的にpushしないという発想
  • Build Servers
    • pushをトリガーとしてサーバ側でテストを含めた自動化が為されていること
  • Quality Control
    • ソフトウェア品質を高めることを目的とした性能測定および静的解析
    • i.e.) Lint toolやStyle Guide, 脆弱性情報を用いたコードの解析

CIのツール(ドキュメント)は以下の通りです。

CD(Continuous Delivery)

リリースまでのパイプラインで言えば, Deploy, Test*5, Approveの自動化がCDに該当します。

CDによる恩恵は, ソフトウェアがいつでもリリースできる状態にあることです。CDでは, deployおよびtest等をまとめて行うため, リリースできる状態が保証されます。

CDのdeployには以下の通り, deploy strategyという手法を状況に応じて使い分けます。

  • Rolling update
    • 新しいバージョンをクラスタ内で部分的に追加し, 問題がなければ古いバージョンを順番にクラスタから消していく手法
  • A/B testing
    • Traficを2つのバージョンのユニットA/Bに分けて調査をする手法
    • 2つのバージョンの性能評価のために用いられる
  • Blue/Green Deployment
    • Dev用にtest traficを流すためのGreen Podと, User用にuser traficを流すBlue Podを用意
    • Green Podで問題なさそうなら, user trafficをGreen Podに流す手法
  • Canary Release
    • 現行サーバの他にBaselineという比較用の現行サーバとCanaryという新しいバージョンのサーバを用意
    • Routerによってtrafficの操作を行い, BaselineおよびCanaryに全体の数パーセント程度のtrafficを流して比較することで新しいバージョンの検証をする手法

CDのツール(ドキュメント)は以下の通りです。

午後 - ハンズオン

こちらのGoogleのチュートリアルを参考にした, 段階的にCI/CDを実現していく形式のハンズオンを行いました。

手動deploy

最初は, 以下の通り手動でdeployしました。

  1. アプリケーションのコンテナ化
    • コンテナのimageIDを取得
  2. 作成したcontainer imageをcontainer repositoryにpush
    • docker imageIDとrepository nameを紐づけ
    • repository nameでpush
  3. kebernetesにmanifestを適用
    • manifestであるyamlファイルを編集して適用

CI/CDパイプラインの構築

手順としては少ないですが, 複数のdeployをする場合は大変ですし, ヒューマンエラーでミスをする可能性もあります。そこで, CI/CDパイプラインを構築することとしました。

変更点は以下の通りです。

  • アプリケーションのコンテナ化およびcontainer repositoryへのpushの自動化(CI)
    • appリポジトリへのpushを起点とするGCP Cloud Buildのトリガを設定
    • 設定用のyamlファイルはこちら
    • yamlファイルでは, docker buildおよびpushをする設定が書かれています
  • アプリケーションdeployの自動化(CD)
    • envリポジトリへのpushを起点とするGCP Cloud Buildのトリガを設定
    • 設定用のyamlファイルはこちら
    • yamlファイルには, kubernetesへのmanifestの適用およびproductionブランチへのpushをする設定が書かれています

ここで, envリポジトリにcandidateブランチおよびproductionブランチがあることが分かります。これらのブランチを分けている理由は, 昔のmanifestを適用することで簡単にGKE上で過去の状態を復元できるようにするためです。

各ブランチの役割は以下の通りです

  • candidateブランチ
    • これから本番環境にdeployするためのコードを保存
    • 最新版を本番環境にdeployするときはこちらを変更
  • productionブランチ
    • 本番環境にdeployされたコードを保存 − candidateブランチが本番環境に適応された段階でcandidateブランチからproductionブランチにpushされる

ログのモニタリング環境構築

自動化したはいいものの, アプリケーションの挙動を見守る必要があるはずです。そこで, ログをモニタリングするための機構を構築します。

ログのモニタリング時には, 以下の4つのシグナルを意識すると良いそうです。

  • リソース(Resources)
  • 使用率(Utilization)
    • リソースが処理中でbusyだった時間の平均
  • 飽和状態(Saturation)
    • リソースにサービスできない余分な作業がある度合い(処理できてないものは大抵キューに入れられいる)
  • エラー(Errors)
    • エラーイベントの数

そして, モニタリングを実現するには, PrometheusおよびGrafanaを用います。それぞれの役割は以下の通りです。

  • Prometheus
    • システムの監視や警告を行う
  • Grafana

また, 変更点は以下の通りです。

おわりに

CI/CDの構築を実践しながら学べるイベントでした。 GCPのサービスは課金が怖くてあまり触っていませんでしたが, これを機に無料枠で少しずつ触ってみようと思えました。 CI/CDを組むようなサービスを構築することは少ないですが, アーキテクチャを学べたのは良かったです。

来年もあればぜひ参加してみてはいかがでしょうか? (これ毎回言ってる気がしますね)

*1:開発者のこと

*2:運用者のこと

*3:経験上どう頑張ってもバグが消えないことは分かっているはずです。

*4:Error Budgetという

*5:こちらはDeployされたものを対象としたTest

NTTコミュニケーションズ セキュリティ脅威分析体験ハンズオン 参加記録

はじめに

2020年2月8日(土)にNTTコミュニケーションズ本社で開催されたTech Workshop「セキュリティ脅威分析体験ハンズオン」に参加しました。

午前中に脅威のシグネチャを検知するためのルールの書き方を, 午後にEDRのログの調査方法を, 実践を交えて学びました。午後の終盤には, 調査したログに対するインシデント報告書を作成して発表しました。

結果として, 「良かった発表」の得票数1位になり, 以下の書籍およびノベルティをいただきました。

午前 - Splunkチャレンジ

一言でいえば脅威のシグネチャを検知するためのルールの書き方を学びました。 具体的にはSplunkで管理しているプロキシログの中から脅威を見つけるためのルールの書き方と, IDSに設定するシグネチャであるSnortシグネチャの書き方を学びました。

参考までに, Splunkのクイックリファレンスガイドのリンクを貼っておきます。

前者も後者もルールを書くまでに3段階の工程を踏みます。 まず, 悪性通信を観察して共通点を見出します。 次に, その共通点をルールとして書いて悪性通信のみの集合に適用し, 全ての悪性通信が検知できていることを確認します。 最後に, そのルールを全体のログに対しても適用して悪性通信の検知を行います。

今回のハンズオンで用いられたログについても同様に, 悪性通信の共通点を見つけ, それをルール化しました。 SplunkとSnortシグネチャで書くクエリは異なりますが, 結局は悪性と考えられる通信の特徴をどれだけ高精度に見つけられるかが重要であると感じました。

私は単純に検知できるルールを書くので精一杯でしたが, 前に座っていた方がルールの精度にこだわっていたので, まだまだだと感じました。

午後 - EDRログ分析

EDR(Endpoint Detection and Response)とは, 脅威の検知とインシデントレスポンスのための記録を行う製品のことです。 EDRは問題が起きる前の予防策として用いるAV(Anti-Virus)と異なり, 脅威の検知やエンドポイントの隔離といった問題が起きた後の対応策のために用いられます。

ハンズオンでは, EDR製品で取得したログを用いてエンドポイントのログをどのように分析するかを学びました。

エンドポイントログ分析には, FireEyeのRedLineを用いました。このアプリケーションは, ログからProcess EventsやRegistry Key Eventsを一覧で表示して, その一覧に対して検索クエリを投げることが出来ます。また, 各ログについて,プロセス番号や親プロセス番号を取得することが出来ます。これらの機能を用いて, 怪しいプロセスを起点に調査範囲を広げていくことが重要になります。更に, ファイルごとのmd5ハッシュも表示されるため, Virus TotalやHybrid Analysisにハッシュ値を投げて既存の解析結果を得ることも重要です。

最終的に調査した内容を発表しました。冒頭にも書いた通り全体の中で最も良い評価を得られたのは, 対策案としてバッチファイルを書いたことだと考えています。これはひとえに大和セキュリティの忍者チャレンジのおかげなので, あのイベントには頭が上がりません。

また, 最後にスタッフの方から模範解答が公表されたので, 意識不足だった部分を3つ書いておきます。
1つ目は, そのログがどのファイルやプロセスから実行されたかを示す証跡を書くことです。EDR製品のログだけでは情報不足の場合もありますが, これを書くことで何がトリガとなって実行されたのかが明確になるため, 重要です。
2つ目は, 感染した端末の初期化を行うことです。いくら解析しようとも, 見落としが100%無いとは言い切れません。そのため, 基本的に感染したPCは初期化するのがベストです。
3つ目は, 同じネットワーク上の他のPCを調査することです。EDRのログで検知されていない他のPCでも感染している可能性があるため, 同じネットワーク上の他のPCも調査すべきです。

以上3点が頭から抜け落ちていたので, 念のため記載しておきます。

おわりに

今回の内容の殆どが未経験だったため, 良い経験になりました。
特に, EDRセキュリティは言葉だけ知っている程度だったため, 実際に手を動かしながら学べたのが非常にありがたかったです。スタッフの皆様, 本当にありがとうございました。

今後も同様のイベントを行うかもしれないので, その際はぜひ参加してみてはいかがでしょうか。