3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JAWS-UG IoTハンズオンイベントのネットワークを自作ルータで構築した話

3
Posted at

はじめに

2026年5月21日に開催されたJAWS-UG IoT専門支部のハンズオンイベントで、参加者にRaspberry Piを配布してIoT体験をしてもらう企画を実施しました。

このイベントでは、会場内に閉じたネットワークを持ち込み、RasPi 22台+参加者PC 20台+管理用端末を収容する必要がありました。合計40台超。現地設営は1時間半。しかも本業の傍らに準備を進めなければならないという制約付きです。

この記事では、ネットワーク設計からルータ構築、RasPi 22台の効率的なセットアップまで、イベント裏方インフラの構築記録をまとめます。

ネットワーク設計 — なぜ自作ルータが必要だったか

要件の整理

まず、今回のネットワークに求められる要件を整理します。

  • 収容台数: RasPi 22台 + 参加者PC 20台 + 管理用 = 40台超
  • 施設ネットワークとの分離: 会場のネットワークに迷惑をかけない
  • インターネット接続: RasPiからAWSへの通信が必要
  • 可搬性: 機材一式を会場に持ち込める構成
  • 設置の容易性: 短時間で設営・撤収できること

Wi-Fi AP の選定

40台超のクライアントを安定して収容するには、家庭用APでは力不足です。業務用APとしてYAMAHA WLX202を選定しました。WLX202は5GHz帯で最大50台、2.4GHz帯で最大50台、合計100台の端末を収容可能なエンタープライズ向けAPです1

ただし、WLX202は純粋なアクセスポイントであり、NAT(マスカレード)機能を持っていません。仕様上の機能は「DHCPクライアント, DHCPサーバー, NTPクライアント」等に限られ、ルーティングやNATの記載はありません1。家庭用ルータのように「WANとLANを分離してNATする」機能は別途用意する必要があります。

つまり、こういう構成が必要になります:

ルータの選択肢

NATルータとして何を使うか。市販のルータを持ち込む手もありますが、今回は手持ちのSeeed Studio reTerminal + E10-1拡張ボードにOpenWrtをインストールする構成を選びました。

理由:

  • reTerminal本体とE10-1でEthernetポートが2つ取れる(2ポート = WAN/LAN分離が可能)
  • E10-1はPoE受電に対応しており(最大25W)、ルータ自体の電源もLANケーブル1本で賄える2
  • OpenWrtなら細かいネットワーク設定が自由自在
  • 5インチタッチディスプレイ付きで、当日のステータス確認にも使える……と期待したが、後述の通り断念

PoEで配線をシンプルに

今回の構成で地味に効いているのがPoE(Power over Ethernet)の活用です。

PoE対応機器

機器 PoE役割 規格
Netgear GS305EP PoE給電スイッチ(中心) IEEE 802.3at (PoE+), 63W総バジェット3
reTerminal + E10-1 PoE受電(ルータ) 最大25W2
YAMAHA WLX202 PoE受電(AP) IEEE 802.3af1

GS305EPは5ポートGigabitスイッチで、うち4ポートがPoE+給電に対応しています3。これを中心に据えることで、ルータもAPもLANケーブル1本で給電+通信が完結します。会場でACアダプタを何個も並べる必要がなく、設営・撤収が格段に楽になります。

ポート割り当て

給電の関係上、PoEスイッチはLAN側に置く必要があります。そのため、通常のルータとは逆の構成になりました:

  • eth0(reTerminal本体側)= WAN — 施設ネットワークに接続、DHCP取得
  • eth1(E10-1拡張側)= LAN — PoEスイッチ経由でAPとクライアントに接続
  • eth0 → WAN: 施設ネットワークからDHCPでIPを取得、NATマスカレード
  • eth1 → LAN: DHCPサーバー(172.25.0.100〜249)を提供

OpenWrtルータの構築

ハードウェア構成

項目 内容
本体 Seeed Studio reTerminal(CM4搭載)
拡張ボード reTerminal E10-1
SoC BCM2711 Quad-Core Cortex-A72 1.5GHz
eth0 reTerminal本体 Gigabit Ethernet(BCM54210PE4) → WAN
eth1 E10-1拡張 Gigabit Ethernet → LAN

ファームウェア書き込み

reTerminalはCM4のeMMCにOSを格納するため、通常のSDカード書き込みではなくrpiboot経由で書き込みます5。eMMCを書き込みモードにするには、背面カバーを開けて内部のBoot Modeスイッチを切り替える必要があります6

# rpibootのビルド(macOS)
brew install libusb pkg-config
git clone --recurse-submodules --shallow-submodules --depth=1 \
    https://github.com/raspberrypi/usbboot
cd usbboot && make

# Boot Modeスイッチを切り替え → USB-C接続
sudo ./rpiboot

rpiboot実行後、eMMCがUSBストレージとして認識されます。

# イメージの書き込み(ディスク番号は diskutil list で確認)
gunzip openwrt-25.12.4-bcm27xx-bcm2711-rpi-4-ext4-factory.img.gz
sudo dd if=openwrt-25.12.4-bcm27xx-bcm2711-rpi-4-ext4-factory.img \
     of=/dev/rdiskN bs=4M status=progress

書き込み後、Boot Modeスイッチを元の位置に戻してE10-1に装着すれば起動します。

OpenWrt 25.12 の変更点

OpenWrt 25.12(2026年3月5日リリース)では従来からいくつか大きな変更があります7:

  • パッケージマネージャ: opkgapk(Alpine Package Keeper)に変更。opkgフォークはメンテナンスされなくなったため
  • ファイアウォール: nftablesベースの firewall4 が標準(OpenWrt 24.10で導入済み、25.12では完全にデフォルト)
  • UCI設定ファイルの書式自体は従来と同じ

opkg installapk add に読み替えが必要です。

ネットワーク設定

# /etc/config/network
config interface 'wan'
    option device 'eth0'
    option proto 'dhcp'

config interface 'lan'
    option device 'eth1'
    option proto 'static'
    option ipaddr '172.25.0.1'
    option netmask '255.255.255.0'
# /etc/config/dhcp — LAN側でDHCPサーバーを動かす
config dhcp 'lan'
    option interface 'lan'
    option start '100'
    option limit '150'
    option leasetime '12h'
# /etc/config/firewall — LAN→WANの転送とマスカレード
config zone
    option name 'wan'
    list network 'wan'
    option masq '1'        # NATマスカレード有効
    option input 'REJECT'
    option forward 'REJECT'

config zone
    option name 'lan'
    list network 'lan'
    option input 'ACCEPT'
    option output 'ACCEPT'
    option forward 'ACCEPT'

config forwarding
    option src 'lan'
    option dest 'wan'

これで、LAN側クライアント(172.25.0.100〜249)がWAN経由でインターネットに出られる構成になります。

ハマりポイント: ディスプレイ出力が使えない

reTerminalには5インチのMIPI DSIディスプレイが内蔵されており、当日のステータス表示に活用したいと考えていましたが、OpenWrtでの利用は断念しました。HDMI出力も含め、画面表示は一切実現できていません。

OpenWrtにはグラフィックス表示の仕組みがない

OpenWrtはルータ・ネットワーク機器向けに設計されたOSであり、グラフィカルな画面表示は設計思想の範囲外です。OpenWrtフォーラムでも開発者から明確に説明されています:

"There are no graphics capabilities (aside from text output) in OpenWrt at all because of the primary targets (i.e. router devices, often consumer all-in-one wifi units, that lack graphics hardware) and the primary use-case (no need for graphics on router)."8

具体的には:

  • グラフィックスドライバが存在しない: テキストモード用の最低限のフレームバッファドライバしかなく、GPUを活用したグラフィックス描画のドライバは提供されていない
  • グラフィックスライブラリがない: Xorg、Wayland、Mesa等のグラフィックスタックは移植されておらず、移植には膨大な労力が必要
  • DSIパネルドライバの問題: reTerminalのDSIディスプレイはRaspberry Pi OS向けの専用ドライバ(STM32G030経由の制御を含む)が必要だが、OpenWrtのカーネルにはこのドライバが含まれていない

HDMI出力の試行

OpenWrt 25.12のbcm2711カーネルは CONFIG_DRM_FBDEV_EMULATION=n でビルドされており、Full KMS(vc4-kms-v3d)では /dev/fb0 が作成されません。Fake KMS(vc4-fkms-v3d)への切り替えも試みましたが、reTerminal実機ではHDMIコンソール出力を得ることはできませんでした。

# 試行した /boot/config.txt の設定
dtoverlay=vc4-fkms-v3d
hdmi_force_hotplug=1
framebuffer_width=1920
framebuffer_height=1080

結局、reTerminalのディスプレイ(DSI・HDMI共に)をOpenWrtから活用することは諦め、ネットワーク管理はSSH経由で行う運用としました。ディスプレイこそ活かせませんでしたが、reTerminalとE10-1はもともと手持ちの機材であり、2ポートEthernet+PoE受電というルータとしての要件は十分に満たしているので、無駄になったわけではありません。

RasPi 22台の効率的セットアップ

2アーキテクチャ問題

今回用意するRasPiは2種類:

モデル 台数 アーキテクチャ ビット幅
RasPi 2 Model B 9台 armv7l 32bit
RasPi 3 Model B 13台 aarch64 64bit

アーキテクチャが異なるため、SDカードイメージを別々に用意する必要があります。22台を1台ずつ手作業でセットアップしていたら日が暮れるので、自動化ツールを作りました。

SDカードイメージの量産フロー

  1. 各アーキテクチャで1台だけ手動セットアップ(ベースイメージ作成)
  2. SDカードイメージを吸い出し&縮小
  3. 縮小イメージを残りのSDカードに焼き付け
  4. 初回起動時に expand-rootfs サービスがパーティション+ファイルシステムを自動拡大

これにより、SDカードの容量が異なっていても同じイメージから展開できます。

自動セットアップスクリプト

SDカードを挿して起動した後の初期設定も自動化しました。

setup-raspi.sh — 1台のRasPiに対して実行する初期セットアップ:

  1. SSH鍵登録(パスワードログイン不要に)
  2. sudoers設定(reboot/poweroffをNOPASSWD化)
  3. apt update && apt upgrade
  4. avahi-daemon設定(mDNSで .local 名前解決)
  5. expand-rootfsサービスのインストール
  6. 再起動&疎通確認

assign-dhcp.sh — ルータ側で実行するアドレス管理:

  1. DHCPリースから未登録のRasPiを自動検出
  2. 連番ホスト名(JAWSUG-01, JAWSUG-02, ...)を付与
  3. OpenWrtのDHCP固定アドレスに登録
# assign-dhcp.sh の動作イメージ
# 新しいRasPiをネットワークに繋ぐだけで:
#   → MACアドレスを検出
#   → 172.25.0.201〜222 の固定IPを割り当て
#   → JAWSUG-XX のホスト名を設定
#   → dnsmasq再起動で即反映

これにより、「SDカードを挿す → 電源を入れる → スクリプトを叩く」の3ステップで1台が完成します。

踏んだ落とし穴

cloud-init がホスト名を毎回上書きする

Raspbian trixie(最新版)では cloud-init が有効になっています。Raspberry Pi Imagerで設定したホスト名が /boot/firmware/user-data に記録され、起動のたびに /etc/hostname を上書きします。

せっかく assign-dhcp.sh でホスト名を設定しても、再起動すると元に戻ってしまう。

解決策:

sudo sed -i 's/preserve_hostname:.*false/preserve_hostname: true/' /etc/cloud/cloud.cfg

cloud-initの公式ドキュメントによると、Set Hostnameモジュールは「If preserve_hostname is set, then the hostname will not be altered. Default: false.」と定義されています9preserve_hostname: true を設定すれば、cloud-init はホスト名を上書きしなくなります。

⚠️ cloud-init clean は絶対に実行しないこと。全状態がリセットされ、自動ログイン設定等が破壊されます。

mDNS (avahi) と Wi-Fi AP の相性

RasPiにavahi-daemonを入れて .local で名前解決できるようにしたのですが、設定時に使う予定だった家庭用AP(IO-DATA WN-G150TR)でテストしたところ、mDNSが全く動きませんでした。

調査の結果、WN-G150TRがWi-Fiクライアント間のマルチキャスト(224.0.0.251:5353)を転送していないことが判明。ファームウェアの制約で設定変更も不可能でした。

本番用のYAMAHA WLX202では正常にmDNSが動作することを確認済みです。業務用APはこういうところがちゃんとしています。

当日の追加対応: ONU直結化に伴うDNS設定変更

イベント当日、会場の上流ネットワークがONU直結の構成に変更されていることが判明しました。これにより、DHCPクライアント側に渡すDNSサーバの設定を追加する必要が発生しました。

OpenWrtのDHCPサーバー(dnsmasq)はデフォルトでルータ自身(172.25.0.1)をDNSサーバとしてクライアントに通知し、DNSリレー(フォワーダー)として動作します。上流のDNSサーバを明示的に指定するため、以下の設定を追加しました:

# /etc/config/dhcp — DNSフォワード先を上流指定のアドレスに設定
config dnsmasq
    list server '<上流指定のDNSアドレス>'

設定反映後、クライアント側で正常に名前解決できることを確認し、ハンズオンを開始しました。

まとめ

コミュニティイベントの「裏方インフラ」は、想像以上に手間がかかります。特に今回のようなハードウェア + ネットワーク + インターネットという構成は様々な外的要因の影響を受けやすく、現場での緊急対応が避けられません。なので、変更やトラブルシューティングを容易にする仕掛けをあらかじめ作り込んでおくことが大切です。

  • 40台超を収容するために業務用AP(WLX202)を選定
  • WLX202にNAT機能がないため、reTerminal + OpenWrtで自作ルータを構築
  • PoE活用で配線をシンプル化(ACアダプタ地獄からの解放)
  • 22台 × 2アーキテクチャのRasPiセットアップを自動化スクリプトで効率化

本業の合間に進める制約があったからこそ、「先に自動化ツールを作る」判断が正解でした。1台目のセットアップに時間をかけてでもスクリプト化しておけば、2台目以降は流れ作業です。

IMG_07573.png

こうして、素敵な会場(KINTOテクノロジーズ様ご提供)にて無事にIoTハンズオン用のネットワークを提供することができました。

参考リンク

  1. YAMAHA WLX202 仕様 2 3

  2. Seeed Studio Wiki - reTerminal E10-1 — "The PoE power input is RJ45 and supports a maximum of 25W power input." 2

  3. NETGEAR GS305EP 製品ページ — "4 x PoE+ 802.3at Ports", "63W" PoE Budget 2

  4. Seeed Studio Wiki - reTerminal Hardware Interfaces — "Gigabit Ethernet PHY ... based on Broadcom BCM54210PE"

  5. raspberrypi/usbboot - GitHub — macOSでのビルド手順およびCM4でのeMMC書き込み方法

  6. Seeed Studio Wiki - Getting Started with reTerminal — 背面カバーを外し、Boot Modeスイッチを切り替えてeMMC書き込みモードにする手順

  7. OpenWrt 25.12.0 Release Notes — "Switch package manager from opkg to apk"

  8. OpenWrt Forum - How to build xorg-xserver on an OpenWRT OS? — OpenWrt開発者による回答(2024年1月)

  9. cloud-init Module Reference - Set Hostname

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?