FreeBSD mpd5でIPv6接続 (PPPoE) その2

前の記事の続き

接続状態の確認

% ifconfig -a
em0: flags=8843<up ,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=8209b<rxcsum ,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
    ether 00:1b:21:xx:xx:00
    inet6 fe80::xxxx:xxxx:xxxx:aaaa%em0 prefixlen 64 scopeid 0x1
    nd6 options=21<performnud ,AUTO_LINKLOCAL>
    media: Ethernet autoselect (1000baseT <full -duplex>)
    status: active
em1: flags=8843<up ,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1454
    options=8209b<rxcsum ,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
    ether 00:1b:21:??:??:01
    inet xxx.xxx.xxx.xxx netmask 0xfffffff8 broadcast xxx.xxx.xxx.xxx
    inet6 fe80::xxxx:xxxx:xxxx:bbbb%em1 prefixlen 64 scopeid 0x2
    inet6 240d:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:bbbb prefixlen 56
    nd6 options=23<performnud ,ACCEPT_RTADV,AUTO_LINKLOCAL>
    media: Ethernet autoselect (1000baseT <full -duplex>)
    status: active
lo0: flags=8049<up ,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
    options=600003<rxcsum ,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
    inet6 ::1 prefixlen 128 
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3
    inet 127.0.0.1 netmask 0xff000000
    nd6 options=21<performnud ,AUTO_LINKLOCAL>
ng0: flags=88d1<up ,POINTOPOINT,RUNNING,NOARP,SIMPLEX,MULTICAST> metric 0 mtu 1454
    inet xxx.xxx.xxx.xxx --> yyy.yyy.yyy.yyy netmask 0xffffffff
    inet6 fe80::xxxx:xxxx:xxxx:bbbb%ng0 prefixlen 64 scopeid 0x5
    nd6 options=21<performnud ,AUTO_LINKLOCAL>
ng1: flags=88d1<up ,POINTOPOINT,RUNNING,NOARP,SIMPLEX,MULTICAST> metric 0 mtu 1454
    inet6 fe80::xxxx:xxxx:xxxx:bbbb%ng1 prefixlen 64 scopeid 0x6
    nd6 options=21<performnud ,AUTO_LINKLOCAL>

ifconfig -aで見るとこんな感じ。
IPv6の見え方がちょっと変なんだよなぁ。LAN側のインターフェース(em1)にIPv6のアドレスが生えてそれがゲートウェイのIPv6アドレスみたいに見えるんだよね。でPPPoEのng1の方には対向ルーターのIPv6アドレスが表示されないから意味がわからんし接続できてるいのか出来ていないのかも解らない。LAN(em1)の方に240dで始まるipv6アドレスが生えてるからようやく接続できているのが解る。っていうか何でここに勝手に生えるの?RA?

サーバ用のISPでは割り当てられたIPv6アドレスはプレフィックス長64ビットだったけどSo-netは56ビットなのね。

と、いうことで、確認するときに大切なのはLAN用のNICの側にinet6 2***で始まるIPアドレスが生えてて最後にprefixlen 56とかprefixlen 64とかプレフィックス長が表示されていること。ここでプレフィクス長が正しく通知されていないということだとdhcp6cのpd周りの設定がおかしくてプレフィックスが移譲されてないと思われる。

So-netは上のようにプレフィックス長が56ビットになっているが、LANでは56ビットではなく64ビットにした方が何かと都合が良い(と思うよねたぶん)。そこで、dhcp6c.confで sla-len 0; に仮設定していたのを sla-len 8; でプレフィックス長に8ビット足して64ビットにする。
次回からのdhcp6cを実行でifconfigで見るとプレフィックス長の表示がprefixlen 64になる筈。(変わらないとおかしい)。
と、いうことで変更できるんだけど、ISPから割り当てられるプレフィックス長が変わることがあるかもなので注意。

mpd5のウェブ画面で確認

mpd5ではログ以外にウェブで接続状態の詳細を見ることができる。前の記事のmpd.confの設定ファイルのstartupにあるコメント付きの行から行頭の#を取ってmpd5を再起動すればウェブブラウザで接続状態を確認できる。上の例だとhttp://IPアドレス:8888/を開き、IDはadmin、パスワードはpasswordで表示できる。
ウェブでの表示はいろいろ試す時だけ有効にして運用フェーズに入ったら無効に戻す方が安全。

接続状態1
この例ではIPv4とIPv6の同時接続。左端のバンドル列がB1の行がIPv4、B2の行がIPv6。うちの環境では何故かIPv6アドレスはIP列に表示されない。青文字のリンクを開くと詳細。

接続状態2
各リンクそれぞれサマリでは表示されない詳細を表示できる。正直あまり役に立たないけど。

arpみたいなの(arpじゃないけど)を見たいならIPv6 neighbor discovery protocolで。

# ndp -a
Neighbor                       Linklayer Address  Netif Expire    S Flags
fe80::xxxx:xxxx:xxxx:xxxx%ng0  (incomplete)         ng0 permanent R 
fe80::yyyy:yyyy:yyyy:yyyy%ng1  (incomplete)         ng1 permanent R 
240d:xxxx:xxxx:xxxx::bbbb      uu:uu:uu:uu:uu:uu    em1 23h59m59s S 
240d:xxxx:xxxx:xxxx::aaaa      vv:vv:vv:vv:vv:vv    em1 permanent R 
fe80::yyyy:yyyy:yyyy:yyyy%em1  vv:vv:vv:vv:vv:vv    em1 permanent R 
fe80::xxxx:xxxx:xxxx:xxxx%em0  ww:ww:ww:ww:ww:ww    em0 permanent R

この例ではExpireに時間が入っている240d:xxxx:xxxx:xxxx::bbbbはLAN内の他のIPv6ホスト。
もちろん、ネットワーク参加済みのIPv6ホストしか表示されない筈なのでネットワークが出来ていないこの時点で他のホストがもう表示されているということは本来はない筈。

PINGを打ってみる。IPv6版のpingはping6。

# ping6 -c2 google.com
PING6(56=40+8+8 bytes) 240d:xxxx:xxxx:xxxx::aaaa --> 2404:6800:400a:806::200e
16 bytes from 2404:6800:400a:807::200e, icmp_seq=0 hlim=54 time=6.859 ms
16 bytes from 2404:6800:400a:807::200e, icmp_seq=1 hlim=54 time=6.770 ms

--- google.com ping6 statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 6.770/6.815/6.859/0.044 ms

もし、名前解決できないなら/etc/resolv.confにネームサーバを追加する。
というか、まだネームサーバを取得する部分は設定してないのでできない筈。
So-netは何故かIPv6用のネームサーバを公開してないので取り敢えず公開リゾルバを追加。So-netのネームサーバは後で取る。

1
2
3
4
nameserver 2001:4860:4860::8888  #google-public-dns-a.google.com
nameserver 2001:4860:4860::8844  #google-public-dns-b.google.com
nameserver 2620:0:ccc::2         #resolver1.ipv6-sandbox.opendns.com
nameserver 2620:0:ccd::2         #resolver2.ipv6-sandbox.opendns.com

/etc/resolv.confはファイルを上書き保存したらすぐに適用される。

続く

FreeBSD mpd5でIPv6接続 (PPPoE) その1

接続

「がとらぼ」の中の人が個人的に使っているインターネットの回線はNTTのFletsで、ISPはSo-net。
何でSo-netかっていうと、特にどうしても使いたいという積極的な理由はなかったが、契約当時の「工事費他諸々無料+キャッシュバック約7万円」というのがあったから。2年縛りなのでもうすぐ自由の身になれそうだが、変更しなければならない理由も特に無いので縛りが切れたらすぐに他所へというのは今のところ考えてない。

で、2016年の目標の一つだったサーバのIPv6化(IPv4+IPv6)が全然手付かずだったのを、いよいよ年末が迫ってきて慌ててやり始めたのだが、サーバ側に変更を加えたところで、それが本当に正しく機能していることを確認するIPv6環境が無かった。

そこで、サーバのIPv6化ついでにプラベート利用のSo-netの回線の方もIPv6化させることに。ただし、当面はIPv4とIPv6を切り替えて使うつもり。

サーバ用の回線の側はISPからIPv6トンネルを使う際の簡単な情報が提供されていたのだが、So-netは2016年12月現在でIPv6については「PPPoEで使えますよ」と「PPPoEの接続ID (パスワードはIPv4と同じ)」の2つの情報しか提供していない。基本的にはIPv6トンネル対応のホームゲートウェイを使うかIPv6トンネル対応アダプタを買って使えということらしい。
つまり、ONUのみの人やIPv6トンネル非対応のホームゲートウェイを使ってる人はIPv6は使わないか金を払ってどうにかしろということらしい。IPv6を使わせようという気あるの?それともPPPoEのIPv6は本命じゃないからIPoEが使えるようになるまでもう暫く待てってこと?

「がとらぼ」の中の人はホームゲートウェイが好きじゃないので単品のONUを使っている。そして、ルーター(PPPoE)はFreeBSDのPCにやらせている。よって、IPv6のPPPoEもPCルーターにさせることになるのだが、もうちょっと情報ないと心配じゃんよ。

FreeBSDでトンネル掘り(PPPoE)はMulti link PPP daemonのmpd5(net/mpd5)を使用している。 今回はこれまで使っていたIPv4のPPPoEとIPv6のPPPoEを同じNICにさせてデュアルスタックで利用、または切り替えてどちらか1本だけの利用も可ということにする。
PPPoEが2本ということは同時利用のセッションが2つということなので既にISPを複数同時に使っている、VPNでも使っている等ということであれば、家庭用のFletsの契約によってはセッションが足りなくなるかもしれないので要確認(基本でセッション2つ)。セッションは増やすこともできるがFletsの月額料金が増えるのと変更時に工事費を取られる。(月額料増加もそうだけど特に工事費はボッタクリ以外の何物でもないのでそろそろ止めようよ>NTT東西)。
IPv4とIPv6を切り替えて使うならセッション数の心配は不要。

mpd5の設定

/usr/local/etc/mpd5/mpd.conf
 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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
startup:
#   set user admin password admin
#   set web self 0.0.0.0 8888
#   set web open

default:
    load PPPoEv4	#切り替えて使うなら使わない方の行頭に#
    load PPPoEv6	#切り替えて使うなら使わない方の行頭に#

PPPoEv4:
    create bundle static B1
#   set iface up-script /usr/local/etc/mpd5/linkup4.sh
#   set iface down-script /usr/local/etc/mpd5/linkdown4.sh
    set iface route default
    set iface enable tcpmssfix
    set iface disable on-demand
    set iface idle 0
    set iface mtu 1454
    set ipcp ranges 0.0.0.0/0  0.0.0.0/0

    create link static L1 pppoe
    set auth authname abcd1234@v4.example.com #接続ID
    set auth password abcdefghij0123456789    #接続パスワード
    set pppoe iface em0                       #PPPoEをするNIC
    set pppoe service "IPv4"
    set link action bundle B1
    set link max-redial 0
    set link keep-alive 10 60
    set link mtu 1454
    set link mru 1454
    set link disable pap chap
    set link accept chap
    open

PPPoEv6:
    create bundle static B2
    set iface up-script /usr/local/etc/mpd5/linkup6.sh
    set iface down-script /usr/local/etc/mpd5/linkdown6.sh
    set iface enable tcpmssfix
    set iface mtu 1454
    set bundle no ipcp
    set bundle enable ipv6cp

    create link static L2 pppoe
    set auth authname abcd1234@v6.example.com #接続ID
    set auth password abcdefghij0123456789    #接続パスワード
    set pppoe iface em0                       #PPPoEをするNIC
    set pppoe service "IPv6"
    set link max-redial 0
    set link keep-alive 10 60
    set link mtu 1454
    set link mru 1454
    set link disable pap chap
    set link accept chap
    set link action bundle B2
    open

PPPoEでトンネルを作るNICは上の例ではem0(Intelの一部のNIC)、LAN側はem1(上では登場していない)を想定している。

B1とかB2っていうのはバンドルのラベルなので任意の文字列で良い筈だけど他の多くの例に合わせて書いている。
L1とかL2っていうのはリンク(Link)のラベルなので任意の文字列で良い筈だけど他の多くの例に合わせて書いている。
サービス名も同様。

トンネルの仮想NICは先に作成されるのがng0、後に作成されるのがng1になる。切り替えて使うなどトンネル1つならng0になる。

上の例ではIPv4の側にもリンクアップ時とリンクダウン時用にup-scriptとdown-scriptを指定している(コメントにしている)が、別に指定しているset iface route defaultでデフォルトルートの付け替えをしてくれる(筈な)ので、Flestsの普通のISPに普通に繋ぐなら特に何かするスクリプトは正直要らない。ファイアウォールのルールを付け替えるとかDHCPで何かする等ということであればスクリプトを使う。

/usr/local/etc/mpd5/linkup6.sh の例
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/bin/sh

[ -z "$1" ] && exit 1

route delete -inet6 default
route -6 add default -iface $1 -mtu 1454

sleep 3

/usr/local/sbin/dhcp6c -c /usr/local/etc/dhcp6c.conf $1
/usr/local/etc/mpd5/linkdown6.sh の例
1
2
3
4
5
6
#!/bin/sh

[ -z "$1" ] && exit 1

kill -9 `pgrep -f 'dhcp6c' `
route delete -inet6 default

PPPoEで接続出来た場合にそれまでのデフォルトルートを削除して新しく出来たインターフェース(ng*)にルートを付け替える。
dhcp6cを実行。
なお、変数 $1 が新しくできたインターフェース(ng*)のこと。上のmpd.confの例では切り替えて使うIPv6接続ならng0になるし、IPv4sとIPv6のデュアルスタックならng1が割り当てられる筈。つまり可変なのでng0などと決め打ちで書かない。

作成したスクリプトに実行権限を付ける。

# chmod +x /usr/local/etc/mpd5/*.sh

/etc/rc.confに以下を追記。

1
2
3
4
5
#IPv6
ipv6_gateway_enable="YES"
route6d_enable="YES"
ipv6_network_interfaces="lo0 em1"
ifconfig_em1_ipv6="inet6 accept_rtadv"

この部分は決め打ちで。 em1はLAN側のNIC

pkgまたはportsでnet/dhcp6をインストールする。

# cd /usr/ports/net/dhcp6
# make install clean
/usr/local/etc/dhcp6c.confを仮作成する。
1
2
3
4
5
6
7
8
9
interface ng1 {
    send ia-pd 0;
};
id-assoc pd {
    prefix-interface em0 {
        sla-len 0;
        sla-id 0;
    };
};

PPPoEを行うNICとしてem0を指定しているので実環境に合わせて変更する。
仮作成なのでトンネルデバイスとしてng1を直指定しているが必要に応じてng0などに変更する。

これで、mpd5を起動(再起動)するかFreeBSDを再起動すれば取り敢えずここまで設定を行ってきたルーターPCではIPv6でインターネットと繋がる筈。
だけど、ルーター以外では何もできない。

続く

Up