セキュリティキャンプ2017 事前課題

セキュリティキャンプ全国大会2017の事前課題をやりました。
ちょっと濃いめの内容だったので記録しておきます。

概要

集中コースZの事前課題。
課題は選択で(定員はありますが)好きなものを選んでやる感じでした。
他の方々はマルウェアの分類などを選択したみたいです。
私の事前課題は以下の通りです。 - バックエンドを持たないオンメモリKey value ストレージを書いてみる
- RESTful APIでネットワークアクセスできるようにしてみる
- Raw tcp/ip でファイルを並列転送し、ファイルシステムに保存するストレージを書いてみる
- SPDKのセットアップ

SPDK? なんかすごそう。 という理由で私はこの課題を選択しました。 選択コースの事前課題と比べてみると"ものつくり"トラックということで実際にプログラムを書くことが多いなという感じ。

制作過程

課題の制作はGithubで管理することになりました。
指示が与えられる -> 指示通りに実装してプルリクエストを投げる。 -> 指示が与えられる。
の繰り返しです。

言語は選択肢としてGo言語とPythonのどちらかでしたが、せっかく強い人から教えてもらえるなら未経験なGo言語をやろうということでGo言語で作成することになりました。 以下、指示があった順に第一、第二と分けて書きます。

第一

unix domain socketを用いてget/set出来るkvsを作る。 という課題でした。
イマイチ感じがつかめなかったので連想配列から値を取得、代入出来るようなインターフェースを書いて、ソケット経由で操作出来るようにしました。
クライアントはひとまずsocatコマンドで代用しました。
人に見てもらうのに実行方法とか書き忘れてしまった以外はうまくいきました。
参考

UNIXドメインソケット - Wikipedia

Unix Sockets in Go - Stack Overflow

How can I communicate with a Unix domain socket via the shell on Debian Squeeze? - Unix & Linux Stack Exchange

第二

切断の検知やタイムアウトを実装。
関数、変数名の命名方法を指摘していただき、切断検知、通知をクライアントに送ることに。 切断検知の実装に伴ってクライアントもGo言語で書くことになりました。
慣れない分野だったのでよくわからない名前を変数やファイルに付けながらも問題なく実装することができました。

参考 変数の命名方法
qiita.com

第三

以前まではset hoge piyoとしたらhogeというキーにpiyoという文字列を格納していましたが、set filenameみたいにしてクライアントがファイル名を指定するとファイルのバイト列とそのハッシュ値を送信するように。
最初、ファイルのハッシュ値md5にしようとしたらツッコまれ、どのハッシュ値にしようか検討するためしばらく進捗停止していましたが、
結局良くわからなかったし変に工夫するのも良くない気がしたのでSHA256でハッシュ値を取るようにしました。

ここで、ファイルのサイズ大きい場合の処理について考え始める。(結局事前課題期間では解決せず)

第四

大きなファイルにも対応したかったけどセキュキャン当日まで時間がなかったっぽい(10日前)のでyaraのスキャンを組み込むことにしました。
yaraというのはパターンマッチでマルウェアを検出してくれるライブラリです。

YARA - The pattern matching swiss knife for malware researchers

yara-pythonリポジトリとGo bindingsのソースを読みながら、DBのデータ更新時にスキャンを掛けたり、yaraのマッチングのルールに変更があれば、サーバー側でも反映させるようにしました。 あと、yaraのルールにマッチしたファイルはログに記録するようにと。

第五

ベンチマークを取れるようにしました。あと、unix domain socketからtcp socketへ交換。

toy-kvs-benchmark --dataset ./files --num-client 100 --repeat 1000

とすると、files以下のファイルをすべて100台のクライアントがそれぞれ1000回づつ送信。という感じです。 クライアントの数が大きいと途中でパイプが壊れたりしてしまうが、直せず。。。

第六

SPDKのセットアップ。 vagrantでcentos7上にspdkの環境構築をします。

github.com

spdkのビルドに失敗したので、gitとかCUnitとかインストールしていろいろしんどくなってきた。
初期起動時にビルドを上手く行くようにしたら上手く動くようになりました。

spdkのセットアップが終わった時点でセキュキャンの2日前となっており、課題が残ったまま事前課題は終了です。 

まとめ

↑の具合で実装を進めていったリポジトリはこちらです。 github.com

Go言語の勉強になりました。goroutineすごい、簡単に非同期処理ができた。

以下講師より

キャンプ中はC言語だそうです。

おわり