市販のネットワークルーターやスイッチに導入することで、元々のファームウェアでは実現できなかった高度な設定や最新のプロトコルが利用できる Linux ディストリビューションの OpenWrt は、2004年の登場から今年でちょうど20周年を迎えた。90年代の Linux ルーターという概念の勃興から、ルーター向け Linux ディストリビューションは DD-WRT や Tomato など複数生まれたが、現在もサポートと新機種の追加が続くほどの活気を保っているのは OpenWrt だけといっても過言ではない。
そんな記念すべき20周年を盛り上げるべく(?)久しぶりにルーター遊びをしたので紹介する。
(本記事は2024年4月26日に岡山理大で開催された Okayama Revengers LT 大会 #2「もう春じゃなぁ〜 LT大会でもするかぁ!」にて発表した以下のスライドを文章にしたものです。)
汎用なコンピューターとしてのルーター
2010年ごろに初めてルーターの代替ファームウェアに手を出した時から、ルーターが汎用なコンピューターと化すそのポテンシャルに私は一貫して魅力を感じていた。その結果、ルーターにディスプレイを接続してみたり、セキュリティ・キャンプで OpenWrt を教材として取り入れたり、といった付き合い方をしてはその成果を発表してきた。
中でも2016年に初めて発表した成果である「BuffaloルータをPCディスプレイにつなげた。」は、その珍奇さもあってか、技術界隈から注目を頂いた。一方で、記事内で紹介した「ルーターでプレゼンをする」という使い方は、当時実現はしたものの詳細を発表しないままだった。
当時のルータープレゼンは、USB 接続の映像出力デバイスを使うという共通点を除けば、以下の2つの手法で実現した。
- カーネル内臓のターミナル (fbterm) 上で擬似的にピクセルを並べる方法
- フレームバッファを直書きしてスライド画像を表示する方法
これらはいずれも、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。この性能を活かさない手はない。
FortiGate 50E の DRAM が 2GB と広大すぎるので /tmp に Alpine Linux armv7 rootfs 置いて chroot して遊んでみた
— Takumi Sueda (@puhitaku) 2023年3月19日
Go, Git, GCC, libusb-dev, musl-dev を apk で入れて mtplvcap を cgo ありでビルドして Nikon D5300 の絵を見るまで行けちゃったw これが全部ルーターでできるのおもろすぎw pic.twitter.com/C2wuVQabIG
加えて地味に嬉しいポイントとして、無線を搭載していないことも挙げられる。ファームウェアを置き換えた無線ルーターで電波を飛ばすことには法的な懸念があるため、通常は無線を無効化するなどの対策を取るが、最初から無線が搭載されていなければそんな心配をする必要もない。
ソフトウェアの準備
50E でプレゼンをするにあたり、おおまかに以下の4ステップで準備していく。50E には既に OpenWrt が導入されているものとする。
- Linux カーネルで USB 映像出力デバイスのドライバを有効化し OpenWrt をビルド
- ビルドしたファームウェアを実機にインストール
- リッチな Linux ディストリビューションのルートファイルシステムを用意(今回は Debian を使用)
- 実機上で Debian に chroot し、Xorg や画像ビューアーをインストール
OpenWrt のビルド
具体的なビルド手順は公式ガイドに譲りつつ、カスタムされた Linux kernel を含むファームウェアをビルドする。今回は、DisplayLink 社製の USB 映像出力デバイスのドライバ、マウスとキーボードのドライバ、フレームバッファで動作するカーネル内臓のターミナルエミュレーター "fbcon"、さらにそれらの動作に必要なビルドフラグを有効化する。
変更点も少ないため、ビルドは一発で成功した。
実機へのインストール
ビルドしたファームウェアは openwrt-mvebu-cortexa9-fortinet_fg-50e-squashfs-sysupgrade.bin
というファイル名で生成される。これを scp で実機の tmpfs へ送り込み、sysupgrade コマンドで実機の flash へ書き込む。
リッチなルートファイルシステムの用意
通常であれば 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 の姿が拝める。
ここから、以下のようなステップで種々の変更を加えていく。
- inittab へ getty を追記(これによりログインシェルが画面側に表示される)
- Debian をマウントして chroot
- 画像ビューアーをインストール:
apt install feh
- プリインストールされているウィンドウマネージャー "jwm" のメニュー項目に画像ビューアーを追加
- xorg.conf にマウスとキーボードの設定を追記
startx
して画像ビューアーの動作を確認
これらの準備が終わった時点で、ごくシンプルな Linux デスクトップが完成する。
あとはプレゼンの PDF を scp で送り込めば準備は完了する。ちなみに、軽量ブラウザの Midori で試しに Google Slides を開いたところ正しく動作したため、fcitx-mozc 等で日本語入力をセットアップすれば実機でスライドを作ることもできる。今回はスピードを優先したため手元の Mac と Keynote で制作した。
準備完了、いざプレゼン!
あとはプレゼンをしたくなったら FortiGate E50 を現地に持っていくだけで発表できる。会場でプロジェクターに接続したら、startx
で Xorg と jwm を起動し、メニューから PDF ビューアーを起動すれば準備が完了する。
冒頭にある通り、本記事は2024年4月26日に岡山理大で開催された Okayama Revengers LT 大会 #2「もう春じゃなぁ〜 LT大会でもするかぁ!」にて発表したプレゼンのいわば小説版である。プレゼンの実際の様子は以下。
puhitakuさんの
— Okayama Revengers (@okarev_staff) 2024年4月27日
「ルーターでプレゼンする」 の発表です🔥
あれ、様子がおかしい。
「うん?ルーターでプレゼンするのね...」
何度でも言うよ✨
||| \\\ ルーターでプレゼン /// |||#okarev pic.twitter.com/uJbK8cNUHf
本番でもトラブルなく進行して「ルーターでプレゼンはできる」ことが証明できた。ラップトップより多少ケーブルは多くなるが、ルーターのファームウェアいじりに興味がある各位はぜひルータープレゼンの構築に挑戦してみて欲しい。