ルールの構成と適用条件

Mihomoのrulesは、順序に従って評価されるルールリストです。一般的な形式はルールタイプ,マッチ対象,適用先で、最後のフォールバックルールはMATCH,適用先と記述します。適用先には、組み込みのDIRECTやREJECTのほか、設定内で定義済みのプロキシやポリシーグループ名を指定できます。

ルールが決めるのは接続の振り分け先であり、システム上のすべての通信を自動的に取り込むわけではありません。ブラウザーがシステムプロキシを使うか、アプリがプロキシを手動指定するか、クライアントがTUNで接続を取り込むかによって、コアがリクエストを認識できるかが変わります。接続一覧に対象アプリの通信が見当たらない場合は、ルールを編集する前に接続方法を確認してください。

まず確認する3つのポイント

  • 現在のモードがruleであること。Globalモードでは通常のルールリストに沿った振り分けは行われず、Directモードではすべて直結になります。
  • 編集中の設定が実際に稼働中のもので、保存と再読み込みが完了していること。クライアントのエディターに表示されている内容と、コアが実際に読み込んだ内容は異なる場合があります。
  • すべての適用先が実在すること。たとえばルールでPROXYを指定するなら、設定内に同じ名前のプロキシまたはポリシーグループが必要です。大文字・小文字や空白も一致させてください。
mode: rule

rules:
  - DOMAIN,example.com,DIRECT
  - DOMAIN-SUFFIX,example.org,DIRECT
  - MATCH,PROXY

以下は既存設定に追加する断片であり、プロキシノード、DNS、リスニングポートを含む完全な設定ではありません。例では既存のポリシーグループ名をPROXYとしています。実際のグループ名が「ノード選択」の場合は、該当する適用先をその名前に変更してください。example.comとexample.orgは説明用のドメインです。実際には振り分けたいサービスに合わせて置き換えてください。

DOMAIN系ルール:完全一致・サフィックス・キーワード

ドメインルールは、Webサイトやドメインで提供されるAPIサービスに適しています。ルールタイプを選ぶときは、まずマッチ範囲を決めましょう。すべてをキーワード指定にすると、範囲が広すぎて、名前の似た無関係なサービスまで振り分けるおそれがあります。

タイプ 例 マッチ範囲
DOMAIN DOMAIN,api.example.com,DIRECT api.example.comのみ完全一致
DOMAIN-SUFFIX DOMAIN-SUFFIX,example.com,DIRECT example.comとそのサブドメイン
DOMAIN-KEYWORD DOMAIN-KEYWORD,example,DIRECT ドメイン名にexampleを含む対象

ルールにはスキームやページパスを記述しない

DOMAINのマッチ対象はドメイン名であり、完全なURLではありません。https://api.example.com/v1をDOMAINルールに指定しても、Webページのパスによる振り分けはできません。通常のドメインルールでは、同じドメイン内のページごとの判別もできません。

rules:
  - DOMAIN,api.example.com,PROXY
  - DOMAIN-SUFFIX,example.com,DIRECT
  - MATCH,PROXY

このルールセットでは、まずapi.example.comをPROXYに振り分け、そのほかのexample.comのサブドメインは直結します。DOMAINの優先順位が自動的に高くなるのではなく、記述順で結果が決まります。最初の2行を入れ替えると、サフィックスルールが先に一致し、完全一致ルールは適用されません。

GEOSITEとルールセット:分類は固定リストではない

GEOSITEはドメイン分類データを参照します。たとえばGEOSITE,cn,DIRECTは、現在のgeositeデータにあるcnという分類に一致する対象を意味します。Webサイトのサーバー所在地で判定するものでも、中国語のページをすべて識別するものでもありません。実際のマッチ範囲は、使用するデータソースとその更新状況によって異なります。

rules:
  - DOMAIN,api.example.com,PROXY
  - GEOSITE,cn,DIRECT
  - GEOIP,CN,DIRECT,no-resolve
  - MATCH,PROXY
  • GEOSITEはドメイン分類を対象とし、GEOIPは宛先IPの分類を対象とします。両者は置き換えて使えません。
  • 参照する前に、必要なデータが利用可能であることを確認してください。データファイルの不足、ダウンロード失敗、存在しない分類名などが原因で、読み込みエラーが発生することがあります。
  • 個別の例外ルールは分類ルールより前に置きます。たとえば特定のドメインをプロキシ経由にしたい場合、そのドメインを含む直結分類ルールの後ろに置かないでください。

RULE-SETを使う前にproviderを定義する

RULE-SETでは、rule-providersに定義した名前を参照します。以下ではローカルファイルを使い、リモートダウンロードの問題とマッチングの問題を切り分けます。ファイルパスはコアの作業ディレクトリを基準とします。クライアントによっては、アクセス可能な場所が制限されている場合があります。

rule-providers:
  local-direct:
    type: file
    behavior: domain
    format: yaml
    path: ./rules/local-direct.yaml

rules:
  - RULE-SET,local-direct,DIRECT
  - MATCH,PROXY

対応するlocal-direct.yamlの内容:

payload:
  - 'example.com'
  - '+.example.org'

behavior: domainの場合、payloadにはドメインのマッチ対象を記述します。+.example.orgは、そのドメインとサブドメインに一致します。behavior: classicalを使う場合、payloadにはDOMAIN-SUFFIX,example.orgなどのルール式を記述し、振り分け先は通常、外側のRULE-SETで指定します。2種類の形式を混在させないでください。また、ファイル拡張子だけでルールセットの種類を判断しないようにしましょう。

IP-CIDRとno-resolve:宛先アドレスでのマッチング

IP-CIDRはIPv4アドレス範囲、IP-CIDR6はIPv6アドレス範囲に一致します。スラッシュの後ろはプレフィックス長です。/32は単一のIPv4アドレス、/24は256個のアドレスを含むネットワークを表します。判定対象は宛先アドレスであり、アクセス元デバイスのアドレスではありません。

rules:
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
  - IP-CIDR6,fc00::/7,DIRECT,no-resolve
  - MATCH,PROXY

no-resolveはDNSを無効にする設定ではない

no-resolveは、そのIP系ルールの評価時にドメイン名の名前解決を自動的に行わないことを示します。接続に利用可能な宛先IPがすでに含まれていればマッチできます。一方、接続にドメイン名しかなく、利用可能なIPがまだない場合は、そのIP判定をスキップして後続のルールに進むことがあります。DNS全体を無効にする設定でも、ほかの段階での名前解決をすべて防ぐ設定でもありません。

そのため、IPルールにno-resolveを付けても、特定のドメインが最終的な名前解決結果に基づいて必ず振り分けられるとは限りません。内網のドメインを確実に直結したい場合は、対応するドメインルールも設定し、コアが適切な内網DNSサーバーからアドレスを取得できるか確認してください。

PROCESS-NAME:プロセスの識別と権限の制約

PROCESS-NAMEはプロセス名でマッチするため、アプリ全体の通信を同じ出口に振り分けたい場合に便利です。コアがOSから取得するプロセス情報に依存しており、ドメイン名からアプリを推測するものではありません。利用可否はOS、クライアントの実装、実行権限、通信の取り込み方法によって異なります。

find-process-mode: strict

rules:
  - PROCESS-NAME,curl,DIRECT
  - PROCESS-NAME,curl.exe,DIRECT
  - DOMAIN-SUFFIX,example.com,PROXY
  - MATCH,PROXY

strictは必要なときにプロセス情報を検索するモードです。切り分け中は一時的にalwaysへ変更し、プロセス情報を取得できるか確認できます。確認後は実際の用途に合わせて設定を戻してください。プロセス名は接続詳細またはOS上の実際の実行ファイル名を基準にし、デスクトップのショートカット名をそのまま使わないでください。

  • Windowsでは名前に.exeが付くことが一般的です。ほかのデスクトップOSでは実行ファイル名が異なる場合があります。
  • ブラウザー、ランチャー、ダウンロードツールは子プロセスを使うことがあります。メインウィンドウの名前と、実際に接続を確立するプロセスの名前は一致するとは限りません。
  • リクエストが別のローカルプロキシプログラムを経由する場合、コアが識別できるのは中継プログラムだけで、最初にリクエストを発生させたアプリを特定できないことがあります。
  • TUNを使うと取り込めるアプリの通信は増えますが、すべてのプラットフォームで完全なプロセス情報が取得できるわけではありません。プロセス欄が空の場合は、まず権限とプラットフォームの対応状況を確認してください。

プロセスルールをドメインルールより前に置くと、そのプロセスの接続は先にプロセスルールで処理されます。ブラウザー内の特定サイトだけを直結し、それ以外をプロキシ経由にしたい場合は、ブラウザーのプロセスルールより前にドメイン例外を置いてください。

マッチ順序:最初に一致したルールとMATCHのフォールバック

この記事で扱う通常のルールリストは、「上から順に確認し、最初に一致したルールの適用先を選ぶ」と理解できます。コアは、すでに一致したルールを飛ばしてより長いドメインサフィックスを探すことも、プロセスルールを自動的にドメインルールより前へ移動することもありません。

よくあるミス:広いルールが狭いルールを先に拾う

rules:
  - DOMAIN-SUFFIX,example.com,DIRECT
  - DOMAIN,api.example.com,PROXY
  - MATCH,PROXY

この例では、api.example.comへのアクセスは1行目に先に一致します。修正するには、同じルールを重複して追加するのではなく、完全一致の例外をサフィックスルールより前に移動してください。同様に、先に記述されたGEOSITE、RULE-SET、プロセスルールが、後続のカスタムルールより先に一致することもあります。

おすすめのルール配置順

  1. 対象を絞った例外:特定のドメイン、プロセス、特殊なアドレス。
  2. LANと内網サービス:実際の環境に合わせてドメインやアドレス範囲を設定。
  3. サービス用ルールセットと地域分類:対象範囲が広いため、相互に重複しないか先に確認。
  4. MATCH:最後に置くフォールバック。前のルールに一致しなかった接続を処理します。

この順序はメンテナンス上の推奨であり、コアが強制するものではありません。LANへの直結を特定のプロセスのプロキシルールより優先する必要があるなら、LANルールを前に置いてください。MATCHにはマッチ対象のフィールドがないため、MATCH,PROXYのように記述します。リストの途中に置くと、後続の通常ルールは一致する機会を失います。

ポリシーグループに一致しても、最終的な接続先が確定したとは限りません。たとえばルールの適用先がPROXYでも、そのグループで現在DIRECTが選択されていれば、実際の接続は直結します。切り分けでは「どのルールに一致したか」と「ポリシーグループが最終的にどの出口を選んだか」を分けて確認してください。

ルールが反映されないとき:接続情報をもとに順番に確認

DNS、TUN、ルール全体を一度に変更しないでください。繰り返しアクセスできる対象を1つ選び、ドメイン名、リクエスト時刻、マッチしたルール、ポリシーチェーン、ログのエラーを記録してから、変更する項目を1つに絞ります。クライアントによってメニュー名は異なるため、接続詳細、実行ログ、現在の設定を確認できる画面を探してください。

  1. 通信がコアに届いているか確認。新しいリクエストを発生させ、接続一覧で対象のドメイン名またはプロセスを検索します。記録がなければ、システムプロキシ、アプリのプロキシ設定、TUNの取り込み範囲を確認してください。
  2. リスニングポートを確認。設定がmixed-port: 7890なら、テストツールの接続先も127.0.0.1:7890にします。ほかのクライアントで使っていたポートをそのまま使わないでください。
  3. 現在のモードと読み込み結果を確認。Ruleモードになっているかを確認し、再読み込み時にYAML、未定義のポリシー、ルールセットの読み込みエラーが出ていないか調べます。
  4. 実際のマッチ対象を確認。アクセス時に別のドメインへリダイレクトされていないか、複数の静的リソースやAPIドメインが使われていないか確認します。ページのメインドメインだけを振り分けても、すべてのリソースが同じ経路を通るとは限りません。
  5. マッチしたルールより前を確認。それより上にあるDOMAIN-SUFFIX、GEOSITE、RULE-SET、プロセスルール、MATCHを探し、対象が先に振り分けられていないか確認します。
  6. 出口と新しい接続を確認。ポリシーグループの現在の選択先を確認し、古い接続を閉じるか、テスト対象のアプリを再起動してください。設定を再読み込みした後は、既存の長時間接続を新ルールのテストに使わないようにします。

curlでテスト経路を固定する

以下のコマンドは、ローカル設定でmixed-port: 7890が有効になっている場合に使えます。--noproxy ""は今回のリクエストでプロキシ除外リストを空にし、環境変数による影響を抑えます。-IはHEADリクエストを送信し、主に接続確立とルールのマッチ状況を確認するためのオプションです。Windows PowerShellでは、実行ファイルを明示するためにcurl.exeを使えます。

curl --noproxy "" -I --proxy http://127.0.0.1:7890 https://example.com
curl --noproxy "" -I --proxy socks5h://127.0.0.1:7890 https://example.com

socks5hは宛先ドメインの名前解決をプロキシ側に任せるため、ローカルで先に名前解決した場合との差を抑えられます。この2つのコマンドで確認できるのは明示的なプロキシ経由の通信であり、TUN経由の通信ではありません。TUNをテストするには、アプリで明示的なプロキシを使っていないことを別途確認し、クライアントの接続記録から通信が実際に仮想インターフェースへ入っているか確認してください。

症状 優先して確認する項目 対処方法
保存後に設定を再読み込みできない インデント、ポリシー名、分類データ、ルールセットの形式 ログの行番号に従って修正し、インデントにスペースを使う
常にMATCHに一致する ドメイン名が一致するか、プロセス情報を取得できるか アドレスバーだけで判断せず、接続に記録された実際のフィールドを確認
PROXYに一致しているのに直結する ポリシーグループでDIRECT、または直結するネストグループが選択されていないか ポリシーチェーン全体を展開し、最終的な出口を確認
サブスクリプション更新後にカスタムルールが消える サブスクリプションから生成されたファイルを直接編集していないか クライアントが対応する永続的なオーバーライド機能を使う

サブスクリプション更新とルールの管理

サブスクリプションが完全な設定を提供する場合もあれば、プロキシノードだけを提供する場合もあります。完全な設定から生成されたファイルを直接編集すると、次回の更新時に上書きされることがあります。クライアントにオーバーライド、マージ、スクリプト処理の機能がある場合は、rulesをどう扱うか確認してください。全体を置き換えるのか、前方に挿入するのか、末尾に追加するのかを把握しておきましょう。

末尾への追加は、「ルールは存在するのに反映されない」状態を招きやすくなります。元のサブスクリプション設定がMATCHで終わっている場合、追加ルールは最終的に適用される設定でMATCHより前に置く必要があります。オーバーライドの編集画面だけで判断せず、マージ後のルール順序を確認し、新しい接続でテストしてください。

変更を元に戻せるよう記録を残す

  • 用途が明確なルールを一度にひとまとまりだけ追加し、対象ドメイン、想定する出口、追加理由を記録します。
  • 外部ファイルだけを復元し忘れないよう、ローカルのルールセットをメイン設定と一緒にバックアップします。
  • クライアントやコアを更新した後は、プロセスの識別、ルールセットの読み込み、重要な例外ルールを再確認し、古い接続結果に頼らないようにします。
  • ログを共有する前に、サブスクリプションURL、ノードの認証情報、コントロールインターフェースのキーを隠してください。切り分けでは、ルールの抜粋とマッチ情報を共有すると役立ちます。

ルールを保守するうえで大切なのは、対象範囲と記述順を説明できる状態にすることです。個別の例外はそれを含む広いルールより前に置き、フォールバックは最後に配置し、接続詳細で実際のマッチ状況を確認します。まず通信の入口、次にマッチ対象のフィールド、最後にポリシーチェーンを確認すると、モードを何度も切り替えるより問題を特定しやすくなります。