まずネットワーク構成を決める:主ルーターは回線接続、バイパスルーターは通信を振り分ける

バイパスルーターでmihomoを直接動かす場合、最初に確認すべきなのはサブスクリプションの読み込みではなく、通信経路です。まずテスト用の端末を1台だけ選び、ゲートウェイを変更して転送、DNS、ルールが正常に動くことを確認してから、DHCPを変更しましょう。この記事では、同一セグメントに単一のLANポートで接続する構成を使います。主ルーターは引き続きPPPoE接続、DHCP、インターネットへの出口を担当し、OpenWrtは主ルーターのLANに接続して、mihomoで指定した端末の通信を処理します。

機器IPv4アドレスデフォルトゲートウェイと役割
主ルーター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 に設定

アドレスは説明用の一例です。実際に設定する前に、ご自身のネットワークに合わせて変更してください。バイパスルーターのアドレスは主ルーターのDHCP割り当て範囲と重ならないようにするか、DHCPで固定割り当てを設定します。OpenWrtの「ネットワーク」→「インターフェース」→「LAN」→「編集」で、静的IPv4アドレス、サブネットマスク、IPv4ゲートウェイを設定してください。バイパスルーター自身のゲートウェイに、自分のアドレスを指定してはいけません。

  • 同じブロードキャストドメイン内でDHCPサーバーは1つだけにします。バイパスルーターのLANにある「DHCPサーバー」→「一般設定」で「このインターフェースを無視」にチェックを入れます。dnsmasqのDNS機能はそのまま利用できます。
  • 主ルーターのデフォルトゲートウェイをバイパスルーターに向けないでください。「バイパスルーターから主ルーターへ転送し、主ルーターからまた戻す」という転送ループが発生するおそれがあります。
  • テスト中は主ルーターの管理画面へ直接アクセスできる経路を確保してください。サービス停止後に端末の設定を変更できなくなる事態を防げます。

カーネルをインストールする:CPUアーキテクチャ、作業ディレクトリ、実行権限を確認

mihomoは、Clash Metaの後継として使われているカーネルの名称です。カーネルを直接導入しても、GUIクライアントは含まれず、OpenWrtのファイアウォール設定も自動生成されません。まずSSHでシステムを確認し、対応するアーキテクチャのLinux実行ファイルをダウンロードしてください。

ubus call system board
uname -m
df -h /overlay /tmp
date
ip -4 route show

x86_64は通常amd64、aarch64は通常arm64に対応します。MIPS機器ではエンディアン、命令セット、浮動小数点ABIも確認が必要です。「64ビットルーター」という情報だけでファイルを選ばないでください。Exec format errorが表示されたら、まずアーキテクチャを確認します。Illegal instructionの場合はCPUの命令セット要件を確認し、YAMLを何度も変更しないでください。

実行ファイルと設定ファイルを配置する

解凍したカーネルをSCPまたはSFTPでルーターの /tmp/mihomo に転送し、次のコマンドを実行します。/tmpは通常メモリー上にあるため、再起動すると内容が消えます。長期運用するカーネルと設定ファイルは、永続ストレージに保存してください。

mkdir -p /etc/mihomo
cp /tmp/mihomo /usr/bin/mihomo
chmod 0755 /usr/bin/mihomo
chmod 0700 /etc/mihomo
/usr/bin/mihomo -v

実際に使用する設定を /etc/mihomo/config.yaml に保存し、chmod 0600 /etc/mihomo/config.yamlを設定します。サブスクリプションURL、ノードのパスワード、コントロールインターフェースのキーは、いずれも機密情報です。設定でルールセットやGeoデータベースを有効にする場合、必要なファイルをダウンロードできること、または作業ディレクトリに配置済みであることを確認してください。フラッシュ容量の少ない機器では、空き容量にも注意が必要です。

TUNを使うにはカーネル側の対応も必要です。OpenWrt 24.10系で一般的なopkg環境の場合は、以下のコマンドを実行できます。別のバージョンでは、先にファームウェアのパッケージマネージャーと配布元を確認してください。カーネルモジュールは使用中のファームウェアのカーネルと一致する必要があります。別バージョンのパッケージを無理にインストールしないでください。

opkg update
opkg install kmod-tun ip-full
test -c /dev/net/tun && echo "TUN device ready"

まず /usr/bin/mihomo -t -d /etc/mihomo を実行して設定を検証します。テストに通っても、構文や一部リソースの初期化が確認できただけで、透過転送の成功を意味するわけではありません。

TUNとredir:必要なプロトコルに合わせて方式を選ぶ

TUNは仮想ネットワークデバイスでIP通信を受け取り、TCPとUDPの両方を処理したい構成に適しています。redirはファイアウォールでTCP接続をカーネルの待ち受けポートへリダイレクトする方式で、通信経路を段階ごとに確認しやすい一方、redir-portだけではUDPを処理できません。まずどちらか一方を選び、複数のプラグイン、TUN、手動設定の透過プロキシルールを同時に有効にしないでください。

項目TUNredir
処理できる通信TCPとUDPに対応。実際の対応状況はノードにも依存主にTCP。UDPにはTPROXYなど別の仕組みが必要
必要な条件/dev/net/tun、ルーティング権限、転送の許可TCPの待ち受けポートとファイアウォールのリダイレクトルール
主な確認箇所ポリシールーティング、出口インターフェースの識別、TUNのファイアウォールゾーンルールの一致、予約済みアドレスの除外、二重処理
この記事の設定例mixed-port: 7890 は明示的なプロキシ接続の確認に使用redir-port: 7892

TUNの基本的な接続テスト用設定

以下は、直接接続による転送を確認するための基本設定です。プロキシノードは含まれず、最終ルールも DIRECT のため、テストに成功してもノード経由のプロキシ接続が成功したことにはなりません。まずTUNとDNSの経路を確認してから、実際に使う proxies、proxy-providers、proxy-groups、振り分けルールを追加してください。バックアップしていない設定に上書きしないでください。

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
ipv6: false

tun:
  enable: true
  device: mihomo
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  strict-route: false
  dns-hijack:
    - any:53

dns:
  enable: true
  listen: 127.0.0.1:1053
  ipv6: false
  enhanced-mode: redir-host
  nameserver:
    - 223.5.5.5
    - 119.29.29.29

rules:
  - IP-CIDR,192.168.10.0/24,DIRECT,no-resolve
  - MATCH,DIRECT

allow-lan: falseが制限するのは明示プロキシの待ち受けであり、TUNによる転送通信の処理を禁止する設定ではありません。auto-routeは通信を取り込むためのルートを作成しますが、OpenWrtのすべてのファイアウォールゾーン設定を代わりに行うものではありません。auto-detect-interfaceには正常なデフォルトルートも必要です。複数WAN、VPNの出口、ほかのポリシールーティングを併用している場合は、出口に応じて interface-name を明示してください。必ず eth0 だと決めつけないでください。

redirを使う場合の注意点

redirを選ぶ場合は tun.enable を無効にし、redir-port: 7892を設定します。次にファイアウォールのpreroutingで、指定したLAN端末のTCP通信だけをリダイレクトしてください。OpenWrt 22.03以降ではfirewall4とnftablesが一般的です。古い手順のiptablesコマンドが、現在有効なルールセットに反映されるとは限りません。

  • ルールでは入力インターフェースとテスト元アドレス 192.168.10.100 を限定し、ルーターの管理用アドレス、LAN、必要な予約済みアドレス範囲を除外してください。
  • カーネル自身が接続するノードへの通信を、再び透過プロキシの入口に戻してはいけません。ルーター本体の通信も処理対象にする場合は、出口への迂回とループ防止を別途設計してください。
  • HTTP/3はUDP/443を使用します。TCP redirだけを設定した場合、ブラウザーのHTTP/2とHTTP/3で出口が異なることがあります。これは 7892 ポートの不具合ではありません。
  • table inet fw4を丸ごと置き換えないでください。ルールを永続化したら、/etc/init.d/firewall reloadも実行してテストし、再読み込み後もルールが残っていることを確認します。

DNSの設定:端末からバイパスルーターへ、ローカルサービスから上位DNSへ

初期設定では、端末から 192.168.10.2:53 に問い合わせ、OpenWrtのdnsmasqから 127.0.0.1:1053 に転送し、mihomoから指定した上位DNSサーバーへ問い合わせる構成がおすすめです。LAN内の名前解決にdnsmasqを利用しながら、2つのサービスが同じアドレスの53番ポートを同時に使用する事態を避けられます。

独自のドメイン別DNS設定がないシンプルな環境では、以下のUCI設定を利用できます。事前に /etc/config/dhcp をバックアップしてください。このコマンドは最初のdnsmasq設定にある既存の共通上位DNSリストを削除します。社内ドメインやほかのローカル転送ルールがある場合は手作業で統合し、そのまま実行しないでください。

cp /etc/config/dhcp /root/dhcp.before-mihomo
uci set dhcp.@dnsmasq[0].noresolv='1'
uci -q delete dhcp.@dnsmasq[0].server
uci add_list dhcp.@dnsmasq[0].server='127.0.0.1#1053'
uci commit dhcp
/etc/init.d/dnsmasq restart

nslookup example.com 127.0.0.1

noresolv='1'を設定すると、dnsmasqが自動生成された上位DNSリストを同時に読み込むのを防げます。mihomoの上位DNSに 192.168.10.2 を設定すると、dnsmasqとmihomoの間でDNS転送ループが発生します。ノードサーバーにドメイン名を使う場合は、プロキシ接続前でも名前を解決できる経路を確保してください。

初回の構築では、名前解決の結果を確認しやすい redir-host を使うのがおすすめです。fake-ipに切り替える前に、バイパスルーターの転送が安定していることを確認し、LAN内のドメイン名や機器との互換性に応じて fake-ip-filter を設定してください。ブラウザーのセキュアDNS、AndroidのプライベートDNS、アプリ内のDoHは、通常の53番ポートへの問い合わせを迂回する場合があります。dns-hijackを使っても、これらの接続が自動的に復号されるわけではありません。

OpenWrtの転送と同一セグメントの戻り経路:TUNの作成だけでは不十分

「ネットワーク」→「ファイアウォール」で、実際のゾーンと転送設定を確認してください。TUNデバイス mihomo 専用のゾーンを作り、LANからそのゾーンへの通信と、TUNから出た直通通信の実際の出口ゾーンへの転送を許可する方法が一般的です。LANポート1つのバイパスルーターでは、出口もLANであることがよくあります。LANポート2つの構成向けの手順をそのまま使い、出口が必ずWANに属すると決めつけないでください。

  • 端末からバイパスルーターのUDP/TCP 53番ポートへのアクセスを許可します。DNSサービスを信頼できないインターフェースに誤って公開しないでください。
  • net.ipv4.ip_forwardが 1 になっているか確認します。カーネルにルートがあっても、転送が無効なら端末はインターネットに接続できません。
  • トラブルシューティング中はソフトウェアとハードウェアのフローオフロードを一時的に無効にしてください。既存の接続が高速経路を通り、ルールのカウンターやパケットキャプチャの確認を妨げる場合があります。
  • ファイアウォールを全面的に無効にして転送を「直そう」としないでください。必要なゾーンと方向だけを許可し、既存ルールの順序も確認してください。

同一セグメントの構成では、見落としやすい問題がもう1つあります。バイパスルーターが直通通信を主ルーターに渡した後、主ルーターから端末へ直接応答が返ると、非対称な経路になる場合があります。往復通信をバイパスルーター経由にする構成では、対象を限定して転送通信の送信元アドレスを変換し、上位ルーターからは送信元が 192.168.10.2 に見えるようにします。LAN全体の全通信に無条件でマスカレードを有効にしないでください。別の方法として、プロキシを使う端末を専用サブネットに分けると、構成が明確になります。

同じインターフェースから入って同じインターフェースへ出る転送では、ICMP Redirectが発生し、端末に主ルーター経由で通信するよう通知されることもあります。この構成では、実際に使うLANデバイスの設定を中心に、関連項目を確認してください。

sysctl net.ipv4.ip_forward
sysctl net.ipv4.conf.all.send_redirects
sysctl net.ipv4.conf.default.send_redirects
sysctl net.ipv4.conf.br-lan.send_redirects

ip -4 route show
ip -4 rule show
ip -4 route show table all

デバイス名が実際に br-lan の場合は、上記3つの send_redirects を 0 に設定し、動作を確認してから永続化できます。インターフェース名にドットが含まれる場合や、ブリッジ構成が異なる場合は、実際のデバイス名に合わせてください。sysctlの設定を一度にすべて変更すると、どの変更が通信経路に影響したのか分からなくなります。

起動時の自動実行:systemdではなくprocdを使う

OpenWrtでは通常procdでサービスを管理します。デスクトップLinux向けの systemctl enable mihomo は使えません。まずほかのプロキシ管理プラグインを停止し、別のプロセスがポートを使用していないこと、同じTUNルートを管理していないことを確認してから、/etc/init.d/mihomoを作成してください。

#!/bin/sh /etc/rc.common

START=99
STOP=10
USE_PROCD=1

start_service() {
    /usr/bin/mihomo -t -d /etc/mihomo || return 1

    procd_open_instance
    procd_set_param command /usr/bin/mihomo -d /etc/mihomo
    procd_set_param respawn 3600 5 5
    procd_set_param stdout 1
    procd_set_param stderr 1
    procd_set_param limits nofile="65535 65535"
    procd_close_instance
}

このスクリプトは設定を確認してから、procdに起動を依頼します。respawnの設定例では、短時間にクラッシュと再起動を繰り返す状態を制限しています。サービスはデフォルトでrootとして実行され、TUNの作成やルートの変更を行います。低権限ユーザーに変更する場合は、必要な権限を別途設計してください。ユーザー名を1行追加するだけでは不十分です。

chmod 0755 /etc/init.d/mihomo
/etc/init.d/mihomo start
logread -e mihomo
ip link show mihomo

# 動作と転送を確認してから自動起動を有効にする
/etc/init.d/mihomo enable

YAMLを変更したら、まず mihomo -t -d /etc/mihomo を実行します。検証に通った後で /etc/init.d/mihomo restart を実行してください。ファイアウォールルールが別途永続化され、DNSサービスが起動し、起動後に必要なリソースをダウンロードできて、初めて再起動後も正常に復旧します。START=99を設定しても、インターネットへの接続が確立したことは保証されません。

動作確認と切り戻し:ポート、DNS、転送、ノードの4段階で確認

動作確認中は、ゲートウェイを変更する端末をテスト用の1台だけにします。まずバイパスルーター上で明示的なプロキシ接続を確認し、次に端末の透過通信を確認してから、最後に主ルーターのDHCPでゲートウェイとDNSを配布します。「カーネルがインターネットに接続できる」状態と「端末の通信が取り込まれている」状態を区別できます。

  1. カーネルの動作を確認。logread -e mihomoを実行し、ポートの競合、ルールのダウンロード失敗、TUNの作成失敗がないか確認します。ssをインストール済みなら、ss -lntupを実行して7890や1053などの実際の待ち受けを確認できます。
  2. 明示的なプロキシ接続を確認。ルーターでcurlを使える場合は、curl -I -x http://127.0.0.1:7890 https://example.comを実行します。このテストでは端末の透過転送を経由しません。失敗した場合は、まずカーネル、上位DNS、出口を確認してください。
  3. 端末のDNSを確認。Linuxのテスト用端末で nslookup example.com 192.168.10.2 を実行し、続けて ip -4 route show default でゲートウェイを確認します。名前解決に成功しても、TCP通信がTUNを通ったとは限りません。
  4. 透過ルールの適用を確認。端末でアプリ内の明示プロキシを無効にして新しい接続を開始し、mihomoのログに表示される送信元アドレス、ルール、出力先を確認します。ノード設定を追加した後は、DIRECTに固定されず、実際のプロキシグループとノードが選択されていることを確認してください。
  5. 再起動後の復旧を確認。サービスの再起動、ファイアウォールの再読み込み、機器の再起動を順番にテストします。DNSが復旧するか、TUNが再作成されるか、端末が想定どおりのゲートウェイを使い続けるかを確認してください。

よくある症状と優先して確認する項目

症状優先して確認する項目
ルーターには接続できるが、端末からは接続できない端末のゲートウェイ、IPv4転送、ファイアウォールゾーン、同一セグメントの戻り経路
IPアドレスへの接続はできるが、ドメイン名では失敗する53/1053番ポート、dnsmasqの上位DNS、DNS転送ループ
一部のアプリがプロキシを経由しないIPv6のデフォルトルート、UDP、アプリ独自のプロキシやDNS
小さな通信は成功するが、ダウンロードが頻繁に止まる経路MTU、上位回線のカプセル化、再送。まずTUNのMTUをむやみに大きくしない
再起動後に動作しなくなるprocdの有効化状態、設定の保存場所、ファイアウォールルールの復元、起動ログ

切り戻す場合は、まずテスト端末のゲートウェイとDNSを主ルーター 192.168.10.1 に戻し、その後mihomoを停止して、独自の透過ルールと転送設定を解除してください。dnsmasqの転送先を1053だけにしていた場合は、上位DNSの設定も同時に戻す必要があります。戻さずにカーネルを停止すると、バイパスルーターが問い合わせを受け取っても、名前解決できるサービスがなくなります。

/etc/init.d/mihomo stop
/etc/init.d/mihomo disable

# バックアップが今回の構築前に取得したものの場合のみ復元
cp /root/dhcp.before-mihomo /etc/config/dhcp
/etc/init.d/dnsmasq restart

最後に、ネットワーク全体へ設定を適用するか判断します。主ルーターではDHCPオプション3でゲートウェイ、オプション6でDNSを配布します。バイパスルーター経由にする必要がある端末にだけ、該当するアドレスを配布してください。ネットワーク構成の記録、設定のバックアップ、切り戻し手順を残しておくと、すべてのルールを一度に適用するより長期運用しやすくなります。各項目の意味は設定リファレンス、クライアントへの設定取り込み方法はクイックスタートをご覧ください。