見出し画像

Edgerouter Xとの戦い〜結〜結局ndppdをビルドする

ndppdのインストール先の問題を修正しました.

NAT6を使って,Edgerrouter X(ER-X)をNURO光の回線の下で,IPv6を設定することはできたのですが,経路が悪いのか,結局,ブラウザによってIPv4が使われてしまう始末・・・・・.そこで,最終手段として,IPv6の経路をルータが上位のルータの代理で取りこなうndppdを導入してみることにしました.しかし・・・これには,多くの「手間」が必要なのです.

ND Proxy

そこまで検索していないのですが,ndppdがND Proxyのデーモンのようです.githubには,二つリポジトリを見つけました.Daniel Adolfsson氏のコードがずっとメンテナンスされているようですが,途中でGoogleのunofficial code,ndprbrdが公開されています.Googleによると,ndprbrdは,

This daemon has a very specific purpose: to give the same IPv6 prefix /64 to several network interfaces using radvd without creating L2 bridge and without need to configure DHCPv6. It's designed to be used together with ndppd for case if ISP gives single /64 without delegating a bigger prefix to your router.

だそうで,どうやら,私が欲しい機能は,このリポジトリにあるようです.しかしながら,すでに本家?ndppdに,この機能はマージされており,いくつかの課題を無視できるなら,ndppdを使えとのこと.というわけで,このリポジトリのドキュメントと参考文献に従って,ndppdを使うことにします.

ndppd 0.2.X

ビルドが面倒臭い人は,こちらからどうぞ.

ndppdによると,現在の最新バージョンはdev-1.0で.安定版は,masterリポジトリの0.2.Xシリーズのようです.とりあえず,最新版をビルドしてみよつうと,dev-1.0をビルドしてみます.

ER-XのCPUは,MIPSなので,WindowsやmacOSなどのマシンでそのままコンパイルしたものを転送することはできません.ER-X上でビルドするか,MIPS用のクロスコンパイル環境と整える必要があります.私はER-X上でやる方がフラストレーションが溜まりそうなので,クロスコンパイルを選びました(先人もいらっしゃいましたし).しかし,macOS上でクロスコンパイルするのはいろいろと面倒なので,Ubuntu上でやりました.私は,Virutal Boxを使い,そこにUbuntuをセットアップし,ソースコードは共有フォルダにし,sshでログインし,ビルドしました.

Virtual Box

UbuntuにVirutal Box用のadditonal packageをインストールし,共有フォルダとsshのログイン用のPort forwardingを設定します.検索するといろいろドキュメントがあります.

スクリーンショット 2020-04-05 16.22.07

sshのタブのPort Forwardingを開き,Virtual Boxを起動しているホストのIPの特定のポートに仮想マシンの22ポートをフォワードさせます.

スクリーンショット 2020-04-05 16.22.20

こうすると,

ssh -p 2222 user@<local IP>

で,仮想マシンにログインできます(sshをインストールしてからですよ).次に,shared folderのタブからホストとの共有フォルダをセットアップしておきます.こうすると,ホストのマシンのエディタでソースコードを編集できるの楽です.

スクリーンショット 2020-04-05 16.22.35

共有フォルダのユーザを設定するところはハマりました.ここの指示に従って,ユーザグループに追加しました.

gpasswd --add {ユーザ名} vboxsf

ビルド master 安定版

まずは,必要なものをUbuntuにインストールします.

apt-get update -y
apt-get install -y g++-mipsel-linux-gnu vim openssh-server
sudo systemctl restart ssh

これでMIPS用のビルド環境がセットアップできるはずです.次にソースコードをチェックアウトし,ビルドしていきます.ソースコードは,ホスト側で共有フォルダにチェックアウト・編集し,ssh経由でビルドするのが楽です.

MIPS用のコンパイラは,

/usr/bin/mipsel-linux-gnu-g++

にインストールされるので,Makefile中のコンパイラのパスを設定します.?=で代入されているので,強制的にセットするように=でセットするようにします.また,標準ライブラリとかのダイナミックリンクがうまく動かないと面倒なので,staticリンクでビルドします(参考文献より).

PREFIX  = /ndppd/local
CXX     = /usr/bin/mipsel-linux-gnu-g++
LDFLAGS = -static

これで,ビルドします.私は,Makefileを汚すのが嫌なので,Makefile.mipsを作成しました.

make -f Makefile.mips

これで,正しくビルドされるはずです.

余談 dev-1.0のビルド

同様に最新のdev-1.0もビルドできます.ただし,最新版は,CでコンパイルしないとC++のコンパイラだとビルドできません.また,dev版はcmakeでビルドするように変わっているようです.本来は,cmakeでMIPSのクロスコンパイル 設定を書けばいいのですが・・・・面倒くさいのMakefileで直接ビルドしました.

/usr/bin/mipsel-linux-gnu-gcc

あと,ドキュメントビルド用にasciidoctorが必要と言われるのも注意が必要です.これもmakeで同様にビルドできましたが,私の環境だと起動後1分程度でクラッシュしてしまいました.設定ファイルも.0.2.Xと互換性がないため,注意が必要です.dev-1.0は,まだまだ問題がありそうです.安定版まで待った方が良さそうです.

IPv6の設定をする

ER-XのIPv6をセットします.

set interfaces ethernet eth0 address '1120:1234:5678:5600::/64'
set interfaces ethernet eth0 description Internet
set interfaces ethernet eth0 duplex auto
set interfaces ethernet eth0 ipv6 address autoconf
set interfaces ethernet eth0 ipv6 dup-addr-detect-transmits 1
set interfaces ethernet eth0 mtu 1500
set interfaces ethernet eth0 speed auto
set interfaces switch switch0 vif 10  ipv6 address eui64 '1120:1234:5678:5600::/64'
set interfaces switch switch0 vif 10  ipv6 dup-addr-detect-transmits 1
set interfaces switch switch0 vif 10  ipv6 router-advert cur-hop-limit 64
set interfaces switch switch0 vif 10  ipv6 router-advert link-mtu 1500
set interfaces switch switch0 vif 10  ipv6 router-advert managed-flag false
set interfaces switch switch0 vif 10  ipv6 router-advert max-interval 600
set interfaces switch switch0 vif 10  ipv6 router-advert other-config-flag true
set interfaces switch switch0 vif 10  ipv6 router-advert prefix '::/64' autonomous-flag true
set interfaces switch switch0 vif 10  ipv6 router-advert prefix '::/64' on-link-flag true
set interfaces switch switch0 vif 10  ipv6 router-advert prefix '::/64' valid-lifetime 2592000
set interfaces switch switch0 vif 10  ipv6 router-advert reachable-time 0
set interfaces switch switch0 vif 10  ipv6 router-advert retrans-timer 0
set interfaces switch switch0 vif 10  ipv6 router-advert send-advert true

これで,eth0とeth1のIPv6の設定が完了です.私はswitch0を使っているので,上記のような設定になっています.switchを使っていない人は適当に読み替えてください.

ndppdをインストールする

まず,ndppdをER-Xにコピーします.scpとかでコピーするとよいでしょう.ビルドしたファイルの他に,設定ファイル,ndppdの起動ファイル,自動起動ファイルが必要です.ndppdのプロセスは,EdgeMaxに管理されないため,バイナリをコピーして,sshで起動させるだけでは,再起動するたびに,マニュアルでndppdのプロセスを起動しなければならないので,自動起動するようにします.

/config/scripts/post-config.dに起動時に実行したいスクリプトをおけばよいのですが,ここに置いたスクリプトは,デーモンの起動にありがちなオプションをつけて,OSが起動したりしてくれません.なので,デーモン起動のスクリプトと,それを起動するスクリプトの二つを作っておく必要があります.

また,/config/scripts/post-config.dと/config/user-data以外に置いたファイルは,EdgeMaxのOSをアップデートするたびにすべて消えてしまうので,ndppdのバイナリや設定ファイル,二つのスクリプトは,そこに置くようにします.

/config/scripts/post-config.dに起動時に実行したいスクリプトをおけばよいのですが,ここに置いたスクリプトは,デーモンの起動にありがちなオプションをつけて,OSが起動したりしてくれません.なので,デーモン起動のスクリプトと,それを起動するスクリプトの二つを作り,後者を/config/scripts/post-config.dのパスにコピーします.

設定ファイルndppd.confには,どのポートから,どのポートにIPv6のRAを流すかを書き込みます.この設定ファイルは,eth0とswitch0.10をつなぐ設定です.環境に合わせて,この設定を書き換えます.

proxy eth0 {
   router no
   timeout 500
   autowire yes
   keepalive yes
   retries 3
   ttl 30000
   rule ::/0 {
       iface switch0.10 
   }
}

proxy switch0.10 {
   router yes
   timeout 500
   autowire yes
   keepalive yes
   retries 3
   ttl 30000
   rule ::/0 {
       auto
   }
}

デーモンとして起動させるスクリプトは,ndppdに含まれているndppd-init-debian-jessiをベースに,ndppd.initscriptとして保存します.

#!/bin/sh
# kFreeBSD do not accept scripts as interpreters, using #!/bin/sh and sourcing.
if [ true != "$INIT_D_SCRIPT_SOURCED" ] ; then
   set "$0" "$@"; INIT_D_SCRIPT_SOURCED=true . /lib/init/init-d-script
fi
DESC="NDP Proxy Daemon"
PIDFILE=/run/ndppd.pid
DAEMON=/config/user-data/ndppd/ndppd
DAEMON_ARGS="-d -p $PIDFILE"

デーモン起動スクリプトを叩くスクリプト,/config/scripts/post-config.dに置くものは,以下のような内容にしておきます.

#!/bin/vbash
/config/user-data/ndppd/ndppd.initscript start

これらは,ここかもダウンロードできます.

このファイルをndppdというディレクトリにまとめておき,scpで丸ごとEdge Roughter Xにコピーします.

scp -r ./ndppd hoge@router:~/

Edge Rougher Xにログインし,~/ndppdに置いたファイルたちを,アップデートしても削除されないuser-dataにコピーします.スクリプトとバイナリに実行権限を付与することを忘れずに.

cp -r ~/ndppd /config/user-data/ndppd

ER-XのLAN側のポートにIPv6のアドレスが,WAN側のポートにIPv6のプレフィックスが振られます(WAN側にアドレスが振られないのはなぜだろう・・・・・).下の図の上の赤枠の部分に設定したIPv6のプレフィックスが,下の赤枠の部分にLAN側のアドレスが表示されます.

画像4

IPv6

これで大丈夫なはずですが・・・・.以下のサイトでIPv6の対応状況を確認できます.

http://www.kame.net
https://test-ipv6.com
https://ipv6-test.com
https://ybb.softbank.jp/member/yf/ipv6-4judge.html
http://v6v4.net

ここまでやってもたまに,Safariの場合,たまに下の図が出ます.Chromeの場合は問題ないようですが・・・・.

スクリーンショット 2020-04-05 19.04.39

こちらのテストでも同様です.Safariは,IPv6判定アルゴリズムがIPv4優先よりなのかな・・・・.

スクリーンショット 2020-04-05 19.06.10

何はともあれ,目的は達成されました.めでたし,めでたし.

参考文献


この記事が気に入ったらサポートをしてみませんか?