Clashのカスタムルール設定ガイド:DOMAIN-SUFFIX・GEOIP・MATCHの優先順位
Clashのルール構文と上から順に最初に一致したルールが適用される仕組みを解説。rule-providersの参照方法や、ルール競合の解決方法も紹介します。
まずルールモードを確認し、次に優先順位を調整する
例外となる具体的なルールを先に、対象範囲の広いルールを後に置き、最後にMATCHで残りの通信を処理します。Clashの通常のルールリストは上から順に評価され、最初に一致したルールのポリシーが適用されます。「より具体的な」ルールが自動的に優先されるわけではありません。
変更前に、クライアントがルールモードになっていることを確認してください。グローバルモードでは通常のルールリストに基づいて通信先が決まらず、直接接続モードではプロキシルールを検証できません。画面上の名称はクライアントによって異なりますが、モード切替で「ルール」または「Rule」を選び、実行中の設定でmode: ruleになっていることを確認します。
ルール・ポリシー・実際の接続先を区別する
- ルール:通信が条件に一致するかを判定します。たとえば、ドメインが
example.comで終わるかどうかです。 - ポリシー:通信の処理先を決めます。組み込みの
DIRECTやREJECT、またはPROXYというポリシーグループを指定できます。 - 実際の接続先:ポリシーグループで現在選択されているノードや直接接続の設定です。
PROXYに一致しても、必ずリモートノードを経由するとは限りません。グループ内の選択先も確認してください。
この記事のPROXYは任意のグループ名で、すべての設定に組み込まれているポリシーではありません。サブスクリプション内のグループ名が「ノード選択」なら、ルールの末尾にもその正確な名前を指定してください。名前や大文字・小文字が異なる場合、または該当するグループがない場合、設定の読み込みに失敗することがあります。
DOMAIN・DOMAIN-SUFFIX・IPルールの違い
対象の情報に応じてルールの種類を選びます。ドメインルールはWebサイトやサービスの振り分けに、IPルールは固定アドレス・ローカルネットワーク・地理的なIP判定に適しています。基本的な書式は種類,マッチ対象,ポリシーです。MATCHにはマッチ対象がないため、フィールドは2つだけです。
| 種類 | ルールの例 | マッチ範囲 |
|---|---|---|
| DOMAIN | DOMAIN,api.example.com,DIRECT |
指定した完全一致のドメインのみ |
| DOMAIN-SUFFIX | DOMAIN-SUFFIX,example.com,PROXY |
ルートドメインとすべてのサブドメイン |
| DOMAIN-KEYWORD | DOMAIN-KEYWORD,example,PROXY |
ドメイン名に指定した文字列を含む対象 |
| IP-CIDR | IP-CIDR,192.168.0.0/16,DIRECT,no-resolve |
指定したIPv4ネットワーク |
| GEOIP | GEOIP,CN,DIRECT |
IPデータに基づきCNに属するかを判定 |
| MATCH | MATCH,PROXY |
前のルールに一致しなかった通信 |
ドメイン欄にはホスト名だけを指定する
DOMAIN-SUFFIX,example.com,PROXYのように記述し、https://example.com/pathとは書きません。プロトコル、パス、クエリパラメーター、ポートは不要です。また、*.example.comと書く必要もありません。サフィックスルールはexample.comとwww.example.comの両方に一致しますが、文字列が似ているだけのnotexample.comには一致しません。
DOMAIN-KEYWORDはマッチ範囲がより広いルールです。キーワードにexampleを指定すると、振り分けたいサイトとは無関係なドメインにも一致する可能性があります。文字列によるマッチが本当に必要な場合にだけ使い、Webサイトの振り分けでは、まず完全一致のドメインかドメインサフィックスを選びましょう。
IP-CIDRとGEOIPの違い
IP-CIDRは、アドレスが指定したネットワーク範囲に含まれるかを直接判定します。GEOIPは、カーネルが読み込んだ地理IPデータを使って判定します。接続先IPの割り当て地域だけを判定し、ページの内容、ドメインの登録地、アクセスする人の場所は判断基準にしません。日本語以外のサイトが海外CDNを使っている場合、GEOIP,CNに一致しないこともあります。
IPv6のネットワークには、IP-CIDR6ルールを使います。たとえばIP-CIDR6,fc00::/7,DIRECT,no-resolveのように記述します。IPv4の例外だけを追加して、同じサービスへのIPv6接続も同じ接続先になると判断しないでください。
最初に一致するルールを基準に、例外とフォールバックを並べる
まず、明確な競合例を確認しましょう。api.example.comは直接接続し、それ以外のexample.comのサブドメインはプロキシ経由にしたい場合、完全一致の例外をサフィックスルールより前に置きます。
rules:
- DOMAIN,api.example.com,DIRECT
- DOMAIN-SUFFIX,example.com,PROXY
- GEOIP,CN,DIRECT
- MATCH,PROXY
api.example.comにアクセスすると、最初のルールに一致してDIRECTが選ばれます。www.example.comにアクセスすると、最初のルールには一致せず、2番目のルールに一致してPROXYに渡されます。- それ以外のドメインでは、IPの割り当て地域を続けて確認し、CNの条件に一致すれば直接接続します。
- ここまでのルールに一致しない通信は、最後の
MATCHによってPROXYに渡されます。
最初の2つのルールを入れ替えると、サフィックスルールが先にapi.example.comを処理するため、完全一致のルールは実行されません。MATCHを先頭に置くと、さらに単純です。後続の通常ルールはすべてマッチする機会を失います。
読み込み可能な最小構成で名前を確認する
次の設定例は構成要素の関係を示すもので、リモートプロキシノードは含みません。PROXYを参照できるよう、同じ名前の選択グループを作成し、仮にDIRECTだけを登録しています。そのため、ルールがこのグループに一致しても最終的には直接接続になります。実際に使う際は、サブスクリプションに含まれるノードやポリシーグループを残してください。
mixed-port: 7890
mode: rule
log-level: info
proxy-groups:
- name: PROXY
type: select
proxies:
- DIRECT
rules:
- DOMAIN,api.example.com,DIRECT
- DOMAIN-SUFFIX,example.com,PROXY
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,PROXY
mixed-port: 7890は、ここではローカルHTTP/SOCKS混合プロキシのポート番号であり、ルールのマッチ条件ではありません。使用中のクライアントが別のポートを使う場合は、実際の待ち受けポートを確認してください。既存の設定を変更するときに、トップレベルのrules:を重複して追加するのも避けてください。既存のリストを編集するか、クライアントの設定マージ機能を利用します。
GEOIP・DNS・no-resolveの関係を理解する
まず明確なドメインルールを適用し、その後でIP判定が必要かを検討します。ドメインだけがあり、利用できる接続先IPがまだない場合、IPルールの評価時に名前解決が行われることがあります。よく使うドメインの例外をGEOIPより前に置くと、振り分けの意図が明確になり、不要なIP判定も減らせます。
no-resolveはDNSを無効にする設定ではない
このオプションに対応するIPルールの末尾にno-resolveを追加すると、そのルールの判定のためにドメインを積極的に名前解決しないよう指定できます。通信に利用可能なIPがすでに含まれていれば、そのIPに基づく判定は引き続き可能です。システムDNSを無効にするものではなく、その後の処理で名前解決が一切行われないことを保証する設定でもありません。
rules:
- DOMAIN-SUFFIX,example.com,PROXY
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- GEOIP,CN,DIRECT,no-resolve
- MATCH,PROXY
この設定は、no-resolveを付けない場合と同じ結果になるとは限りません。接続先IPがまだ分からないと、オプション付きのGEOIPルールに一致せず、リクエストはそのままMATCHに進むことがあります。名前解決を減らすために、すべてのIPルールへ機械的にこのパラメーターを追加するのは避けてください。
カーネルにドメイン情報が渡らなければ、ドメインルールでは判定できない
アプリがIPアドレスへ直接接続したり、暗号化DNSで独自に名前解決したりする場合があります。その場合、接続記録に元のドメイン名が含まれないことがあります。TUNで通信を取り込んでも、すべてのリクエストのドメイン名が必ず保持されるわけではありません。Fake-IPのマッピングや適切に設定されたスニッフィング機能によって、条件が合えばドメイン情報を復元できる場合がありますが、すべてのプロトコルで復元できるとは限りません。
- まず接続の詳細でホスト名と接続先IPを確認し、カーネルが実際に取得している情報を把握します。
- 次に、DNSリクエストが想定どおりカーネルに渡っているか確認します。アプリとシステムで別々の名前解決経路を使っていないかも調べてください。
- 最後にDNSやスニッフィングの設定を調整します。ドメイン情報がない問題を、ドメインルールの追加で覆い隠さないでください。
rule-providersでルールファイルを分割する
繰り返し管理するルールは個別のファイルにまとめ、RULE-SETで参照できます。rule-providersではルールの取得元を宣言し、rulesで参照する位置によって優先順位が決まります。プロバイダーを宣言しただけでは、ルールは自動的に振り分けに使われません。
メイン設定でローカルルールセットを宣言する
以下はmihomoが対応するローカルファイルプロバイダーの例です。ファイルパスはカーネルの作業ディレクトリを基準に解決されます。クライアント独自の設定ディレクトリを使う場合もあるため、カーネルの作業ディレクトリを確認してからrules/local-direct.yamlを作成してください。
rule-providers:
local-direct:
type: file
behavior: classical
format: yaml
path: ./rules/local-direct.yaml
rules:
- DOMAIN,api.example.com,PROXY
- RULE-SET,local-direct,DIRECT
- GEOIP,CN,DIRECT
- MATCH,PROXY
ルールファイルにはマッチ条件だけを書く
次の内容を上記のパスに保存します。classical形式では、ドメインやネットワーク範囲などの条件を記述できます。最終的なポリシーはメイン設定のRULE-SET,local-direct,DIRECTで指定するため、各ルールには記述しません。
payload:
- DOMAIN-SUFFIX,example.com
- DOMAIN,intranet.example.net
- IP-CIDR,192.168.0.0/16,no-resolve
この順序では、api.example.comはメイン設定の完全一致ルールに先に一致し、PROXYに渡されます。それ以外でルールセットの条件に一致する通信はDIRECTになります。RULE-SETを先頭に移動すると、ルールセット内のサフィックス条件が先にAPIドメインを処理します。
behavior: domain、ipcidr、classicalでは内容の形式が異なります。宣言だけを変更して、互換性のないファイル内容をそのまま使うことはできません。他の人のルールセットを使う場合は、形式、パス、カーネルの対応状況を確認してから再読み込みし、ログをチェックしてください。リモートプロバイダーではダウンロードや更新状態も関係します。ダウンロードに失敗した場合は、ルールの順序を疑う前にプロバイダーを確認しましょう。
接続ログからルールの競合を特定する
同じ接続先に新しく接続し、「一致したルール」「ポリシーの経路」「実際の接続先」の3点を記録します。ページが表示されるかどうかだけでルールの有効性を判断しないでください。キャッシュ、既存の接続、ポリシーグループの選択によって、結果が変わらないように見えることがあります。
- 通信が取り込まれているか確認:クライアントの接続一覧を開き、対象にアクセスします。該当する接続が表示されない場合は、ルールを変更し続ける前に、システムプロキシ、アプリのプロキシ設定、またはTUNでの通信取り込みを確認してください。
- モードを確認:ルールモードになっていることと、変更した設定が有効になっていることを確認します。
- 最初に一致したルールを確認:接続の詳細やログでルールの種類とマッチ対象を調べ、メイン設定またはルールセット内の該当箇所を特定します。
- ポリシーの経路を確認:グループ内で現在選択されている項目を確認します。たとえば
PROXYに一致しても、グループ内でDIRECTが選択されていれば、実際には直接接続されます。 - 接続を作り直す:設定を保存して再読み込みしたら、テスト対象の既存接続を閉じて、もう一度試します。既存の接続は通常、ルールを更新しても自動的に接続先が切り替わりません。
ローカルポートを指定してテストする
混合プロキシが127.0.0.1:7890で実際に待ち受けている場合、以下のコマンドでそのポートを経由するリクエストを送信できます。実際のサービスをテスト対象にしてください。ここにある予約済みのサンプルドメインはコマンドの形式を示すもので、回線の動作を表すものではありません。
curl --proxy http://127.0.0.1:7890 --connect-timeout 10 --max-time 20 -I https://example.com
SOCKS経由でテストし、ドメイン名の名前解決をプロキシ側に任せる場合は、socks5hを使えます。ローカルで先に名前解決するテスト方法とは、プロキシに渡されるドメイン情報が異なる場合があります。結果を比較するときは、使用したプロトコルも記録してください。
curl --proxy socks5h://127.0.0.1:7890 --connect-timeout 10 --max-time 20 -I https://example.com
| 現象 | まず確認する項目 | 対処方法 |
|---|---|---|
| すべての接続がMATCHに一致する | MATCHの位置、接続先にドメイン名があるか、前段のルールが読み込まれているか | フォールバックを末尾に移し、実行中の設定と接続メタデータを確認する |
| 完全一致のドメイン例外が適用されない | 前にあるサフィックスルール、キーワードルール、またはRULE-SET | 例外となる具体的なルールを、対象を包含するルールより前に移動する |
| プロキシグループに一致しても直接接続される | ポリシーグループで現在選択されている項目と、ネストされたポリシーの経路 | 必要な接続先を選択してから、新しい接続を確立する |
| 設定の再読み込みに失敗する | YAMLのインデント、ポリシー名、ルールセットのパスと形式 | エラーログから該当項目を特定し、設定を使える状態に戻してから一つずつ変更する |
サブスクリプション更新後もカスタムルールを維持する
クライアントが明示的に対応している永続的な上書き、マージ、またはカスタムルール機能を優先して使いましょう。サブスクリプションから生成された設定を直接編集すると、次回の更新で変更が上書きされる可能性があります。クライアントによってメニュー名や処理手順は異なるため、その機能が元の設定を変更するのか、設定ファイルを生成するのか、一時的に実行中の設定だけを編集するのかを確認してください。
エディターだけでなく、最終的な実行設定を確認する
- ルールの挿入位置を確認:「先行ルール」には具体的な例外を指定します。
MATCHより後ろに追加したルールはマッチする機会がありません。 - 配列の処理方法を確認:マージ方法によって、
rulesに追加される場合と、リスト全体が置き換わる場合があります。まずテスト用のルールを1つ使って動作を確認してください。 - 名前が変わっていないか確認:サブスクリプションの更新でポリシーグループ名が変わった場合は、存在しないポリシーを参照しないようローカルルールも更新します。
- プロバイダーの状態を確認:メイン設定の参照、プロバイダーファイル、パスがすべて有効である必要があります。どれか一つが欠けても読み込みに影響することがあります。
一度に変更するルールの種類は一つにし、変更前後の使える設定をそれぞれ保存してください。まず完全一致のドメインで検証し、その後ドメインサフィックスやルールセットへ広げます。これにより、「ルールに一致していない」「誤ったポリシーに一致した」「接続先そのものに接続できない」を切り分けやすくなり、サブスクリプション更新後の確認も簡単になります。