公式情報と概要
NanoPi NEO(無印)自体は例えば秋月電子で2017/07/14発売など国内でも大分前から販売されており、現在はOpenWrtも動作するのでWireGuardを使いたいだけならOpenWrtを使えばよく、ここではOpenWrtより一般的なLinux環境が欲しいためFriendlyCore(Ubuntu coreベースのLinux)でWireGuardを使う場合を考える。
なお、NanoPi NEOはメモリがモデルにより256MB/512MB、NICが100Mbpsであるなど最近(2024年現在)の同種のボードと比べるとスペックも低く、これから新たに買う理由は他より安いことくらいしかなく、今更需要のある話ではないと思うけど…
問題の説明
別に持っているNanoPi NEO3だと問題なく動いているのであまり気にしていなかったが、NEO3向けに配布されているFriendlyCoreはFocal(Ubuntu core 20.04)ベースでkernelが6.1.y(ただし私がインストールした時点では5.15.y)だが、NEO向けに配布されているものはJammy(Ubuntu core 22.04)ベースでkernelが4.14.yであり、WireGuardがLinux kernelに組み込まれたのは5.6なのでNEO向けにはbackportを組み込まないと使えないが、組み込まれていないものが配布されている。つまりkernelを自分で再構築しないといけない。
前出公式Wikiの8 Make Your Own FriendlyCoreにはkernelのクロスコンパイル方法が記載されているが、現在は8.1 Use Mainline BSPにしたがえばよく、その下の8.2のlicheeというのは以前のkernel 3.4の話になっている(から関係ないのに気づかず混乱していた。要はきちんと読まないのが悪い)。
解決の手順
クロスコンパイルといってもFrindlyElecがかなり自動化したものを配布しているので、そんなに面倒でもない。
事前準備
VMwareでUbuntu 24.04 LTS環境を用意した。VMwareはデフォルトで20GBの仮想ディスクを作成するが、ちょっと心許ないので30GBくらいにしておいた方が安全かも知れない。それとrootかsudoできるアカウントで作業する必要がある。
必要な物は他にもあるようだが、後述の./build-kernel.sh内でaptが呼び出されて追加でインストールされるようになっているから、ここでは適当に。
$ sudo apt install gcc
$ sudo apt install make
$ sudo apt install libncurses-dev
$ sudo apt install u-boot-tools
$ sudo apt install git
$ git clone https://github.com/friendlyarm/prebuilts.git -b master --depth 1
$ cd prebuilts/gcc-x64
$ cat toolchain-4.9.3-armhf.tar.gz* | sudo tar xz -C /
具体的なkernel再構築&SDカード用イメージ作成手順
この辺を参考にしているので、細かい説明はリンク先を参照(他力本願)。
- https://wiki.friendlyelec.com/wiki/index.php/Building_U-boot_and_Linux_for_H5/H3/H2%2B
- https://github.com/friendlyarm/sd-fuse_h3
$ git clone https://github.com/friendlyarm/sd-fuse_h3 -b master --single-branch sd-fuse_h3
$ cd sd-fuse_h3
$ wget http://112.124.9.243/dvdfiles/h3/images-for-eflasher/friendlycore-jammy-images.tgz
$ tar xvzf friendlycore-jammy-images.tgz
$ export KERNEL_SRC=$PWD/kernel
$ git clone https://github.com/friendlyarm/linux -b sunxi-4.14.y --depth 1 ${KERNEL_SRC}
ここでsunxi-4.14.yにbackportされているWireGuardのバージョンが大分古い(20171111)のが気になるので
$ cd
$ git clone https://git.zx2c4.com/wireguard-linux-compat -b master
$ cd wireguard-linux-compat
$ rm -r $KERNEL_SRC/net/wireguard/*
$ cp -pr src/* $KERNEL_SRC/net/wireguard/
とかやって20220627に入れ替えた(ここはやらなくても動くか動かないかで言えば動く)。続けて
$ cd $KERNEL_SRC
$ touch .scmversion
$ make ARCH=arm sunxi_defconfig
$ make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
# ここでメニューが表示されるが、よくわからないので何も変更せずExit
$ make ARCH=arm CROSS_COMPILE=arm-linux- savedefconfig
$ vi defconfig
CONFIG_WIREGUARD=m
# と、追記する
$ cp defconfig ./arch/arm/configs/my_defconfig
$ git add ./arch/arm/configs/my_defconfig
$ cd -
$ export KERNEL_SRC=$PWD/kernel
$ export KCFG=my_defconfig
$ ./build-kernel.sh friendlycore-jammy
# スクリプト内でsudoしてパスワードを要求してくるので注意
$ ./mk-sd-image.sh friendlycore-jammy
とすると、SDカードに書き込むためのイメージが作成される(8GBくらいある)。
実際にSDカードに書き込む手順は通常のFriendlyCoreやOpenWrtと同じくWin32 Disk Imagerとかを使うなりすればよいので割愛。余談だけどWin32 Disk ImagerはGoogleドライブ(アプリ)など仮想ドライブを設定する類のアプリが動作していると起動しないことがあり、いったんアプリを終了させてからWin32 Disk Imagerを起動する必要があることがある(これも以前はまって苦労した)。
WireGuardの導入・設定
一般的なLinuxなので、例えば以下のような一般的な導入・設定をすればよい。
そういえばiptablesが入っていなかった。
$ sudo apt install iptables
$ sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
なおNanoPi NEOを(再)起動した際、wg-quick
が/etc/wireguard/wg0.confのPostUpにあるコマンドを実行しようとするとまだeth0が上がっていないせいかiptables
の実行に失敗するようで、sleep 20
を入れてごまかしている。sleep 5
くらいだとうまく行かないので、多分タイミングのせい。知らんけど。
PostUp = sleep 20; iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
速度測定
同じハードウェアでOpenWrtより速度が出るのではないかという全く根拠のない期待をしていたが、そんなことはないようだった。
参考にしたサイト
この記事がなければWireGuardのkernel moduleが入っていないこと自体と、その対応としてkernelを再構築すればよい、ということに気づけなかった(これ以外に同趣旨の記事を見つけられなかった)。ありがとうございました。
(2024.05.24 – 2024.06.06)