メインルーターとバイパスルーター:まず通信経路を確認

OpenWrtでmihomoを動かすうえで重要なのは、バイナリをインストールすることだけではなく、対象の通信をmihomoに通すことです。mihomoはClash Metaの後継として使われているコアの名称です。コアはプロキシプロトコルやルール判定、接続処理を担い、OpenWrtはネットワークインターフェース、ルーティング、ファイアウォール、サービス管理を担います。設定ファイルの構文チェックに通っても、LAN内の端末の通信がmihomo経由になったとは限りません。

メインルーターは通常、インターネットへの出口、NAT、DHCPを担います。バイパスルーターはLAN内に設置する別の機器で、メインルーターは引き続き接続や上位ネットワークへの通信を担当します。この記事では、同一セグメントに接続したシングルポート構成を例にします。デュアルポートで直列に接続する場合は、実際のインターフェースに合わせて転送ゾーンを再設計してください。同一セグメント向けの設定をそのまま流用することはできません。

構成例と各機器の役割
項目メインルーター構成バイパスルーター構成
インターネットへの出口OpenWrtが上位ネットワークに直接接続既存のメインルーターを出口として利用
端末のデフォルトゲートウェイOpenWrtのLANアドレス通信を振り分ける端末でバイパスルーターを指定
DHCPサーバー通常はOpenWrtが提供引き続きメインルーターが提供可能
障害時の影響すべての端末に及ぶ可能性まずはテスト端末1台に限定可能
主な注意点出口側のファイアウォールとリソース負荷ゲートウェイ、戻り経路、DNSの整合性

同一セグメントでのアドレス例

  • メインルーター:192.168.10.1/24。インターネット接続とDHCPを担当します。
  • OpenWrtのバイパスルーター:192.168.10.2/24。デフォルトゲートウェイは 192.168.10.1 です。
  • テスト端末:192.168.10.100/24。デフォルトゲートウェイとDNSはいったんどちらも 192.168.10.2 に設定します。

アドレスは実際のLAN環境に合わせて変更してください。バイパスルーターには固定アドレスを設定するか、DHCPサーバーで固定リースを割り当て、動的アドレスプールとの重複を避けます。同じブロードキャストドメインで、連携せずに複数の機器からDHCP設定を配布しないでください。

導入前の確認:アーキテクチャ、ストレージ、ファームウェア

まずOpenWrtの「ステータス」→「概要」でファームウェア情報を確認し、SSHでCPUとシステム情報を調べます。製品名に「64ビットプロセッサ」と記載されていても、ファームウェアのアーキテクチャが分かるわけではありません。同じハードウェアでも、異なるビット幅のユーザーランドが動作する場合があります。

ubus call system board
uname -m
cat /etc/openwrt_release
df -h /overlay /tmp
free -m

x86_64は通常amd64ビルド、aarch64は通常arm64ビルドに対応します。32ビットARMでは命令セットも確認し、MIPSではエンディアンと浮動小数点ABIを区別してください。リリース資産の命名規則は変わることがあるため、mihomoのリリースノートを確認して選びます。ファイル名に「linux」とあるだけで利用可能と判断しないでください。

パッケージ管理とカーネルモジュール

  • opkgを使うファームウェアでは opkg print-architecture、apkを使うファームウェアでは apk --print-arch でパッケージのアーキテクチャを確認できます。2つのパッケージマネージャーのコマンドを混在させないでください。
  • TUN方式を使うには、ファームウェアがTUNに対応している必要があります。関連パッケージとしては kmod-tun が一般的です。TPROXY方式には、対応するファイアウォールとカーネルモジュールが必要です。
  • OpenWrt 22.03以降では通常、デフォルトのファイアウォールにfirewall4が使われ、内部ではnftablesが動作します。古い解説にあるiptablesのルールを、firewall4環境にそのままコピーしないでください。
  • カーネルモジュールは、現在動作しているファームウェアのカーネルに適合している必要があります。リポジトリが利用できない場合やバージョンが一致しない場合は、まずファームウェアとパッケージソースの不整合を解消してください。

コアを直接実行:設定テストと明示的プロキシから始める

一般的な導入方法は、OpenWrtのプラグインでコアを管理する方法と、mihomoを直接実行する方法の2つです。プラグインはサービススクリプト、ファイアウォール、DNS、サブスクリプション更新などをまとめて管理することが多く、直接実行する場合はそれぞれ個別に設定する必要があります。同じインスタンスはどちらか一方で管理し、プラグイン起動のコアと手動起動のプロセスが待ち受けポートを奪い合わないようにしてください。

以下では、アーキテクチャに合ったコアを解凍して /usr/bin/mihomo に配置し、完全な設定を /etc/mihomo/config.yaml に置いたものとします。これらはこの記事で使用するパスであり、すべてのプラグインのデフォルトパスではありません。サブスクリプションにノード一覧しか含まれていない場合は、プロキシグループやルールなどを含む設定一式を補う必要があります。

chmod 0755 /usr/bin/mihomo
/usr/bin/mihomo -v
/usr/bin/mihomo -t -d /etc/mihomo -f /etc/mihomo/config.yaml

-vはプログラムが実行できることと、実際のバージョンを確認するために使います。-tは設定ファイルのテストに使います。Exec format errorが出た場合は、まずアーキテクチャとファイルの解凍状態を確認してください。YAMLの解析エラーが出た場合は、インデント、フィールドの型、参照しているルールセットを修正します。ネットワーク設定を追加して先に進めないでください。

7890番ポートでプロキシ経路を確認

以下の設定例を、既存の完全な設定に追加してテストできます。この例では、バイパスルーターのLANアドレスだけで待ち受けます。他の端末から接続できるかどうかは、ファイアウォールの設定にも左右されます。allow-lanを有効にしても、このポートをインターネットに公開しないでください。

mixed-port: 7890
allow-lan: true
bind-address: 192.168.10.2
mode: rule
log-level: info

テストに通ったら、SSHのフォアグラウンドでコアを起動してエラーを確認します。この段階では、同じインスタンスを別途起動しないでください。

/usr/bin/mihomo -d /etc/mihomo -f /etc/mihomo/config.yaml

テスト用PCでHTTPプロキシを 192.168.10.2:7890 に設定するか、次のコマンドでHTTPSリクエストを送信します。成功すれば、明示的プロキシの入口からノード、接続先サイトまでの基本経路が利用できると分かります。UDPや透過プロキシが動作していることを示すものではありません。

curl -I --proxy http://192.168.10.2:7890 https://example.com/

フォアグラウンドでの確認後、procdのサービススクリプトに管理を移し、自動起動と異常終了時の再起動を設定します。サービスでは絶対パスを指定し、ログをシステムログに記録してください。SSH切断後に終了する可能性のある一時プロセスに依存しないでください。

透過プロキシの選択:REDIRECT、TPROXY、TUN

端末にプロキシを手動設定する方法では、その設定に従うアプリしか対象になりません。バイパスルーターで通常の転送通信も受けるには、透過プロキシの入口と適切なルーティングが必要です。以下の3方式は、自由に同時有効化できるスイッチではありません。特に、プラグインのルールと手動設定のルールで同じ通信を二重に捕捉しないようにしてください。

Linuxの透過プロキシ方式を比較
方式主な入口追加条件
REDIRECTredir-port: 7892。通常はTCP用NATリダイレクトルールが必要。UDPも捕捉できるとは限りません
TPROXYtproxy-port: 7893。TCPとUDPに対応可能透過ソケット、マーク、ポリシールーティングが必要
TUN仮想ネットワークインターフェースTUN対応、ルーティングと転送の権限、適切なファイアウォール処理が必要

TUN設定例の適用範囲

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53
    - tcp://any:53

この設定例はmihomoのTUN設定の方向性を示すもので、OpenWrtの透過プロキシを完全に構築するスクリプトではありません。auto-routeで関連ルートを設定できますが、あらゆるLAN構成で通信が通ることを保証するものではありません。LANからの転送通信がTUNに入るか、外向き接続がメインルーターに届くか、firewall4が必要な転送を許可しているかを確認してください。

複数の出口がある環境では、自動検出で意図しない出口が選ばれる場合があります。実際のルートを確認し、必要に応じてコアの設定ドキュメントを参照してインターフェースを指定してください。Linuxのauto-redirectはnftablesに関わる別のオプションです。利用可否や動作は実際に使用するmihomoのバージョンで確認し、新しいバージョンの設定例を古いコアにそのまま適用しないでください。

ゲートウェイとDNS:それぞれ個別に検証

デフォルトゲートウェイは通常の通信の次の転送先を決め、DNSはドメイン名の問い合わせ先を決めます。DNSだけ変更しても、通信がバイパスルーターを経由するとは限りません。ゲートウェイだけ変更した場合も、端末が以前のDNS設定やIPv6のDNS、アプリ独自の暗号化DNSを使い続けることがあります。

まず端末1台でゲートウェイを確認

  1. LuCIの「ネットワーク」→「インターフェース」→「LAN」→「編集」で、バイパスルーターのアドレスとサブネットマスクを確認します。ファームウェアによってタブ名が多少異なる場合があるため、実際の画面に従ってください。
  2. バイパスルーター自身のデフォルトルートが 192.168.10.1 を経由していることを確認します。ip route show default を実行して調べてください。
  3. テスト端末だけデフォルトゲートウェイを 192.168.10.2 に変更し、メインルーターからネットワーク全体へ配布するDHCP設定はまだ変更しないでください。
  4. 端末からバイパスルーターとメインルーターにアクセスできることを確認してから、外部サイトへの接続をテストします。ゲートウェイ変更後も、既存の接続は以前の経路を使い続ける場合があります。

DHCPで一括配布する場合、IPv4のオプション3はデフォルトゲートウェイ、オプション6はDNSサーバーです。変更後は端末にリースを更新させ、実際に取得した値を確認してください。同一セグメントのバイパスルーターでは、直接接続の戻り経路が非対称になったり、ICMPリダイレクトが発生したりする場合があります。パケットキャプチャを確認し、制御対象の転送通信に送信元NATが必要か判断してください。送信元NATを使うとメインルーターから見える送信元アドレスが変わります。「マスカレードを有効にする」ことを、すべての構成で必須の手順と考えないでください。

dnsmasqの53番ポートを維持する

切り分けやすい構成の一例は、dnsmasqがLANの 53 番ポートで待ち受け、mihomoのDNSが 127.0.0.1:1053 で待ち受けるようにし、dnsmasqからmihomoへ上流問い合わせを転送する方法です。以下の例は既存設定に追加して使います。指定した上流DNSに実際のネットワークから到達できることを確認してください。

dns:
  enable: true
  listen: 127.0.0.1:1053
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 223.5.5.5
    - 119.29.29.29

一般的なLuCIレイアウトのファームウェアでは、「ネットワーク」→「DHCP/DNS」→「一般設定」のDNS転送先に 127.0.0.1#1053 を指定します。ほかの上流DNSも読み込まれていないか確認し、意図した経路を迂回しないようにしてください。mihomoの上流がdnsmasqを指していると、DNSループが発生します。

Fake-IPが返す合成アドレスは、透過プロキシの経路で正しく処理される必要があります。明示的プロキシのテスト段階では、ネットワーク全体のDNSをこの方式に切り替えるのは避けてください。LAN内のドメイン名、プリンター、特定のアプリに互換性の問題がある場合は、実際のドメインに応じてフィルタリングするか、適切な名前解決モードを選びます。DNS設定をすべて削除するのは避けてください。

例にある上流DNSは通常のDNSで、待ち受けと転送の関係を示すものです。問い合わせが暗号化されることを意味しません。ブラウザーのセキュアDNS、アプリ内DoH、AndroidのプライベートDNSは、dns-hijackを設定しただけですべて自動的に捕捉されるわけではありません。

段階的に切り分ける:プロセスからIPv6まで

トラブルシューティング中は、ゲートウェイを変更していない管理用端末を1台残し、変更前の設定を記録しておきます。入口、ルーティング、名前解決、ルールの順に確認すると、ノードを何度も切り替えるより問題を特定しやすくなります。以下のコマンドは状態確認用であり、ファイアウォール設定の代わりにはなりません。

pgrep -af mihomo
logread -e mihomo
ip addr show
ip route show table all
ip rule show
nft list ruleset
nslookup example.com 192.168.10.2
よくある症状と最初に確認する項目
症状最初に確認する項目確認方法
コアが起動直後に終了する設定テスト、ポートの競合、ファイル権限起動ログに待ち受け失敗や設定エラーがないか
7890は使えるが、透過プロキシは使えない端末のゲートウェイ、転送経路、ポリシールーティング対象の通信が実際にバイパスルーターへ届いているか
外部IPには接続できるが、ドメイン名ではアクセスできない53番・1053番ポートの待ち受けと上流転送問い合わせがタイムアウトするか、名前解決ループが発生していないか
TCPは正常だが、ゲームやQUICに問題があるUDPの捕捉、ノードのプロトコル、サーバー側の対応状況TCPだけがリダイレクトされていないか
一部のアプリだけ元の出口を使い続けるIPv6のデフォルトルート、アプリ独自のプロキシやVPN端末に別の利用可能なネットワーク経路がないか

IPv6の経路はIPv4のゲートウェイ変更に連動しない

端末のIPv4ゲートウェイをバイパスルーターに設定しても、メインルーターからRAを受信し、IPv6のデフォルトルートを取得している場合があります。その場合、IPv6通信はメインルーターを直接経由する可能性があります。IPv4とIPv6のルート、DNS、ファイアウォールを個別に確認し、IPv6も完全に経由させるか、テスト環境で一時的にIPv6ルートの配布を停止するか判断してください。mihomoのIPv6関連オプションを無効にしても、端末にすでに設定されたルートは削除されません。

スループットは遅延だけで判断しない

バイパスルーターのCPU、暗号化プロトコル、LANポートの速度、仮想マシンのネットワークアダプターは、いずれもスループットに影響します。まず通常のLAN内転送をテストし、同じ接続先へのダウンロード速度を明示的プロキシと透過プロキシで比較してください。テスト時にはCPU使用率、通信経路、実際に選択されたノードを記録します。1回の遅延テストだけで帯域を判断しないでください。原因を調べる間はソフトウェアまたはハードウェアのフローオフロードを一時的に無効にすると、既存の高速転送経路によるルール検証への影響を抑えられます。

本番導入と切り戻し:対象範囲は一度に1つずつ拡大

  1. 基準設定を保存。OpenWrtのネットワーク、ファイアウォール、DHCP、mihomoの設定をバックアップし、メインルーターの元のゲートウェイとDNS配布方法を記録します。
  2. 明示的プロキシを確認。まずコア、サブスクリプション、プロキシグループ、ルールが正常に動作することを確かめてから、透過プロキシを設定します。
  3. 端末1台で確認。Webサイト、DNS、UDP、LAN機器へのアクセス、IPv6をそれぞれテストし、特定のサイトだけで判断しないでください。
  4. 再起動後の復旧を確認。インターフェースの準備完了後にサービスが起動すること、DNSが起動前のプロキシ経路に依存しないこと、ファイアウォールの再読み込み後もルールが正しいことを確認します。
  5. DHCPの配布範囲を拡大。1台で安定して動作した後、バイパスルーターのアドレスを段階的に配布します。メインルーターを直接管理できる端末は残してください。

切り戻す場合は、まずテスト端末またはDHCPで配布するゲートウェイを 192.168.10.1 に戻し、利用可能なDNS設定も復元してから、端末のリースを更新します。その後、透過プロキシサービスを停止し、サービスが管理するルールを削除します。mihomoだけを停止してDNS転送や透過リダイレクトを残すと、端末が引き続きネットワークに接続できなくなる可能性があります。

バイパスルーター導入で大切なのは、通信経路の整合性です。端末が正しいゲートウェイに通信を渡し、DNSの応答を対応する経路で処理でき、コアの外向き接続が再び捕捉されないことを確認してください。この3点を押さえてからルールセット、サブスクリプション更新、監視を追加すると、導入手順を再現しやすく、切り戻しも容易になります。クライアントとコアの違いは用語ガイド、各プラットフォームのインストール手順は全プラットフォームガイドをご覧ください。