もう6年くらいは安定稼働していた BUFFALO製 WZR-600DHP2 というWiFi APが、2ヶ月くらい前から不安定な挙動をするようになってしまいました。突然、通信が切れたり、mDNS(multicast)が通らなくなったりするのです。
再起動を行うことで、少しの間は復旧するのですが、一週間に一度の定期再起動というのにも疲れてきましたので、INS64の頃に印象が良かったNEC製のAtermに買い換えました。
数十年ぶりに触るAtermはかなり残念な感じになってしまっていたのですが(syslogどころかlogの表示でできないだとか、Bridgeモードの仕様だとか・・)それはさておき、捨てる直前だったWZR-600DHP2にOpenWrtが導入できると知り導入してみました。
Contents
OpenWrtとは
家庭用ルータ向けのカスタムファームウェアです。対応している製品用にそれぞれカスタムイメージが作られています。
Official Web : https://openwrt.org/
対応しているデバイス一覧はこちら
もちろん WZR-600DHP2にも対応しています
OpenFlowが流行し始めた頃、BUFFALOのルータにOpenWRTとopenvswitchをインストールしてOpenFlow switchにするというblog記事が話題になった事がありました。
近頃すっかり耳にしなくなったOpenFlowですが、個人で遊べるOpenFlowスイッチが廃物利用で作れるとなれば、やらない手はありません。
更にラッキーな事に、BUFFALO製の家庭用ルータにはdebugモードが搭載されていて導入が簡単との評判なのです。
導入準備
ファームウェアのバージョンを確認する
BUFFALOからリリースされている最新版のファームウェアは、セキュリティ強化対策としてdebugモードが無効化されています。
もし最新の1.14が導入されていたら一つ前の1.13へダウングレードを行います。古いファームウェアは、BUFFALOのページからダウンロード可能です。
工場出荷状態へ初期化する
使っていた頃の設定が原因でハマると嫌なので、工場出荷状態への初期化を行います。
初期化の方法は以下の通り。
- 底面にあるresetスイッチを押しながら電源On
- 電源LEDが赤く点滅を始めたら押すのをやめる
- その後、LEDが緑に点灯したら初期化完了です
BUFFALO公式YouTubeに動画がありました。動画ではWZR-900DHP2ですが、方法は同じです。
DebugモードでWebUIを開く
工場出荷状態のLAN側IPアドレスは、192.168.11.1 が設定されています。
192.168.11.0/24へconnectedで到達できるネットワーク環境を整えてから、LAN側にケーブルを接続。その後、ブラウザで次のURLを開きます。
認証がかけられていますので、ID, Passを使ってloginします。
http://192.168.11.1/cgi-bin/cgi?req=frm&frm=py-db/55debug.html
ID: bufpy
Pass: otdpopypassword ※otdpopy+<設定されているadminパスワード>
まずはメニューからtelnetdを起動してtelnetでloginします。
フラッシュメモリのバックアップを取得
ぼくは元に戻すつもりは無いのですが、念のためflashの中身をバックアップしておきます。WZR-600DHP2にはUSBポートがひとつあり、USBメモリスティックを挿してmountすることができますので、そこへバックアップを取りましょう。
1 2 3 4 5 6 7 8 9 10 11 |
cd /mnt/usb0_0 cat /proc/mtd > ./mtd-inf.txt dd if=/dev/mtdblock/0 of=./mtdblick0.dd bs=1 dd if=/dev/mtdblock/1 of=./mtdblick1.dd bs=1 dd if=/dev/mtdblock/2 of=./mtdblock2.dd bs=1 dd if=/dev/mtdblock/3 of=./mtdblock3.dd bs=1 dd if=/dev/mtdblock/4 of=./mtdblock4.dd bs=1 dd if=/dev/mtdblock/5 of=./mtdblock5.dd bs=1 dd if=/dev/mtdblock/6 of=./mtdblock6.dd bs=1 dd if=/dev/mtdblock/7 of=./mtdblock7.dd bs=1 dd if=/dev/mtdblock/8 of=./mtdblock8.dd bs=1 |
bs=1で取得しているので、時間がかかります。
for でグルっと回したくなりますが、妙に不安定でたまに書き込みに失敗して roモードに落とされます。
※1 こんなんで大丈夫なのかな?
※2 mtdblock/7 は、何度やっても失敗しました。
書き込みエラーが発生し、USBメモリがRead Onlyになってしまった場合は、umount してからUSBメモリを抜き差しします。mountし直されたら、失敗したファイルから再開です。
OpenWRTのファームウェアをダウンロード
WZR-600DHP2のページにある、Firmware OpenWrt Installのリンクからダウンロードしておきます。
OpenWrtのインストール
OpenWrtのページを読んでいると、インストールの方法はいくつかあるそうです。一般的な方法はtftpです。しかし、WZR-600HDP2はmini CFE Web Serverを起動できるので、CEF Web Server経由でファームウェアをインストールするのが最も簡単だと思います。
telnetでWZR-600HDP2へログインし、次のコマンドを発行します。
1 2 3 4 |
nvram show nvram set boot_wait=on nvram set wait_time=30 nvram commit |
これで次にブートした時、mini CFE Web Serverが起動するようになります。
注意: IPアドレスが変わります!
BUFFALO純正ファームでは、LANポートに192.168.11.1が割り当てられていました。しかし、mini CFE Web Serverは、192.168.1.1でListenを行います。
作業足場に192.168.1.0/24へのリーチャビリティ環境を整えておきましょう。
いったんリブート
リブートといっても電源のOff/Onです。電源が入ったらpingで疎通を確認します。
1 2 3 4 5 6 |
$ ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=100 time=0.622 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=100 time=0.221 ms : : |
ttl=100のreplyが返ってきたら、mini CFE Web Serverが起動しています。ブラウザで http://192.168.1.1/ を開きましょう。
ファームウェアのアップロード
先にダウンロードしておいたファームウェアをアップロードします。
成功しました!少し待てと書かれているのでしばらくpingを打ちながら安定するのを待ちます。
無事にインストールが完了したようです。初期パスワードは何も設定されていないので、そのままLoginボタンを押すと・・・
やったー!無事にインストールが完了して利用できるようになりました!!
openvswitchのインストール
WAN interfaceを有効にする
インストール直後のLAN側Interfaceは、linux bridgeによる仮想switchに接続されている構成になっています。openvswitchを導入する時は、このlinux bridgeをopenvswitchで置き換える事になります。当然、一時的にLAN側InterfaceはDown状態になります。
インストール中に疎通が取れなくなるのは困ります。
WAN側ポートはlinux bridgeに追加されていませんので、WANポートをmanagement portとして利用してしまいましょう。
[system] -> [administration] -> [SSH Access] へ進み、wanのinterfaceを追加します。
WANポートでsshを有効にしても、iptablesによるフィルタでrejectされてしまいます。wanポートからの22番を許可するルールを追加します。面倒なので0/0で許可していますが、気になる方はもう少し厳密にどうぞ。
WanポートにIPアドレスを付与
初期設定でのWANポートはdhcpが有効になっています。
普段使っているネットワークでdhcpが有効になっていれば、LANケーブルをWANポートに接続するだけでIPアドレスが付与されます。ついでにdefault routeも付いて一石二鳥です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
$ ssh 192.168.0.230 -l root The authenticity of host '192.168.0.230 (192.168.0.230)' can't be established. RSA key fingerprint is SHA256:1VG7nwApsLUmsEWB3ux1B1t2SdRQb18rZnVlH+Wcqew. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.0.230' (RSA) to the list of known hosts. root@192.168.0.230's password: BusyBox v1.30.1 () built-in shell (ash) _______ ________ __ | |.-----.-----.-----.| | | |.----.| |_ | - || _ | -__| || | | || _|| _| |_______|| __|_____|__|__||________||__| |____| |__| W I R E L E S S F R E E D O M ----------------------------------------------------- OpenWrt 19.07.4, r11208-ce6496d796 ----------------------------------------------------- root@OpenWrt:~# |
ルーティング
1 2 3 4 |
root@OpenWrt:~# ip route show default via 192.168.0.1 dev eth0.2 src 192.168.0.230 192.168.0.0/24 dev eth0.2 scope link src 192.168.0.230 192.168.1.0/24 dev br-lan scope link src 192.168.1.1 |
パッケージリストをupdate
OpenWrtには、opkgというパッケージ管理ツールが付属しています。debianのdpkgに名前は似ていますが異なる物です。
デバイスからインターネットへ出られるようにしていれば、パッケージリストの更新、インストールができます。インターネットへ接続できなければ、ローカルにパッケージを持ってきてファイルを直接インストールする事も可能です。
しかし、依存パッケージなどもありますので、ネットに接続できるような環境を整えておくのがベストでしょう。
OpenWrt内部ではdnsmasqが稼働しています。なので何もせずとも名前解決はできるはずですが、名前解決に失敗するようなら /etc/resolv.conf を修正しておきましょう。
package listをupdate
1 2 3 4 5 6 |
root@OpenWrt:~# opkg update : : root@OpenWrt:~# opkg list | grep '^openvswitch -' openvswitch - 2.11.3-1 - Open vSwitch root@OpenWrt:~# |
openvswitchをインストール
1 2 3 4 5 6 7 8 9 |
root@OpenWrt:~# opkg install openvswitch Installing openvswitch (2.11.3-1) to root... Downloading http://downloads.openwrt.org/releases/19.07.4/packages/arm_cortex-a9/packages/openvswitch_2.11.3-1_arm_cortex-a9.ipk Installing librt (1.1.24-2) to root... : : : root@OpenWrt:~# ovs-appctl -V ovs-appctl (Open vSwitch) 2.11.3 |
無事にインスートルできました。
インストール直後は、openvswitchが無効になっています。有効化してから起動を行います。
/etc/config/openvswitch を修正
1 2 3 4 5 6 7 8 9 10 |
root@OpenWrt:/etc/config# diff -u /tmp/openvswitch /etc/config/openvswitch --- /tmp/openvswitch 2020-09-16 00:03:14.374526155 +0900 +++ /etc/config/openvswitch 2020-09-16 00:01:28.000000000 +0900 @@ -1,5 +1,5 @@ config ovs ovs - option disabled 1 + option disabled 0 config ovn_northd north option disabled 1 |
openvswitchの起動
1 2 3 4 5 6 7 8 9 10 11 12 |
root@OpenWrt:/etc/config# /etc/init.d/openvswitch start /etc/openvswitch/conf.db does not exist ... (warning). Creating empty database /etc/openvswitch/conf.db. Starting ovsdb-server. Configuring Open vSwitch system IDs. Starting ovs-vswitchd. /usr/share/openvswitch/scripts/ovs-ctl: line 42: hostname: not found Enabling remote OVSDB managers. root@OpenWrt:/etc/config# ovs-vsctl show 95d9bd54-e3bc-46d4-868c-78b64a6c8a5c ovs_version: "2.11.3" |
openvswitchの設定
eth0.1がlan側のportになっていますが、linux bridgeで利用中です。最初にlinux bridgeを停止します。
この時点で、lan側のポートはdownするので注意が必要です。必ずwan側からloginした端末で作業を進めること。
1 2 3 4 5 6 |
root@OpenWrt:/# ip link set down dev eth0.1 root@OpenWrt:/# ip link set down dev br-lan root@OpenWrt:/# brctl delbr br-lan root@OpenWrt:/# brctl show bridge name bridge id STP enabled interfaces root@OpenWrt:/# |
openvswitchでbrdigeを作成し、eth0.1を参加させる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
root@OpenWrt:/etc/config# ovs-vsctl add-br br0 root@OpenWrt:/etc/config# ovs-vsctl add-port br0 eth0.1 root@OpenWrt:/etc/config# ovs-vsctl show 95d9bd54-e3bc-46d4-868c-78b64a6c8a5c Bridge "br0" Port "br0" Interface "br0" type: internal Port "eth0.1" Interface "eth0.1" ovs_version: "2.11.3" root@OpenWrt:/etc/config# ip addr add 192.168.1.1/24 dev br0 root@OpenWrt:/etc/config# ip link set up dev eth0.1 root@OpenWrt:/etc/config# ip link set up dev br0 |
作業場サーバからのリーチャビリティが復活しました!
1 2 3 4 5 6 7 8 9 |
% ping -c 2 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.25 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.454 ms --- 192.168.1.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 2ms rtt min/avg/max/mdev = 0.454/0.852/1.250/0.398 ms |
以上でopenvswitchの稼働まで確認できました。
あとはopenflow controller(今はどんなのがあるのだろう?)を接続してみたり、flowを入れてみたりして楽しめると思います!
linux bridgeを廃止してopenvswitchを利用するよう設定する
上ではマニュアル操作でlinux bridgeを停止/削除しopenvswitchのbridgeを作成しました。
しかし、このままでは再起動を行うと毎回linux bridgeが復活してしまいます。再起動後もopenvswitchのbrdigeが動作させる為には /etc/config/network ファイルを修正します。
WZR-600DHP2は、GbEポートが5つ持っています。写真のように右から1…5と呼ぶことにします。今までWANポートと呼んでいたGbEインターフェースは、Port 5です。
構成図
どのように使うかは個人で異なると思います。ぼくはこんな様に設定してみました。
/etc/config/network
interface設定や起動時に付けるip addr.等が設定されているファイルです。記述を間違えるとloginする手段が無くなり、ファームを書き込み初期化するしか無くなってしまいますのでご注意下さい。
準備
bridgeに参加していないポート(WANポート)からloginした端末を使い、ovsの設定を行います。
br1 .. br4 の bridgeを作成し、それぞれにinterfaceを追加します。存在しないinterfaceを追加するとエラーになりますが、DBには書き込まれているので、正しいconfigを書いた後に再起動すると、正常に動くようになります。
1 2 3 4 5 6 7 8 |
ovs-vsctl add-br br1 ovs-vsctl add-br br2 ovs-vsctl add-br br3 ovs-vsctl add-br br4 ovs-vsctl add-port br1 eth0.1 ovs-vsctl add-port br2 eth0.2 ovs-vsctl add-port br3 eth0.3 ovs-vsctl add-port br4 eth0.4 |
物理interfaceの定義
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
config interface option ifname 'eth0.1' option proto 'static' option macaddr 'B0:C7:45:89:29:a0' config interface option ifname 'eth0.2' option proto 'static' option macaddr 'B0:C7:45:89:29:a1' config interface option ifname 'eth0.3' option proto 'static' option macaddr 'B0:C7:45:89:29:a2' config interface option ifname 'eth0.4' option proto 'static' option macaddr 'B0:C7:45:89:29:a3' config interface option ifname 'eth0.5' option proto 'static' option macaddr 'B0:C7:45:89:29:a4' |
ポート番号 | device名 |
1 (LAN) | eth0.1 |
2 (LAN) | eth0.2 |
3 (LAN) | eth0.3 |
4 (LAN) | eth0.4 |
5 (WAN) | eth0.5 |
macアドレスを指定しないと、同じmacアドレスが振られる事がありました。同じブロードキャストドメイン内に同じmacアドレスを持つinterfaceが存在すると通信が不安定になります。それを避けるために、全てのinterfaceに異なるmacアドレスを指定しています。
ここのポート番号とデバイス名のマッピングは、下に出てくるswitch_vlanで対応させます。
仮想interfaceの定義
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
config interface 'lan' option ifname 'br1' option proto 'static' option ipaddr '192.168.1.1' option netmask '255.255.255.0' config interface 'lan2' option ifname 'br2' option proto 'dhcp' config interface 'lan3' option ifname 'br3' option proto 'dhcp' config interface 'lan4' option ifname 'br4' option proto 'dhcp' config interface 'wan' option ifname 'eth0.5' option proto 'static' option ipaddr '192.168.0.14' option netmask '255.255.255.0' config interface 'wan6' option ifname 'eth0.5' option proto 'dhcpv6' |
br1は、staticでIPアドレスを付与します。
eth0.5は、dhcp経由でIPアドレスを取得します。
物理interfaceとポート番号のマッピング
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
config switch option name 'switch0' option reset '1' option enable_vlan '1' config switch_vlan option device 'switch0' option vlan '1' option ports '0 5t' config switch_vlan option device 'switch0' option vlan '2' option ports '1 5t' config switch_vlan option device 'switch0' option vlan '3' option ports '2 5t' config switch_vlan option device 'switch0' option vlan '4' option ports '3 5t' config switch_vlan option device 'switch0' option ports '4 5t' option vlan '5' |
option vlan ‘vlanID’のVlanIDが、eth0.x にマッピングされます。そしてそのeth0.xに、どの物理ポートが割り当てられるか?を option ports ‘0 5t’で指定します。
数字はポート番号。0から始まるので注意です。’t’が付くと、taggedを指定した事になります。
正しく書けている事を確認したら、一度再起動を行います。
確認
openvswitchの状態
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
root@OpenWrt:~# ovs-vsctl show b532721a-8df3-4d56-899d-cf6a0cfb1d49 Bridge "br2" Port "eth0.2" Interface "eth0.2" Port "br2" Interface "br2" type: internal Bridge "br3" Port "eth0.3" Interface "eth0.3" Port "br3" Interface "br3" type: internal Bridge "br4" Port "eth0.4" Interface "eth0.4" Port "br4" Interface "br4" type: internal Bridge "br1" Port "eth0.1" Interface "eth0.1" Port "br1" Interface "br1" type: internal ovs_version: "2.11.3" |
interfaceの状態
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
root@OpenWrt:~# ip a s dev br1 20: br1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN qlen 1000 link/ether b0:c7:45:89:29:a0 brd ff:ff:ff:ff:ff:ff inet 192.168.1.1/24 brd 192.168.1.255 scope global br1 valid_lft forever preferred_lft forever inet6 fe80::7c56:2cff:fedf:254c/64 scope link valid_lft forever preferred_lft forever root@OpenWrt:~# ip a s dev eth0.5 25: eth0.5@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000 link/ether b0:c7:45:89:29:a4 brd ff:ff:ff:ff:ff:ff inet 192.168.0.14/24 brd 192.168.0.255 scope global eth0.5 valid_lft forever preferred_lft forever inet6 fe80::b2c7:45ff:fe89:29a4/64 scope link valid_lft forever preferred_lft forever |
意図した構成を作ることができました!