Clash カスタムルール
DOMAIN、DOMAIN-SUFFIX、IP-CIDR、GEOIP、PROCESS-NAME などのルール種別を解説。上から順に評価される仕組みや no-resolve、rule-providers の使い方も紹介します。
ルール適用の3つの前提
Clash のルールは接続に適用する出力先を選ぶもので、プロキシノードを生成するものではありません。設定内のノード、グループ、ルールはそれぞれ役割が異なります。ノードは接続先を提供し、グループは選択可能な接続先をまとめ、rules が接続をどの接続先に渡すかを決めます。問題を切り分ける際は、この3つを分けて考え、ノードが使えない状態をルールの不一致と混同しないようにしましょう。
- 接続がコアに到達している。システムプロキシが適用されるのは、通常、プロキシ設定に従うアプリだけです。ゲーム、一部のコマンドラインツール、UDP通信はプロキシを経由しないことがあります。TUNを使うと取り込める通信の範囲は広がりますが、ルーティング、除外設定、権限も確認が必要です。
- 現在のモードがルールモードになっている。設定では
mode: ruleに該当します。グローバルモードやダイレクトモードでは、通常、このルール一覧に沿った振り分けは行われません。 - 実際に稼働している設定を変更している。クライアント上のサブスクリプション原文、オーバーライド設定、コアが最終的に読み込む設定は異なる場合があります。保存後に設定の検証結果を確認し、再読み込みしてください。
ルールの構文と主な種類
多くのルールは 種類,マッチ条件,ポリシー の形式です。区切りには半角カンマを使い、YAMLのリスト項目として rules: の下に記述します。各項目の先頭にはハイフンを付けます。組み込みポリシーの DIRECT は直接接続、REJECT は通信拒否を意味します。その他のポリシー名は、定義済みのノード名またはグループ名と完全に一致させてください。
| ルールの種類 | 例 | マッチ範囲 |
|---|---|---|
DOMAIN | DOMAIN,api.example.com,DIRECT | 指定したドメインに完全一致します。サブドメインは対象外です。 |
DOMAIN-SUFFIX | DOMAIN-SUFFIX,example.com,DIRECT | ルートドメインとそのサブドメインに一致します。otherexample.com は対象外です。 |
DOMAIN-KEYWORD | DOMAIN-KEYWORD,example,DIRECT | ドメイン名に含まれる文字列に一致します。サフィックスルールより広い範囲が対象です。 |
IP-CIDR | IP-CIDR,192.168.0.0/16,DIRECT,no-resolve | IPv4の宛先ネットワークに一致します。この例では 192.168.0.0 から 192.168.255.255 までが対象です。 |
IP-CIDR6 | IP-CIDR6,fc00::/7,DIRECT,no-resolve | IPv6ネットワークに一致します。この例はユニークローカルアドレスの範囲です。 |
GEOIP | GEOIP,CN,DIRECT,no-resolve | ローカルのIP位置情報データベースを使ってアドレスを判定します。精度はデータベースに左右されます。 |
PROCESS-NAME | PROCESS-NAME,curl.exe,DIRECT | コアが認識したプロセス名に一致します。結果はOSや権限によって異なります。 |
MATCH | MATCH,接続先 | それまでにマッチしなかった接続をすべて受け止めます。マッチ条件は記述しません。 |
ドメインルールにプロトコル、ポート、パスは記述しない
https://api.example.com:443/v1/status を振り分ける場合、ドメインルールに記述するのは api.example.com だけです。URL全体を DOMAIN に指定しても、Webアドレスとしてマッチしません。宛先ポートで振り分ける場合は、コアが対応していれば DST-PORT を使えます。ただし、DST-PORT,443,接続先 は、その位置より後にあるすべての443番ポートへの接続に適用され、特定のWebサイトだけが対象になるわけではありません。
本文に登場する example.com は、構文を示すための予約済みサンプルドメインです。実際の設定では、振り分けたいドメインに置き換えてください。サンプルのルールを追加しても、よく使うサイトの接続経路は変わりません。
ルールの評価順序と例外設定
通常のルールは一覧の上から順に評価され、最初にマッチしたルールのポリシーが適用されます。それ以降のルールは評価されません。コアが自動的に「より具体的な」ルールを選んだり、後続の拒否ルールを見て結果を再判定したりすることはありません。そのため、例外は通常ルールより前に置き、MATCH は最後に記述します。
rules:
- DOMAIN,api.example.com,DIRECT
- DOMAIN,ads.example.com,REJECT
- DOMAIN-SUFFIX,example.com,接続先
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- MATCH,接続先
api.example.comは1つ目のルールにマッチし、直接接続されます。ads.example.comは2つ目のルールにマッチし、接続が拒否されます。www.example.comは3つ目のルールにマッチし、「接続先」グループに渡されます。- 宛先アドレスが
192.168.1.20と判明していて、それより前のドメインルールにマッチしない接続は、LAN向けルールにマッチします。 - それ以外の接続は最後の
MATCHに渡されます。
3つ目のサフィックスルールを1つ目に移すと、api.example.com と ads.example.com の両方が先にそのルールにマッチします。後続の直接接続ルールや拒否ルールは、構文が正しくても実行されません。
プロセスルールも同じ順序で評価される
PROCESS-NAME,curl.exe,DIRECT をリストの先頭に置くと、Webサイトのルールを確認する前に、そのプロセスの接続が直接接続される可能性があります。特定のドメインだけを例外にする場合は、ドメインルールを使うのがおすすめです。アプリ全体の接続経路を固定したい場合は、プロセスルールを使います。Windowsではプロセス名に .exe が付くことが一般的ですが、LinuxやmacOSでは通常付きません。接続の詳細に表示される実際のプロセス名を確認してください。
no-resolve の正確な意味
no-resolve は、このIP系ルールを評価する際、ドメイン名だけが分かっている接続に対して追加の名前解決を行わないようにするオプションです。DNS自体を無効にするものでも、最終的にドメイン名が解決されないことを意味するものでもありません。クライアントのDNS設定、ほかのルール、実際に出力接続を確立する過程で名前解決が行われる場合があります。
rules:
- DOMAIN-SUFFIX,example.com,接続先
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- GEOIP,CN,DIRECT,no-resolve
- MATCH,接続先
接続情報にドメイン名しかなく、1つ目のルールにもマッチしないケースを考えてみましょう。後続のIPルールを評価する際、no-resolve があれば、そのルールのためだけに追加の名前解決を行いません。接続に利用可能な宛先IPアドレスがすでにあれば、IP系ルールで判定できます。実際の宛先IPアドレスが利用できるかどうかは、DNSモード、接続の入口、メタデータに左右されます。ドメインを実際に名前解決した結果だけを見て、ルールに必ずマッチすると判断することはできません。
よくある2つの選択肢
- ドメインによる振り分けを優先する:主要なドメインルールを前に置き、IPルールに
no-resolveを付けて、ルール評価に伴う追加の名前解決を抑えます。その代わり、ドメイン名しか分からない一部の接続は、そのままフォールバックに進む可能性があります。 - 名前解決後のIPアドレスで分類する:特定のIPルールから
no-resolveを外し、評価時の名前解決を許可します。その分、DNS応答や名前解決の所要時間に左右されるため、DNS設定も併せて確認してください。
GEOIP,CN が判定するのは、データベース上のIPアドレスの割り当て先です。Webサイトの運営主体を判定するものでも、「中国国内のすべてのWebサイト」を意味するものでもありません。CDNを利用するサイトは、名前解決されたアドレスによって判定結果が変わることがあります。安定した振り分けが必要なサービスには、明示的なドメインルールが適しています。
rule-providers でルールを再利用する
複数の設定で同じドメインやネットワーク範囲を使う場合、マッチ条件をルールプロバイダーにまとめ、RULE-SET から参照できます。プロバイダーはルールの読み込みを担います。優先順位を決めるのはプロバイダーの宣言位置ではなく、メインの rules リスト内にある RULE-SET の位置です。
メイン設定:ローカル classical ルールセット
rule-providers:
local-direct:
type: file
behavior: classical
path: ./rules/local-direct.yaml
rules:
- DOMAIN,api.example.com,接続先
- RULE-SET,local-direct,DIRECT
- MATCH,接続先
ルールセットファイル:rules/local-direct.yaml
payload:
- DOMAIN-SUFFIX,example.com
- IP-CIDR,192.168.0.0/16,no-resolve
- IP-CIDR6,fc00::/7,no-resolve
ルールセット内の項目には DIRECT やポリシーグループ名を記述しません。接続先のポリシーは、メイン設定の RULE-SET,local-direct,DIRECT でまとめて指定します。この例では、api.example.com は引き続きメインリストの1つ目のルールにマッチします。同じルートドメインのほかのサブドメインは、ルールセットに進んで直接接続されます。
path は通常、コアの作業ディレクトリを基準に解決されます。ダウンロードしたサブスクリプションファイルの保存先と同じとは限りません。クライアントが許可するルールファイルの保存場所を確認し、先にファイルを作成してください。ファイルがない、ディレクトリにアクセスできない、内容の形式が正しくない場合は、プロバイダーの読み込みに失敗することがあります。
| behavior | 内容形式 | 用途 |
|---|---|---|
classical | タイプ付きルール(例:DOMAIN-SUFFIX,example.com) | ドメインやIPなど、複数種類の条件を同じセットにまとめる場合。 |
domain | コアのドメインルールセット構文に沿って、ドメインを記述する | ドメインの一覧を管理する用途。classical のタイプ接頭辞は使いません。 |
ipcidr | 192.168.0.0/16 などのネットワーク範囲を記述する | IPv4・IPv6のネットワーク範囲を管理する用途。 |
behavior だけを変更して、3つの形式を混在させることはできません。HTTPプロバイダーに切り替える場合は、実在する信頼できるルールのURLと更新間隔も設定してください。リモートルールは振り分け結果を変えるため、配信元と更新内容を確認し、出所不明のセットをカスタム例外より前に置かないでください。
動作確認に使える最小構成
以下の設定は、mihomo の構文とルールの評価順序を確認するためのものです。プロキシノードは含まず、「接続先」グループには DIRECT だけが設定されているため、拒否ルール以外の通信は実際には直接接続されます。ルールの動作を確認してから、既存のノードやノードプロバイダーをグループに追加してください。
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
proxy-groups:
- name: 接続先
type: select
proxies:
- DIRECT
rules:
- DOMAIN,api.example.com,DIRECT
- DOMAIN,ads.example.com,REJECT
- DOMAIN-SUFFIX,example.com,接続先
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
- 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,::1/128,DIRECT,no-resolve
- IP-CIDR6,fc00::/7,DIRECT,no-resolve
- MATCH,接続先
ここではコマンドラインからテストしやすいよう、ポート番号に 7890 を指定しています。ほかのプロセスが使用中の場合は、空いているポートに変更し、テストコマンドも同じ番号に合わせてください。allow-lan: false はLANにプロキシの入口を公開しません。実際のクライアントではリッスンポートが上書きされる場合があるため、稼働中の設定とリッスン状態を確認してください。
設定を検証してからリクエストを確認する
mihomo -t -f ./config.yaml
curl -I --proxy http://127.0.0.1:7890 https://example.com
1つ目のコマンドを実行するには、ローカルで mihomo という名前の実行ファイルが使え、現在のディレクトリに config.yaml がある必要があります。GUIクライアントの場合は、クライアントの設定チェック機能を使ってください。2つ目のコマンドでは、リクエストをHTTPプロキシに明示的に送信し、コマンドラインツールがシステムプロキシ設定を引き継ぐかどうかの影響を避けています。Windows PowerShellでは、curl.exe を使って該当のプログラムを実行できます。
サンプルのリクエストは DOMAIN-SUFFIX,example.com,接続先 にマッチするはずです。確認には、接続の詳細やログに表示されるルール種別、マッチした内容、ポリシーの経路を使います。Webページの表示速度や出口IPだけでは判断できません。異なるルールが同じポリシーを指すこともあるため、出口が同じだからといって同じルールが適用されたとは限りません。
ルールが適用されないときの確認手順
- 接続が表示されるか確認する。クライアントの接続一覧に対象のリクエストが表示されない場合は、まずプロキシの入口、TUNのルーティング、アプリの設定を確認してください。リクエストがコアに届いていなければ、ルールの順序を変えても解決しません。
- 実際のルールモードを確認する。グローバルモードやダイレクトモードになっていないか、また、エディターに表示されたファイル名だけでなく、現在どの設定が有効かを確認してください。
- 最初にマッチしたルールを確認する。範囲の広いサフィックス、キーワード、プロセスルールに接続がマッチしている場合は、必要な例外をその前に移動します。有効にしたいルールを
MATCHの後に追加してはいけません。 - ポリシー名を確認する。「接続先」と「プロキシ接続先」は別の名前です。未定義のポリシーを参照すると、設定の検証に失敗することがあります。まず読み込みエラーを解消してください。
- ドメインとプロセスのメタデータを確認する。接続情報がIPアドレスだけの場合、ドメインルールのマッチ対象が見つからないことがあります。プロセス名が空なら、プロセスルールも想定どおりに機能しません。TUNを使っても、すべての接続にドメイン名やプロセス情報が自動で付与されるわけではありません。
- プロバイダーの状態を確認する。ファイルが存在し、形式が
behaviorと一致していること、クライアントがルールセットを正常に読み込んでいることを確認してください。ローカルファイルを変更した後は、クライアントの手順に従ってプロバイダーを更新するか、設定を再読み込みします。 - テスト接続を作り直す。設定を更新しても、確立済みの長時間接続には以前の出力先が引き継がれることがあります。元のリクエストを停止して新しい接続を開始し、必要に応じて該当する接続を閉じてから再テストしてください。
ルールを整理する際は、順序を決めておくと管理しやすくなります。明示的な拒否や直接接続の例外を先頭に置き、続いてサービスのドメインセットを配置します。プロセス系やIP系のルールは必要な優先順位に合わせ、最後に分かりやすい MATCH を残してください。一度に変更する条件は1種類に絞り、新しい接続でマッチ結果を確認しましょう。DNS、TUN、ルール全体を同時に変更するより、原因を特定しやすくなります。