2022/03/09(水)OpenWrtでIPv6とDS-LiteとPPPoEを全部使う

OpenWrtを設定&構築したメモ。DS-LiteではなくMAP-Eでも参考になるかと思います。

※ネットワークの知識がない方はOpenWrtには手を出さないでください。

ことの発端

家庭内ルーターとして「NEC Atermシリーズ」を使っていたのですが、性能は申し分ないものの問題点があります。

  • 最新機種でもDS-Lite使用時PPPoEをパススルーできない*1
  • そのせいで、PPPoEとDS-Liteの併用ができない。*2
  • LAN内にDNSサーバを立てるとルータのDNSマスカレード機能が不安定になる。

WG1200HSはDS-Lite非対応なので、PPPoEと併用可能なら新しいのに買い替えてもよかったのですが、こんな状況ではAtermが選択肢に入らない。かといってBuffaloは安定性に問題ありそうなので、いっそのことOpenWrtルーターすればよいのでは? と。

*1 : DS-Lite以外ほぼすべての設定でパススルー可能であるのに、DS-Liteだけは絶対に許可しないという謎仕様を貫き通すNEC。

*2 : PPPoEをメインにしてLAN内のLinux等でDS-Liteを構築することは可能ですが、それは求めていない。

構築目標

openwrt-network.png

  • PPPoEとDS-Liteを併用する
  • LAN内の一部のマシンのみPPPoE側を使用する。

前提条件

  • ルーターのWAN側にはONU(光回線終端装置)が接続されている。
  • IPv6オプション(IPv6ネイティブ通信)が利用可能になっている。
  • DS-Lite(or MAP-E等)が使える状況になっている。
  • PPPoEが使える状況になっている(プロバイダ側で併用が許可されている)。

OpenWrtと対応機種

OpenWrtはLinuxで動作するフリーのルーターソフトウェアです。市販ルーター等のファームを入れ替えて使用することができます。

公式サイトの対応機種一覧を眺めてみると、TP-Linkあたりが価格も安く性能もそこそこでも入手性も良さそうです。今回はArcher A6を買ってみました(日本で発売されているものはA6 v3です)。

Device TechdataにCPU/Flash ROM/RAMが書かれていますので、対応ルーター選ぶ際は参考にすると良いです。

OpenWrtのインストール

ファームウェアダウンロードページから該当機種の「Install」用イメージをダウンロードし、ルーター(Stock ROM)のファームウェア更新画面からアップロードしてインストールします。

インストールに成功すると、192.168.1.1でルーターが起動しますので有線LANにPCを接続します(DHCPで自動取得するはず)。その後 http://192.168.1.1 にアクセスして、初期設定を行います。この辺の詳しい話は、検索すれば出てきますので、そちらを参考にしてください。

うまく行かない場合は、sshで192.168.1.1にアクセスし、root/passなしでログイン。下記コマンドを入力してください。

opkg update
opkg install luci

luci(Webインターフェイス)の日本語化には「luci-i18n-base-ja」パッケージをインストールしてください。

IPv6パススルーの設定

まずはこれを設定しないと始まりません。WAN6インターフェイスの設定を開き、DHCP設定→IPv6設定の各種項目をリレーモードに設定します。masterを忘れずにチェックしてください。

openwrt-wan6-dhcp.png

続いてLANインターフェイスの、同じくDHCP設定→IPv6設定を開きます。こちらもリレーモードに設定しますが、masterはチェックしません(できません)。

openwrt-lan-dhcp.png

設定の適用(もしくは再起動)をすれば、WAN6インターフェイスにIPv6アドレスが振られ、同じネットワークのアドレスのIPv6アドレスがLAN内にも振られるかと思います。

こうなればIPv6通信が可能になっているはずです。うまく行かない場合は、Firewallの設定を疑ってください。

解説

IPv6の経路情報は、RAやNDPといったICMPv6パケットでやり取りしています。これらの情報をリレーさせることで、ブリッジが実現するみたいです。

DS-Liteの設定

IPv6通信ができる状態になっていることを確認し、ds-liteモジュールをインストールします。opkgでも、Webの管理画面でもお好きな方法でインストールしてください。

既存のWANインターフェイス(DHCPv4)のプロトコルをDS-Liteに変更します。ファイアーウォールの手動設定をしたくなければインターフェイスを削除せず、必ず編集から変更してください。*3

  • AFTRアドレス: gw.transix.jp(IIJmioの場合)
    • プロバイダ指定のものを入力します。AFTRはIPoE(IPv4 over IPv6)トンネル通信の相手を示しています。IPv6アドレス直書きではなく、ホスト名が無難です。*4
  • 詳細設定: 「トンネルインターフェイスのMTU」に1460
    • MTU初期値が1280になっていますので、1460に設定します。
  • 詳細設定: 「ピアから通知されたDNSサーバーを使用」のチェックを外す
    • OpenWrtがDNSマスカレード(proxyみたいなもの)をしてくれているのですが、このDNSマスカレードの上位DNSとしてIPv6のものを使用したいからです*5。DS-Liteのものに上書きされたくないので、このチェックを外します。

LAN内からIPv4通信がうまくいけば成功です。うまく行かない場合は、Firewallの設定を疑ってください。

*3 : OpenWrtはファイアーウォール設定が本当に鬼門ですので注意してください。

*4 : transixのAFTRは2アドレスが公表されていますが、現時点でgw.transix.jpを引くと3アドレスに増えてます。

*5 : なぜならWAN側にLANケーブルさえ刺さっていれば使用可能と条件が緩く安定して(IPv4まわりの設定変更中も)使用可能だからです。

PPPoEとマルチルーティングの設定

PPPoE接続と条件によるルーティング振り分けを設定します。

ルーティングテーブルを増やす

OpenWrt(Linux)はルーティング時に参照するテーブルを複数持つことができます。テーブル情報ファイルにPPPoE用のルーティングテーブル情報を作成します。

/etc/iproute2/rt_tables ファイルを編集し、次の行を最後に追加します。

200	pppoe

Webインターフェイスからは編集できませんので、sshで接続しvi等で書き換えてください。

編集後、ルーターを再起動してください。

この作業を行いたくない場合は、以下の項目でルーティングテーブルを指定する際「prelocal (128)」を使用すれば問題なさそうです(未確認)。

pppoeインターフェイスを作成する

  • エイリアスではない(デバイス一覧にある)wanデバイスを指定します。
  • 詳細設定の「IPv4 ルーティングテーブルのオーバーライド」にpppoeテーブルを指定します。
  • 詳細設定の「ピアから通知されたDNSサーバーを使用」のチェックを外します。
  • ファイヤーウォールゾーンは既存の「wan」を指定してください。
    • pppoeゾーンを分ける方法はファイアウォールの項目で説明します。
  • DHCPタブで、DHCPサーバをセットアップしてから「このインターフェースを無視」をチェックします。DHCP→IPv6設定もすべて無効にします。
    • この作業をしないと、wan側(wan6)のDHCPv6が機能しなくなります。
  • 詳細設定の「IPv6アドレス取得」は無効にしないこと(自動のままにする)。
    • 無効に設定すると、wan6がIPv6アドレスを取得できなくなります。*6

「デフォルトゲートウェイを使用」はチェックしたままにしておきます。これらの設定より、PPPoEによる接続とそのルーティング情報は、ルーティングテーブル「pppoe」に記録されるようになります。

ルーティング設定

メニューの「ルーティング」→「IPv4ルール」に移動し、ルーティング条件を設定します。

LANのIPは 192.168.1.0/24 とします。

openwrt-ipv4-rule.png

画像では「192.168.1.1~62」の範囲のIPを持つ機器からの接続をPPPoE経由で接続するように設定しています。*7

ここまで設定できれば、指定範囲のIPを持つ機器からのインターネット接続はPPPoEを経由しているはずです。

接続が安定しない場合

サイトによって読み込みが不安定な場合、mssに原因があることがあります。ファイヤーウォール設定の「wan ⇒ REJECT」(Masqueradingにチェックがある)の編集を開き、「MSS clamping」をチェックします。

*6 : OpenWrtのハマりどころなのですが、エイリアスデバイスに対してIPv6無効化やIPv4/v6のみを迂闊に設定すると、同じ物理デバイスを使用する他のエイリアスに影響を与え動作しなくなることが多々あります。

*7 : LAN側を複数のネットワークやVLANに切り分けて、VLAN(インターフェイス)ごとに接続を分けるといったことも可能です。

ファイヤーウォールの設定

ゾーン設定

今回は以下のように設定しました。

openwrt-firewall-zone.png

ゾーン設定をいじっていると個別のTraffic Rules(個別ルール)が消失し、一時的にネットに繋がらなくなることがあります*8。ネットワーク知識のない方はゾーン設定をデフォルトのまま使用し、決して変更しないでください。

Linuxのiptablesと同じですが、INPUTはOpenWrt自体へのアクセスを意味しています。基本的にINPUTはdropしたいのですが、間違えてLAN側からのINPUTをDROPするとルーターにアクセスできなくなりますので、(ゾーンではなく)基本ルールのINPUTはacceptのままにておきましょう(死亡した場合は復旧モードを参照)。

  • 各ゾース詳細設定にある「Restrict to address family」は「IPv4 and IPv6」のままにしてください
    • 例えばDS-LiteはIPv4のみなので「IPv4」に、同様にwan6は「IPv6」に設定したくなりますが、これを設定すると同インターフェイスを共有する接続が死亡したりします。*9
  • 「PPPoE ⇒ REJECT」の設定にある「MSS clamping」はチェックを入れてください。
    • MTU/MSSを適切に設定し、各種のサーバと適切に通信するために必要です。

個別ルールの設定

デフォルトのままでも良いかと思いますが、自分で使用している最低限のルールを説明しておきます。

openwrt-firewall-rules.png

  • DNS: DNSを正しく動作させるためのルールです。IPv6のDNSだけ生かしているので、IPv6だけ通過させています。
  • DHCPv6: IPv6通信をするために必須です。
  • ICMPv6: IPv6では経路情報等をICMPパケットで交換するため、IPv6通信に必須です。*10

最後の行は、LAN内のサーバをIPv6で外部公開するための設定です。細かいセキュリティはサーバ自体のip6tables(ファイヤーウォール)で行っていますので、ルータでは単純にパケット転送だけしています。

また、IPsecを構築する場合は、さらに追加のルールが必要になります。

*8 : Traffic RulesにはDHCP/DNS/IPsecなどが通るように初期設定されていますが、これが消失するとゾーン設定によってはDNSなどが引けなくなりますし、IPv6アドレスの取得も失敗します……。

*9 : PPPoEの項目でも述べましたが、エイリアスインターフェイスにIPv4/IPv6に関する設定をすると問題が発生することが多いようです。ハマりどころなので注意してください。

*10 : OpenWrtの標準ルールでは、ICMPのパケットタイプを限定したものが設定されています。

フェイルセーフモードと強制復旧方法

OpenWrtには、設定ミスや何らかのバグ等で起動しなくなった場合の復旧方法が用意されています。

詳しくはFailsafe Mode, Factory Reset, and Recovery Mode翻訳)にありますが、以下簡単に説明します。

ファクトリーリセット

OpenWrtの全設定消去機能です。OpenWrtが正常起動している状態(LEDが点滅していない状態)で、リセットボタンを10秒押し続けます。

モジュールやカーネルの不具合等で、そもそも起動しない(起動が無限ループしている)場合、この方法は使用できません。

failsafeモードへ

起動時に適切なタイミングでリセットボタン押します。

モードLED点滅
フェイルセーフ待機中5回/秒
フェイルセーフモード10回/秒
通常起動2.5回/秒

フェイルセーフモードの待機中にリセットボタンを押すとフェイルセーフモードに入ります。*11

フェイルセーフモードでは、ルーターは 192.168.1.1 のIPで起動しますので、LAN 1ポートに有線接続して、ssh ID:root/PASSなしでルーターにログインし、次のコマンドを入力します。

firstboot -y && reboot

これですべての設定を消去して、ルーターを再起動できます(CUIから個別に設定を修正することも可能ですが、この方が楽かと思います)。

リカバリーモード

OpenWrtの機能ではなく、ルーターそのものが持つ復旧手段を用いて、ルーターのファームウェアを復旧する方法が、Rescue from failed firmware upgrade翻訳)にまとめられています。

TFTPを使うものが多いようです。

ここにある方法を使うと、OpenWrtから元のルーターファームに戻すといったことも可能になります。

*11 : リセットボタンを押しながら電源投入し、5回/秒点滅になったらもう一度ボタンを押してもファイルセーフモードに入れるようでした。

その他の設定

ルーティング/NATのオフロード設定

カーネルのルーティング負荷を減らす設定がファイヤーウォールの項目に存在します。Hardwareオフロードはデバイスによるかと思いますが、Archer A6(MediaTek MT7621)ではこの設定でパフォーマンスが倍ぐらい良くなるので、各自確認すると良いかと思います。

openwrt-nat-offloading.png

PPTP接続(VPN接続)のパススルー

このままでは、LAN内のPCからの外部のPPTPサーバへの接続がうまく行きません。DS-LiteやMAP-EはそもそもVPN接続ができませんが、PPPoEでも設定が必要です。

PPTPの場合、GREという特殊なパケット*12が通過できないのが原因です。「Port Forwards」で設定する方法もありますが、LAN側のIPを固定する必要が出てくるのでカーネルにモジュールを導入します。

  • パッケージ管理ツールから「kmod-nf-nathelper-extra」をインストール。
  • 「システム」→「スタートアップ」→「ローカルスタートアップ」のexitより前に次を追加。
    sysctl net.netfilter.nf_conntrack_helper=1
    sysctl net.netfilter.nf_conntrack_gre_timeout_stream=86400
    
    ※sysctl.confを書き換えても構いません。

サーバの外部公開

もしLAN内にサーバがありIPv4で外部公開したい場合は、ファイヤーウォールの「Port Forwards」の項目を設定します。

ゾーンごとの設定になりますので、意味のないDS-Lite側のポート転送を一緒に設定したくなければ、ゾーンを分離する必要があります。

*12 : TCPやUDPやICMP等と同じ分類でのGRE。IPプロトコル番号47番。

通信速度例

IIJmio + DS-Lite, OpenWrt on Archer A6(v3), check by iNoniusスピードテスト.

openwrt-speedtest-inonius.png

見ての通りPPPoEのほうが速いのですが、PPPoEはたまに極端な速度低下をするので、その点DS-Liteのほうが安定している印象です。

余談

元々、LAN側4ポートの中に1つ100Mbpsの機器があり、それがあるとLAN→ルーターへの転送(LAN内転送は問題ない)が100Mbpsで頭打ちになる問題がありました。

openwrt-speedtest-inonius_100Mbps.png

Archer A6のLAN側はスイッチではなく、イーサネットが4ポートある仕様になっています。この辺ドライバの仕様っぽい感じなので4ポートブリッジをやめ、「3ポートブリッジ」+「1ポート」とVLANを分けて対策しました。

※追記:OpenWrt 23.05.3に更新したところ、この謎症状は治ったようです。

まとめ

  • 安価で、非常に自由度の高いルーターを手に入れた。
  • OpenWrtの設定はWebインターフェイスだけで、ほぼ困らない。
  • OpenWrtは安定しているが、設定時の注意点(罠)が多い。

Linuxなので、ネットワークを柔軟に設定できるのがとても良いです。

メモ

ルール(ルーティングテーブルの参照)設定を確認する。

ip rule

特定のルーティングテーブルの中身を表示する。

ip route show table pppoe