この記事で分かること
rule-providersは、Clash や Mihomo の設定ファイルからルール本体を分離し、外部ファイルとして読み込むための仕組みです。プロキシ設定が大きくなると、毎回メインの YAML を直接編集する方法は管理しにくくなります。特定サービス用のドメイン一覧、社内システムの除外リスト、開発環境だけで使う一時ルールなどを別ファイルに分ければ、用途ごとの変更履歴を追いやすくなり、複数の端末へ同じ分流ポリシーを配布する作業も簡単になります。
本稿では、GitHub で自作ルールを管理し、Clash の rule-providers から定期取得する構成を、Clash Verge Rev や Mihomo 系クライアントで利用することを前提に説明します。プロバイダーの定義、外部ルールファイルの YAML 記述、RULE-SET による呼び出し、更新間隔とキャッシュの考え方、ルールの優先順位、さらに「ファイルは更新したのに通信が変わらない」「GitHub から取得できない」といったトラブルの調査までを一通り扱います。
重要なのは、GitHub を単なるファイル置き場として使わないことです。誰が変更したのか、何のために追加したのか、どのクライアントで検証したのかをコミット履歴や Pull Request に残すことで、ルール変更を設定変更ではなく小さなコード運用として扱えます。個人利用でも、後から原因を戻せるという点で大きなメリットがあります。
rule-providers の仕組みと設計方針
通常の Clash 設定では、rules: の下に多数のルールを直接並べます。この方法は少量のルールなら分かりやすい一方、ドメインが数十件、数百件に増えると、プロキシグループの変更とルールリストの変更が同じファイルに混在します。rule-providers では、メイン設定に「どの URL から、どの形式のルールを取得し、どこへ保存するか」だけを定義し、個々のルールは別ファイルに置きます。
概念的には、次の三層に分けて考えると整理しやすくなります。
- プロバイダー定義:名前、取得方式、URL、ルール形式、更新間隔、ローカル保存先を指定します。
- ルール本体:対象となるドメインや IP、正規表現などを一行ずつ記述します。
- 呼び出し側:
RULE-SET,プロバイダー名,ポリシーの形で、どのグループへ送るかを指定します。
最初に決めたいのは、ルールを用途別に分ける基準です。たとえば ai-services、github-dev、streaming、direct-domains のようにサービスや通信方針で分けると、変更の影響範囲を説明しやすくなります。一方で、ドメインを一つずつプロバイダーにするのは細かすぎます。更新頻度、担当者、送信先ポリシーが異なる単位を目安にしてください。
behavior と取得方式を選ぶ
ルールファイルの形式は、内容に合わせて選択します。一般的なリストを一行一ルールで管理するなら classical が扱いやすく、既存のルール記法をそのまま読み込めます。ドメインだけを列挙する場合は、クライアントの対応状況を確認したうえで domain 系の形式を使う方法もあります。形式と実際のファイル内容が一致しないと、取得自体は成功してもルールがマッチしません。
取得方式は、GitHub の公開ファイルを定期的に読むなら type: http が基本です。url にはブラウザで表示する GitHub の HTML ページではなく、実データを返す Raw URL を指定します。GitHub のリポジトリ画面の URL をそのまま設定すると、YAML ではない HTML を受け取るため、構文エラーや空のプロバイダーとして扱われる原因になります。
GitHub リポジトリの分け方
小規模な個人運用では、専用リポジトリを一つ作り、ルールをディレクトリごとに管理する構成が便利です。README には、各ファイルの目的、想定するポリシー、更新日、検証方法を書いておきます。ファイル名にサービス名と用途を含めると、Clash のログや設定画面で見たときにも意味を把握しやすくなります。
- rules/ai-services.yaml:AI API や関連コンソールなど、同じ経路へ送るドメイン。
- rules/github-dev.yaml:GitHub、リリース配布、開発用 SaaS などのルール。
- rules/direct.yaml:プロキシを通さない社内サービスや地域サービス。
- tests/:追加したドメインの目的や、確認に使ったコマンドを記録する場所。
公開リポジトリでは、購読 URL、認証情報、社内ホスト名、個人の IP アドレスを絶対に含めないでください。公開が適さないルールは非公開リポジトリや自分で管理する HTTPS サーバーを使い、アクセス制御と配布方法を別途設計します。GitHub の URL を知っている人なら誰でも取得できる構成では、機密情報を保護できません。
Clash の YAML にプロバイダーを定義する
次の例は、GitHub の Raw URL に置いた classical 形式のルールを 24 時間ごとに取得し、ローカルへ保存する最小構成です。プロキシグループ名の Proxy は、実際の設定に存在する名前へ置き換えてください。
rule-providers:
ai-services:
type: http
behavior: classical
url: https://raw.githubusercontent.com/example/clash-rules/main/rules/ai-services.yaml
path: ./ruleset/ai-services.yaml
interval: 86400
rules:
- RULE-SET,ai-services,Proxy
- MATCH,DIRECT
path は取得したファイルをクライアントが保存する場所です。相対パスを使う場合、プロファイルの保存場所やクライアントの権限によって挙動が異なることがあります。Clash Verge Rev で複数のプロファイルを使う場合は、どのプロファイルが実際に有効なのかを先に確認してください。設定を編集したファイルと、現在動作中のファイルが違うという問題は非常に多くあります。
interval は秒数です。GitHub Actions で一日に一度更新するルールなら、86400 程度で十分です。数分単位に短くしても、GitHub 側の更新、Raw CDN のキャッシュ、クライアント内部のキャッシュがあるため、即時反映が保証されるわけではありません。頻繁な取得は不要なアクセスを増やすため、実際の更新頻度より短くしないのが原則です。
ルールファイルの書き方
classical 形式では、Clash の rules: に記述できる形式を一行ずつ並べます。たとえば特定のドメインとそのサブドメインをまとめて対象にするなら、DOMAIN-SUFFIX を使います。完全一致だけにしたい場合は DOMAIN を選びます。広すぎる DOMAIN-SUFFIX を使うと、意図していない関連サービスまで同じポリシーへ送られる可能性があるため、実際の通信ログで範囲を確認してください。
payload:
- DOMAIN-SUFFIX,example.dev
- DOMAIN,api.example.dev
- DOMAIN-SUFFIX,githubusercontent.com
配布するファイルの形式は、使用する Mihomo のバージョンやクライアントの仕様に合わせてください。環境によっては先頭キーに payload: が必要な形式と、ルール行だけを並べる形式があります。公式ドキュメントや現在のクライアントが生成するプロバイダー例を基準にし、まず一つの小さなファイルで読み込みを検証するのが安全です。ルールを大量に移行してから形式の違いを調査すると、どの行が原因か分かりにくくなります。
ルールの優先順位を確認する
Clash のルールは通常、上から下へ評価され、最初に一致した行のポリシーが採用されます。したがって、rule-provider を定義しただけでは通信経路は変わりません。rules: の中で RULE-SET を呼び出す必要があります。また、広い範囲を対象にするルールを上へ置くと、下にある例外ルールへ到達しません。
- まず、特定の例外や社内ホストなど、範囲が狭いルールを置きます。
- 次に、サービス単位の
RULE-SETを配置します。 - 最後に
GEOIP、一般的な地域ルール、MATCHなどの広い条件を置きます。
たとえば同じドメインが「DIRECT」と「Proxy」の両方に含まれている場合、上にある方が勝ちます。ルールファイル同士の重複を完全になくす必要はありませんが、意図的な例外にはコメントを付け、README に理由を書いてください。後から見た人が単純な重複ミスと判断して削除すると、通信経路が変わることがあります。
GitHub を使った更新運用
ルールの追加は、いきなり本番用のファイルを上書きするのではなく、変更理由を小さく分けてコミットすると安全です。たとえば「API エンドポイントを追加」「不要な CDN を削除」「プロキシ経由の動作を確認」という単位で記録します。コミットメッセージが具体的なら、通信障害が発生した際に直前の変更だけを戻して比較できます。
複数人で管理する場合は、Pull Request に対象ドメイン、想定される通信、DIRECT と Proxy のどちらを選ぶ理由、検証したクライアントを記載します。レビューでは、ドメインの範囲が広すぎないか、個人情報や内部ホストが混ざっていないか、既存ルールより上に置く必要があるかを確認します。ルールは短いテキストでも通信全体へ影響するため、通常の設定ファイルより軽く扱わないことが大切です。
GitHub Actions を使えば、YAML の構文チェックや重複検出を自動化できます。たとえば Pull Request ごとにファイルの空行や不正な記法を検査し、main ブランチへマージされた後だけ配布対象にする方法があります。ただし、自動チェックが成功しても、実際の DNS 解決、TLS 接続、プロキシグループの可用性まで保証されるわけではありません。最終的には Clash のログと実通信で確認してください。
更新を反映するタイミング
GitHub 上のファイルを更新した直後に、Clash の画面で古い内容が表示されることがあります。これは設定ミスとは限らず、クライアントが interval に従って次回更新を待っている、ローカルの path に保存されたファイルを使っている、Raw 配信側のキャッシュが残っている、といった理由が考えられます。まずプロバイダー画面から手動更新を実行し、その後にルールの最終更新時刻や取得状態を確認してください。
設定を変更した場合は、保存だけでなくプロファイルの再読み込みが必要なクライアントもあります。再読み込み後にプロキシグループが初期化されることがあるため、意図したグループが選択されているかも確認します。更新頻度を短くする前に、手動更新、設定再読み込み、クライアント再起動の順でどこまで反映されるかを把握しておくと、日常の運用が安定します。
通信トラブルをログから調査する
rule-provider を導入した後に通信できなくなった場合、最初から TUN や DNS を大きく変更するのではなく、問題を「取得」「解析」「マッチ」「出口」の四段階に分けます。各段階を一つずつ確認すれば、GitHub 側の問題と Clash 側の問題を混同せずに済みます。
- 取得を確認する:ブラウザや
curlで Raw URL にアクセスし、期待するテキストが返るか確認します。404、リダイレクト、GitHub のエラーページが返る場合は URL やブランチ名を見直します。 - 形式を確認する:プロバイダーの
behaviorと、実ファイルの構造が一致しているか確認します。YAML のインデント、キー名、不要な Markdown のコードフェンスも調べます。 - マッチを確認する:アクセス先のホスト名がルール内のドメインと一致しているか、Clash のログで実際に適用されたルール名を確認します。ブラウザの表示 URL と、裏で接続する API ホストが異なる場合もあります。
- 出口を確認する:ルールは正しくマッチしていても、選択したプロキシグループのノードが停止していれば通信できません。別ノードや DIRECT との比較で出口側を切り分けます。
特に多いのが、GitHub では更新済みなのに、Clash のログでは古いプロバイダー名しか出ないケースです。この場合は編集したブランチと URL のブランチが違う、ファイル名を変更したのに URL を更新していない、複数のプロファイルのうち別のものが有効になっている、といった可能性があります。設定画面で現在使用中のプロファイルを確認し、Raw URL を直接取得して内容とコミットを照合してください。
ルールがマッチしない場合は、まず対象ホストを広げるのではなく、ログに出ている完全なドメイン名を記録します。CDN、認証、更新サーバーなどが別ホストになっていることがあるためです。ただし、関連しそうなドメインを無制限に追加すると、不要な通信まで Proxy へ送ることになります。追加後は対象アプリのログイン、更新、主要機能をそれぞれ確認し、不要なルールを整理してください。
同類の GUI ツールでは、ルールを画面上で簡単に追加できても、変更履歴の比較や複数端末への再配布が難しく、設定を作り直すたびに例外が消えることがあります。Clash の rule-providers なら、GitHub のコミット履歴で差分を追跡し、用途別ファイル、更新間隔、ルール優先順位、Clash ログを一つの運用にまとめられます。自作ルールを継続的に改善したい人にとって、この再現性と切り戻しやすさが実用上の大きな利点です。