OpenWRTとシングルボードコンピュータでIPv6 IPoE対応ルーターをつくる

一般家庭用のBUFFALOのルーターを使っていたのですが、ファームウェアのアップデートを機に不安定になってしまい、古いバージョンに戻しても不安定なままになってしまいました。

自動でアップデートしておいて不安定になるというのが気に食わないので、OpenWRTでルーターをつくることにしました。 既存のルーターには無線LANのAPとして余生を過ごしてもらいましょう。

PINE A64?なにそれ?

今回はシングルボードコンピュータのPINE A64を使用します。

Raspberry Piが値上がり&在庫なしの時代に、秋月電子で2,980円でいつでも在庫があるシングルボードコンピュータです。

2022年となっては型落ち感がありますが、Raspberry Pi使う大抵の用途ってこのスペックで十分なのでは?と思ってたりします。電源が2Aでいいのも調達がラク

PINE A64+1GB BOARD (PINE64): マイコン関連 秋月電子通商-電子部品・ネット通販

NICはひとつしかないため、手元に余っていた100BASE-TXのUSB-LANアダプタ、USB無線LANドングルを追加しました。

流れ

さて、こんな流れでつくります。

  1. OpenWRTの用意
  2. 設定
  3. ニチバンベンチ対策
  4. ケースを作る

OpenWRTの用意

OpenWRT公式サイトからイメージをダウンロードするのですが、今回は事前にイメージをカスタマイズします。

バージョンはあえて最新の22ではなく21を使用します。

22はファイアウォールiptablesじゃなくてnftablesになっていて、iptables前提の後述のニチバンベンチ対策ができないので見送りました。

https://firmware-selector.openwrt.org/?version=21.02.5&target=sunxi%2Fcortexa53&id=pine64_pine64-plus

今回はいくつかパッケージを追加する必要があったので、事前にカスタマイズしておくことにしました。

以下、カスタマイズで入れたパッケージ一覧。

base-files
brcmfmac-firmware-usb
busybox
ca-bundle
cgi-io
dnsmasq
dropbear
e2fsprogs
firewall
fstools
fwtool
getrandom
hostapd-common
ip6tables
iptables
iptables-mod-conntrack-extra
iptables-mod-ipopt
iw
iwinfo
jshn
jsonfilter
kernel
kmod-brcmfmac
kmod-brcmutil
kmod-cfg80211
kmod-fs-vfat
kmod-hid
kmod-hid-generic
kmod-rt2800-usb
kmod-input-core
kmod-input-evdev
kmod-ip6-tunnel
kmod-ip6tables
kmod-ipt-conntrack
kmod-ipt-conntrack-extra
kmod-ipt-core
kmod-ipt-ipopt
kmod-ipt-nat
kmod-ipt-offload
kmod-ipt-raw
kmod-iptunnel6
kmod-lib-crc-ccitt
kmod-libphy
kmod-mii
kmod-mmc
kmod-nat46
kmod-nf-conntrack
kmod-nf-conntrack6
kmod-nf-flow
kmod-nf-ipt
kmod-nf-ipt6
kmod-nf-nat
kmod-nf-reject
kmod-nf-reject6
kmod-nls-base
kmod-nls-cp437
kmod-nls-iso8859-1
kmod-nls-utf8
kmod-ppp
kmod-pppoe
kmod-pppox
kmod-slhc
kmod-sound-core
kmod-usb-core
kmod-usb-hid
kmod-usb-net
kmod-usb-net-asix
libblkid1
libblobmsg-json20210516
libc
libcomerr0
libext2fs2
libf2fs6
libgcc
libgcc1
libip4tc2
libip6tc2
libiwinfo-data
libiwinfo-lua
libiwinfo20210430
libjson-c5
libjson-script20210516
liblua5.1.5
liblucihttp-lua
liblucihttp0
libnl-tiny1
libpthread
librt
libsmartcols1
libss2
libubox20210516
libubus-lua
libubus20210630
libuci20130104
libuclient20201210
libustream-wolfssl
libustream-wolfssl20201210
libuuid1
libwolfssl5.2.0.99a5b54a
libxtables12
logd
lua
luci
luci-app-firewall
luci-app-opkg
luci-base
luci-lib-base
luci-lib-ip
luci-lib-jsonc
luci-lib-nixio
luci-mod-admin-full
luci-mod-network
luci-mod-status
luci-mod-system
luci-proto-ipv6
luci-proto-ppp
luci-ssl
luci-theme-bootstrap
map
mkf2fs
mtd
netifd
odhcp6c
odhcpd-ipv6only
openwrt-keyring
opkg
partx-utils
ppp
ppp-mod-pppoe
procd
px5g-wolfssl
rpcd
rpcd-mod-file
rpcd-mod-iwinfo
rpcd-mod-luci
rpcd-mod-rrdns
uboot-envtools
ubox
ubus
ubusd
uci
uclient-fetch
uhttpd
uhttpd-mod-ubus
urandom-seed
urngd
usign
wireless-regdb
wpad-basic-wolfssl

USB-LANアダプタ、USB無線LANドングルを使うので、そのドライバを追加しています。

  • kmod-rt2800-usb
  • kmod-usb-net-asix

あとは、MAP-E関連で必要なパッケージを追加しました。

生成されたイメージはext4ではなくsquashfsの方をダウンロードし、sdカードに書き込みました。

設定

以下、自分用めも。

  1. PCとPINE A64のLANポートを接続し、電源ON
  2. WiFi設定。アクセスポイントとして動くようにする
  3. アクセスポイントに接続し、以後そこから設定する
  4. OpenWRT – OSAKANA TAROのメモ帳 ここを参考に設定
  5. WAN6 -> WAN -> LAN(ここで既存のブリッジは削除した) -> MAP-E
  6. DNS設定
  7. Network > DHCP and DNS
    • General Settings
    • Resolv and Host Files
      • Ignore resolve file のチェックをいれる

ニチバンベンチ対策

Network > Firewall > Custom Rules に以下スクリプトを設定します。

# This file is interpreted as shell script.
# Put your custom iptables rules here, they will
# be executed with each firewall (re-)start.

# Internal uci firewall chains are flushed and recreated on reload, so
# put custom rules into the root chains e.g. INPUT or FORWARD or into the
# special user chains, e.g. input_wan_rule or postrouting_lan_rule.

units1=15 #V6plus:15 OCN:63
units2=4096 #V6plus 4096 OCN:1024
IP4='YOUR_IP'
PSID='YOUR_PSID'
TUNDEV='map-WAN_MAP'


iptables -t nat -F PREROUTING
iptables -t nat -F OUTPUT
iptables -t nat -F POSTROUTING

rule=1
while [ $rule -le $units1  ] ; do
  mark=`expr $rule + 16`
  pn=`expr $rule - 1`
  portl=`expr $rule \* $units2 + $PSID \* 16`
  portr=`expr $portl + 15`

  iptables -t nat -A PREROUTING -m statistic --mode nth --every $units1 --packet $pn -j MARK --set-mark $mark
  iptables -t nat -A OUTPUT -m statistic --mode nth --every $units1 --packet $pn -j MARK --set-mark $mark

  iptables -t nat -A POSTROUTING -p icmp -o $TUNDEV -m mark --mark $mark -j SNAT --to $IP4:$portl-$portr
  iptables -t nat -A POSTROUTING -p tcp -o $TUNDEV -m mark --mark $mark -j SNAT --to $IP4:$portl-$portr
  iptables -t nat -A POSTROUTING -p udp -o $TUNDEV -m mark --mark $mark -j SNAT --to $IP4:$portl-$portr
  rule=`expr $rule + 1`
done

System > Startup > Local Startup に以下を追記します。

sleep 30
sh /etc/firewall.user

ケースを作る

あとはいい感じにケースを作ります。

fusion360モデリングして、Prusa i3 MK3S+で出力しました。

PNE A64はRaspberry Pi互換のピンヘッダが備わっているので、3.3VとGNDを使ってファンを動かしています。

ということで!

十分なスループットが出せるルーターができました。

我が家は回線が速くないからね。。。

セットアップしたり、ケース設計したり、そんな手間がなくても10,000円あれば購入できる普通のルーター、優秀ですねぇ。

余談

余ってたLED付ファンにしたので、主張が激しい。