it.todo("should be a (web)log");

役に立(つ/たない)技術情報やポエム

ICTSC2022に参加しました

ICTトラブルシューティングコンテスト(以下 ICTSC)が開催されたので参加してきました。 結果としては 2855 点の満点を最初に達成し、優勝でした。

チーム

word-unknown-tsukuba-otaku で参加しました。

メンバーは以下の通りです。(順不同)

応募まで

去年まで MIS.W 1 に所属していたこともあり ICTSC には強い興味を持っていたのですが、2021年度に行われた冬の陣を最後に動きがなく、参加してみたいという気持ちだけがある状態でした。 この一年 UNIVERGE IX2 や EdgeRouter3 などで遊んでいた4こともあり、よい力試しにもなると考えていました。 開催が発表されたときは本当に驚きました。 Twitterで人来なさすぎ!!!と叫んでいたら友達を呼ぶことに成功したので友達の友達達とチームを組み、出場することができました。

戦略

概ね部屋に集まって問題を解いていました。各メンバーが解いている問題の管理には Discord のフォーラムチャンネルを使っていました。 前日に「そういえば問題の会場が必要だな」と思いスレッドとどっちが便利か10秒くらい悩んだ後に適当に作ったのですが、GitHub の Issue ライクな管理が Discord 上で可能になるので非常に便利でした。

問題

チームメンバーの得意そうな分野をざっと聞いたところ、一番(ICTSC のスコープでの)ネットワークの知識がありそうだったので主にネットワークの問題を解いていました。

IPv6DHCP - gwe (1日目)

FRRouting5 (以下 FRR) で DHCPv6 もしくは SLAAC6 を用いてアドレスの配布をせよという問題でした。 ネットワーク構成は以下のようになっていました。

dhcp-server <--> client

ステートフルな DHCPv6 は設定が面倒であり、十分な大きさのアドレス空間が割り当てられている状態において IPアドレスのみを設定するという今回の問題では特段やる理由は無いので SLAAC を設定する方向で解きました。 FRR を直接触るのは初めてでしたが、UNIVERGE IX を触っていたこともあり7、特に混乱することもなく8設定することができました。 client の側にも Router Advertisement を受け取らないといったような罠は存在しなかったので dhcp-server 側の設定だけで解くことができました9

解答: https://gist.github.com/tosuke/6200159392634184489d655adb3a281a

俺はインターネットの一員になるんだ! - mzr (1日目着手・2日目解決)

GRE トンネルを通して eBGP のセッションを構築し、トンネル対向アドレスを含む経路を受け取るとトンネル対向への経路も乗っ取られてしまい、トンネル自体が疎通しなくなってしまうという問題でした。ネットワーク構成は以下のようになっていました。

(transit) <--(L3 network)--> Router <--> PC

デフォルトルート(::/0)を/48の経路が上書きしているので Linux の経路選択アルゴリズムを理解していれば特に混乱することもないはずです。 しかし1日目ではなぜか BGP で経路を受け取っていない状態でのトンネル対向への経路を間違って認識していて、どうして経路が乗っ取られているのかを理解できないまま一度手放していました。

2日目に正しい状態において選ばれるべきトンネル対向への経路がスタティックルートで設定されているデフォルトルートであることを見つけ、この問題の構造が自宅サーバーをインターネットに接続するために構成しているネットワーク10と同じであることに気付きます。

自宅のサーバネットワークではこの問題を VRF を使って解決していたので同じ方法で解決しようとしました。 VRF を新たに作り、トンネル(tun1)とトンネルを通るべき通信(eth2)のルーティングテーブルをトンネル自体の(カプセル化された)通信のものと分離することで問題を自然に解決することができます。 しかし VRF を用いると ping <ip> vrf <vrf>のようなコマンドを用いなければ ping の疎通を確認できません。そのためこの方針で正しいのか少し悩みました11が、質問をしたところ問題ないようだったので解きました。

解答: https://gist.github.com/tosuke/cc34f0999becbe6c4284491c32702cbc

俺自身がDHCPサーバーとなることだ - wsm (1日目)

DHCP サーバーを構築して配下のホストに IP アドレスを設定せよという問題でした。 isc-dhcp-server が入っていたことを確認し、設定もいい感じに見えたので起動したところ、ホストからの応答がなくなってしまいました。 完全にわからなくなってしまったので残していたところ、azrsh と pyusuke が解いてくれました。ホスト自身の DHCP クライアントと起動したサーバが干渉してしまい、壊れてしまったということだったようです。友達がいてよかった〜

余談

  • やりたいこととしては DHCP リレーを構築するべきだったのかもしれないとは思います
  • systemd-networkd の DHCP サーバ機能を使えば特に詰まることなく構築ができるというのは閉会式で言われるまで気付きませんでした。確かにクライアントとサーバが同じなら干渉しにくそう

やらかしたかもしれない… - lty (1日目)

sudo suを実行して root ユーザーになるとcd /が実行できないという問題でした12。 cd が制限されていると出たので "cd restricted" あたりで調べてみると rbash というやつがあるらしいということを知りました。 適当に chsh してみるもうまくいかずに悩んでいました。 sudo su以外の方法(sudo -isudo -ssudo su -)では問題が起きなかったこともあり、sudo suでは読まれない bash の profile あたりに何かがあるのではないかと思って調べていましたが、特段怪しいところはなく、手が止まってしまいました。 ここで cyanolupus が引き取って調べてくれました。結果としては最初に試した chsh のやり方が悪く、効果がなかったということでした13。友達がいてよかった〜(2)

データベースに入れない! - ing (1日目)

coorde に 「VyOS なんもわからん」と言われたので手を付けました。 実際には VyOS も含まれるがファイアウォールとソケット周り、MySQL の権限周辺の複合問題でした。 ネットワーク構成は以下のようになっていました。

PC <-> Router <-> Server

PC から Router を経由して Server にある MySQL にアクセスしたいという問題です。ただしセキュリティ要件を考慮する必要があり、以下のようなアクセスは許されません。

  • PC の存在するネットワークから Server の存在するネットワークの他のサービスへのアクセス
  • Server の存在するネットワークの他のホストからの Server 上の MySQL へのアクセス

Router と Server にあるファイアウォールを適切に設定すると MySQL のバインドアドレスが127.0.0.1になっているという問題に遭遇するのでそれを直し, それを直すと MySQL のアドレス認証の設定が必要になったのでやりました。

しかし、人の話を聞かなかった結果「coorde が既に VyOS にファイアウォールを投入していた」「問題の制約に新しい MySQL のユーザーを作ってはいけないとされている」ことを知らずに解いてしまい、大幅に減点されました。

その後2日目に azrsh がちゃんと考慮して解いてくれた結果満点をもらうことができました。友達がいてよかった〜(3)

Beer - sjq (2日目)

ピアリングのための情報が与えられ、FRR を使って設定をするという問題です。 pyusuke が FRR の設定で詰まっていそうだったのでちょっと見ていました。 ポリシー周りで受け取ったプレフィックスが破棄されていそうだったので自宅の VyOS なルータだとどうなっているんだっけ?と思って見た14ところno bgp ebgp-requires-policyという記述があったので入れたらこの部分を解決することができました。 ただし FIB への反映がされず、関係するようなエラーメッセージを見つけられずに困ってしまい pyusuke に戻して他の問題を解いていました。 後で pyusuke が解いてくれました。友達がいてよかった〜(4)

トラブルシューターの初仕事 - omu (2日目)

OSPF とファイアウォールの問題でした。ネットワークは以下のようになっていました。

pc <--> rt01 <--> rt02 <--> srv01
          |         |
          +-----> rt03 <--> srv02

rt01 と rt02、rt03 の間で OSPF を使って経路交換を行い、PC から最適なホップ数で srv01 と srv02 に到達できるようにして、かつ srv01 から srv02 へのアクセスは遮断したいという問題でした。

まず rt01 と rt02 のルーターIDが被っていることに気付きます。命名規則から rt02 のほうが間違っているように見えるのでそれを修正し,デーモンを再起動します。 次に rt03 に存在する OSPF や配下のホストへのアクセスを遮断しているファイアウォールを修正しました。

ここまでで pc から各サーバに到達できる状態にはなったのですが、なぜか srv02 への経路に rt02 が含まれていました。 結果としては rt01 に静的ルートの設定が存在することによって起きており、その設定を削除することによって解決しました。

解答: https://gist.github.com/tosuke/01ab812da6f9e58edf8b1110ca517047

おわりに

ICTSC は初出場でしたが、優勝できてよかったです。運営委員としても参加したいところではあるのですが、卒論があるのでどうなるか……

やったね

最後になりますが、運営の皆様はお疲れ様でした。楽しいコンテストをありがとうございました!

おもいで

なかよし

最後の解答を提出した後、yakudo15 を上げる嫌な後輩

祝杯


  1. 早稲田大学経営情報学会。ICTSC の文脈では mis1yakudo の元ネタ(の元ネタ)として有名だと思われます。
  2. VPN対応高速アクセスルータ UNIVERGE IXシリーズ | NEC
  3. Ubiquiti Networks の出していたルーター製品シリーズで、VyOS の元となった OS である Vyatta のフォークが入っています。
  4. FD.pdf を読んで面白そうな機能を試す、とりあえず EdgeOS の set を連打して面白そうな機能を探すなど
  5. https://frrouting.org/
  6. Stateless Address Auto Configuration。ルーターを含むマシンが ICMPv6 メッセージをやりとりすることでアドレスを記憶して(ステートを持って)集中管理するマシンなしで各マシンの IPv6 アドレスを設定する方法
  7. IX2105 を貸してくれた友人に感謝
  8. vtysh も UNIVERGE IX もいわゆる Cisco ライクな設定の文法を持っているので同じようなノリで操作できます。この文法が別に良いものとは思えませんが……
  9. この問題は100点問題なのであまり難しい構成にはならないのはメタ的には明らか
  10. https://scrapbox.io/tosuke/サーバネットワーク
  11. pingIPアドレス以外の指定を許した場合、出力インターフェースを指定することで経路の設定を無視してパケットを送信することができてしまう
  12. 若者なのでsudo -i以外を使うことがなく、挙動の差異を知らなかったので勉強になりました
  13. やらかした…
  14. VyOS は内部で FRRouting を使っている
  15. #traP1yakudo OR #mis1yakudo - Twitter Search / Twitter