NURO 2GプランのONU(F660P)の有線LANで2Gbps出したい

こんばんは。tukapiyoです。

タイトルの通りなのですが、最近NURO 2Gプランを導入しました。
今回はこのNUROから貸与されるONU(F660P)で、有線LANポートで2Gbps出せるようにするために苦労した話です。

はじめに

改めてですが、最近NURO 2Gプランを契約しました。
本当はソニー系のISPなんて導入したくはなかったのですが、やむを得ずです。

で、NUROってやっぱりクソなんですが、何がクソか列挙しておきますね。

  • 貸与ONU(ルータ)利用が必須で、ブリッジモードにできない
  • MAP-E強制で、IPv4のポート数が割り当てがしょっぱい(240個セッションしか張れない)
    おそらくIPv6ではポート制限はないので、IPv6を主で利用していれば何とかやりくりできる?
  • IPsecは送信方向もフィルタリングされている、IPv6もフィルタリングされている
  • そして今回の問題点である、貸与ONUのLANポートが1000BASE-Tである

まぁこれでは可哀想なので良い点を挙げておくならば、ISPの性能の観点で、「うちの環境では今のところ2Gbps程度の速度がちゃんと出る」ということだけは言及しておきます。

F660P

さて、本題ですが、2Gbpsプランなのに貸与ONU(F660P)の有線ポートは1000BASE-Tです。
3ポートあるので複数機器をそれぞれのポートで使えば速度出るでしょ?ってことなんだろうと思います。

ところがどっこい、tukapiyoはそんなのでは満足できない。
1台の機器で2Gbps出させてくれよ!と。

今回は、「1台の機器で2Gbps出す」ことを目的に試行錯誤し、結果、無事実現できたのでメモしておきます。

検討

まず机上で検討してみると、F660Pは物理的に1000BASE-Tなわけですから、有線で2Gbps出すためには2ポート使う必要があります。
2ポートを良い感じに負荷分散できれば2Gbps出せそうですね。
当家ではゲートウェイルータにVyOSを採用していますので、こんな感じでVyOSとF660Pとの間を2本のケーブルで接続して、なんとかできないでしょうか。

2ポート繋ぐとしても負荷分散の方式はどうするかが問題です。
VyOSでやれることを考えると、こんなパターンが考えられます。

  • L2負荷分散(bonding)
  • WAN負荷分散(load-balancing)
  • NAT負荷分散(nat load-balance)
  • L3負荷分散(ECMP)

実はこれら全部試しました。
結論はECMPが正解なのですが、これも一筋縄には行かなかったのです…

試行錯誤

L2負荷分散(ダメパターン)

まずL2負荷分散ですが、これは2つのインターフェースをbondingしてL2の負荷分散を行います。
LACPを使うことが多いですが、LACPは対向側機器も対応している必要があり、F660Pのような機器が対応しているわけもありません。

VyOSではLACPを使用せずともさまざまな負荷分散方式を選択可能ですが、実際に設定すると1つのインターフェースで使用したときよりも大幅に速度が低下します。
これはおそらく、F660Pから見たときにMACフラップが発生して、MACアドレステーブルの更新が頻繁に発生するためと思われます。

VyOSでbondingを設定すると、2つのインターフェースでMACアドレスが同一になります。
同じMACアドレスで2つのポートから通信が来るわけですから、F660Pは混乱してしまいますね。

ということでこの方式はボツになりました。

WAN負荷分散(却下パターン)

VyOSにはload-balancing機能があり、WAN負荷分散をする機能があります。
これを使えばうまくやれそうだと思ったのですが、設定を進めていくうちに重大な問題が判明しました。
それは、IPv6に対応していない、という点です。

冒頭に書いたとおり、NUROにおいてIPv6は非常に重要です。
IPv4はポート数が絞られているためです。

ということでこの方式は却下されました。

NAT負荷分散(ダメ&却下パターン)

VyOSは二重ルータとなるので、IPv4ではNAPTしています。
ちなみにIPv6についても、当家ではNUROとは別に割り当てられているセグメントをLAN側で使用しているため、NAT66をしています。

VyOSのNAT(NAPT)機能にはload-balance機能があり、変換先IPアドレスを負荷分散することができます。
これを使ってVyOSからの送信元IPアドレスを2つにして、2つのインターフェースから別々に発出すればうまくやれそうです。

ところがこちらも問題が2つありました。
IPアドレスに応じて発出するインターフェースを指定できないIPv6(NAT66)ではload-balance機能が実装されていないのです。

前者を解消すべく色々試しましたが、NATはルーティングの後に処理されるためPBRも利用できず詰み。
インターフェースが指定できないと、2つのインターフェースから2つのIPアドレスがランダムに発出されてしまい、カオスな状況となりました。

後者はそもそも却下事由でした。

L3負荷分散(うまく行かなかったパターン)

最後にECMPです。
ECMPはEqual Cost Multi Path Routingのことで、複数の経路を等コストで設定することで経路を分散させることができる技術です。

これを使えば複数のインターフェースで経路を使い分けられるのではないか、そう思ったtukapiyoは甘かった。
結果的にいえばECMPだけではうまく行きませんでした。

問題はnext-hopが同じだということです。
F660Pは3ポートあるとはいっても、これはスイッチポートなので、IPアドレスは1つです。
つまりnext-hopが同じ2つの経路を設定することができず、計画は失敗に終わりました。

解決策

では、どのようにやれば良いのでしょうか。

結論、ECMPに加えてVRFを使うことで解決しました。
VRFを使えばnext-hopを変えて2つの経路が設定できるので、問題だったnext-hopが同じという点を克服できます。

実装イメージは以下の様な感じです。

実装イメージ、複雑でキモいですね。

VRFの設定

VRF1VRF2を作成し、VRF1にはeth2veth21/22を、VRF2にはeth3veth31/32を収容します。
veth21veth22は、GRT(Global Routing Table)とVRF1を繋ぐ役割を担います。
veth31veth32も同様です。

  • VRF1
    • eth2(192.168.1.2/24, bbbb::1/65)
    • veth21(172.30.2.1/30, a:b:c:d:e::2:1/126)
    • veth22(172.30.2.2/30, a:b:c:d:e::2:2/126)
  • VRF2
    • eth3(192.168.1.3/24, bbbb::8000:0:0:1/65)
    • veth31(172.30.3.1/30, a:b:c:d:e::3:1/126)
    • veth32(172.30.3.2/30, a:b:c:d:e::3:2/126)

コンフィグはこんな感じ。

set interface ethernet eth2 address '192.168.1.2/24'
set interface ethernet eth2 address 'bbbb::1/65'
set interface ethernet eth2 vrf 'VRF1'
set interface ethernet eth3 address '192.168.1.3/24'
set interface ethernet eth3 address 'bbbb::8000:0:0:1/65'
set interface ethernet eth3 vrf 'VRF2'

set interface virtual-ethernet veth21 address '172.30.2.1/30'
set interface virtual-ethernet veth21 address 'a:b:c:d:e::2:1/126'
set interface virtual-ethernet veth21 peer-name 'veth22'
set interface virtual-ethernet veth22 address '172.30.2.2/30'
set interface virtual-ethernet veth22 address 'a:b:c:d:e::2:2/126'
set interface virtual-ethernet veth22 peer-name 'veth21'
set interface virtual-ethernet veth22 vrf 'VRF1'

set interface virtual-ethernet veth31 address '172.30.3.1/30'
set interface virtual-ethernet veth31 address 'a:b:c:d:e::3:1/126'
set interface virtual-ethernet veth31 peer-name 'veth32'
set interface virtual-ethernet veth32 address '172.30.3.2/30'
set interface virtual-ethernet veth32 address 'a:b:c:d:e::3:2/126'
set interface virtual-ethernet veth32 peer-name 'veth31'
set interface virtual-ethernet veth32 vrf 'VRF2'

ルーティングの設定

VRF1VRF2は独立したルーティングテーブルを持つので、デフォルトルートが同じnext-hopだったとしても問題なく設定できます。
また、LAN側向けはそれぞれGRTに向くようにします。

GRTのデフォルトルートは、ECMPでVRF1VRF2に振り分けられるように設定します。
やりたかったことをやれてる実感がありますね。

コンフィグはこんな感じ。

set vrf name VRF1 protocols static route 0.0.0.0/0 next-hop 192.168.1.1 interface 'eth2'
set vrf name VRF1 protocols static route 192.168.0.0/16 next-hop 172.30.2.1
set vrf name VRF1 protocols static route6 ::/0 next-hop fe80::1 interface 'eth2'
set vrf name VRF1 protocols static route6 a:b:c:d::/56 next-hop a:b:c:d:e::2:1
set vrf name VRF1 table '100'

set vrf name VRF2 protocols static route 0.0.0.0/0 next-hop 192.168.0.1 interface 'eth3'
set vrf name VRF2 protocols static route 192.168.0.0/16 next-hop 172.30.3.1
set vrf name VRF2 protocols static route6 ::/0 next-hop fe80::1 interface 'eth3'
set vrf name VRF2 protocols static route6 a:b:c:d::/56 next-hop a:b:c:d:e::3:1
set vrf name VRF2 table '200'

set protocol static route 0.0.0.0/0 next-hop 172.30.2.2 distance '5'
set protocol static route 0.0.0.0/0 next-hop 172.30.2.2 interface 'veth21'
set protocol static route 0.0.0.0/0 next-hop 172.30.3.2 distance '5'
set protocol static route 0.0.0.0/0 next-hop 172.30.3.2 interface 'veth31'

set protocol static route6 ::/0 next-hop a:b:c:d:e::2:2 distance '5'
set protocol static route6 ::/0 next-hop a:b:c:d:e::2:2 interface 'veth21'
set protocol static route6 ::/0 next-hop a:b:c:d:e::3:2 distance '5'
set protocol static route6 ::/0 next-hop a:b:c:d:e::3:2 interface 'veth31'

NAPT/NAT66の設定

eth2eth3から出て行く際に、IPv4はNAPT、IPv6はNAT66をしてあげます。
IPv6はセグメントを2つに分けて、eth2から出て行くときには/64の前半(bbbb::/65)、eth3から出て行くときには/64の後半(bbbb::8000:0:0:0/65)を使うようにしています。

またNAT66の際はndp-proxyを設定しないと通信ができないので、忘れないようにしておきます。

コンフィグはこんな感じ。

set nat source rule 30 outbound-interface name 'eth2'
set nat source rule 30 translation address 'masquerade'
set nat source rule 31 outbound-interface name 'eth3'
set nat source rule 31 translation address 'masquerade'

set nat66 source rule 30 outbound-interface name 'eth2'
set nat66 source rule 30 translation address 'bbbb::/65'
set nat66 source rule 31 outbound-interface name 'eth3'
set nat66 source rule 31 translation address 'bbbb::8000:0:0:0/65'

set service ndp-proxy interface eth2 prefix bbbb::/65
set service ndp-proxy interface eth3 prefix bbbb::8000:0:0:0/65

結果

有線LANに接続した端末でfast.comでも2Gbpsを達成しました。

「1台の機器で2Gbps出す」という目的が達成できて満足です。

ちなみにこの実装をした結果、IPsecのサイト間VPNが張れないという問題も発生しました。
張れない理由はNUROのフィルタリングの話もあるのですが、VRFに収容されたインターフェースからは張れないというVyOSの制約(?)もありました。
これはこれで別途解消していますが、本記事の話題とは逸れてしまうので割愛します。

さて、逸般の誤家庭ではこれぐらいの設定は十分やれると思いますから、皆様も是非試してみてくださいね。

おすすめ

コメントを残す