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でインターネットと繋がる筈。
だけど、ルーター以外では何もできない。

続く