Edgerouter XでIPv6 IPoE + IPv4 over IPv6 (transix) と IPv4 PPPoEを併用する

目次

環境

大学の学生宿舎にて有料で提供されているインターネット接続サービスであるDoCanvasが、IPv6 IPoE と IPv4 over IPv6 に対応するようになるとのニュースがあったためEdgerouter Xで設定を行う。

また、オプションでグローバルIPアドレスサービスにも加入しているため、PPPoEのユーザ情報が手元にあり、今まで使っていた。

しかし、DoCanvasのPPPoEは通信速度が遅いのはまぁ許せるのですが、時々PPPoEのセッションが切れしばらく再接続されないみたいな状況が続いていた。 そのときにIPv6サービスの提供の話があり、これはやってみるしかないとなった。

また、自宅鯖を外部に公開するためにPPPoEは残しておいてPBR(Policy-Based Routing)により使い分ける。

前提

共用部で光終端装置とルータがあり、グローバルIPアドレスサービスを契約していない人でも各部屋までは来ているLANポートに指せば使えるようになっているため、もちろんDoCanvasには光電話のサービスはない。 そのため、共用部のルータから /64 のIPv6プレフィクスがRAにより配布されている。

また、配布されたIPv6プレフィックスを調べてみるとInternet Multifeedの物だったので transix のサービスが使えると思われる。

また、EdgerouterではRAをLAN側にも通知するためのNDProxy機能が標準では搭載されていないため、自前でビルドする必要がある。

説明に用いている表記は、

# (configureモード)
$ (通常モード)

となっていて、configureモードから通常モードに移行した際はcommit; save; exitをしている物とする。

PPPoEとDSLite(transix)によるIPv4環境

PPPoEの設定

まずは普通にPPPoEの設定をする

# set interfaces ethernet eth0 pppoe 0 default-route none
# set interfaces ethernet eth0 pppoe 0 description PPPoE
# set interfaces ethernet eth0 pppoe 0 mtu 1452
# set interfaces ethernet eth0 pppoe 0 name-server auto
# set interfaces ethernet eth0 pppoe 0 password ${PPPoE_PASS}
# set interfaces ethernet eth0 pppoe 0 user-id ${PPPoE_USER}

ここで重要なのがdefault-route noneとすること こうしないとPPPoEによる通信が優先されてしまう

NATの設定もする

# set service nat rule 5010 description 'masquerade for WAN(PPPoE)'
# set service nat rule 5010 outbound-interface pppoe0
# set service nat rule 5010 type masquerade

IPv6のプレフィックスを調べる

プレフィックスを調べるためautoconfによりアドレスの自動設定を行う。

# set interfaces ethernet eth0 ipv6 address autoconf
# set interfaces ethernet eth0 ipv6 dup-addr-detect-transmits 1
$ ip -6 address show dev eth0
4: eth0@itf0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 24XX:XXXX:XXXX:XXXX:xxxx:xxxx:xxxx:xxxx/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::aaaa:bbbb:cccc/64 scope link
       valid_lft forever preferred_lft forever

eth0にリンクローカルアドレス(fe80::%)ではなく24XXから始まるグローバルアドレスが割り当てられたら、アドレスの上位64bit(24XX:XXXX:XXXX:XXXX)をメモしておく。

$ ip -6 neigh show dev eth0
fe80::feed lladdr 00:60:b9:aa:bb:cc router REACHABLE

また、対岸のルータのリンクローカルアドレス(fe80::feed)もメモしておく。

IPv6アドレスを静的設定する

EdgeOSではipip6トンネルを作成する際のローカルアドレスは手動設定であるため、先ほど割り当てられたプレフィックスから好きなtokenを設定する。

また、このアドレスを設定するのはLAN側のインターフェイスであるswitch0であることに注意する。

今回はIPv4アドレスに合わせて、::100:1というtokenを使用する。

# delete interfaces ethernet eth0 ipv6
# set interfaces switch switch0 address 172.16.100.1/24
# set interfaces switch switch0 address '24XX:XXXX:XXXX:XXXX::100:1/64'

IPv6のdefault routeを設定する

このままではswitch0は外部と繋がっていなく、通信できないためeth0を経由して先ほど調べた対岸のルータのリンクローカルアドレスをネクストホップとして設定する。

# set protocols static route6 '::/0' next-hop 'fe80::feed' interface eth0

DSLiteの設定

# set interfaces ipv6-tunnel v6tun0 description DSLite
# set interfaces ipv6-tunnel v6tun0 encapsulation ipip6
# set interfaces ipv6-tunnel v6tun0 local-ip '24XX:XXXX:XXXX:XXXX::100:1'
# set interfaces ipv6-tunnel v6tun0 mtu 1452
# set interfaces ipv6-tunnel v6tun0 multicast disable
# set interfaces ipv6-tunnel v6tun0 remote-ip '2404:8e01::feed:100'
# set interfaces ipv6-tunnel v6tun0 ttl 64

local-ipには先ほど設定したswitch0の静的アドレスを設定する。

remote-ipにはtransixのAFTRのアドレスを設定する。

  • NTT西日本エリア

    • 2404:8e01::feed:100
    • 2404:8e01::feed:101
  • NTT東日本エリア

    • 2404:8e00::feed:100
    • 2404:8e00::feed:101

ここで、v6tun0に対するNATの設定を行うと通信が不安定になるため行わない

ルーティングテーブルの設定

PBR(Policy-Based Routing)により、送信元IPアドレスによりどちらを経由して通信を行うかを設定するために、ルーティングテーブルを設定する。

# set protocols static table 1 interface-route 0.0.0.0/0 next-hop-interface pppoe0
# set protocols static table 2 interface-route 0.0.0.0/0 next-hop-interface v6tun0

Policy-Based Routingの設定

Policy-Based Routingはfirewallのmodifyで設定する。

IPアドレスが172.16.100.1-172.16.100.10の範囲をサーバセグメントとして、PPPoEによる通信を行い、 それ以外の172.16.100.11-172.16.100.254ではDSLiteによる通信を行うように設定する。

# set firewall modify LAN_PBR rule 10 action modify
# set firewall modify LAN_PBR rule 10 description 'LAN to WAN(PPPoE)'
# set firewall modify LAN_PBR rule 10 destination address '!172.16.100.0/24'
# set firewall modify LAN_PBR rule 10 modify table 1
# set firewall modify LAN_PBR rule 10 source address 172.16.100.1-172.16.100.10

# set firewall modify LAN_PBR rule 20 action modify
# set firewall modify LAN_PBR rule 20 description 'LAN to WAN(DSLite)'
# set firewall modify LAN_PBR rule 20 destination address '!172.16.100.0/24'
# set firewall modify LAN_PBR rule 20 modify table 2
# set firewall modify LAN_PBR rule 20 source address 172.16.100.11-172.16.100.254
# set interfaces switch switch0 firewall in modify LAN_PBR

switch0インターフェイスにこのルールを適応する。

これでIPアドレスにより、DSLiteとPPPoEによる通信を併用することが出来る。

NDProxyによるIPv6環境

LANにRAを配布する

# set interfaces switch switch0 ipv6 dup-addr-detect-transmits 1
# set interfaces switch switch0 ipv6 router-advert cur-hop-limit 64
# set interfaces switch switch0 ipv6 router-advert link-mtu 1500
# set interfaces switch switch0 ipv6 router-advert managed-flag false
# set interfaces switch switch0 ipv6 router-advert max-interval 600
# set interfaces switch switch0 ipv6 router-advert other-config-flag true
# set interfaces switch switch0 ipv6 router-advert prefix '::/64' autonomous-flag true
# set interfaces switch switch0 ipv6 router-advert prefix '::/64' on-link-flag true
# set interfaces switch switch0 ipv6 router-advert prefix '::/64' valid-lifetime 2592000
# set interfaces switch switch0 ipv6 router-advert reachable-time 0
# set interfaces switch switch0 ipv6 router-advert retrans-timer 0
# set interfaces switch switch0 ipv6 router-advert send-advert true

これにより、クライアントにIPv6アドレスが割り当てられる

NDProxyのクロスコンパイル

github.com

この実装を用いる

ローカルのコンピュータでDockerを用いてクロスコンパイルを行う

EdgeRouter Xはmipselで、EdgeRouter Lite 3はmipsであるため、それぞれの環境にあったコンパイラをインストールする

FROM debian:stretch

RUN apt-get update -y
RUN apt-get install -y g++-mipsel-linux-gnu g++-mips-linux-gnu make file

CMD ["/bin/bash"]
$ sudo docker buld -t mips .

ndppdをcloneする

$ git clone https://github.com/DanielAdolfsson/ndppd.git
$ cd ndppd

以下のように mipsel.Makefileを作成する

CXX      = /usr/bin/mipsel-linux-gnu-g++
CXXFLAGS = -O2 -s
LDFLAGS  = -s

ビルドする

(Local)$ sudo docker run --rm -it -v `pwd`:/ndppd mips
(docker)#  cd /ndppd
(docker)#  make -f mipsel.Makefile -f Makefile
(docker)#  file ndppd
ndppd: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, interpreter /lib/ld.so.1, BuildID[sha1]=a2a060155ad0e5b70791ea5c06526695126abba7, for GNU/Linux 3.2.0, stripped
(docker)#  exit
(Local)$ scp ndppd er-x:

カレントディレクトリにndppdが生成されるのでscp等でEdgerouterに持って行く

NDProxyの設定

先ほど持ってきたndppd/config/user-data/ndppdに移動させる

$ sudo mv ndppd /config/user-data/ndppd

/config以下に配置することでファームウェアの更新の際も残る

それぞれ以下のようにファイルを作成する。

/config/user-data/ndppd.conf

proxy eth0 {
  router no
  timeout 500
  autowire yes
  keepalive yes
  retries 3
  ttl 30000
  rule ::/0 {
    iface switch0
  }
}

proxy switch0 {
  router yes
  timeout 500
  autowire yes
  keepalive yes
  retries 3
  ttl 30000
  rule ::/0 {
    auto
  }
}

/config/user-data/ndppd.service

[Unit]
Description=ndp_proxy_daemon
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/sbin/ndppd -d -p /run/ndppd.pid
Type=forking
PIDFile=/run/ndppd.pid

[Install]
WantedBy=multi-user.target

/config/user-data/setup_ndppd.sh

#!/bin/sh

ln -s /config/user-data/ndppd /usr/sbin/ndppd
ln -s /config/user-data/ndppd.conf /etc/ndppd.conf
ln -s /config/user-data/ndppd.service /etc/systemd/system/ndppd.service

systemctl daemon-reload
systemctl start ndppd.service
systemctl enable ndppd.service

セットアップを行う。

$ sudo /bin/sh /config/user-data/setup_ndppd.sh

/config/user-data/setup_ndppd.shはファームウェアの更新などによって消えてしまった際に実行することでセットアップを行うことが出来る。

再起動を行い、クライアントからもIPv6によるアクセスが出来ることを確認する。

$ reboot

f:id:akashisn:20210329193109p:plain

f:id:akashisn:20210329193113p:plain

この通りかなりの改善をすることが出来た。

ファイアウォールの設定

このままでは危ないのでファイアウォールの設定行う

set firewall ipv6-name WANv6_IN default-action drop
set firewall ipv6-name WANv6_IN description 'WANv6 to LAN'
set firewall ipv6-name WANv6_IN enable-default-log
set firewall ipv6-name WANv6_IN rule 10 action accept
set firewall ipv6-name WANv6_IN rule 10 description 'Allow established/related'
set firewall ipv6-name WANv6_IN rule 10 state established enable
set firewall ipv6-name WANv6_IN rule 10 state related enable
set firewall ipv6-name WANv6_IN rule 20 action accept
set firewall ipv6-name WANv6_IN rule 20 description 'Allow IPv6 ICMP'
set firewall ipv6-name WANv6_IN rule 20 protocol ipv6-icmp
set firewall ipv6-name WANv6_IN rule 30 action drop
set firewall ipv6-name WANv6_IN rule 30 description 'Drop invalid state'
set firewall ipv6-name WANv6_IN rule 30 state invalid enable
set firewall ipv6-name WANv6_LOCAL default-action drop
set firewall ipv6-name WANv6_LOCAL description 'WANv6 to Router'
set firewall ipv6-name WANv6_LOCAL enable-default-log
set firewall ipv6-name WANv6_LOCAL rule 10 action accept
set firewall ipv6-name WANv6_LOCAL rule 10 description 'Allow established/related'
set firewall ipv6-name WANv6_LOCAL rule 10 state established enable
set firewall ipv6-name WANv6_LOCAL rule 10 state related enable
set firewall ipv6-name WANv6_LOCAL rule 20 action accept
set firewall ipv6-name WANv6_LOCAL rule 20 description 'Allow IPv6 ICMP'
set firewall ipv6-name WANv6_LOCAL rule 20 protocol ipv6-icmp
set firewall ipv6-name WANv6_LOCAL rule 30 action accept
set firewall ipv6-name WANv6_LOCAL rule 30 description 'Allow DHCPv6'
set firewall ipv6-name WANv6_LOCAL rule 30 destination port 546
set firewall ipv6-name WANv6_LOCAL rule 30 protocol udp
set firewall ipv6-name WANv6_LOCAL rule 40 action accept
set firewall ipv6-name WANv6_LOCAL rule 40 description 'Allow DSLite'
set firewall ipv6-name WANv6_LOCAL rule 40 protocol ipip
set firewall ipv6-name WANv6_LOCAL rule 50 action drop
set firewall ipv6-name WANv6_LOCAL rule 50 description 'Drop invalid state'
set firewall ipv6-name WANv6_LOCAL rule 50 state invalid enable

set interfaces ethernet eth0 firewall in ipv6-name WANv6_IN
set interfaces ethernet eth0 firewall local ipv6-name WANv6_LOCAL

set firewall name DSLite_IN default-action drop
set firewall name DSLite_IN description 'WAN(DSLite) to LAN'
set firewall name DSLite_IN rule 10 action accept
set firewall name DSLite_IN rule 10 description 'Allow established/related'
set firewall name DSLite_IN rule 10 state established enable
set firewall name DSLite_IN rule 10 state related enable
set firewall name DSLite_IN rule 20 action drop
set firewall name DSLite_IN rule 20 description 'Drop invalid state'
set firewall name DSLite_IN rule 20 state invalid enable
set firewall name DSLite_LOCAL default-action drop
set firewall name DSLite_LOCAL description 'WAN(DSLite) to Router'
set firewall name DSLite_LOCAL rule 10 action accept
set firewall name DSLite_LOCAL rule 10 description 'Allow established/related'
set firewall name DSLite_LOCAL rule 10 state established enable
set firewall name DSLite_LOCAL rule 10 state related enable
set firewall name DSLite_LOCAL rule 20 action drop
set firewall name DSLite_LOCAL rule 20 description 'Drop invalid state'
set firewall name DSLite_LOCAL rule 20 state invalid enable

set interfaces ipv6-tunnel v6tun0 firewall in name DSLite_IN
set interfaces ipv6-tunnel v6tun0 firewall local name DSLite_LOCAL

set firewall name PPPoE_IN default-action drop
set firewall name PPPoE_IN description 'WAN(PPPoE) to LAN'
set firewall name PPPoE_IN rule 10 action accept
set firewall name PPPoE_IN rule 10 description 'Allow established/related'
set firewall name PPPoE_IN rule 10 state established enable
set firewall name PPPoE_IN rule 10 state related enable
set firewall name PPPoE_IN rule 20 action drop
set firewall name PPPoE_IN rule 20 description 'Drop invalid state'
set firewall name PPPoE_IN rule 20 state invalid enable
set firewall name PPPoE_LOCAL default-action drop
set firewall name PPPoE_LOCAL description 'WAN(PPPoE) to Router'
set firewall name PPPoE_LOCAL rule 10 action accept
set firewall name PPPoE_LOCAL rule 10 description 'Allow established/related'
set firewall name PPPoE_LOCAL rule 10 state established enable
set firewall name PPPoE_LOCAL rule 10 state related enable
set firewall name PPPoE_LOCAL rule 20 action accept
set firewall name PPPoE_LOCAL rule 20 description 'Allow ping'
set firewall name PPPoE_LOCAL rule 20 destination group address-group ADDRv4_pppoe0
set firewall name PPPoE_LOCAL rule 20 log disable
set firewall name PPPoE_LOCAL rule 20 protocol icmp
set firewall name PPPoE_LOCAL rule 30 action drop
set firewall name PPPoE_LOCAL rule 30 description 'Drop invalid state'
set firewall name PPPoE_LOCAL rule 30 state invalid enable

set interfaces ethernet eth0 pppoe 0 firewall in name PPPoE_IN
set interfaces ethernet eth0 pppoe 0 firewall local name PPPoE_LOCAL

set firewall options mss-clamp interface-type pppoe
set firewall options mss-clamp mss 1412