【MS-01】OpenWRT で enひかりXpass を使う

enひかりXpass は IPv4 over IPv6 (DS-Lite) という方式で IPv4 通信を行う。DS-Lite 通信では IPv4 アドレスが変動し使えるポートに制限もある。固定IP オプションを付けて IPIP 通信にすると固定IPになり全ポート独占できる。しかし外部から攻撃を受けやすくなる。
OpenWRT などの高機能なルーターを使えば DS-Lite と IPIP を同時に繋げることができ、ゲーム機は IPIP、その他の端末は DS-Lite などのルーティングが可能になる。その手順を説明する。

  1. (初期状態)OpenWRT インストール直後のデフォルトのネットワーク設定
  2. DS-Lite (可変IP) のみ接続を通す
  3. IPIPv6 (固定IP) のみ接続を通す
  4. ルーティングを有効にして DS-Lite と IPIPv6 の同時接続を通す

全体の流れはこのようになる。

IPv6 の接続設定

ONU に繋いだ IPv6 通信を行うポートの通信設定とそこに通す DS-Lite トンネル設定を行う。
IPv6 通信設定の clientid として通信ポートの MAC アドレスが必要になるのでそれを調べる。

root@OpenWrt:~# ifconfig eth1  # eth1 は任意のネットワークポート
eth1      Link encap:Ethernet  HWaddr AA:BB:CC:DD:EE:FF

/etc/config/network を編集する。

IPv6 インターフェースの wan6 の clientid には DUID-LL 形式の値を指定する。
00030001[eth1のMACアドレス12桁] というフォーマットになる。

 # /etc/config/network

 config interface 'lan'
 	option device 'br-lan'
 	option proto 'static'
 	list ipaddr '192.168.1.1/24'
-	option ip6assign '60'
+	option ip6assign '64'
+	option ip6hint '00'
 
 # wan は消しておく
-config interface 'wan'
-	option device 'eth1'
-	option proto 'dhcp'

 # clientid に DUID-LL を指定
 config interface 'wan6'
 	option device 'eth1'
 	option proto 'dhcpv6'
+	option reqaddress 'try'
+	option reqprefix '56'
+	option clientid '00030001aabbccddeeff'

DS-Lite (可変IP) の接続設定

ds-lite と ip-full パッケージをインストールする。

root@OpenWrt:~# apk update

root@OpenWrt:~# apk add ds-lite ip-full

ONU に繋いだ IPv6 通信を行うポートの通信設定とそこに通す DS-Lite トンネル設定を行う。
IPv6 通信設定の clientid として通信ポートの MAC アドレスが必要になるのでそれを調べる。

root@OpenWrt:~# ifconfig eth1  # eth1 は任意のネットワークポート
eth1      Link encap:Ethernet  HWaddr AA:BB:CC:DD:EE:FF

/etc/config/network を編集する。

IPv6 インターフェースの wan6 の clientid には DUID-LL 形式の値を指定する。
00030001[eth1のMACアドレス12桁] というフォーマットになる。

 # /etc/config/network

 config interface 'lan'
 	option device 'br-lan'
 	option proto 'static'
 	list ipaddr '192.168.1.1/24'
-	option ip6assign '60'
+	option ip6assign '64'
+	option ip6hint '00'
 
 # wan は消しておく
-config interface 'wan'
-	option device 'eth1'
-	option proto 'dhcp'

 # clientid に DUID-LL を指定
 config interface 'wan6'
 	option device 'eth1'
 	option proto 'dhcpv6'
+	option reqaddress 'try'
+	option reqprefix '56'
+	option clientid '00030001aabbccddeeff'

 # DS-Lite 接続の設定
+config interface 'wan_dslite'
+	option proto 'dslite'
+	option peeraddr 'dgw.xpass.jp'
+	option tunlink 'wan6'
+	option encaplimit 'ignore'
+	option mtu '1460'

AdguardHome を使っていてドメイン名の解決に失敗する場合は peeraddr に 2001:f60:0:200::1:1 を指定する。
ここ以外でも AdguardHome が有効の場合は名前解決に失敗することがある。そのときは適宜 IP 直打ちに変える。

新たに追加したインターフェース wan_dslite をファイアーウォールの zone に追加する。
DS-Liteは ISP 側で NAT 処理を行うのでルーター側の NAT を off (masq 0)にする。

 # /etc/config/firewall

 config zone
 	option name		wan
-	list   network		'wan'
 	list   network		'wan6'
+	list   network		'wan_dslite'
 	option input		REJECT
 	option output		ACCEPT
 	option forward		DROP
-	option masq		1
+	option masq		0
 	option mtu_fix		1

reload_config または reboot で設定の変更を反映すると、IPv4 と IPv6 の通信が通るようになる。

IPIPv6 (固定IP) の接続設定

Xpass 固定IP のプランが有効になると enひかりから固定IP情報の紙が届く。内容は以下のとおり。

  • IPv4アドレス: 203.0.113.1/32 <en_ipv4>
  • Tunnel destination アドレス: aaaa:bbbb:cccc:dddd::eeee <en_dst>
  • FQDN: xxxx.xpass.jp <en_fqdn>
  • DDNS ID: xxxx.xpass.jp <en_ddnsid>
  • DDNSパスワード: xXxXxXxX <en_ddnspw>
  • Basic認証ID: xxxxxxxx <en_basicid>
  • Basic認証パスワード:xXxXxXxX <en_basicpw>
  • DDNSアップデート先URL: https://xxx.yyy.zzz.jp/cgi-bin/ddns_api.cgi <en_ddnsurl>
    (表のすぐ下に書いてある)

この情報を使って接続設定を書く。
パラメータを紐付けやすいよう山括弧に囲んだ名前を付けた。

 # /etc/config/network

 config interface 'wan6'
 	option device 'eth1'
 	option proto 'dhcpv6'
 	option clientid '00030001aabbccddeeff'  # 
+	option norelease '1'

 config interface 'wan_dslite'
 	option proto 'dslite'
 	option peeraddr 'dgw.xpass.jp'
 	option tunlink 'wan6'
 	option encaplimit 'ignore'
 	option mtu '1460'
+	option disabled '1'

+config interface 'wan_ipip6'
+	option proto 'ipip6'
+	option peeraddr 'aaaa:bbbb:cccc:dddd::eeee'  # <en_dst>
+	option ip4ifaddr '203.0.113.1'  # <en_ipv4>
+	option tunlink 'wan6'
+	option encaplimit 'ignore'
+	option mtu '1460'

接続確認のため DS-Lite の接続は一度切っておく。
IPIPv6 は wan6 の IP が頻繁に変わると不都合がある(後述)。再接続時に IPv6 アドレスを維持してくれる場合もあるので norelease オプションを追加しておく。

IPIPv6 は DS-Lite とは逆で NAT が必須となる。
ファイアーウォールに wan_ipip6 用の zone 新規で追加する。


 # /etc/config/firewall

 config zone
 	option name		wan
 	list   network		'wan6'
	list   network		'wan_dslite'
 	option input		REJECT
 	option output		ACCEPT
 	option forward		DROP
 	option masq		0
 	option mtu_fix		1
 
+ config zone
+	option name		wan_fixed
+	list   network		'wan_ipip6'
+	option input		REJECT
+	option output		ACCEPT
+	option forward		DROP
+	option masq		1
+	option mtu_fix		1

 config forwarding
 	option src		lan
 	option dest		wan
 
+config forwarding
+	option src		lan
+	option dest		wan_fixed

これで一度 reload_config または reboot する。
初めて IPIPv6 を通す場合、この時点で受信が通らなくなる。
wan_ipip6 のインターフェース情報を LuCI で見ると TX の値が増えていき、RX は 0 のままとなる。
TX は送信パケットで RX は受信パケットなので、受信パケットが届いていない状態と分かる。

いま、IPv6 トンネルを通した IPv4 パケットは相手にまでは届いている。
そして相手はこちらから通知した IPv4 にパケットを送り返そうとしている。
しかしこちらは IPv6 トンネルで待ち受けているので、IPv4 アドレスが書かれていても宛先の IPv6 アドレスが分からずパケットが行方不明になっている。
これを解決するために IPv4 から IPv6 アドレスを引く DDNS への情報登録が必要になる。

まずは自身の IPv6 アドレスを調べる。

root@OpenWrt:~# wget -qO - https://ipv6.ident.me/ && echo ""
bbbb:cccc:dddd:eeee::ffff

出力の最後に改行を入れるように echo “” を追加している。
ここで取得した IPv6 アドレスを <wan6_ipv6> とする。

まずは、テストも兼ねて手動で DDNS をアップデートする。
適切なフォーマットを指定してURLにアクセスするというシンプルな方法で DDNS 情報をアップデートできる。
(フォーマットの仕様は重要な情報だが FortiGate IPoE 設定ガイド からしか情報を得られなかった)

https://<en_basicid>:<en_basicpw>@<en_ddnsurl>?u=<en_ddnsid>&p=<en_ddnspw>&d=<en_fqdn>&a=<wan6_ipv6>
という形式で、サンプル値で埋めると
https://xxxxxxxx:xXxXxXxX@xxx.yyy.zzz.jp/cgi-bin/ddns_api.cgi?u=xxxx.xpass.jp&p=xXxXxXxX&d=xxxx.xpass.jp&a=bbbb:cccc:dddd:eeee::ffff
となる。

wget でこの URL にアクセスする。
本来なら避けるべきだがサーバー側の SSL 証明書が期限切れとなっているため --no-check-certificate オプションを付ける。

root@OpenWrt:~# wget --no-check-certificate -qO - "https://xxxxxxxx:xXxXxXxX@xxx.yyy.zzz.jp/cgi-bin/ddns_api.cgi?u=xxxx.xpass.jp&p=xXxXxXxX&d=xxxx.xpass.jp&a=bbbb:cccc:dddd:eeee::ffff" && echo ""
  • DDNS API
    • Query parameter check : OK
    • routerinfo check : OK
    • records check : OK
    • routerinfo update : OK
    • records update : OK
    • DDNS API update : Success

DDNS のアップデートに成功するとこのような文書が HTML で返ってくる。
その後、10 分程度で wan_ipip6 の受信が通るようになる。

手動で DDNS をアップデートできたら、DDNS の自動アップデート設定を行う。
IPv6 アドレスは DHCP で取得しているので再接続したときに変わる場合がある。

自動で DDNS をアップデートするためのパッケージ ddns-scripts をインストールする。

root@OpenWrt:~# apk update

root@OpenWrt:~# apk add ddns-scripts

ddns-scripts の設定ファイル /etc/config/ddns を書き換える。

 # /etc/config/ddns

-config service "myddns_ipv4"
-	option service_name	"dyndns.org"
-	option lookup_host	"yourhost.example.com"
-	option domain		"yourhost.example.com"
-	option username		"your_username"
-	option password		"your_password"
-	option interface	"wan"
-	option ip_source	"network"
-	option ip_network	"wan"
-	option use_api_check	"0"
-
-config service "myddns_ipv6"
-	option update_url	"http://[USERNAME]:[PASSWORD]@your.provider.net/nic/update?hostname=[DOMAIN]&myip=[IP]"
-	option lookup_host	"yourhost.example.com"
-	option domain		"yourhost.example.com"
-	option username		"your_username"
-	option password		"your_password"
-	option use_ipv6		"1"
-	option interface	"wan6"
-	option ip_source	"network"
-	option ip_network	"wan6"
-	option use_api_check	"0"
+config service "enhikari_ipip6"
+	option enabled		"1"
+	option update_url	"http://[USERNAME]:[PASSWORD]@xxx.yyy.zzz.jp/cgi-bin/ddns_api.cgi?u=xxxx.xpass.jp&p=xXxXxXxX&d=[DOMAIN]&a=[IP]"
+	option lookup_host	"xxxx.xpass.jp"  # <en_fqdn>
+	option domain 		"xxxx.xpass.jp"  # <en_fqdn>
+	option username		"xxxxxxxx"  # <en_basicid>
+	option password		"xXxXxXxX"  # <en_basicpw>
+	option use_ipv6		"1"
+	option use_https	"1"
+	option cacert		"IGNORE"
+	option interface	"wan6"
+	option ip_source	"network"
+	option ip_network	"lan"
+#	option ip_source	"web"
+#	option ip_url		"https://ipv6.ident.me/"

update_url オプションの [USERNAME], [PASSWORD], [DOMAIN], [IP] はスクリプト実行時に置換されるので置き換えずにそのまま書く。
Basic認証の ID とパスワードは設定項目にあるが、DDNS の ID とパスワードはないので update_url に埋め込む。
wan6 インターフェース情報からグローバル IPv6 アドレスを取得できないが、lan インターフェースから取得できる。
インターフェース情報からの取得が難しい場合は ip_source を web にして ip_url で指定した URL から IPv6 アドレスを取得させる。

`/etc/init.d/ddns restart` で設定の変更を反映できる。
動作確認は `logread | grep ddns` か /var/log/ddns/ に出力されたファイルを見る。

DS-Lite と IPIPv6 の同時接続設定

/etc/config/network にルーティングルールを追加する。

 # /etc/config/network

 config interface 'wan_dslite'
 	option proto 'dslite'
 	option peeraddr 'dgw.xpass.jp'
 	option tunlink 'wan6'
 	option encaplimit 'ignore'
 	option mtu '1460'
-	option disabled '1'
+	option metric '10'

 config interface 'wan_ipip6'
 	option proto 'ipip6'
 	option peeraddr 'aaaa:bbbb:cccc:dddd::eeee'  # <en_dst>
 	option ip4ifaddr '203.0.113.1'  # <en_ipv4>
 	option tunlink 'wan6'
 	option encaplimit 'ignore'
 	option mtu '1460'
+	option metric '20'
+	option ip4table '120'

+config rule 'to_lan'
+	option dest '192.168.1.0/24'
+	option lookup 'main'
+	option priority '29000'
+
+config rule 'from_lan_3263_to_ipip6'
+	option src '192.168.1.32/27'
+	option lookup '120'
+	option priority '30000'

このようにすると 192.168.1.32 ~ 192.168.1.63 は wan_ipip6 通信で、それ以外は優先となっている wan_dslite 通信となる。
pbr パッケージも使ってみたが、DS-Lite と IPIPv6 通信はゲートウェイが 0.0.0.0 に設定されるせいか pbr にリンクダウン状態と判定されてルーティングが有効にならなかった。

ファイアーウォールなどのセキュリティについては詳細に設定していないが OpenWRT のデフォルトでも基本的な防御は行われる。ただし万全とは言えないので利用環境に合わせた詰めが必要となる。

参考ページ・支援モデル

OFUSEで応援を送る