ICTトラブルシューティングコンテスト2022(ICTSC2022)に参加しました
3/4 から 3/5 にかけて開催された ICTトラブルシューティングコンテストに参加しました。
最終的に2785点を獲得し、3位でした。残り1問解ければ全完でした。
チームメンバー
- gotti
- k1h
- sho
- rand0m
- nakanokurenai
この5人でチーム「結束baud」(ケッソク バウド*1)として参加しました。
作戦
2日間共に出ることができる人が私を含めて2人であったこともあり、なにも考えずに各自が解けそうなものを好きに解いていました。 とはいえ私は皆が選択して残った問題をやろうと思っていました。
各日は次のメンバーたちが来てくれました。
- 3/4: gotti rand0m
- 3/5: gotti k1h sho
また、すべてオンラインで行いました。そのための工夫としては
- Discord 上で通話を常に繋いでおく
- 問題を解き始める・手放すときは Discord のテキストチャンネルで宣言をする
- 引き継ぎができるように Scrapbox に情報を書いておく
といった感じでした。
解いた問題
私は以下の問題を解きました。
ajl
protocが... 見つからない!?rct
盲点の窓cya
オレオレS3dkv
答えてくれPingサーバー、ここにはuserモードとsystemdと、俺がいる!cfb
ストレージ消し飛んだ...ing
データベースに入れない!omu
トラブルシューターの初仕事
どのように進めたか、簡単に説明します。
1日目
私は前日に早めに寝た結果2時頃に起きてしまって、そのままぼんやり時間を過ごしていたら開会式の時間になっていました。
開会式の間に気合を入れるためにシャワーを浴びており、開会式に出ているのは gotti だけという状態でした。
10:30 からはしばらく問題を喋りながら眺めて、触れそうかつ点の高いものから適当にやることにしました。
ajl
protocが... 見つからない!?
11:10 頃に取りかかりました。
~builder
内の Dockerfile を見たら Alpine Linux を使っており、経験から即座に共有ライブラリのせいだろうと思いました。
とはいえ根拠なしに変更するのもよくないので、PATH
が通っていることや、ファイルがあることを確認して(ldd
を ld
と混同してコマンドがないと言われたりもしてから)シュッとベースイメージを変更しました。
そのあと ~builder/deploy
を叩いたら protoc-gen-go
がないよ、と言われたのでそういえばそうだったなと思いながら足して、動きました。
9c9 < FROM golang:1.20.1-alpine AS builder --- > FROM golang:1.20.1-bullseye AS builder 10a11,12 > RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 && \ > go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
当初はイメージの容量が制約条件になく満たしていたのですが、11:52 頃に運営から builder:v1
イメージが 300MB を越える事態はゆるしまへんとの通告がなされたため、Alpine Linux で動くように直しました。*2
ldd
を見ると libstdc++
と libgcc
を入れることでとりあえず動きそうなので入れて試したものの解決しなかったので、さらに gcompat
を追加することで動かしました。
参考文献を探したところ Alpine Linux の wiki に Running glibc programs というページがあり、面白がっていました。
ところで、docker image ls
したら alpine ベースなのに size が 280MB くらいあったのですが、なぜなのかわからずじまいでした。そういう罠?
解答: https://gist.github.com/otofune/236952a4dc0001e8254b6fa94dc220a9#file-ajl-md
ing
データベースに入れない!
12:35 頃に取りかかりました。
nc
を使って TCP パケットの疎通を確認しながらファイアウォールの設定を調整しました。人生初 VyOS でしたが show firewall
した内容を真似するだけですんなり使えました。
その後、MySQL の bind-address を修正し、その上で user
アカウントに接続できないのは host が限定されているためだということもすぐにわかりました。
制約からユーザーを変更することは許されていると考え CHANGE USER
を使おうとしたものの user
ユーザーでは当然叩けず、root@localhost
に入りたかったのですが方法がわからず詰まりました。
このときは MySQL は host の名前解決を行うことを利用し、嘘解答を出しました。
具体的にはどういう副作用があるかはわからないものの /etc/hosts
に次の行を追加し、動作させました。
172.16.1.128 localhost
そもそも採点されないかと思いきや、165点と高得点を頂けたためしばらく放置することになります。
rct
盲点の窓
14:48 頃に取りかかりました。
systemd status をしたところ次のように open が失敗して、nginx が stop していました。
Mar 04 04:25:00 blog-server nginx[292]: nginx: [emerg] open() "/etc/nginx/sites-enabled/blog.example.jp" failed (40: Too many levels of symbolic links) in /etc/nginx/nginx.conf:62
ファイルを確認したところ、相対パスでシンボリックリンクを貼っており「やるよね〜」と思いながら絶対パスで貼り直し、nginx -t
が通ることを確認してから再起動しました。
そのあと 502 エラーが起こったので proxy_pass
と journalctl -u blog
のログと見比べて、ホストが違っていたのでシュッと直して提出しました。
解答: https://gist.github.com/otofune/236952a4dc0001e8254b6fa94dc220a9#file-rct-md
cya
オレオレS3
15:15 頃に取りかかりました。
問題文を見ただけで path-style
のことを思い出していたので、もう一日目は終わり際だったこともあり、のんびりドキュメントを調べてから提出しました。
詰まった点としては fluentd が td-agent
という形で配布されていることを覚えていなかったこと、adm
グループがなにに使われているか調べようとしたもののよくわからず無駄に時間を食ったことくらいでした。
解答: https://gist.github.com/otofune/236952a4dc0001e8254b6fa94dc220a9#file-cya-md
1日目の終わり
1日目と2日目でどうも問題が同じそうだぞと思いながら集まったのですが、gotti 共々昼飯を抜いてぶっ続けで解いていたせいで疲れきっており、準備をする気力はありませんでした。
代わりにひたすら雑談をして、Splatoon 3 をやって寝ました。
2日目
前日に寝不足でありながら起きていた影響か 10:00 ぴったりくらいに起床して遅刻。 たまごかけご飯とインスタント味噌汁を食べてから開始しました。
dkv
答えてくれPingサーバー、ここにはuserモードとsystemdと、俺がいる!
10:27 頃に取りかかりました。 rand0m が提出して0点だった問題でした。
どうも問題の解明はできており、解決方法が前提条件と合致せず採点されなかったようでした。 具体的には systemd コマンドを直接叩いており、解答の中で許可されるアクションに合致していなかっただけでした。
いい感じに修正して提出。
解答: https://gist.github.com/otofune/236952a4dc0001e8254b6fa94dc220a9#file-dkv-md
cfb
ストレージ消し飛んだ...
11:30 頃に取りかかりました。
ぱっと見るとフルバックアップを戻してから、増分バックアップを順に戻せばよさそう。
zfs send
の逆操作を調べて出てきた Oracle のページを見たら、フル・増分バックアップどちらであっても受信する時に使うコマンドは同じということを感じとりました。
また、丁度同じページに zfs recv -F
(force) を使うといい感じに rollback もしてくれるらしいと知りました。
ただし、新しい増分スナップショットを受信するには、まず受信側のファイルシステムをロールバックする必要があります。または、-F オプションを使用すれば、ロールバック手順を実行する必要がなくなります。 https://docs.oracle.com/cd/E24845_01/html/819-6260/gbchx.html
どうせ zpool は壊れているので適当に復元してもいいだろうと思い、あんまり調べずこのコマンドをそのままつっこんで試すことにしました。 ls backups を bash の for で回してやれば順番通りになりそうだったので、シュッと recv する bash スクリプトを書いて通ったので提出。
解答: https://gist.github.com/otofune/236952a4dc0001e8254b6fa94dc220a9#file-cfb-md
ing
データベースに入れない!(2)
12:40 頃に取りかかりました。 私が提出して165点だった問題でした。
わからんなあと思いながら触っていたところ、なにかの拍子に sudo mysql -u root
が通ることに気付きました。
気付いた時点ですべての問題を誰かが解いている状態だったので、なぜ認証が通るのかのんびりと調べて、始めて auth_socket
認証を知りました。
The socket plugin checks whether the socket user name (the operating system user name) matches the MySQL user name specified by the client program to the server. https://dev.mysql.com/doc/refman/8.0/en/socket-pluggable-authentication.html
また、Ubuntu のデフォルト設定では root パスワードを設定しないと root は auth_socket
のみになるらしく、デフォルトだったのかとひとり納得していました。
解答: https://gist.github.com/otofune/236952a4dc0001e8254b6fa94dc220a9#file-ing-md
omu
トラブルシューターの初仕事
13:45 頃に取りかかりました。 gotti が提出して175点だった問題でした。
再展開をし、まっさらな状態で設定を眺めていたところ、報告書から漏れている static route の設定を見つけました。 聞いたところ、認識していたにも関わらず手順書に入れ忘れていたことが判明し、気付けてよかった〜 となりました。
ついでに ufw まわりの設定をちゃんとやるぞと思って man を調べてどうも protocol は次のようにすれば通せるらしい、と思ってやったところコケて泣いていました。
user@rt03:~$ sudo ufw allow proto 89 to any from any ERROR: Unsupported protocol '89'
iptables ルールを ufw と共存させる方法もあったなあと調べて https://wiki.ubuntu.com/UncomplicatedFirewall#Advanced_Functionality を読んだりもしていました。
が、作業中に間違えて iptables -vF
を叩いて再展開の刑を受けてしまったこともあり、ルーター本体に関するセキュリティ要件はないことはわかっていたため行いませんでした。
解答: https://gist.github.com/otofune/236952a4dc0001e8254b6fa94dc220a9#file-omu-md
おわりに
チーム word-unknown-tsukuba-otaku
の tosuke に影響されてチームを作っており、倒してやろうと思っていたら優勝されて悔しいです。
とはいえ、3位という大きな結果を残すことができました! 出てみたいと思いながら学内で人を集めなければならないことにハードルを感じていたのですが、呼びかけをしたら5人と上限人数まで集まり、各人しっかり問題を解いてくれました。感謝しかありません。
私としては小さな得点の問題や部分点となった問題を拾ってチーム全体に貢献できたのではないかと満足している部分はありながら、ネットワークまわりがあまりわからず任せっきりで、助けになれなかったことが悔しいです。
初参加だったのですが、とても楽しく、休止を乗り越えてくれてよかった*3と心から思います。 運営の皆さん、本当にありがとうございました。
VyOS にも入門できたことですし、もっとネットワークまわりを触って、来年は全員を薙ぎ倒すぞ!