Raspberry PiでIPv6 PPPoE対応ルータを作る

Raspberry PiIPv6 PPPoE接続、パケット転送、LAN内へのRA送信を行い、IPv6ルータにしてみる。

環境

Raspberry Pi 3 (Raspbian Jessie Lite)

$ uname -a
Linux raspberrypi 4.1.19-v7+ #858 SMP Tue Mar 15 15:56:00 GMT 2016 armv7l GNU/Linux

$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)"
NAME="Raspbian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

背景

NTT東西の提供するフレッツ網および対応プロバイダでは、下の例のようにIPv6が使えるようになっている。

IPv6接続の方式にはPPPoE方式とIPoE方式があるが、PPPoE形式の場合、以下のようなIPv6 PPPoEトンネル対応ルータを用意する必要がある。

このような機器を利用する以外の方法としては、LinuxマシンでIPv6 PPPoE接続を行い、IPv6ルータとして設定することでもIPv6通信を行うことができる。 ここでは、次のような構成でIPv6通信できるようにすることを考える。

f:id:inaz2:20160419011047p:plain

なお、NGN IPv6網の代わりにプロバイダのIPv6網に接続するため、前者を用いるフレッツサービス情報サイトやひかり電話は使えなくなる。

必要なもの

ブロードバンドルータの設定

まず、ブロードバンドルータで次のような設定を行う。

  • PPPoEパススルー(PPPoEブリッジ)機能を有効にする
  • IPv6パススルー(IPv6ブリッジ)機能を無効にする
    • NGN IPv6から配られるRAを端末に転送しないようにするため

フレッツサービスにおけるPPPoEセッション数の上限は通常2となっている。 そこで、プロバイダのIPv4IPv6それぞれでPPPoE接続を使えるようにするために、「フレッツ・スクウェア」へのPPPoE接続を無効にしておく。

Raspbianの設定

まず、PPPoE接続を行うために有線LAN接続にしておく。

次に、/etc/sysctl.confに以下を追記する。

net.ipv6.conf.eth0.accept_ra = 0
net.ipv6.conf.all.forwarding = 1

accept_raはRA(Router Advertisement)を受け取らない設定、forwardingは自分宛でないパケットを転送する設定である。

ip6tablesの設定

インターネットからLAN内への接続を制限するために、ip6tablesでフィルタ設定を行う。

まず、iptables-persistentパッケージをインストールする。

$ sudo apt-get install iptables-persistent

次に、/etc/iptables/rules.v6を編集し、以下のようなフィルタ設定を追加する。

$ sudo vi /etc/iptables/rules.v6
# Generated by ip6tables-save v1.4.21 on Sun Apr 17 21:20:30 2016
*filter
:INPUT ACCEPT [0:0]
:INPUT-SERVICES -
-A INPUT -i lo -j ACCEPT
-A INPUT -p ipv6-icmp -j ACCEPT
-A INPUT -p udp --dport 546 --sport 547 -s fe80::/10 -d fe80::/10 -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -j INPUT-SERVICES
-A INPUT -j DROP
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
# Completed on Sun Apr 17 21:20:30 2016

UDP 547から546への通信を許可するルールは、DHCPv6でIPv6アドレスを取得するための設定である。

再起動し、設定したルールが有効になっていることを確認する。

$ sudo reboot
$ sudo ip6tables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all      anywhere             anywhere
ACCEPT     ipv6-icmp    anywhere             anywhere
ACCEPT     udp      fe80::/10            fe80::/10            udp spt:dhcpv6-server dpt:dhcpv6-client
ACCEPT     all      anywhere             anywhere             state RELATED,ESTABLISHED
INPUT-SERVICES  all      anywhere             anywhere
DROP       all      anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain INPUT-SERVICES (1 references)
target     prot opt source               destination

PPPoEの設定

次に、PPPoE接続の設定を行う。

まず、次のパッケージをインストールする。

$ sudo apt-get install pppoe pppoeconf

次のコマンドを実行し、必要なアカウントの設定を行う。 IPv6 PPPoEアカウントのユーザ名、パスワードについては、プロバイダの契約情報およびサービス仕様を参照。

$ sudo pppoeconf

新しく作られるppp0インターフェースがIPv6アドレスを持つように、/etc/ppp/peers/dsl-providerに次の行を追記する。

+ipv6
ipparam ipv6default

再起動した後、/var/log/syslogのpppdのログを確認しながら、しばらくの後ppp0インタフェースが追加されることを確認する。 また、ppp0インタフェースにIPv6リンクローカルアドレスが振られていることを確認する。

$ sudo reboot
$ tailf /var/log/syslog
$ ifconfig
ppp0      Link encap:Point-to-Point Protocol
          inet6 addr: fe80::8d3:caeb:c0ce:9856/10 Scope:Link

dhcpcdの設定

次に、DHCPクライアントデーモンの設定を行い、DHCPv6-PDIPv6アドレスを受け取れるようにする。

/etc/dhcpcd.confを開き、次の行を追記する。

noipv6rs

interface ppp0
  ipv6rs
  iaid 1
  ia_pd 1 eth0

デフォルトルートの設定

次に、ppp接続時にデフォルトルート設定を行うようにする。

/etc/ppp/ipv6-up.d/routingを新規作成し、以下の内容を記述する。

#!/bin/sh
if [ -z "${CONNECT_TIME}" ]; then
    if [ "${PPP_IPPARAM}" = "ipv6default" ]; then
        ip -6 route add default dev ${PPP_IFACE}
    fi
fi

ここで、作成したファイルのパーミッションを実行可能にしておく。

$ sudo chmod +x /etc/ppp/ipv6-up.d/routing

再起動した後、/var/log/syslogのpppdのログを確認しながら、しばらくの後eth0インタフェースにグローバルIPv6アドレスが振られることを確認する。 また、デフォルトルートがppp0インタフェースになっていることを確認する。

$ sudo reboot
$ tailf /var/log/syslog
$ ifconfig
eth0      Link encap:Ethernet  HWaddr b8:27:eb:06:b3:3e
          inet addr:192.168.0.2  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::ba27:ebff:fe06:b33e/64 Scope:Link
          inet6 addr: 2400:4030:XXXX:XXXX::1/64 Scope:Global

$ ip -6 route
default dev ppp0  metric 1024

ping6コマンドでIPv6接続できるか確認してみる。

$ ping6 -n -c 4 ipv6.google.com
PING ipv6.google.com(2404:6800:400a:806::200e) 56 data bytes
64 bytes from 2404:6800:400a:806::200e: icmp_seq=1 ttl=52 time=12.8 ms
64 bytes from 2404:6800:400a:806::200e: icmp_seq=2 ttl=52 time=12.7 ms
64 bytes from 2404:6800:400a:806::200e: icmp_seq=3 ttl=52 time=12.8 ms
64 bytes from 2404:6800:400a:806::200e: icmp_seq=4 ttl=52 time=12.8 ms

--- ipv6.google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 12.757/12.819/12.859/0.042 ms

接続できない場合は、NGN IPv6のアドレスがインターフェースに振られていないか、ルート設定に加えられていないか確認する。

radvdの設定

最後に、LAN内にIPv6アドレスを配るため、IPv6 Router Advertisement Daemon(radvd)を設定する。

まず、パッケージをインストールする。

$ sudo apt-get install radvd

次に、/etc/radvd.confを新規作成し、次の内容を記述する。

interface eth0 {
  AdvSendAdvert on;
  MinRtrAdvInterval 3;
  MaxRtrAdvInterval 10;
  prefix ::/64 {
    AdvOnLink on;
    AdvAutonomous on;
    AdvRouterAddr on;
  };
};

LAN内の適当な端末のインタフェース設定を確認し、グローバルIPv6アドレスが振られていることを確認する。 また、ルート設定を確認し、デフォルトゲートウェイRaspberry PiのリンクローカルIPv6アドレスになっていることを確認する。

>ipconfig
Wireless LAN adapter Wi-Fi:

   接続固有の DNS サフィックス . . . . .:
   IPv6 アドレス . . . . . . . . . . . .: 2400:4030:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX
2
   一時 IPv6 アドレス. . . . . . . . . .: 2400:4030:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX

   リンクローカル IPv6 アドレス. . . . .: fe80::d146:3b6e:5092:b8c2%4

>route PRINT -6
IPv6 ルート テーブル
===========================================================================
アクティブ ルート:
 If メトリック ネットワーク宛先      ゲートウェイ
  4    276 ::/0                     fe80::ba27:ebff:fe06:b33e

LAN内の端末からhttp://test-ipv6.com/を開いたときのスクリーンショットを次に示す。

f:id:inaz2:20160419030055p:plain

LAN内から正常にIPv6通信が行えていることが確認できる。

サーバの再起動等によりLAN内の端末から通信できなくなった際は、radvdを再起動するとよい。

$ sudo systemctl restart radvd.service

DNSサーバでのAAAAフィルタについて

IPv6IPv4が共存する環境では、まず最初にIPv6の接続が行われる。 ここでIPv6での通信に失敗する場合、IPv4での接続まで時間がかかってしまうため、プロバイダによってはDNSサーバでAAAAフィルタを行っていることがある(参考)。 AAAAフィルタは、IPv6用のDNSレコード(AAAAレコード)を返さないようにする仕組みである。

OCNの場合、IPv6が有効な環境向けにAAAAフィルタが行われていないDNSサーバが別途提供されている。

*3 現在「OCN 『フレッツ 光ネクスト』対応 IPv6インターネット接続」をWindowsXPまたはMac OSでご利用のお客さまは、6月6日以降、IPv6接続のご利用に際して機器の設定変更が必要になります。こちらのPDFファイルをクリックして手順をご確認ください。

必要に応じて、ブロードバンドルータにこのようなDNSサーバを手動で設定しておくとよい。 OCN以外のプロバイダについては、次が参考になる。

関連リンク