「v6プラス」固定IPサービスを ひかり電話契約あり でNVR510から利用する

# 前書き

YAMAHAの[NVR510](https://network.yamaha.com/products/routers/nvr510/)を導入したのを機に[小型ONU](https://business.ntt-east.co.jp/service/onu/)化やIPoEでのIPv6接続に変更したが、NVR510を再起動するとIPv4接続でしか外部に出られなくなる現象が…。
半年くらい放置していたが思わず再起動するとIPv4以外で通信できなくなるので、重い腰を上げて色々試したところ解消できたのでまとめておく。

# 環境

- NVR510(Rev.15.01.14)
- JPNEが提供する[「v6プラス」固定IPサービス](https://www.jpne.co.jp/service/v6plus-static/)
- 光回線はNTT東日本のフレッツ光
- ひかり電話の契約あり

# config

YAMAHAの[IPIPトンネリング 設定例8：IPv4 over IPv6トンネル接続 日本ネットワークイネイブラー株式会社 (以下JPNE) v6プラス (固定IP)](http://www.rtpro.yamaha.co.jp/RT/docs/ipip/index.html#setting8)にある「ひかり電話を契約している場合：DHCPv6-PD」設定を元にONU向けに変更します。

【上記ページのひかり電話を契約している場合：DHCPv6-PD】(2019/5/16時点)

```
【経路設定】
 ip route default gateway tunnel 1
 ipv6 route default gateway dhcp lan2

【LAN設定】
 ip lan1 address 192.168.100.1/24

【NGNとの接続設定】
 ipv6 lan2 address dhcp-prefix@lan2::(インターフェイスID)/64
 ipv6 lan2 dhcp service client
 ngn type lan2 ntt

【BRに対するIPIPの設定】
 tunnel select 1
  tunnel encapsulation ipip
  tunnel endpoint address (BRのIPv6アドレス)
  ip tunnel nat descriptor 1
  ip tunnel tcp mss limit auto
  tunnel enable 1

【NAT設定】
 nat descriptor type 1 masquerade
 nat descriptor address outer 1 (固定IPv4アドレス)

【DHCPの設定】
 dhcp service server
 dhcp server rfc2131 compliant except remain-silent
 dhcp scope 1 192.168.100.2-192.168.100.191/24

【DNSの設定】
 dns host lan1
 dns service fallback on
 dns server dhcp lan2
 dns server select 500000 dhcp lan2 any .
 dns private address spoof on

【IPv6アドレスの通知設定】
 ipv6 lan2 prefix change log on
 lan linkup send-wait-time lan2 5
 schedule at 1 startup * lua (通知用Luaスクリプトファイル名)
```

これを元に、ONU向けに設定

```conf
# IPv4のデフォルト経路を「tunnel 1」にする
ip route default gateway tunnel 1
# IPv6のデフォルト経路を「ONU1に与えられるデフォルトゲートウェイ」を使う
ipv6 route default gateway dhcp onu1
# ONU1がDHCPv6で取得した /56 のプレフィックスをひかり電話と分割し /64 のプレフィックスを ID:1 で用意する
ipv6 prefix 1 dhcp-prefix@onu1::/64
# LAN1インターフェイスのIPv4アドレスを 192.0.2.1 としネットマスクを /24 とする
ip lan1 address 192.0.2.1/24
# LAN1の代理ARPをONにする
ip lan1 proxyarp on
# ONU1がDHCPv6で取得した /64 のプレフィックスに ::1 を付け足してIPv6アドレスを作りLAN1に割当てる
ipv6 lan1 address dhcp-prefix@onu1::1/64
# ルータ広告の送信制御。LAN1に対して "ipv6 prefix 1" で設定したプレフィックスを送信する。
# またオプション情報をホストに自動取得させる(o_flag)。
ipv6 lan1 rtadv send 1 o_flag=on
# LAN1においてDHCPv6をserverとして動作させる
ipv6 lan1 dhcp service server
# ONU1の説明を "JPNE" にする
description onu1 JPNE
# ONU1インターフェイスのリンクアップ後の送信制御時間を5秒にする(リンクアップ後 5秒後にパケットを送信しだす)
onu linkup send-wait-time onu1 5
# ONU1インターフェイスはDHCPクライアントとしてIPを取得する(IPv4)
ip onu1 address dhcp
# ONU1インターフェイスはDHCPクライアントとしてIPを取得する(IPv6)
ipv6 onu1 address dhcp
# ONU1がDHCPv6で取得した /64 のプレフィックスに インターフェイスID を付け足してIPv6アドレスを作りONU1に割当てる
ipv6 onu1 address dhcp-prefix@onu1::(インターフェイスID)/64
# ONU1のIPv6プレフィックスに変化があった場合ログに記録する(LUAスクリプト用)
ipv6 onu1 prefix change log on
# ONU1のDHCPv6はclientとして動作させる
ipv6 onu1 dhcp service client
# NGN網に接続するインターフェイスをONU1とする
ngn type onu1 ntt
# tunnel 1の設定
tunnel select 1
  # トンネルの説明
  description tunnel "V6PLUS Fix-IP"
  # IPv6 over IPv6トンネル
  tunnel encapsulation ipip
  # トンネルインターフェイス端点のIPアドレス。BRのIPv6アドレスを指定する。
  tunnel endpoint address (BRのIPv6アドレス)
  # NATディスクリプターの1を適用する
  ip tunnel nat descriptor 1
  # TCPセッションのMSS制限をautoにする
  ip tunnel tcp mss limit auto
  # tunnel 1を有効にする
  tunnel enable 1
# NATディスクリプター 1をマスカレードタイプにする
nat descriptor type 1 masquerade
# NATディスクリプター 1の外側IPを 203.0.113.1(例示用IPなので編集必要) にする
nat descriptor address outer 1 203.0.113.1
# 外側から受信したパケットを破棄し何も返さない(0～1023/tcpは破棄してRSTを返す)
nat descriptor masquerade incoming 1 reject
# DHCPをサーバとして機能させる
dhcp service server
# DHCPのRFC2131対応動作としてremain-silent(リース情報を持たないクライアントからの DHCPREQUEST を無視する)以外
# がRFC2131対応機能とする
dhcp server rfc2131 compliant except remain-silent
# DHCPスコープ1のIP範囲
dhcp scope 1 192.0.2.2-192.0.2.254/24
# リンクダウンした場合に情報を解放する
dhcp client release linkdown on
# DNSサーバへアクセスできるホストをLAN1インターフェイスとする
dns host lan1
# DNSフォールバック機能を利用する
dns service fallback on
# DNSサーバアドレスを取得するインターフェイスとしてONU1を設定する
dns server dhcp onu1
# 500000番目のテーブルとしてONU1のDNSを利用する。
# 全て(any)のレコードタイプで、全てのドメイン(.)にマッチする(番号順にテーブルは適用される)
dns server select 500000 dhcp onu1 any .
# プライベートアドレスに対する処理を行なう
dns private address spoof on
# ルータ自身のFQDN
dns private name setup.netvolante.jp
# 起動時(startup)にLuaスクリプトを実行する
schedule at 1 startup * lua /lua-scripts/jpne-v6plus.lua
# ナンバー・ディスプレイをTEL1ポートに対して有効にする
analog arrive number display 1 on
# TEL1ポートに対して analog sip call myname で設定されているアドレスに対する着信のみ許可
analog sip arrive permit 1 myname
# TEL1ポートの自己SIPユーザー名(000000000 は実際の電話番号にする)
analog sip call myname 1 sip:000000000
# 疑似機能としてINSキャッチホン機能使用
analog supplementary-service pseudo call-waiting
# SIP発行の場合のプレフィックス
analog extension dial prefix sip prefix="9#"
# TEL1ポートはNGN網のONU1インターフェイスから発呼する
analog extension dial prefix port=1 ngn onu1
# SIPによるVoIP機能を利用する
sip use on
# ONU1インターフェイスで利用するVoIPの音声コーデックをg711u(G.711 μ-law)とする
sip codec permit onu1 g711u
```

**<font color="red" style="font-size: smaller;">このconfigは記事投稿向けにIPアドレスなどを変更しています。
実際に稼働しているconfigファイルはこの設定以外も追加しています。
このconfigを参考にする場合などは自己責任にてお願いいたします。</font>**

configの中で出てくる、192.0.2.0/24 や 203.0.113.1 は例示用のIPです。

| IP           | 用途                                                                                              |
| ------------ | ------------------------------------------------------------------------------------------------- |
| 192.0.2.0/24 | 例示用ローカルIP。<br>実際に設定する際は 192.168.0.0/24 や 192.168.0.1 などに置換える必要がある。 |
| 203.0.113.1  | 例示用グローバルIP。<br>実際に設定する際はプロバイダから通知されているIPv4に置換える必要がある。  |
| 2001:db8:0124:1200::/64 | 例示用IPv6プレフィックス。 |

また、```(インターフェイスID)```や```(BRのIPv6アドレス)```は、契約時に通知されたものを利用します。

NVR510に設定を適用すると、うまく接続できたように見えるのですが [IPv6 test - IPv6/4 connectivity and speed test](https://ipv6-test.com/)でIPv4/6のアクセス状況をチェックすると、IPv4しか反応しない状態になっています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85034/d2a5d5af-5d02-c73e-8369-e22f50d64741.png" alt="ipv6-test" width="50%">



# 調査

IPv4で外部とは通信できているのにIPv6では通信ができないという不思議な状況になっている。
この状態で、以下のコマンドを実行し、LAN1に設定しているIPv6アドレスを再設定すると、通信できるようになったりする。

```
no ipv6 lan1 address dhcp-prefix@onu1::1/64
ipv6 lan1 address dhcp-prefix@onu1::1/64
```

WebGUIのTECHINFOを取得して色々見ていると以下のような出力がある。

```
# show ipv6 route
Destination              Gateway                  Interface  Type
default                  fe80::aabb:ccdd:eeff     ONU1(DHCP) static
2001:db8:0124:1200::/56  -                        ONU1       implicit
2001:db8:0124:1200::/64  -                        ONU1       implicit
```

宛先が「2001:db8:0124:1200::/64」の場合がONU1になっている。

```no ipv6 lan1 address```と```ipv6 lan1 address ...```コマンドを実行してから、ルーティングを確認すると「2001:db8:0124:1200::/64」はLAN1になる。

```
# no ipv6 lan1 address dhcp-prefix@onu1::1/64
# ipv6 lan1 address dhcp-prefix@onu1::1/64

# show ipv6 route
Destination              Gateway                  Interface  Type
default                  fe80::aabb:ccdd:eeff     ONU1(DHCP) static
2001:db8:0124:1200::/56  -                        ONU1       implicit
2001:db8:0124:1200::/64  -                        LAN1       implicit
```

差分としてはこんな感じ

```diff
  # show ipv6 route
  Destination              Gateway                  Interface  Type
  default                  fe80::aabb:ccdd:eeff     ONU1(DHCP) static
  2001:db8:0124:1200::/56  -                        ONU1       implicit
- 2001:db8:0124:1200::/64  -                        ONU1       implicit
+ 2001:db8:0124:1200::/64  -                        LAN1       implicit
```

暗黙(implicit)のルーティングとして 2001:db8:0124:1200::/64 宛てのパケットが LAN1 インターフェイスになりパケットが届くようになる。

# どの設定があやしいか

起動時点で↓この設定が暗黙的に追加されている。

|Destination            |Gateway|Interface|Type    |
|-----------------------|:-----:|:-------:|--------|
|2001:db8:0124:1200::/64|-      |ONU1     |implicit|

これが追加される理由がありそう。
configで /64 を指定しているのは以下、

(1) これは、ただ宣言しているだけ

```conf
# ONU1がDHCPv6で取得した /56 のプレフィックスをひかり電話と分割し /64 のプレフィックスを ID:1 で用意する
ipv6 prefix 1 dhcp-prefix@onu1::/64
```

(2) これは、LAN1インターフェイスのIPv6アドレスの決定に関与している。

```conf
# ONU1がDHCPv6で取得した /64 のプレフィックスに ::1 を付け足してIPv6アドレスを作りLAN1に割当てる
ipv6 lan1 address dhcp-prefix@onu1::1/64
```

(3) これは、ONU1インターフェイスのIPv6アドレスの決定に関与している。

```conf
# ONU1がDHCPv6で取得した /64 のプレフィックスに インターフェイスID を付け足してIPv6アドレスを作りONU1に割当てる
ipv6 onu1 address dhcp-prefix@onu1::(インターフェイスID)/64
```

宣言しているだけの (1) は、そもそもどのインターフェイスに対しての設定なのかも明示しないので影響しなさそう。
(2)は、`no ipv6 lan1 address`と`ipv6 lan1 address ...`コマンドを実行するとIPv6で通信できるようになるから、この設定はOKそう。
(3)、**ひかり電話の場合、NGNから /56 のプレフィックスでIPv6アドレスが割当てられる**とすれば、ONU1に対して設定するIPv6なので /64 ではなく /56 なのではなかろうか？



# ONU1へのIPv6割当てを /64 から /56 にしてみる

```
no ipv6 onu1 address dhcp-prefix@onu1::(インターフェイスID)/64
ipv6 onu1 address dhcp-prefix@onu1::(インターフェイスID)/56
```

とコマンドを実行してからNVR510を再起動。

```
# show ipv6 route
Destination              Gateway                  Interface  Type
default                  fe80::aabb:ccdd:eeff     ONU1(DHCP) static
2001:db8:0124:1200::/56  -                        ONU1       implicit
2001:db8:0124:1200::/64  -                        LAN1       implicit
```

「2001:db8:0124:1200::/64」のインターフェイスが「LAN1」になってる。

[ipv6-test.com](https://ipv6-test.com/) でチェック。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85034/927bdf10-f55b-0d81-8e5c-87f747b0ec60.png" alt="ipv6-test" width="50%">

IPv4、IPv6ともに通信できたっ。

# 結論

ひかり電話契約**あり**の場合、ONU1に設定するIPv6アドレスは /56 プレフィックスにする。

# 最終的な config

**<font color="red" style="font-size: smaller;">このconfigは記事投稿向けにIPアドレスなどを変更しています。
実際に稼働しているconfigファイルはこの設定以外も追加しています。
このconfigを参考にする場合などは自己責任にてお願いいたします。</font>**

```conf
# IPv4のデフォルト経路を「tunnel 1」にする
ip route default gateway tunnel 1
# IPv6のデフォルト経路を「ONU1に与えられるデフォルトゲートウェイ」を使う
ipv6 route default gateway dhcp onu1
# ONU1がDHCPv6で取得した /56 のプレフィックスをひかり電話と分割し /64 のプレフィックスを ID:1 で用意する
ipv6 prefix 1 dhcp-prefix@onu1::/64
# LAN1インターフェイスのIPv4アドレスを 192.0.2.1 としネットマスクを /24 とする
ip lan1 address 192.0.2.1/24
# LAN1の代理ARPをONにする
ip lan1 proxyarp on
# ONU1がDHCPv6で取得した /64 のプレフィックスに ::1 を付け足してIPv6アドレスを作りLAN1に割当てる
ipv6 lan1 address dhcp-prefix@onu1::1/64
# ルータ広告の送信制御。LAN1に対して "ipv6 prefix 1" で設定したプレフィックスを送信する。
# またオプション情報をホストに自動取得させる(o_flag)。
ipv6 lan1 rtadv send 1 o_flag=on
# LAN1においてDHCPv6をserverとして動作させる
ipv6 lan1 dhcp service server
# ONU1の説明を "JPNE" にする
description onu1 JPNE
# ONU1インターフェイスのリンクアップ後の送信制御時間を5秒にする(リンクアップ後 5秒後にパケットを送信しだす)
onu linkup send-wait-time onu1 5
# ONU1インターフェイスはDHCPクライアントとしてIPを取得する(IPv4)
ip onu1 address dhcp
# ONU1インターフェイスはDHCPクライアントとしてIPを取得する(IPv6)
ipv6 onu1 address dhcp
# ONU1がDHCPv6で取得した /56 のプレフィックスに インターフェイスID を付け足してIPv6アドレスを作りONU1に割当てる
ipv6 onu1 address dhcp-prefix@onu1::(インターフェイスID)/56
# ONU1のIPv6プレフィックスに変化があった場合ログに記録する(LUAスクリプト用)
ipv6 onu1 prefix change log on
# ONU1のDHCPv6はclientとして動作させる
ipv6 onu1 dhcp service client
# NGN網に接続するインターフェイスをONU1とする
ngn type onu1 ntt
# tunnel 1の設定
tunnel select 1
  # トンネルの説明
  description tunnel "V6PLUS Fix-IP"
  # IPv6 over IPv6トンネル
  tunnel encapsulation ipip
  # トンネルインターフェイス端点のIPアドレス。BRのIPv6アドレスを指定する。
  tunnel endpoint address (BRのIPv6アドレス)
  # NATディスクリプターの1を適用する
  ip tunnel nat descriptor 1
  # TCPセッションのMSS制限をautoにする
  ip tunnel tcp mss limit auto
  # tunnel 1を有効にする
  tunnel enable 1
# NATディスクリプター 1をマスカレードタイプにする
nat descriptor type 1 masquerade
# NATディスクリプター 1の外側IPを 203.0.113.1(例示用IPなので編集必要) にする
nat descriptor address outer 1 203.0.113.1
# 外側から受信したパケットを破棄し何も返さない(0～1023/tcpは破棄してRSTを返す)
nat descriptor masquerade incoming 1 reject
# DHCPをサーバとして機能させる
dhcp service server
# DHCPのRFC2131対応動作としてremain-silent(リース情報を持たないクライアントからの DHCPREQUEST を無視する)以外
# がRFC2131対応機能とする
dhcp server rfc2131 compliant except remain-silent
# DHCPスコープ1のIP範囲
dhcp scope 1 192.0.2.2-192.0.2.254/24
# リンクダウンした場合に情報を解放する
dhcp client release linkdown on
# DNSサーバへアクセスできるホストをLAN1インターフェイスとする
dns host lan1
# DNSフォールバック機能を利用する
dns service fallback on
# DNSサーバアドレスを取得するインターフェイスとしてONU1を設定する
dns server dhcp onu1
# 500000番目のテーブルとしてONU1のDNSを利用する。
# 全て(any)のレコードタイプで、全てのドメイン(.)にマッチする(番号順にテーブルは適用される)
dns server select 500000 dhcp onu1 any .
# プライベートアドレスに対する処理を行なう
dns private address spoof on
# ルータ自身のFQDN
dns private name setup.netvolante.jp
# 起動時(startup)にLuaスクリプトを実行する
schedule at 1 startup * lua /lua-scripts/jpne-v6plus.lua
# ナンバー・ディスプレイをTEL1ポートに対して有効にする
analog arrive number display 1 on
# TEL1ポートに対して analog sip call myname で設定されているアドレスに対する着信のみ許可
analog sip arrive permit 1 myname
# TEL1ポートの自己SIPユーザー名(000000000 は実際の電話番号にする)
analog sip call myname 1 sip:000000000
# 疑似機能としてINSキャッチホン機能使用
analog supplementary-service pseudo call-waiting
# SIP発行の場合のプレフィックス
analog extension dial prefix sip prefix="9#"
# TEL1ポートはNGN網のONU1インターフェイスから発呼する
analog extension dial prefix port=1 ngn onu1
# SIPによるVoIP機能を利用する
sip use on
# ONU1インターフェイスで利用するVoIPの音声コーデックをg711u(G.711 μ-law)とする
sip codec permit onu1 g711u
```

# あとがき

そもそも勘違い設定とかあれば、ご指摘ください m(_ _)m