まずカーネル、モード、プロキシグループを確認

「中国本土のサイトは直結、海外サービスはプロキシ経由」という設定は、サービスの所在地を自動判定するスイッチではなく、接続ごとに照合するルールの集合です。Clashはrulesの先頭から順に確認し、最初に一致したルールの出力ポリシーを適用します。それ以降のルールは確認されません。そのため、同じドメインでも記述する位置によってルーティング結果が変わることがあります。

この記事では、Clash Metaの後継として使われるmihomoカーネルを主な設定環境としています。クライアントは管理画面であり、ルールを解析するのはカーネルです。クライアント名が似ていても、対応するフィールドが同じとは限りません。旧版Clashカーネルでは、GEOSITEを含む設定例をそのまま使えません。まずクライアントのカーネル情報で実際のカーネルを確認し、ログに「未知のルールタイプ」やデータファイルの読み込み失敗がないかチェックしてください。

変更前に確認する3つのポイント

  1. モードがRule:設定の値がmode: ruleになっていることを確認します。Globalモードでは全体ポリシーが適用され、Directモードではすべて直接接続になります。どちらもこの記事のルール一覧による振り分けは行いません。
  2. プロキシグループが存在する:この記事では、既存のポリシーグループ名を海外プロキシと表記しています。現在の設定に実在するグループ名に置き換え、プロキシ画面で利用可能なノードを選んでください。ルールを変更しただけではノードは作成されません。
  3. 元の設定を残す:まず現在の設定を複製し、コピーでテストしてください。サブスクリプションの更新で直接編集した内容が上書きされることがあります。継続して使う場合は、クライアントが対応するオーバーライドまたはマージ機能で管理し、最終的に適用された設定を確認してください。

4種類のルール:ドメイン・地理データ・ルールセット

種類照合対象用途
DOMAIN-SUFFIX指定したドメインとそのサブドメイン少数のサイトに対する個別指定
GEOSITEドメイン分類データ中国本土・海外のドメイン分類
GEOIP接続先IPアドレスの所在地接続先IPが判明している場合の振り分け
RULE-SET外部またはローカルのルールプロバイダーサイトのルールをまとめて個別管理

DOMAIN-SUFFIX:個別の例外設定に便利

DOMAIN-SUFFIX,github.com,海外プロキシはgithub.comとapi.github.comに一致しますが、githubusercontent.comには一致しません。後者は別のドメインなので、個別のルールが必要です。特定のホストだけを対象にする場合は、DOMAIN,api.github.com,海外プロキシを使うと、ドメイン全体のサービスを同じ出口にまとめずに済みます。

GEOSITE:分類はデータファイルに依存

GEOSITE,cn,DIRECTは地理ドメインデータ内のcn分類を使うもので、「末尾が.cnのすべてのドメイン」を意味するわけではありません。同様に、一般的なデータセットのgeolocation-!cnは海外ドメインの分類であり、数学的な意味でのcn集合の完全な補集合ではありません。分類の有無や対象サイトは、読み込まれているデータファイルとその更新時期によって変わります。

この例を使う前に、mihomoがcnとgeolocation-!cnを含むgeosite.datを正常に読み込んでいることと、GEOIPで使う地理IPデータがあることを確認してください。geodata-mode: trueの場合はgeoip.datを使います。一般的なデフォルトモードではMMDBデータが使われます。データの更新方法はクライアントごとに異なるため、ログで読み込み成功を確認してください。

GEOIP:IPアドレスを判定し、サイトの所属先は判定しない

GEOIP,CN,DIRECTは、接続先IPが中国本土のアドレス範囲に属するかを判定します。海外サービスが中国本土のCDNを使っている場合、そのIPもCNに一致することがあります。反対に、中国本土のサービスが海外のクラウドを使っていると、一致しない場合があります。IP分類より前にドメイン分類を置くことで、サービス単位の接続方針を優先できます。

ルール末尾のno-resolveは、このIPルールのためにドメイン名の解決を積極的に行わないという指定で、「DNSを禁止する」という意味ではありません。接続に実際の接続先IPが含まれていれば照合できますが、ドメイン名しかなく実IPを利用できない場合は、このルールがスキップされることがあります。追加するとルール照合による名前解決を減らせますが、データに含まれない中国本土のドメインがすべて直接接続されるとは限りません。

ルールの順序:LAN、個別指定、分類、フォールバック

以下の設定例は、「中国本土でよく使うサイトは直接接続し、それ以外の通信はデフォルトでプロキシ経由」にする場合に適しています。順序は、LAN向けの除外、手動指定した海外サイト、中国本土ドメインの分類、海外ドメインの分類、中国本土IP、最後のフォールバックです。MATCHは残りの接続すべてに無条件で一致するため、必ず最後に配置します。

# mihomoの設定例。海外プロキシは既存のポリシーグループを指定
mode: rule

rules:
  - DOMAIN,localhost,DIRECT
  - DOMAIN-SUFFIX,lan,DIRECT
  - 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-CIDR,169.254.0.0/16,DIRECT,no-resolve
  - IP-CIDR6,::1/128,DIRECT,no-resolve
  - IP-CIDR6,fc00::/7,DIRECT,no-resolve
  - IP-CIDR6,fe80::/10,DIRECT,no-resolve

  - DOMAIN-SUFFIX,github.com,海外プロキシ
  - DOMAIN-SUFFIX,githubusercontent.com,海外プロキシ
  - DOMAIN-SUFFIX,githubassets.com,海外プロキシ

  - GEOSITE,cn,DIRECT
  - GEOSITE,geolocation-!cn,海外プロキシ
  - GEOIP,CN,DIRECT,no-resolve
  - MATCH,海外プロキシ

LAN向けルールを先頭に置く理由

ルーターの管理画面、NAS、社内サービスは、通常プライベートIPアドレスを使います。たとえば192.168.1.1への通信をリモートプロキシに送っても、現在のネットワーク内にあるルーターには届きません。プライベートアドレスを先に直接接続することで、最後のプロキシへのフォールバックに拾われるのを防げます。172.16.0.0/12の範囲は172.16から172.31までです。1つの小さなネットワークだけをカバーする172.16.0.0/16と混同しないでください。

ドメインルールが決めるのは出力先であり、名前解決ができることまでは保証しません。社内ドメインでは社内DNSが必要な場合があります。また、.localはmDNSで使われることが多く、ドメインを直接接続するルールを追加するだけでは解決できません。TUNを有効にしている場合は、内部ネットワークのルートとDNSの引き継ぎ設定も確認してください。ルールがDIRECTに一致することと、システムからLANにアクセスできることは、別々に確認する必要があります。

フォールバックはプロキシと直接接続のどちらにするか

ここでいう「海外プロキシ」は接続方針を表すもので、通信品質を保証するものではありません。ポリシーグループでDIRECTが選択されていれば、ルールがそのグループに一致しても最終的には直接接続されます。調査時は、一致したルールと最終的な接続経路の両方を確認してください。

RULE-SET:よく使うサイトのルールを個別管理

手動で管理するドメインルールが増えてきたら、ルールプロバイダーに移せます。以下ではローカルのYAMLファイルを使うため、ルールのダウンロードは不要です。ファイルはカーネルから読み取れる作業ディレクトリに置いてください。相対パスの基準は通常カーネルの作業ディレクトリで、現在のサブスクリプションファイルの場所とは限りません。

手順1:ローカルルールファイルを作成する

rules/overseas.yamlとして保存します。これはルールセットのファイルであり、クライアントのメイン設定ではありません。ルートキーは必ずpayloadにします。以下ではclassical形式を使います。各項目にはルールタイプを含めますが、出力ポリシーは含めません。

payload:
  - DOMAIN-SUFFIX,github.com
  - DOMAIN-SUFFIX,githubusercontent.com
  - DOMAIN-SUFFIX,githubassets.com

手順2:メイン設定に宣言して参照する

以下のプロバイダー設定を既存のrule-providersに統合し、前のセクションにある3つのGitHubドメインルールをRULE-SETに置き換えます。参照ルールはLAN向けルールの後、GEOSITEルールの前に配置してください。以下はその前後だけを示した例です。省略した既存ルールは実際の設定に残してください。

# メイン設定の一部:ローカルプロバイダーを宣言
rule-providers:
  overseas-manual:
    type: file
    behavior: classical
    format: yaml
    path: ./rules/overseas.yaml
# rules一覧の該当位置の例。リスト全体ではありません
  - RULE-SET,overseas-manual,海外プロキシ
  - GEOSITE,cn,DIRECT
  - GEOSITE,geolocation-!cn,海外プロキシ
  - GEOIP,CN,DIRECT,no-resolve
  - MATCH,海外プロキシ

behavior: domain、ipcidr、classicalはそれぞれ項目の形式が異なります。フィールドだけを変更して、元のファイル内容をそのまま使うことはできません。HTTPプロバイダーに切り替える場合は、実際の取得元、キャッシュパス、更新間隔も設定し、ダウンロードが成功することを確認してください。ルール一覧にRULE-SETがあっても、ルールファイルの読み込み成功を意味するわけではありません。プロバイダーの状態とカーネルのログを確認してください。

振り分けを検証する:ページが開くかだけでなく、新しい接続を確認

ページが開けても、何らかの経路でアクセスできたことしか分からず、想定した出口を通った証明にはなりません。設定を保存して再読み込みした後、クライアントの「接続」画面で対象ドメイン、接続先IP、一致したルール、ポリシーの経路を確認してください。「ログ」画面ではルールファイルの読み込みエラーを確認します。画面名はクライアントによって異なるため、プロキシのオン・オフだけを見るのではなく、この4つの項目を探してください。

再現可能な確認手順

  1. 設定でmode: ruleが有効になっていることを確認し、テスト中はlog-level: infoを使います。名前解決の詳細を調べる場合のみdebugに変更し、完了したら戻してください。大量のログが長時間出続けるのを防げます。
  2. 現在のテスト接続を終了してから、新しいリクエストを送信してください。ブラウザーが接続を再利用すると、以前の出口が引き続き使われることがあります。ルール変更後に古い接続が表示されても、新しいルールが無効とは限りません。
  3. github.comにアクセスし、手動のドメインルールまたはoverseas-manualに一致して、最終的な接続経路に選択したプロキシノードが含まれることを確認します。
  4. 実際に利用している中国本土のサイトにアクセスし、GEOSITE,cnに一致するか確認します。MATCHに流れた場合は、まずドメイン分類とDNSの結果を確認してください。
  5. 現在のネットワークに実在するLAN機器にアクセスし、該当するプライベートネットワークのルールに一致してDIRECTで接続されるか確認します。機器が存在しない場合、接続タイムアウトをルールの不具合と判断しないでください。

指定したプロキシ経由でテストする

実際に適用されている設定がmixed-port: 7890の場合、以下のコマンドを使うとローカルのHTTPプロキシを明示的に経由できます。これにより、システムプロキシの設定がターミナルに適用されていない問題を切り分けられます。ポート番号に固定の標準値はありません。実際のポートが異なる場合は、コマンド内の数字を変更してください。

curl --proxy http://127.0.0.1:7890 --head --max-time 15 https://github.com

--max-time 15は、リクエスト全体の待ち時間の上限を15秒に設定するオプションです。アクセス速度を実測するものではありません。HTTPステータスコードや応答時間だけでは、ルールに一致したかどうかは判断できません。接続画面のルーティング記録と照らし合わせてください。このコマンドで確認できるのは明示的に指定したプロキシ経由の接続であり、すべてのTUN通信が取り込まれていることの検証にはなりません。

よくある設定ミスとDNS・TUNの注意点

症状まず確認する項目修正方法
すべての接続が同じ出口を通るモードがRuleではない、またはMATCHが先頭にあるルールモードを有効にし、フォールバックを末尾に移動
設定を読み込めないポリシーグループ名、YAMLのインデント、カーネルの対応状況ログから原因を特定し、グループ名が完全に一致するか確認
GEOIPが反映されていないように見えるno-resolveの指定と接続先の実IPが利用可能かまずDNSとドメインルールの一致状況を確認
サブスクリプションの更新後にルールが消えるオーバーライド元ではなく生成済みファイルを編集している対応するオーバーライド機能で管理し、最終設定を再確認
海外サービスの一部リソースが読み込めないリソース用ドメインとトップページのドメインが異なる失敗した接続の記録を確認し、個別のドメインルールを追加
LAN内のドメインを開けない内部DNS、TUNのルート、接続先への到達性まず正しいアドレスに名前解決できるか確認してから、直接接続ルールを確認

DNSの振り分けと接続の振り分けは別

nameserver-policyはドメイン名の解決に使うDNSサーバーを選び、rulesはアプリの接続先を選びます。役割は異なります。中国本土のドメインにローカルDNSを設定しても、接続が自動的に直接接続になるわけではありません。逆に、DIRECTルールを指定しても、ローカルDNSが使われるとは限りません。名前解決の経路を制御する場合は、dnsの設定も個別に確認してください。

該当フィールドに対応するmihomoでは、respect-rulesを使うとDNSの上流接続にもルーティングルールを適用できます。ただし、有効にする前にproxy-server-nameserverなどの初期名前解決用設定を正しく構成し、プロキシサーバーのドメイン解決がプロキシ自身に依存する状態を防ぐ必要があります。どの設定にも追加するだけで、すべてのDNS問題を解決できるスイッチではありません。

Fake-IPやTUNを使っても、最初に一致したルールが適用される

Fake-IPは、割り当てたアドレスとドメイン名を関連付けて、後続の接続処理に使う仕組みです。すべてのサイトを自動的に中国本土と海外に分類するものではありません。接続先アドレスがよく使われる198.18.0.0/16のマッピング範囲に見えても、振り分けを「修正」するために範囲全体をDIRECTに追加しないでください。ドメインのマッピングとルールの照合が正常か確認しましょう。

TUNで広がるのは通信を取り込む範囲であり、ルールモードがグローバルプロキシに変わるわけではありません。システムプロキシはプロキシ設定に従うアプリだけに影響します。TUNはより多くのIP通信を取り込めますが、権限、ルート、除外設定の影響を受けます。ルールが適用されるのはカーネルに渡された接続だけです。その他のVPN、システムルート、アプリが独自に確立する接続は、それぞれ個別に確認してください。