shinobe179の日記

@shinobe179 の技術メモ・やらかし録

【ISUCON】ISUCON10予選突破した話と、インフラ担当としての振り返り

はじめに

先日開催されたISUCON10で、私が所属する某チームは予選を突破しました。:tada: なぜかチームメンバーの誰もブログを書かないので、決勝に備えて某チームのインフラ担当たる自分のことだけでも振り返っておこうと思います。

※注意: 自分のことしか書かないので、チームとしてどうやって点数を上げていった的な話は他のメンバーに任せます。他のメンバーも何も、諸般の事情で所属チーム非公開なんですけれども。

よかったこと

Netdata

これまでのISUCONでもNetdataは使ってきたんですが、オリジナルのダッシュボードを作っての参加ははじめてでした。これで方針が決まったりしてて、正直バチボコに"効いた"と思っています。公開したときほとんど反応なかったけど、これ使って決勝出たんでよろしければお手にとってみてください。決勝に向けて改善の予定もあります(後述)。

github.com

befs-anne.hatenablog.com

ミドルウェアさばき

アプリ2名インフラ1名(私)みたいな割り振りだったので、インフラのオペレーションは(事前事後の連絡・相談はするものの)私に一任されていました。今回毎週平日1回、予選が近くなってからは追加で土曜日まる1日練習に費やしていたし、事前によくあるオペのチートシートも作ってあったので、これまでのISUCONとは比べようもないくらいスピードと正確さが上がっていたと思います。ほとんどググらなかったです。

課題

解析力の向上

Netdataはよかったですが、今のところ代表的なコンピュータリソースの確認しかできていません。予選ではそれで十分だったわけですが、決勝はより踏み込んだ解析に対応するために、例えばMySQLのCache hit rateやBuffer poolなどの指標も可視化できるように改良するつもりです。

また、ベンチマーカーが吐くネットワークパケットの解析もあまりできませんでした。WireSharkだけだと結構無理があるので、別のツールを作っているところです。これも間に合えばGithubで公開しちゃおうかと思っています。

また、可視化だけしてもしょうがないので、それらを利用するための事前知識も養おうと思っています。こちらも(ネットワークはこれまで積み重ねてきたものである程度なんとかなりそうなので)MySQLが主になる予定です。この本、おすすめです。

さいごに

決勝進出は本当にメンバーの力によるところが大きいなと思っていますが、手前味噌ながら私もそれなりに貢献できたんじゃないかと思います。決勝参加者の皆さん、対戦よろしくお願いします。持てるリソース全ツッパして、悔いのない戦いをしたいです。最後のISUCONですからね。ん……?最後のISUCON……でしたよね……?

【インフラ】ISUCON用Netdataダッシュボードを自作したので公開する

はじめに

もうすぐISUCON10予選ですね。私もとあるチームの一員として出場します。今回の開催が最後ということでチーム一同気合が入っておりまして、特訓の日々です。

さて、競技中のモニタリングというのは言うまでもなく重要なポイントでありまして、今回ISUCON向けに3台のサーバーの主要指標(CPU、メモリ、ディスクI/O、ネットワークI/O)を1画面で見られるようなNetdata用ダッシュボードを準備しました。せっかくなので公開します。取り立ててよいところがあるわけではないですが、シンプルで見やすいと思うのでよかったら使ってみてください。

github.com

よく分かる解説

見方

上からメモリ使用率、プロセス毎のCPU使用割合、CPU使用率、ディスクI/O、(消えてますが)ネットワークI/Oです。このうち「プロセス毎のCPU使用割合(Apps CPU Time on servers)」については注意が必要なので後述しますね。

f:id:befs_anne:20200907004027p:plain

「Apps CPU Time on servers」について

上から2番目「Apps CPU Time on servers」は、どのプロセスがCPUを食ってるのかを調べるためのものです。しかし、Netdata(厳密にはapps.plugin)がアプリケーションとして認識できるのは、apps_goups.confに記述されているもののみです。有名どころは認識されるようになってますが、それ以外はグラフ上では「Other」という扱いになります。つまり、ISUCON用にこさえられたアプリは「Other」として扱われる わけです。私は割り切ってこのまま使っていきますが、気になる方は以下をご参照ください。※サーバー側とクライアント側両方のapps_groups.confをいじってもOtherのままだったので、んーまあいいかってなった

learn.netdata.cloud

github.com

接続方法

ローカルでNetdataを動かして、競技用サーバー(こっちでもNetdataが動いてます)へは安易にSSHポートフォワードで接続することを前提としています。競技用サーバーとは別にNetdataがインストールされたモニタリングサーバー的なものを用意して、isucon.htmlをパブリックに見られるようにしたほうがOX(Operator Experience(造語))が上がると思うんですが、ちょっとめんどくさいなと。あくまで弊チームでの利用を前提としたものという点のみ、すみませんがご承知おきを。

その他

これ、全く以て超絶技巧ではなく、Netdataをインストールすると付いてくる tv.html をちょいちょいっといじっただけのものです。 /usr/share/netdata/web/ の下にあると思いますんで、自分だけの最強のダッシュボードを作ってみてくれよな。

おわりに

公開は競技後でいいかーと思ってたんですが、よく考えたら今回最後じゃんということで、今のタイミングで公開することにしました。出し惜しみするほどのものでもないんですけど、Netdataのこういう使い方を知らなかった人にこの記事が届いたら嬉しいです。弊チームだけでなく、全ての参加者にとって悔いのないラストISUCONになるといいですね。言うて、きっとなんらかの形で続きはするんだろうなという気もする。

ここ最近のトピックまとめ(2020/07/01 - 07)

はじめに

2020年7月1日〜7日のもろもろをまとめました。1ヶ月はちょっと貯め過ぎて、1週間分見るのに30分以上かかったのでやむを得ず小分けに……。

トピック

技術

MVP

なるほどなと思った。

Elasticが検知ルールを無償提供

Elastic SIEMと合わせて使ってみたい。

SIEMって何?

何?

WebView

ふぁぼった時はなんの気なしにだったけど、最近色々あってスマホアプリのキャッチアップすることになったのでメモ。

イエラエ社

イエラエ社の動向にはめちゃくちゃ注目している。

低レイヤーガール

観よう。

gixy

Nginx設定不備の解析ツール

github.com

Ncom不正アクセス事件

あったな。これきっかけで『ゼロトラストネットワーク』を買った。社内ネットワーク運用に興味が出てきた。ドメインテイクオーバーもこの頃だったと思うけど、特にふぁぼってなかった。

foxsecurity.hatenablog.com

PenTesterAcademy

VHLが終わったらやるかも。終わるのか……?

www.pentesteracademy.com

CRYPTRECガイドライン

読まなきゃね。

www.cryptrec.go.jp

番外

ユニクロの白Tの話

よかった。

紙の話

電子書籍やマークダウンでのメモにシフトしようと頑張ってたけど、無視できないレベルのオーバーヘッドがある気がして。結局本は物理を買うことにした。

ここ最近のいいねまとめ(2020/06/30)

はじめに

ここ最近のいいねまとめました。

セキュリティ業界に就職したいなら

MVP。全ての某書読者は朝晩声に出して読むべき。

脅威インテリジェンスの教科書

以前読んだ『インテリジェンス駆動型インシデントレスポンス』とセットで、あらためてインプットしたい。

t.co

AWS 認定セキュリティ専門知識対策本

出るらしいです。たぶん買う。

www.amazon.co.jp

技術を知らないマネージャー

自分にあって相手にないものが自分の価値。資格だけエンジニアとかも叩かれがちだけど、分母だけが大きくなっていくのは相対的に自分の価値が高まることになるので、そういう観点からは(独善的だとは思うけど)割と好ましく思っています。

バグバウンティを狙う際には、絶対にルールを読みましょう。

はい。

Tsunami 試してみた

デモとは言え、出力される情報が結構心許ないか気がする。 CVE 番号とかが出てくれるとすごく嬉しいんだけど。これなら OpenVAS のほうがいいかなと思ったけど、 OpenVAS に比べて手軽に使えるのが魅力か。

NTT フレッツ光における通信速度などの現状について、背景や仕組みから正しく理解する 2020

既知の内容っぽかったけど解像度が段違いだった。本題から外れるけど、「引っ越しで光配線方式をツモりたい」は参考にしたいところ。

htn.to

ハニーポットまとめ

構築したい気持ちと、構築したところでちゃんとお世話しないだろうなという気持ちがある。

github.com

AWS 認定ソリューションアーキテクト プロフェッショナル 対策本

買った。

www.amazon.co.jp

tcpdump チートシート

ええやん。

https://cdn.comparitech.com/wp-content/uploads/2019/06/tcpdump-cheat-sheet.jpg

(おわり)

【VirtualBox】ゲスト OS を放置してたら DHCP で割り当てられる IP アドレスが消えていたときの対処

はじめに

ゲスト OS の Linux を放置しているといつの間にかインターネットに接続できなくなっていて、 ip aip r すると NAT インターフェイスがなくなってデフォゲがなくなっていることがあります。 sudo systemctl restart network-manager とか sudo ifconfig eth0 downup とかしても解決しないので、 ゲスト OS を再起動していました。

結論

ゲスト OS で sudo dhclient したら、無事 IP アドレス/デフォゲ共々復活しました。リース期限切れなのか、はたまた別の理由なのかは不明です。

参考(「linux ipconfig renew」でググったら見つけた): https://www.atchfactory.com/mvt/cat2/linux/ipconfig-renew-ubuntu.html

【Python】テキストファイルを開いて for で読み込むときは改行コードに注意しましょう(自戒

はじめに

あまりに初歩的過ぎて書くまでもないと思ったけど、そういうのだからこそ(自分のために)残しておく価値があると言い聞かせて書く。とは言え初歩的過ぎて凹んでいるので Twitter に流すのはやめておこうと思う。

結論

テキストファイルを for 文で 1 行ずつ読み込むときは改行コードがくっついてくるので必要に応じて処理する。

発端

CTF for Beginners 2020 の Spy に挑戦している最中、事前情報として提示された社員名簿 (employee.txt) を 1 行ずつ for 文で読み込んでログインを試行するスクリプトを組んだ。

import requests
import string
import json

URL = 'https://spy.quals.beginners.seccon.jp/'
with open('employees.txt') as f:
    for u in f:
        data = {
            'name': u,
            'password': ''
        }
        r = requests.post(URL, data=data)
        print(f'status: {r.status_code}, user: {u}, time: {r.text}') # 所要時間だけパースするのが面倒なので、 HTML ごとテキストに書き出して別途 grep した

見立てが正しければ、システムにアカウントが存在する場合とそうでない場合とで、ログイン処理にかかる時間に差が生じるはずだが、有意な差は得られなかった。しかし、手作業で 1 アカウントずつ確認していったら有意差が確認できた。結局、 flag は手作業頼りで取った。

原因

flag を取った後に data を print したら以下のようになっていた。 \n が含まれているせいで全アカウント存在しないものとして扱われたから、有意差が得られなかったということが分かった。

$ python3 enumerate.py
{'name': 'Arthur\n', 'password': ''}
{'name': 'Barbara\n', 'password': ''}
{'name': 'Christine\n', 'password': ''}
...

対策

rstrip()\n を除去すればよい。そもそも予想通りでない時点で print デバッグすればよかったし、 VSCode とか IDE を使っていればすぐに気づけた気がする。

import requests
import string
import json

URL = 'https://spy.quals.beginners.seccon.jp/'
with open('employees.txt') as f:
    for u in f:
        data = {
            'name': u.rstrip(),
            'password': ''
        }
        r = requests.post(URL, data=data)
        print(f'status: {r.status_code}, user: {u}, time: {r.text}') 

参考

qiita.com

【プログラミング】AtCoder ABC164-D の解法に関するメモ

はじめに

1 年以上ぶりの ABC は C 完でした。 D の理解にすごく苦労したので、メモを残します。

アプローチ

たくさんの解説記事を拝読しましたが、皆さん editorial と同じアプローチのようで、それを踏襲しました。大まかには以下のような感じです。

  • 1つ目の for 文で、 s の各区間の mod 2019 の結果の数を mods に保存する。
  • 2つ目の for 文で、 mods に格納された mod 2019 の結果が同一になる組み合わせの数を足し上げる。

atcoder.jp

s = input()[::-1]
v = 0
mods = [ 0 for i in range(2019) ]
mods[0] = 1
d = 1
 
for c in s:
    v += int(c) * d
    v %= 2019
    d *= 10
    d %= 2019
    mods[v] += 1
 
ans = 0
for n in mods:
    ans += (n * (n - 1)) // 2
 
print(ans)

なんで 10 と 2019 が互いに素だと、/ 10n を無視してよくなるの?

ここからは、私が個人的に理解できなかった部分の補足です。

この部分については、どの解説記事にも特に解説がなかったと思います。解説するまでもないことなのかもしれませんが、数学弱者が直感的にこの結果に辿り着くのは厳しかった……。

Twitterで明け方までうんうん唸っていたら、解説記事を投稿してくださっていたタムログさんが解説してくださいました。

※タムログさんの解説記事はこちら

タムログさんの例にのっかると、 2019 / 3 の mod 2019 を計算するときに、分母を無視すると 2019 ≡ 0 (mod 2019) ですが、分母を考慮に入れると 2019 / 3 = 693 ですから、 693 !≡ 0 (mod 2019)となって、結果が変わってしまう(分子だけだと合同だけど、分母込みだと合同でなくなる)わけです。これがなぜ起こるかというと、分母が 2019 と互いに素でない値だと、2019 の因数を除してしまうからですね。

以下は、分子を 20190 、分母を 10 もしくは 3 としたときの、それぞれの分母なし・ありでの合同式の真偽を確認したメモです。最後のほう、 6930 に見えますが 6730 です。

f:id:befs_anne:20200502200149j:plain

なんで mods[0] = 1 するの?

前述したような処理で解が求められるのは、「(区間A - 区間B) % 2019 ≡ 0 (mod 2019)」であるかどうかを、「区間A ≡ 区間B (mod 2019)」であることを検証することで求められるからです。各区間の mod 2019 の結果の中にはもちろん 0 も含まれるわけですが、区間 A が s[len(s-1)]、つまり s の右端の値を含む場合、区間 B は 0 ということになります。この場合の区間 B ついても区間のひとつとして扱い、0 ≡ 0 (mod 2019) としてカウントしなければ、仮に s の右端の値を含む区間 A の mod 2019 が 0 だった場合に、組み合わせの数が正しく計算されません。

なんで v %= 2019 するの? mod の結果は別で保存したほうがよくない?

n 回目のループで mod しようがしまいが、 n+1 回目のループでの v %= 2019 の結果には影響を及ぼしません(mod 2019 の結果に再度 mod 2019 しても値は変わらない)。計算効率の観点から見ると、v に mod した値を使うことで、後述の d %= 2019 の処理と同様効率を高めていることになると言えそうです。

なんで d %= 2019 するの?していいの?

これをしないと、ループ毎に d が 10 ずつ増えていくので、そのまま乗じてしまうと桁数がかなり大きくなってしまって v %= 2019 の処理に時間がかかってしまうんですね(実際、これがないと TLE になりました)。これをして結果に影響が及ばないかどうかについては、「(3 * 10000) % 2019」 の結果と 「(3 * 1924) % 2019」(※) の結果が、どちらも 1734 であることを以て証明できている気がします。

※…10000 % 2019 = 1924

さいごに

緑コーダー目指して、解けない問題に真剣に向き合ってみました。ふつうに延べ 1 日くらい費やしました。しんどかったです。数学やアルゴリズムの基礎理解が乏しいので厳しい戦いが続きそうですが、強くなるためにやっていこうと思います。