WZR-900DHPをOpenWrt化

## やったこと

- WZR-900DHPに執筆時点で最新のOpenWrt23.05.3を導入しました
- おまけとしていろいろ遊んでみたのでそれも軽くまとめます

## WZR-900DHPについて

https://openwrt.org/toh/hwdata/buffalo/buffalo_wzr-900dhp

- CPU: Broadcom BCM47081A0CPU
- Package architecture: arm_cortex-a9
- Core: 1
- CPU MHz: 800
- Flash MB: 128
- RAM MB: 256

アーキテクチャがARMv7で、RAMも256MB積んであります。ユーザーが自由に触れるフラッシュ領域は大したサイズにならないものの、なんとUSB3.0ポートが付いているのでもう割とすべてがどうにでもなります。

オモチャとして非常に優秀で、雑に扱ってもかなりの無茶ができます。
それでいて安く手に入りやすい。ぶっちゃけ何やらせたって楽しいガジェットです。

## 使用環境

- WZR-900DHP（WZR-900DHP2でも海外版でもない機種です）
- MacBook Air（ブラウザ開けてcurl叩けりゃなんでも良いです）

## 注意点

:::note alert
- 本手順をそのまま実施すると、その機器では恒久的にWi-Fiがまともに使用できなくなる可能性があります
- 元の純正ファームウェアに書き戻すことも叶わない可能性が高いです
- 運用によっては技適違反となる可能性があります
:::

WZR-900DHPはフラッシュの特定領域に無線チップ用の暗号化されたファームウェアが書き込まれていて、しかもその領域は純正のファームウェアには含まれていないそうです。今回は諸事情でこれをバックアップせずにそのまま上書きするため、本手順を上からなぞるとその機器ではWi-Fiがまともに使えなくなります。（どのくらいまともじゃないかというと、5GHzは飛ばず、2.4GHzも5mくらいしか飛ばないというレベル）

さらに、（理解が誤っていた場合申し訳ないのですが）一般的に日本国内でルータのファームウェアをメーカーサポート外のものに書き換えて無線機能を使用した場合、技適取得時点の適合性を満たさなくなるために違法となるそうです。

総じて、無線機能の使用を目的としてOpenWrt化を行うのはやめましょう。やめましょうね！言いましたからね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15850/b4e092f9-7b74-2233-242b-844f6af0a269.png)

またここからはかなり曖昧な理解なのですが、WZR-900DHPは通常のファームウェア復元手順では（無線ファームウェアの領域以外にも？）暗号化の都合で元に戻せないフラッシュ領域がいくつかあるようです。これらは事前に領域ごとのダンプを取得して純正ファームウェアに足してあげたものを書き戻す...という手法で解決できるようですが、今回は検証していません。一応記事の最後の方に参考情報を掲載しておきます。

## やることざっくりまとめ

1. ファームウェアを作業PCにダウンロードする
1. 作業PCのIPアドレス設定を192.168.1.0/24のものに変更する（ルータは192.168.1.1）
1. pingを192.168.1.1に飛ばし続けてリンクアップしたタイミングを見落とさないようにする
1. リンクアップした瞬間curlでファームウェアを投げ込む
1. 成功レスポンスが返ってきたら完了

参考：
https://w.atwiki.jp/ddwrt_openwrt/pages/70.html

## 詳細手順

### 1. ファームウェアをPCにダウンロードする

[OpenWrt Firmware Selector](https://firmware-selector.openwrt.org/)にアクセスして、検索窓に「WZR-900DHP」と入力します。プルダウンで機種一覧が表示されますので、一致するものを選択してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15850/258ed9e7-b5c2-b404-ee11-c7d5fac07dcb.png)

執筆時点では23.05.3が最新のバージョンですが、もし同様に検索してヒットしなかった場合、未来のリリースではサポートが終了している可能性があります。検索窓右側のプルダウンから23.05.3付近のバージョンを選べば画像と同様の画面になるかと思いますので、遠い未来にこの手順を追う方がいらっしゃればお試しください。

一覧でいくつか表示されるかと思いますが、ここでは「TRX」と書いてあるボタンからファームウェアをダウンロードしてください。今回は「openwrt-23.05.3-bcm53xx-generic-buffalo_wzr-900dhp-squashfs.trx」をダウンロードしたものとして進めます。（他のバージョンのものをダウンロードした場合は以降適宜読み替えてください）


### 2. 作業PCのIPアドレス設定を変更する

この後ルータを特殊な方法で起動するのですが、そのときルータは必ず固定の192.168.1.1/24で起動してきます。
PC側のEthernetインターフェース設定は192.168.1.100とかにしておきましょう。

![スクリーンショット 2024-06-07 15.36.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15850/ec4e0921-7800-92f0-c6a0-a43cea81eb32.png)


### 3. ルータを接続

作業用PCとルータをLANケーブルで繋ぎます。ルータ側はWANポートではなく、LANポートに接続するようにしてください。また、背面の電源スイッチから電源がOFFとなっていることを確認した上で、ACアダプタも接続しておきます。

必要があれば本体をスタンドで自立させ、とにかく安定して背面電源スイッチと正面AOSSボタンにアクセスできる状態にしておきましょう。

### 4. ファームウェアをインストール

まずターミナルのウィンドウを2つ並べて開いてください。

片方では
```shell
ping 192.168.1.1
```
を叩いて、ルータにpingが飛ぶかを常時監視させます。（Windowsだったら-tとか付ける）

もう片方では以下のコマンドを入力しておきます
```shell
curl -F "name=@[ファームウェアファイルが置いてあるパス]" http://192.168.1.1/f2.htm
```
まだEnterは入力しないでください。すぐ叩いて送信できるように準備だけしておきます。

ここまで準備が整ったら、ルータ正面AOSSボタンを長押ししながら背面の電源スイッチを押して電源をONにします。すると一度正面の全ランプが点灯しますが、数秒も経たずにPOWERランプのみが緑点灯となるはずです。それを確認したらすぐに手を放し、急いで作業用PCに戻ります。

ping監視をしているターミナルの画面を見ながら、TTL=100のパケットが返ってき次第、即座にcurlを入力しておいたターミナルでEnterを入力し、ファームウェア送信を試みます。

![スクリーンショット 2024-06-07 15.38.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15850/e09ff821-375c-ef53-2241-3013030da2b7.png)

画像のように、「Upload completed」が含まれるHTMLが返ってくれば成功です。

失敗してしまった場合、ルータの電源を一度落としてこの手順の頭からやり直します。
今回はLAN直繋ぎで一発成功しましたが、上手く行かないときは間にHUB噛ませといた方が良さそうですね。

### 5. インストール成功確認

そのまましばらく待っていると（数分かかることがあります）、192.168.1.1からTTL=64とかのパケットが返ってくるようになります。

したらば作業用PCからブラウザを開いて、http://192.168.1.1 にアクセスしましょう。
OpenWrtのログイン画面が表示されれば成功です。ユーザー名はroot、パスワードは空欄でsubmitします。

![GPZOh9XaUAAAksx.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15850/7735ffd4-0ce0-553f-5ae4-9835ea3557da.jpeg)

これが「Luci」というOpenWrt標準のWebコンフィグです。
ほとんどの設定がここから行えますので、あとはご自由にお楽しみください。

## いろいろセットアップ（おまけ）

### 管理者パスワード設定

上の画像（Luciログイン直後の画面）の「Go to password condiguration...」というボタンから、管理者パスワードを設定できます。
ログインしたらすぐにやっておきしょう。

### WANファイアウォール設定

本来であればルータというのは、
```
[上位ルータ] <---> (WANインターフェース) [ルータ] (LANインターフェース) <---> [クライアント機器]
```
と接続するものかと思います。

ただ残念ながら私の場合、WZR-900DHPをルータとして使うつもりはあまりありません。WANインターフェースに上位ルータからのLANケーブルを1本挿してインターネットに接続させ、それで終わりとしたいのです。

OpenWrtではデフォルトでWANインターフェース側からのインバウンド通信は遮断する設定となっているため、そのままではWAN側ネットワーク上の別機器からWebコンフィグやSSHなどにアクセスすることができません。これを回避するために、ファイアウォール設定を解除しましょう。

Luci→Network→Firewallsと進み、WAN⇒REJECTと書いてある行のInputをdenyからacceptに変更し、Save&Applyを押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15850/bd804e57-b299-d524-c5fd-ab499fd63fd9.png)

これでWAN側からのアクセスが完全に開放されました。例えば上位ルータから192.168.100.150/24とDHCPが払い出されれば、同一ネットワークからそのIPアドレスでWebコンフィグを開いたりSSH叩いたりができるようになります。（普通のPCと同じ感覚ですね）

もしここの内容がよくわからない場合、ここで紹介したファイアウォール設定は実施せずに、素直にLANポートに接続した作業用PCからルータへアクセスするようにしてください。

### Python3インストール

ハックしたルータでPythonを動かしたくなるというのは大変普遍的な感情ですね。
まず作業用PCからSSHで接続しましょう。ユーザー名パスワードはLuciにログインするときのものと同様です。

```
ssh root@192.168.1.1
```

お次にPythonのパッケージをインストールします。

```
opkg update
opkg install python3
python3 --version
```

### rootfs拡張

Python入った...！楽しい...！とかいろいろやっていると、ふとあることに気が付きます。ストレージが全然足りません。ですが安心してください！このルータにはUSBポートが付いています。

ルータと生涯を共にして良いUSBメモリを用意したら、背面ポートに挿しましょう。
詳しい設定手順はこちらの記事にて解説されていました。参考に試してみてください。

https://qiita.com/somainit/items/014aea356946b13957ff

私が手元のWZR-900DHPにてこれを試したときは、```uci show fstab```したときに/dev/sda1の設定は```fstab.@mount[1]```の方に記述があり（```fstab.@mount[0]```は/dev/sdaの設定）かつenabledが1ではなく0になっていたため、手動で/etc/config/fstabの当該行を変更し、```uci commit```しました。

```shell
root@OpenWrt:~# cat /etc/config/fstab

config global
        option anon_swap '0'
        option anon_mount '0'
        option auto_swap '1'
        option auto_mount '1'
        option delay_root '5'
        option check_fs '0'

config mount
        option target '/mnt/sda'
        option uuid '2024-04-24-11-29-09-00'
        option enabled '1'

config mount
        option target '/mnt/sda1'
        option uuid '0883dd96-a2c8-4820-bbc3-ffb57f28f320'
        option enabled '1' # <- ここを0から1に変えた
```

また、パーティションは事前に慣れた環境で全部消しておくと楽です。


## フラッシュのバックアップについて

### 何故バックアップをサボったのか

WZR-900DHPは、特定の領域を保存しておかないと純正ファームウェアに書き戻すことすらできません。では何故今回これをサボってOpenWrtへの片道切符を切ったか、というお話です。

WZR-900DHPの純正ファームウェアにはDebugモードというものがあるそうです。以下のアドレスでルータにアクセスし、ID:bufpy PW:otdpopypasswordでログインするとシェルが叩けるんだか特殊な設定変更ができるんだか、とにかくいろいろ遊べる画面が開くようです。（全然調べてなくてすみません）
http://192.168.11.1/cgi-bin/cgi?req=frm&frm=py-db/55debug.html
その画面からtelnetを有効化して、telnetでシェルを開いてからフラッシュ領域をUSBにダンプして...ということをやっていくようです。

ただしこれはver1.14未満の古いファームウェアに限った話で、1.14からは脆弱性対策のためにこのDebugモードが塞がれてしまっています。

そのため一度ダウングレードしてから作業を開始することになるのですが、公式サイトを見たら現在の最新ファーム1.16のみが公開されている状態でした。どうせ少し掘ればちゃんと古いファームウェアも見つかるんだとは思うんですが、気持ち的には今すぐにでもARMv7環境のOpenWrtを触りたかったので、今回は見て見ぬフリをして強行突破することにしました。

※普通に公式ファームウェアのサイトに古いファームウェアへのリンクが公開されてました（照）

**1.11（1.14未満で一番新しいファームウェア）の公開リンク**

https://www.buffalo.jp/support/download/detail/?dl_contents_id=61640&version=1.11

### 取得手順と書き戻し手順

こちらに解説がされています。
そのうちもう1台入手したら、手元で検証して更新する予定です。

https://w.atwiki.jp/ddwrt_openwrt/pages/70.html

https://memo205.wordpress.com/2017/07/17/wzr-900dhp%e3%81%ab%e3%83%a1%e3%83%bc%e3%82%ab%e3%83%bc%e3%83%95%e3%82%a1%e3%83%bc%e3%83%a0%e3%82%92%e6%9b%b8%e3%81%8d%e8%be%bc%e3%82%80%ef%bc%88with-%e3%82%b7%e3%83%aa%e3%82%a2%e3%83%ab%ef%bc%89/

## 感想など

確か800～1000円くらいで売ってたんですけど、MIPSアーキテクチャのルータが立ち並ぶ中でARMv7環境のヤツがおるやん！となり、躊躇いなく買ってきました。無線周りの不具合は想定外ではありましたが、それを差し引いてもこれだけ快適にOpenWrtで遊べるってのは良いものですね。ビジュアルも割と好きです。スマートな色合いながら、やっぱり角が丸いルータは可愛げがありますね。

今のところTailscaleとかCloudflare Tunnelを試したり、LuciのArgonテーマが前から気になってたので導入してみたり、地味に自前でsamba構築したことがなかったので試してみたりと遊んでいます。

Dockerもある程度問題なく動いているのですが、composeでnginxを立ち上げたときにexited with code 132でコンテナが落ちてしまいました。どうもCPUが命令セットに対応していないときに起こるエラー？のようです。composeがもっと気楽に運用できたら大変ありがたいんですが...。

フラッシュバックアップの後悔が若干残ってますので、多分もう1台はそのうち確実に調達してくると思います...！まだまだ楽しめそうですね！