まず押さえたいルールの優先順位:上から順に評価し、最初に一致したルールを適用

Clashのカスタムルールは、条件を細かくすれば自動的に優先されるわけではありません。ルールモードではリストの上から順に確認し、最初に一致したルールで接続先の出力ポリシーが決まります。以降のルールは評価されません。そのため、特定ドメインの例外を先に置き、ドメインサフィックスのルールを後に続け、MATCHはリストの最後に配置します。振り分けの誤りは、接続先ノードを何度も変えるより、ルールの順番を見直すことで解決できる場合があります。

この記事では、Clashで一般的なルール構文を解説し、ルールセットについてはmihomo(Clash Meta)の使い方も紹介します。設定画面やオーバーライドの仕組み、コアのバージョンはクライアントごとに異なるため、クライアント名だけで拡張フィールドの対応状況を判断することはできません。まずはDOMAIN、DOMAIN-SUFFIX、IP-CIDR、MATCHで基本的な振り分けを設定し、マッチ結果を確認してから拡張しましょう。

システムプロキシとTUNモードは、通信をコアに取り込む方法を決めます。ルールは、取り込まれた通信の出力先を決めます。TUNを有効にしても、特定のルールが優先されるわけではありません。アプリの通信がClashに取り込まれていなければ、ルールが正しくても接続履歴には表示されません。

ルールの基本形式:タイプ、マッチ対象、出力ポリシー

ルールは通常、YAML設定のrules:リストに記述します。基本形式はタイプ,マッチ対象,出力ポリシーで、タイプによっては追加パラメーターを指定できます。リスト項目にはハイフンを使い、インデントにはスペースを使います。タブは使用しないでください。以下は既存の設定に追加できるルール例です。ノード、ポート、DNSを含む完全な設定ではありません。

rules:
  - DOMAIN,login.example.org,DIRECT
  - DOMAIN-SUFFIX,example.org,REJECT
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - MATCH,DIRECT

DIRECTは直接接続、REJECTは接続拒否を表す組み込みの出力ポリシーです。例では予約済みのサンプルドメインを使って順序を説明します。login.example.orgは直接接続し、それ以外のexample.orgのドメインは拒否します。先行するルールに一致しない接続は、最後のルールで直接接続します。

ポリシーグループを指定する場合は、設定内に同じ名前が必要

proxy-groupsに「ノード選択」というポリシーグループがすでにある場合は、ルールの出力ポリシーにその名前を指定できます。例:DOMAIN,api.example.org,ノード選択。ただし、これは組み込みの共通名ではありません。設定に該当グループがない場合、そのままコピーすると設定の検証や読み込みに失敗します。

  • 設定内のトップレベルに置くrules:キーは1つだけにし、既存のリストにルールを追加してください。ファイル末尾に同じキーを重複して記述しないでください。
  • ルールをコピーするときは半角カンマを使い、全角カンマによる構文エラーを避けてください。
  • ルールの出力先にポリシーグループを指定した場合、実際のノードはグループの選択方法や速度テストによって決まります。ルールへのマッチとノードの利用可否は、別々に確認してください。

DOMAINとDOMAIN-SUFFIX:例外を先に、対象範囲の広いルールを後に

タイプルール例マッチ対象
DOMAINDOMAIN,api.example.org,DIRECT指定した完全一致のドメインのみ
DOMAIN-SUFFIXDOMAIN-SUFFIX,example.org,DIRECTルートドメインとそのサブドメイン
DOMAIN-KEYWORDDOMAIN-KEYWORD,example,REJECTドメインに指定した文字列を含む接続

サフィックスは任意の文字列の末尾とは一致しない

DOMAIN-SUFFIX,example.org,DIRECTは、example.org、www.example.org、a.b.example.orgに一致します。一方、notexample.orgはそのサブドメインとして扱われません。ドメインとすべてのサブドメインを対象にする場合は、ルートドメインをそのまま指定します。https://やパス、*.は付けないでください。

ルールに指定するのは完全なURLではなく、ドメインです。https://example.org/accountにはプロトコルとパスが含まれているため、そのままDOMAINに指定することはできません。通常のドメインルールでは、同じサイト内の/accountと/imagesを区別できません。HTTPSではパスが暗号化されたアプリケーション層の情報に含まれるため、ドメインによる振り分けでWebページのパスをフィルタリングすることはできません。

キーワードルールは意図しないマッチに注意

DOMAIN-KEYWORDは手軽に使えますが、想定以上に広い範囲にマッチすることがあります。「example」はexample.orgとは無関係なドメインにも含まれる可能性があります。完全なドメインがわかっている場合はDOMAIN、サイト全体を対象にする場合はDOMAIN-SUFFIXを使い、短いキーワードで範囲を指定しないようにしましょう。

rules:
  - DOMAIN,download.example.org,DIRECT
  - DOMAIN-SUFFIX,example.org,REJECT
  - MATCH,DIRECT

この順序では、ダウンロード用サブドメインを例外として扱います。サフィックスルールを先頭に移すと、ダウンロード用ドメインも先に拒否ルールへ一致し、その下にある、より具体的なDOMAINによる再判定は行われません。Clashが具体的なドメインを広範囲のルールより前に自動で移動することはありません。

IP-CIDRとno-resolve:対象アドレスと名前解決の動作を区別する

IP-CIDRは接続先のIPv4アドレスが属するネットワーク範囲でマッチします。書式の例:IP-CIDR,192.168.1.0/24,DIRECT,no-resolve。/24はネットワークプレフィックス長で、対象範囲は192.168.1.0から192.168.1.255です。単一のIPv4アドレスには/32を指定します。IPv6にはIP-CIDR6を使い、単一のIPv6アドレスには/128を指定します。

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

これらはよく使われるプライベートアドレス範囲の例であり、特殊なアドレスをすべて網羅するものではありません。企業ネットワークや自前のルーター、VPNには、ほかのネットワーク範囲が設定されている場合があります。接続先のネットワークに社内トンネル経由でアクセスする必要がある場合、プライベートアドレスだからといって通常の直接接続で到達できるとは限りません。

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

接続にドメイン名が含まれていて、マッチ判定に使える実際の接続先IPアドレスがまだない場合、IP系ルールはアドレスがネットワーク範囲内か判定するために名前解決を行うことがあります。no-resolveを付けると、そのルールのためだけにドメイン名を追加で名前解決しません。利用可能な接続先IPアドレスがすでにある場合や、アプリがIPアドレスに直接接続している場合は、このルールにマッチできます。

既知のプライベートIPアドレス宛ての通信を直接接続させる場合は、no-resolveによってネットワークルールのための追加の名前解決を避けられます。この設定はアプリによるDNS問い合わせを妨げるものではなく、接続時に名前解決が不要になることを保証するものでもありません。Fake-IP、DNSマッピング、スニッフィングの設定によってコアが取得できる情報は変わります。問題を調べる際は、実際の接続履歴を確認してください。

MATCHとルールセット:フォールバックは最後に配置

MATCHは、残りのすべての接続に無条件でマッチします。指定するフィールドはMATCH,出力ポリシーの2つです。リストの先頭に置くと、後続のドメインルールやIPルール、ルールセットは機能しなくなります。一般的には「個別の例外 → カテゴリー別ルール → 必要なアドレスルール → MATCH」の順にします。ただし、カテゴリー間の優先順位も実際のリスト順で決まります。

ルールセットに独立した優先順位はない

mihomoではrule-providersでルールセットを管理し、RULE-SETで参照できます。ルールセットが評価されるタイミングは、rules内で参照を記述した位置によって決まります。ルールセットのファイルが大きくても、その前にある個別ルールより自動的に優先されるわけではありません。

  • 特定のドメインをルールセットの対象外にするには、そのドメインの完全一致ルールを、対応するRULE-SETの参照より前に配置します。
  • 使用前にprovider名が定義されていることを確認し、behaviorが実際のコンテンツ形式と一致しているか確認してください。たとえば、ドメインセットとCIDRセットでは内容の形式が異なります。
  • ルールセットの更新失敗と「どの項目にもマッチしない」は別の問題です。まず読み込みログを確認し、その後でルールの順序を調べてください。

Clashの各ブランチとmihomoでは、ルールセットの形式や論理ルール、その他の拡張機能に違いがあります。コアを移行する際は、RULE-SETの行だけをコピーしないでください。providerの定義もあわせて確認し、移行先コアの設定検証機能で対応状況を確かめてください。

フォールバックを直接接続にするかプロキシにするかは、目的に応じて決める

この記事の例では、外部のポリシーグループに依存しないようMATCH,DIRECTを使っています。すべてのサブスクリプションで、フォールバックを直接接続にすべきという意味ではありません。未分類の接続をプロキシ経由にする場合は、最後のルールを設定内に存在するプロキシポリシーグループ名に変更してください。まずサブスクリプション本来のフォールバック設定を維持し、個別の例外を少しずつ追加すると、変更点を特定しやすくなります。

サブスクリプション更新後にルールが消える場合:オーバーライドの位置とマージ順を確認

クライアントがダウンロードしたサブスクリプションのYAMLを直接編集すると、次回の更新時にリモートの内容で上書きされることがあります。長期的な管理には、クライアントが提供するローカルオーバーライド、設定のマージ、スクリプト機能を使う方法が適しています。メニューやマージ方法はクライアントによって異なるため、現在のサブスクリプションの操作メニューでローカル設定の拡張方法を確認してください。「編集」ボタンが常に永続的なオーバーライドとして保存されるとは限りません。

  1. まず、現在動作している設定をバックアップします。有効なサブスクリプション、現在のモード、元の最後のルールを記録し、テスト後に元へ戻せるようにしてください。
  2. まず、結果を確認できる個別ルールを1つ追加します。たとえば、テスト用ドメインを一時的に拒否するルールを設定します。一度に数百件の新しいルールを追加しないでください。
  3. 最終的に適用される設定を確認します。マージ後にカスタムルールが元のMATCHの後ろへ追加されていると、ファイルに記述されていてもマッチしません。
  4. 再読み込み後、サブスクリプションをもう一度更新します。ローカルルールが残っていて、正しい位置にあることを確認できたら、設定が保持されていると判断できます。

オーバーライド機能は、リストを置き換える場合、先頭に挿入する場合、末尾に追加する場合があります。動作はそれぞれ異なります。rulesを丸ごと置き換えると、サブスクリプション本来の振り分け設定が失われます。単純に末尾へ追加すると、フォールバックルールの後ろに配置される可能性があります。「保存しました」という表示だけでなく、クライアントのマージ方法を確認することが重要です。

ルールが機能しないときの確認順:モード、接続、マッチ結果、出力先

変更が反映されたかどうかは、Webページが開くかどうかだけで判断しないでください。キャッシュや既存の長時間接続、ブラウザーによる接続の再利用が確認を妨げることがあります。ルールを再読み込みした後、対象サイトの既存接続を閉じてから新たにリクエストしてください。必要に応じてクライアントの接続一覧から該当する接続を終了します。正常に動作しているすべてのアプリを切断する必要はありません。

症状まず確認すること対処方法
対象の接続履歴がないアプリがシステムプロキシを使っているか、TUNが実際に通信を取り込んでいるかまず通信の入口を解決し、マッチ条件の変更は後にする
接続にGlobalまたは直接接続のモードが表示される現在のプロキシモードルールモードに切り替え、新しい接続を作成する
MATCHにマッチしているドメインが一致しているか、IPアドレスを利用できるか、ルールが読み込まれているか接続詳細と最終的なルールリストを照合する
範囲の広いサフィックスルールにマッチしている個別の例外ルールが後ろに配置されていないか例外ルールを範囲の広いルールより前に移動する
想定したポリシーにマッチするが、リクエストに失敗するポリシーグループで選択中のノードと接続先への到達性振り分けの成功と出力先への接続失敗を切り分ける

同じ接続先で変更前と変更後を比較する

現在の混合ポートが実際に7890に設定されている場合は、以下のコマンドでリクエストをローカルHTTPプロキシ経由にできます。実際のポートが異なる場合は、クライアントに表示されている値を使用してください。Windowsでは、PowerShellの旧バージョンで同名の別名と競合しないようcurl.exeを使います。このコマンドはリクエストのテスト用です。一定の遅延や成功率を保証するものではありません。

curl --proxy http://127.0.0.1:7890 --connect-timeout 10 --max-time 20 -I https://example.org/

次に、接続詳細で接続先ドメイン、マッチしたルール、ポリシーグループ、最終的な出力先を確認します。このテストで検証できるのは明示的なHTTPプロキシ経由の通信であり、TUNによる通信の取り込みやUDP転送ではありません。アプリがIPアドレスへ直接接続している場合、ドメインルールに必要なドメイン名が取得できないことがあります。mihomoのスニッフィング機能は、対応するプロトコルと設定のもとで情報を補完できますが、暗号化されたすべての通信からドメイン名を特定できるわけではありません。

安定した設定の進め方は、動作確認済みの設定を残し、少数のルールだけを変更して新しい接続のマッチ記録を確認し、サブスクリプション更新後も設定が保持されるか検証することです。サブスクリプション、DNS、TUNモードの設定を続ける場合はClash総合ガイドをご覧ください。接続に関するよくある問題はよくある質問を確認し、あらゆるネットワーク障害をルール構文の問題と決めつけないようにしましょう。