🍯

「イマーシブDDoS」を展示しました

2024/10/18に公開

学祭でXR展示企画の一部として、シューティングゲームを出展しました。

シューティングゲーム自体は何の変哲もないものですが、普段は意識しない通信の中のパケットを意識できます。サイバー空間上のパケットを現実世界に映し出したという点でXR(クロスリアリティー)です。
サーバの偉大さを実感するとともに、サーバになれる素質を持った方がおられることがわかりました。

展示の趣旨

普段何気なく利用しているサーバですが、サーバが思い起こされるのはサーバがダウンした時だけです。
この展示でサーバの大変さを体験することによりサーバへの感謝を思い起こせます。
また近年増えているDDoSの恐ろしさを身をもって実感できると良いと思いました。
さらに最近はイマーシブが流行りということで、イマーシブDDoSにしました。

シューティングゲームについて

ゲーム内容
  • 降ってくる障害物を避けるゲーム
  • 泡の発射で障害物を退ける
  • 退けたパケット数と避けたパケットの総バイト数が得点
特徴
  • 障害物はサーバの受信パケット

  • ゲーム開始時にサーバ上でpingのプロセスが100個作られる

  • eBPFプログラムをXDPにアタッチして受信パケットを監視

  • サーバーの気持ちになれます

  • パケットの到着が多くなると難易度が上がります

  • 普段は意識しない通信の特にパケットを意識できます

撃ち落とした時の例

アーキテクチャ
  • ホストのXDPでパケット受信情報監視
  • ホスト上のサーバーの別スレッドでeBPFマップから読み出し
  • ホストからWebSocketでクライアントにパケット情報送信
  • クライアント側で受け取ったパケット情報に応じて、障害物生成
    ※サーバはメインスレッド(Flaskサーバ) + 別スレッド(eBPFマップからパケット情報読み出す人)
サーバマシン上での受信パケットの生成

自然な受信パケットのみでは、パケットの受信量に波があります。なので受信パケットが減ったときにゲームがつまらなくなります。そこで受信パケットを自ら増やすことにしました。
サーバー側でクライアントから接続があったらホスト上でpingを100プロセスつくり、隣のコンピュータにむかってICMPエコーリクエストを送信します。XDPにアタッチしてるので、RXしか監視できませんが、送ったICMPエコーリクエストがそのままICMPエコーリプライとなってかえってくるのでそれを見ます。
擬似DDoS!と思ったけどUDPが強すぎてほとんどロスしていた、、?

スコア計算方法

スコアは打ったパケット x 10 + 避けたパケットのバイト数の総和で集計しました。
\text{Score} = \text{Bastered Packet Num} \times 10 + \sum \text{dodged bytes of Packet}

スコアとbpsの分布

以下が学祭2日間のスコアの分布です。
2日目は700プレイくらいしていただいたようです。

Day1

二日目はbpsとゲーム難易度の相関を見たいと思ってゲームオーバ時のbpsも取りました。

Day2

スコアを見ると人間は通常のトラフィックでも耐えきれずにスコアを伸ばせていない可能性があります。が一部には高スコアを叩き出しているのも見られるので、サーバになる素質を秘めた方もおられるようです。後日測った際の平均受信バイト数は平均3000~5000バイト/sなので、2~3秒程でゲームオーバになっていることが分かります。この2~3秒というのはゲーム開始から障害物が画面下にいるプレイヤーと交差するくらいの時間です。多くの人が序盤の段階で迫り来るパケットの量に圧倒されてしまっていることが推察されます。

bpsの分布は割と正規分布の形になっています。ゲームオーバ時のbpsでは40,000~60,000bpsが多く、後日測った平均受信bpsが24,000bpsなのでそれよりは高いことが多いようです。バースト時にゲームオーバになっている可能性があります。

本来は得点とbpsとの相関も見たかったのですが、これはゲームオーバ時のbpsに加えて、ゲームプレイ中の平均bpsもとっておくべきでした。またゲームオーバ時直近5秒間のbpsをとっていたらバースト/スパイクとゲーム難易度の相関がより理解できたかもしれません。

サーバ上の平均受信bps

後日サーバ上の平均bpsを調べました。サーバ上の平均受信bpsは, 1, 5, 2, 4, 1, 1, 1, 5なので大体3KB/sくらいです。これは, 3 \times 8 \times K = 24,000bps
多い時で50,000bpsの時もありそうです。
ゲームオーバ時の最頻値は40,000~60,000bpsなので、やはりバースト風なことが起きた時にゲームオーバになっている可能性が示唆されます。(過去5sくらいのbps取っとけばよかった...)
※ちなみにこの受信bpsは別の日にとったやつなので展示日のパケット受信量と同じかは不明。

$ ifstat -i enp1s0f0 1
     enp1s0f0
 KB/s in  KB/s out
    1.54      2.47
    5.43      2.83
    2.75      1.83
    4.21      3.18
    1.34      1.44
    1.26      1.59
    1.28      1.44
    5.36      2.49

改善点

  • ICMPがあまり見えずにUDPが多発していた
    これはおそらくCloudflare Tunnelを使ってサーバをインターネットに公開したのが原因です。cludflaredがCloudflareのデータセンタとの通信にQUICを使っているので、UDPが大量発生していたのかと思われます。(たぶん)
  • プレイ中の平均bpsも計測しておけばよかった
    していたらゲームオーバ時のbpsは平均bpsより高い的なことが分かったかもしれない。平均受信bpsが高いほど得点が低いみたいなことが分かればより面白かった。
  • サーバーがeBPFマップからパケットデータを受け取るときにロスしている可能性
  • モニターでのIPアドレスの匿名化
  • IPアドレスごとに色を変えるとか
  • プレイヤーがどれか分からないとか

まとめ/感想

割と皆さんすぐにゲームオーバーになってしまっていたように感じます。サーバーにとってはたいしたことはなくても人間にとっては処理しきれない量となり十分DDoSとなりることがわかりました。それでもパケロスして少なくなったパケット量の可能性があるので、サーバが普段どれほどのパケットを捌いてくれているかが伺えます。

サーバーの偉大さを思い知りました。人間には到底処理しきれない量のパケットを捌いてくれていることを実感できました。頭が上がりません。感謝です。

余韻

休憩から帰って来たら、誰かがコンソールを開いた形跡がありました。
普段使いではないラズパイ上でブラウザを開いているだけの展示だったので特に問題はなかったですが、よからぬことを企む人はいるようです。コマンドの履歴を見ても自分の打ったもの以外は無さそうでした。単に開いただけなのか、はたまたそれすらも消したのか。。。?
写真撮るの忘れた、、

追記:
先輩に教えてもらったのですが、bash_historyに残さないような設定が環境変数でできるようです。この設定はsudo権限いらなさそうなので誰でもできます。ラズパイのマイクロSDカードが危険品扱いになりました。

Discussion