記事一覧に戻る

OpenWrtで10Gルーターを自作してみた

OpenWrt

今年から自宅の回線を光クロスへ移行したのでWAN LAN両方10G対応のルーターを買おうとしてたのですが、あまりにも高いので自作することにしました。

基本的にこちらの記事の通りに進めましたが、一部openwrtのバージョンや環境の違いがあったので手順を変えています。

用意したもの

Lenovo ThinkCentre M720q

ヤフオクでi5-8600Tとメモリ4GBが載ったものを購入

Intel Optane Memory 16GB

ストレージとして使用します。今や誰も存在を覚えていないであろうOptaneですが、SSDが高騰している昨今でも1000円程度で買える唯一のnvmeです。16GBあればOpenWrt動かすには十分ですからね。

image

Intel X520-DA2

10G対応のSFP+ NICです。アリエクで購入

ライザーカード

M720qのpcieスロットは独自規格のためライザーカードが必要になります。こちらもアリエクで購入 このライザーカードはいくつか世代があり、01AJ940が一番最新のものになります。

SFP+ to RJ45モジュール

SFP+のNICを使うならONUとルーター間の接続で1個は必要になります。

Broadcom BCM84891のチップが載った80Mのモジュールは比較的発熱しないらしいのでこちらを購入。

SFP DACケーブル

アリエクで購入。光ケーブルは取り回しがしんどそうなので銅にしました

実際にかかった費用は以下の通りです。アリエクのセールやクーポンを駆使したあとの金額ですのでご了承ください

機材金額
M720q Core i5-8600T 4GB11,000円
Optane Memory 16GB558円
Intel X520-DA22,740円
ライザーカード800円
Lenovo 65W ACアダプター1,199円
SFP+モジュール4,473円
SFP DACケーブルx21,631円
合計22,403円

OpenWrtのインストール

OpenWrtにはインストーラーなるものがありません

m.2スロットが余ってるpcかUSBの変換を使ってイメージを書き込む必要があります

M720qへ取り付けてOpenWrtを起動する

作成したIntel OptaneをM720qへ戻し、Intel X520-DA2もPCIeライザー経由で取り付けます。

OpenWrtが起動したら、最初にrootパスワードを設定

passwd

NICの割り当てを確認

ip -br link

M720qにはオンボードの1GbE NICが1ポートあり、X520-DA2を追加すると合計3ポートになります。

私の場合はこのように割り当てました

  • eth0(オンボード 1GbE): LAN
  • eth1(X520-DA2 ポート1): WAN
  • eth2(X520-DA2 ポート2): 10GbE LAN

LANブリッジの設定

オンボード1GbEの eth0 とX520-DA2の eth2 を同じLANとして使用します。

LuCIの画面で Network → Interfaces → Devices → br-lan → Configure を開き、Bridge ports に eth0 と eth2 を追加します。

これでオンボード1GbEと10GbEポートの両方がLANになります。

WAN6の設定

X520-DA2の eth1 をONUへ接続します。

LuCIで Network → Interfaces → Add new interface を開き、WAN6を作成します。

項目設定値
Namewan6
ProtocolDHCPv6 client
Deviceeth1
Request IPv6-addresstry
Request IPv6-prefix of lengthAutomatic

BIGLOBE 光クロスではIPv4通信もMAP-Eを利用するため、IPv4側で通常のDHCP WANを取得する構成にはしていません。

LAN側へIPv6を配布する

LuCIで Network → Interfaces → LAN → Edit → DHCP Server → IPv6 Settings を開きます。

項目設定
RA-ServiceServer mode
DHCPv6-ServiceServer mode
NDP-ProxyDisabled

正常にWAN6が接続されると、LuCIのインターフェース画面にIPv6-PDが表示されます。

image

IPv6-PDを取得できない場合

OpenWrt 25.12系では、DHCPv6クライアントの既定DUIDとしてDUID-UUID type 4が使用されます。一方、フレッツ光クロスでは端末側のDUIDとしてDUID-LLまたはDUID-LLTが要求されているため、既定設定のままではDHCPv6-PDを取得できない場合があります。

私の環境ではWAN6のClient IDをDUID-LLへ変更することでIPv6-PDを取得できました。

まずWAN側NICのMACアドレスを確認します。

cat /sys/class/net/eth1/address

例えばMACアドレスが aa:bb:cc:dd:ee:ff の場合、Ethernet用DUID-LLは次のようになります。

00030001aabbccddeeff

内訳:

  • 0003 : DUID-LL
  • 0001 : Ethernet
  • aabbccddeeff : NICのMACアドレス

WAN6へClient IDを設定して再接続します

uci set network.wan6.clientid='00030001aabbccddeeff'
uci commit network
ifdown wan6 && ifup wan6

MAP-Eの設定

詳しいことはこちらの記事を見た方が早いと思います

パッケージの導入

apk update
apk add map

MAP-Eのパラメータを取得

MAP-Eの設定値は、回線側から取得したIPv6プレフィックスによって変わります。

LuCIの Network → Interfaces からWAN6に割り当てられたIPv6-PDを確認し、こちらの計算ツールへ入力

設定

LuCIの画面で Network → Interfaces → Add new interface を開きます。

  • Protocol: MAP / LW4over6
    • Name: map
    • General Settings: 算出した各パラメータを入力
    • Advanced Settings:
      • Tunnel Link: wan6
      • Use legacy MAP: 有効
    • Firewall Settings: wan ゾーンを選択

再起動後、LuCIでMAP-EインターフェースがUpになっていれば設定完了です。

MAP-Eにおけるポート枯渇問題の対策

OpenWrtのMAP-Eの実装では、割り当てられたポート群のうち先頭の16ポートしか利用されず、IPv4のセッションが枯渇する問題が発生していたため、nftablesの numgen を利用して、割り当てられた全240ポートへ均等にセッションを分散させます。

OpenWrt本体に含まれる /lib/netifd/proto/map.shを直接書き換える方式が主流らしいですが、Attended Sysupgradeや owut で map.sh が上書きされるとのことでしたので、こちらで実装されていたhotplug方式を採用しました。

nft list table inet mape を実行して、numgen inc mod 240 を使ったSNATルールが適用されていることを確認できれば完了です。

IPv4とIPv6の接続を確認

でテストし、すべてOKになれば完了です

(おまけ)AdGuard Homeのインストール

パッケージをインストールしたら、自動起動を有効にして起動させます

apk add adguardhome
service adguardhome enable
service adguardhome start

dnsmasqを54番ポートへ移動する

dnsmasqが53番ポートを使用しているので、54に移動させてAdGuard HomeをメインDNSとして53番で待受させます。

uci set dhcp.@dnsmasq[0].port='54'
uci set dhcp.@dnsmasq[0].domain='lan'
uci set dhcp.@dnsmasq[0].local='/lan/'
uci set dhcp.@dnsmasq[0].expandhosts='1'
uci set dhcp.@dnsmasq[0].cachesize='0'
uci set dhcp.@dnsmasq[0].noresolv='1'
uci -q delete dhcp.@dnsmasq[0].server
uci commit dhcp
service dnsmasq restart

初回セットアップ

次のように設定しました

項目設定
管理画面のListen interface192.168.0.1
管理画面のPort8080
DNSのListen interfaceAll interfaces
DNSのPort53

LAN内クライアントへのDNS通知設定

LAN内の機器が自動的にAdGuard Homeを経由して名前解決を行うように設定します。

  1. IPv4クライアント向けの設定:
    • LuCIで Network → Interfaces → LAN → Edit → DHCP Server → Advanced Settings を開く
    • DHCP-Options に 6,192.168.0.1 を追記して保存・適用
  2. IPv6クライアント向けの設定:
    • LuCIで Network → Interfaces → LAN → Edit → DHCP Server → IPv6 Settings を開く
    • 「ローカル IPv6 DNS サーバー」を有効
    • 「Announce IPv4/6 DNS servers」の項目は空欄にしておきます(Cloudflareなどの外部DNSを直接端末へ通知すると、AdGuard Homeを迂回されてしまうためです)。

ローカルホスト名の解決連携

インターネット向けのDNS問い合わせはAdGuard Homeが処理し、LAN内機器のホスト名解決(.lan)は54番ポートへ退避させたdnsmasqへ転送するように設定します。

  1. AdGuard Homeの管理画面(http://192.168.0.1:8080)を開きます。
  2. 設定 → DNS設定 を開きます。
  3. アップストリームDNSサーバー に以下の行を追加します:
    [/lan/]127.0.0.1:54
  4. プライベート逆引きDNSサーバー に以下を設定します:
    127.0.0.1:54

これでLAN内のホスト名もAdGuard Home経由で正常に名前解決できるようになります。

パフォーマンスと運用の確認

Flow Offloadingの有効化

LuCIで Network → Firewall → Routing/NAT Offloading を開き、Software flow offloading および Hardware flow offloading を有効にします

uci show firewall.@defaults[0] および nft list flowtable inet fw4 ft を実行して、設定が反映されていることを確認します。

SFP+モジュールの温度の監視

発熱しやすい10GBASE-T SFP+モジュールの動作温度を監視します。

apk add ethtool-full
ethtool -m eth1 | grep temperature
Module temperature                        : 59.31 degrees C / 138.76 degrees F
Module temperature high alarm             : Off
Module temperature low alarm              : Off
Module temperature high warning           : Off
Module temperature low warning            : Off
Module temperature high alarm threshold   : 80.00 degrees C / 176.00 degrees F
Module temperature low alarm threshold    : -10.00 degrees C / 14.00 degrees F
Module temperature high warning threshold : 75.00 degrees C / 167.00 degrees F
Module temperature low warning threshold  : -5.00 degrees C / 23.00 degrees F

59度でした。思ったより熱いな…?

エアフローの改善

エアフローを改善するためMakerWorldで公開されていた全面メッシュのフタを印刷してみました。

これで多少はマシになるといいですが、NICを直接冷やすようにファンを追加した方が早いかもです。

image

スピードテスト

最後に速度を計っておきます。 測定環境はM4 Macbook Pro とRTL8159 10G NICです

マンションタイプの10Gの割にはかなり早くて大満足です。

image

参考文献