NanoPi NEO2をv6プラスのルーターにする 後編

新しく NanoPi NEO3をv6プラスのルーターにする systemd-networkd + nftables を書きました。この記事と合わせてご参照下さい。

NanoPi NEO2をv6プラスのルーターにする
USBネットワークアダプタ(黒)を繋いだNanoPi NEO2(金)。ネットワークケーブルは未接続。これにダイソーのmicroUSBのACアダプタを繋ぐ。ストレージは後述するが200円程度の2GBのmicroSDカードなのでケース含めてNanoPi NEO2はシステム全体で3000円程度。追加で今回は1000円のUSBネットワークアダプタ。でも正直なところUSBネットワークアダプタは無くても良いしUSB2.0の制限で最大速度が遅くなるのでむしろ要らないかな。

題名は「NanoPi NEO2を」と書いているけどNanoPi NEO2でなくてはならない要素は全く無くて機材としてはPCなどを含めほぼ何でも、Linux全般で通用します。

前回はv6プラスのMAP-Eを設定するためのアドレス・ポートのマッピングを計算した。今回はその値を使ってNanoPiNEO2をIPv4ルーターにする。

この記事ではNanoPi NEO2のネットワークポートはeth0でこれをLAN側NICとする。 USBのネットワークアダプタはenxenxXXXXXXXXXXXXで、これをIPv6のWAN側NICとする。IPv4 over IPv6のトンネルを掘るのでそのネットワークインターフェースをip6tnl1とする。

armbian公式サイトのNanoPi NEO2用のダウンロードページではDebian StretchとUbuntu Xenialは2018年1月下旬のものが最新で、それ以降更新されていない。更新されているのはUbuntu bionicだけ。それさえもNightly言いつつ途切れ途切れでリリースされている状況。
個人的にはDebian Stretchが好みなので時々ビルドしてGoogle Driveに上げている。ビルドオプションは弩ノーマルなので野良ビルドでよければ使って下さい。この記事ではビルドしたArmbian_5.55_Nanopineo2_Debian_stretch_next_4.17.11で動作確認している。
イメージを書き込むmicroSDカードは2GB程度あればイメージを書き込んだ状態でルートFSの使用率が70%程度。いろいろ入れてということではなくルーター専用程度なら書き換えもほぼ発生しないので激安の2GBで十分かと。最近は4GBが送料込みで200〜400円程度。2GBはもう売ってるのを見かけない。日本だとAmazonとかならまだあるかも。無駄に高いから買わないけど。

armbianの最近のdebian stretch(他も)はネットワークインターフェースのeth0が標準で無効という嫌な状態になっているので以前のようにmicroSDカードにOSイメージを焼いてネットワークケーブル繋いだらすぐにSSHで通信できるというようには優しくない。microSDカードにarmbianを書き込んだら、NanoPi NEO2に挿す前にPCでそのmicroSDカードのファイルシステムを開いて以下の変更を行う。

/etc/network/interfaces.default (2行追記)
1
2
3
#auto eth0
allow-hotplug eth0
iface eth0 inet dhcp

書き込んだらmicroSDカードを安全な方法でアンマウントしてから、NanoPi NEO2に挿して電源投入。
armbianの初期設定を適切に行う。(この記事では初期設定は省略)

/etc/sysctl.conf (1行変更、1行追記)
1
2
net.ipv4.ip_forward=1                    #IPv4ルーターの指定
net.ipv6.conf.eth0.disable_ipv6=1        #LAN側はIPv6を無効にする

今回はIPv4用のルーターにするのでnet.ipv4.ip_forward=1を指定した。
ただし、フォワーディングさせたいのはトンネルインターフェイスだけなので、他のネットワークインターフェイスでフォワーディングは困るという場合は/etc/sysctl.confでnet.ipv4.forwarding=1を指定するのではなく、トンネルを張った後にsysctl net.ipv4.conf.トンネルIF名.forwarding=1 を実行する。システム起動時にはトンネルインターフェイスが存在しないので/etc/sysctl.confでは指定できない点に注意。

tracerouteとtcpdumpをインストールする。これがあるとネットワークの疎通確認に便利。

# apt-get update                      #パッケージ情報の更新
# apt-get upgrade                     #パッケージを最新のものに更新
# apt-get install traceroute tcpdump

トンネル

DS-LiteとMAP-Eはズボンの表と裏のようなものなので結構似ている。カプセル化はDS-Liteと同じだし。 なので、トンネル堀りは基本的に以前のDS-Liteと同じ。DS-LiteのAFTRをBRのアドレスに読み替えて、CE側のアドレスも前回はIPv6アドレス指定だったのをインターフェース名にした程度。ただし、最近のLinuxの仕様変更なのかしら、そのままだとパケットを送ることはできても一切パケットが返ってこない。エラーになるなら調べやすいのだが、何も返ってこないというのは調べようがなくて凄い悩まされた。

参考記事:
愚行録 the Next Generation

こちらの記事はMAP-EではなくVPS目的のようだけど症状が同じで原因も特定されていた。(EncapsulationLimit=none)
参考記事では.netdevファイルを作成する方法を使ってるので設定の書き方は違うけど ipコマンドのトンネルでも同様の指定ができるのでコマンドで書くことにした。(encaplimit none)

NAT

正直Linuxのiptablesに不慣れなので苦労するかと思ったが、パケットにマークする、返ってきたパケットをマークで見分けるというなかなか素晴らしい方法が使えるということなのそれを採用することに。 で、ポートの範囲ごとにそれぞれTCP,UDP,ICMPのNATを書く。
が、面倒なのでスクリプトにしようと決意。で、ググッてたら1年半も前の2chのスレにそのものズバリがあったのね。

2ch v6プラス スレ
http://maguro.2ch.sc/test/read.cgi/isp/1473155603/
-----------------------------------------------------
358 : 名無しさんに接続中…[sage] 投稿日:2016/12/26(月) 17:08:09.63 ID:3u+uf4Mv.net [1/1回]
OpenWrtの真似してNATテーブル作って
CEからBRにIPIPトンネル張って流したら繋がった
CE同士の直接通信はできないけど
http://pastebin.com/QCSKwq72

WXR-1750DHP使うのやめてLinuxルータに戻そうかな
-----------------------------------------------------
/usr/local/bin/map.sh (新規作成)
 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
30
31
32
33
34
35
#!/bin/sh

BR='BRのIPv6アドレス'
CE='CEのIPv6アドレス'
IP4='IPv4アドレス'
PSID='PSIDを10進数に変換したもの'
WANDEV='enxXXXXXXXXXXXX'
TUNDEV='ip6tnl1'

ip -6 addr add $CE dev $WANDEV
ip -6 tunnel add $TUNDEV mode ip4ip6 remote $BR local $CE dev $WANDEV encaplimit none
ip link set dev $TUNDEV mtu 1460
ip link set dev $TUNDEV up

route delete default
route add default dev $TUNDEV

iptables -t nat -F

rule=1
while [ $rule -le 15  ] ; do
  mark=`expr $rule + 16`
  pn=`expr $rule - 1`
  portl=`expr $rule \* 4096 + $PSID \* 16`
  portr=`expr $portl + 15`
  iptables -t nat -A PREROUTING -m statistic --mode nth --every 15 --packet $pn -j MARK --set-mark $mark
  iptables -t nat -A OUTPUT -m statistic --mode nth --every 15 --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

iptables -t mangle -o $TUNDEV --insert FORWARD 1 -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1400:65495 -j TCPMSS --clamp-mss-to-pmtu

緑字のCE, IP4, PSIDの部分に前回求めた値を書き込む。BRのアドレスはググれば見つけられる筈。WANDEVは今回はNanoPi NEO2のUSBネットワークアダプタのNIC名。(ちなみにLAN側はeth0)
TUNDEVはトンネルを作ると生まれるインターフェース名。
掲示板の人のスクリプトのままだと(最近は?)BRからの戻りパケット全く通らないのでトンネル作成時にencaplimit noneを追加指定している。
触ったのはそれくらい。NATの部分は詳しい人からするともっと上手い方法あるよというのがあるかもだけど、iptablesは不慣れなので掲示板の人のそのままで十分過ぎるほど上手だと思ってる。

スクリプトに実行属性を付ける。
# chmod +x /usr/local/bin/map.sh
システム起動時に自動的にMAP-Eで接続させる。
/etc/rc.local (2行挿入)
1
2
sleep 10
/usr/local/bin/map.sh

exit 0の行の直前あたりに挿入する。上の例ではシステム起動後10秒待ってからMAP-Eで接続させるようにしたが、待ち時間は好みで。

他のPCがIPv4でインターネットに出るためのルートとしてNanoPi NEO2を指定する。DHCPサーバを使っているならDHCPサーバの設定でIPv4のルーターアドレスをNanoPi NEOのLANのIPアドレスに変える。トンネル用のIPv4アドレスではない点に注意。向き先を手動で変更するかPC(等)を再起動する。

speedtest.net
土曜日の21時半というまぁまぁ混む時間帯にSpeedtest.netで計測した結果。 この時間でこれなら深夜や午前中はもっと速度は出る筈。特に上り側。しかし、NanoPi NEO2のUSBが2.0なので300Mbpsが精一杯というところか。
画像の時刻を見て「昼過ぎじゃん」って思う人がいるので念の為。GMTならその時刻に9時間足したのが日本時間ね。

v6プラスの接続図
今回NanoPi NEO2は標準のネットワークポートとUSBネットワークアダプタの2つのポートでルーターにしているが、使用したUSBネットワークアダプタはUSB3.0対応なもののNanoPi NEO2側がUSB2.0なのでどう足掻いてもネットワークの実効速度は300Mbpsいくかいかないか程度。
それならNanoPi NEO2標準のネットワークポートだけ、1ポートでやる方が速いかもと思った。どうせ2ポートでも両端を同じハブに繋ぐんだし。思っただけでまだやってないわけだがヒマがあったら1ポートでも試したい。

2018年9月3日追記:
事前の予想では240ポート(TCPセッション)だと足りなくて使い物にならないんじゃないかと思ってたけど、約1ヶ月使ってみて意外にも不満無く普通に使えてる。家庭用のMAP-E対応ルーターとか買う必要無いと思った。

関連記事:

コメント: NanoPi NEO2をv6プラスのルーターにする 後編

  1. map.shですが、OCN バーチャルコネクトだと
    while [ $rule -le 63 ] ; do として、
    portl=`expr $rule \* 1024 + $PSID \* 16`
    とすれば実態とぴったり合います。

  2. すばらしい。
    OCNユーザーも悩まずに済みますね。

コメントは締め切られています。