Zopfcode

かつてない好奇心をあなたに。

ルーターでプレゼンする。

市販のネットワークルーターやスイッチに導入することで、元々のファームウェアでは実現できなかった高度な設定や最新のプロトコルが利用できる Linux ディストリビューションの OpenWrt は、2004年の登場から今年でちょうど20周年を迎えた。90年代の Linux ルーターという概念の勃興から、ルーター向け Linux ディストリビューションは DD-WRT や Tomato など複数生まれたが、現在もサポートと新機種の追加が続くほどの活気を保っているのは OpenWrt だけといっても過言ではない。

そんな記念すべき20周年を盛り上げるべく(?)久しぶりにルーター遊びをしたので紹介する。

(本記事は2024年4月26日に岡山理大で開催された Okayama Revengers LT 大会 #2「もう春じゃなぁ〜 LT大会でもするかぁ!」にて発表した以下のスライドを文章にしたものです。)

speakerdeck.com

汎用なコンピューターとしてのルーター

2010年ごろに初めてルーターの代替ファームウェアに手を出した時から、ルーターが汎用なコンピューターと化すそのポテンシャルに私は一貫して魅力を感じていた。その結果、ルーターにディスプレイを接続してみたり、セキュリティ・キャンプで OpenWrt を教材として取り入れたり、といった付き合い方をしてはその成果を発表してきた。

www.zopfco.de

www.zopfco.de

中でも2016年に初めて発表した成果である「BuffaloルータをPCディスプレイにつなげた。」は、その珍奇さもあってか、技術界隈から注目を頂いた。一方で、記事内で紹介した「ルーターでプレゼンをする」という使い方は、当時実現はしたものの詳細を発表しないままだった。

当時のルータープレゼンは、USB 接続の映像出力デバイスを使うという共通点を除けば、以下の2つの手法で実現した。

  • カーネル内臓のターミナル (fbterm) 上で擬似的にピクセルを並べる方法
  • フレームバッファを直書きしてスライド画像を表示する方法

前者の手法。絶望的に解像度が低い。

後者の手法。スライドを記述する DSL として Python を使い、Pillow でスライド画像を動的に生成して投影した。

これらはいずれも、OpenWrt のような質素な環境でも簡便に実装できるやり方として選択した。というより、当時は知識が乏しく、OpenWrtを激しく拡張して高度なことをする手が取りにくかった。

それから幾年が経った今、この記事で紹介するのは「chroot で擬似的にルーターに Debian を導入し、その上でプレゼンをする」という手法である。

使用するルーター

今回は、ほぼ1年前に @musashino_205 が OpenWrt のポーティング(移植)に成功した FortiGate 50E を使う。このルーターはこれまで OpenWrt がポートされてきた数あるルーターの中でも異質な存在で、デュアルコアの高性能な Arm SoC に加え、極度に大きな 128 MiB の flash*1 と 2 GiB の DRAM、さらに USB 3.0 ポートまで贅沢に兼ね備えている。

FortiGate シリーズは業務用ルーターであることを加味しても、Raspberry Pi と大差ないその性能には大きな魅力と可能性がある。

これまでは OpenWrt をビルドする時にちまちまと必要なソフトを準備していたのが、50E では大胆に chroot で別のルートファイルシステムを組み合わせ、必要なものを実機上で用意することすら苦ではなくなった*2。この性能を活かさない手はない。

加えて地味に嬉しいポイントとして、無線を搭載していないことも挙げられる。ファームウェアを置き換えた無線ルーターで電波を飛ばすことには法的な懸念があるため、通常は無線を無効化するなどの対策を取るが、最初から無線が搭載されていなければそんな心配をする必要もない。

ソフトウェアの準備

50E でプレゼンをするにあたり、おおまかに以下の4ステップで準備していく。50E には既に OpenWrt が導入されているものとする。

  • Linux カーネルで USB 映像出力デバイスのドライバを有効化し OpenWrt をビルド
  • ビルドしたファームウェアを実機にインストール
  • リッチな Linux ディストリビューションのルートファイルシステムを用意(今回は Debian を使用)
  • 実機上で Debian に chroot し、Xorg や画像ビューアーをインストール

OpenWrt のビルド

具体的なビルド手順は公式ガイドに譲りつつ、カスタムされた Linux kernel を含むファームウェアをビルドする。今回は、DisplayLink 社製の USB 映像出力デバイスのドライバ、マウスとキーボードのドライバ、フレームバッファで動作するカーネル内臓のターミナルエミュレーター "fbcon"、さらにそれらの動作に必要なビルドフラグを有効化する。

OpenWrt のビルド対象やフラグを設定する menuconfig。

変更点も少ないため、ビルドは一発で成功した。

OpenWrt のビルドが終了したところ。コマンドは `make` を実行するだけ。

実機へのインストール

ビルドしたファームウェアは openwrt-mvebu-cortexa9-fortinet_fg-50e-squashfs-sysupgrade.bin というファイル名で生成される。これを scp で実機の tmpfs へ送り込み、sysupgrade コマンドで実機の flash へ書き込む。

sysupgrade コマンドでファームウェアを書き込んでいる画面。Flash の読み取り専用領域のロックが解除され、erase と write が交互に走っている。

リッチなルートファイルシステムの用意

通常であれば Debian や Ubuntu 機で debootstrap を使ってルートファイルシステムを生成するのが正攻法だが、今回は電子辞書Linux "Brainux" としてビルドされ各種ソフトウェアも既に導入されたファイルシステムを流用する。電子辞書の最近のモデルとルーターの SoC がどちらも Arm (armhf/armv7) だからこそできる芸当である*3

GitHub から Brainux の SD イメージをダウンロードし、dd などの適当な方法で USB メモリに書き込む。先頭パーティションは電子辞書用のカーネルが含まれる FAT32 パーティションがあるため、その次にある Ext4 パーティションを実機で使用する。

実機で chroot し依存パッケージをインストール

E50 の USB ポートに USB 3.0 ハブを接続し、そこに DisplayLink のデバイス、キーボード、マウス、そして先ほどルートファイルシステムを書き込んだ USB メモリを接続する。近年の fbcon には tty の自動アタッチ機能があるため、これだけでカーネルログと Tux の姿が拝める。

手持ちの LCD を接続して起動したところ。

ここから、以下のようなステップで種々の変更を加えていく。

  1. inittab へ getty を追記(これによりログインシェルが画面側に表示される)
  2. Debian をマウントして chroot
  3. 画像ビューアーをインストール: apt install feh
  4. プリインストールされているウィンドウマネージャー "jwm" のメニュー項目に画像ビューアーを追加
  5. xorg.conf にマウスとキーボードの設定を追記
  6. startx して画像ビューアーの動作を確認

これらの準備が終わった時点で、ごくシンプルな Linux デスクトップが完成する。

Xorg, jwm, さらにファイルマネージャーの Nautilus を起動した画面。

あとはプレゼンの PDF を scp で送り込めば準備は完了する。ちなみに、軽量ブラウザの Midori で試しに Google Slides を開いたところ正しく動作したため、fcitx-mozc 等で日本語入力をセットアップすれば実機でスライドを作ることもできる。今回はスピードを優先したため手元の Mac と Keynote で制作した。

画像ビューアー feh でスライド画像を開き、フルスクリーンに切り替えるところ。フルスクリーンにするとズームが自動調整される。

準備完了、いざプレゼン!

ルータープレゼンの実際の構成。

あとはプレゼンをしたくなったら FortiGate E50 を現地に持っていくだけで発表できる。会場でプロジェクターに接続したら、startx で Xorg と jwm を起動し、メニューから PDF ビューアーを起動すれば準備が完了する。

冒頭にある通り、本記事は2024年4月26日に岡山理大で開催された Okayama Revengers LT 大会 #2「もう春じゃなぁ〜 LT大会でもするかぁ!」にて発表したプレゼンのいわば小説版である。プレゼンの実際の様子は以下。

50E を起動したところ。左下に OpenWrt の motd がある。実機に接続したキーボードで操作している。

タイトルスライドを表示している場面。

本番でもトラブルなく進行して「ルーターでプレゼンはできる」ことが証明できた。ラップトップより多少ケーブルは多くなるが、ルーターのファームウェアいじりに興味がある各位はぜひルータープレゼンの構築に挑戦してみて欲しい。

*1:ブートローダー、Linux カーネル、ルートファイルシステムなどが保存される領域。

*2:旧来のルーターでも当然 chroot はできるが、DRAM が少ないため、リッチなパッケージ管理や各種ビルドに難がある。たとえば make の途中に OOM-killer が発動するなど。

*3:SoC が異なるのでカーネルスペースのコードは全く異なるが、共通の ABI とシステムコールによって分離されたユーザースペースであれば同じバイナリが動く。