Clash config.yamlの構成を徹底解説:portからrulesまで

Clash config.yamlの主要項目を上から順に解説。共通設定、dns、proxies、proxy-groups、rulesの役割や、YAMLのインデントと項目間の参照関係を確認できます。

まずは全体像:5つの設定ブロックのつながり

設定を読むときは、まず入口を確認し、次に名前解決、ノード、ポリシーグループ、ルールの順に見ていきましょう。config.yamlは上から順に実行されるスクリプトではありません。トップレベルの項目は通常、並び順を変更できますが、リスト内の順序は動作に影響する場合があります。特に注意が必要なのがrulesです。ファイルを5つのブロックに分けて整理するのは、読みやすく、問題を見つけやすくするためであり、コアが5段階で順番に処理するという意味ではありません。

この記事では、Clash形式の設定に対応するmihomoコアを主な例として解説します。ClashクライアントはGUIで操作するための入口で、設定の解析や接続処理はコアが担当します。クライアントによっては、port、DNS、TUNなどの項目を追加で統合または上書きする場合があります。編集前に、使用中のコアと、変更対象がサブスクリプションの元ファイル、オーバーライドファイル、またはクライアントからコアに渡される最終的な実行設定のどれなのかを確認してください。

設定ブロック主な役割関連する項目
共通設定待ち受けポート、動作モード、待ち受け範囲を設定アプリのプロキシ設定、クライアントの切り替え
dnsコアのDNS名前解決方式と上流サーバーを設定ドメイン名の名前解決、Fake-IP、DNSの取り込み
proxiesプロキシノードの接続パラメーターを定義ポリシーグループのメンバー名
proxy-groupsノードや他のポリシーをまとめ、選択できる出口を提供ルールの転送先名
rules接続を順番に照合し、転送先を指定ポリシーグループ、ノード、または組み込みポリシー

よくある参照の流れは、rulesがポリシーグループを参照し、そのグループがノード名を参照、ノードが最終的にサーバーアドレス、ポート、認証情報を提供する形です。DIRECTとREJECTは組み込みポリシーなので、proxiesに追加で定義する必要はありません。

共通設定:port、モード、待ち受け範囲

3種類のプロキシポートは、3つのノードを意味しない

portはHTTPプロキシの待ち受けポートで、一般的なHTTPS CONNECTトンネルにも対応します。socks-portはSOCKSプロキシの待ち受けポート、mixed-portは同じポートでHTTPとSOCKSの両方のプロキシリクエストを受け付けます。いずれもローカル側の入口であり、リモートノードのportとは別のものです。

port: 7890
socks-port: 7891
mixed-port: 7892
allow-lan: false
bind-address: "127.0.0.1"
mode: rule
log-level: info
ipv6: false

この設定例では、項目間の関係を示すために3つの異なるポートを使っています。実際の利用で、すべてを有効にする必要はありません。混合プロキシだけを使う場合は、mixed-port: 7892だけを残せます。その場合、ブラウザーやOSのHTTPプロキシには127.0.0.1:7892を指定します。SOCKS対応アプリも同じ混合ポートに接続できます。コアのポートを変更したら、アプリ側の設定も更新してください。アプリが古い7890に接続し続けないようにしましょう。

modeとallow-lan、それぞれの役割

  • mode: rule:ルール一覧に基づいて通信を振り分けます。ドメイン名やIPアドレスごとに接続先を変える、一般的な使い方に適しています。
  • mode: global:主にグローバルポリシーで接続先を選択します。通常のルール一覧に沿って1件ずつ振り分ける方式ではありません。
  • mode: direct:直接接続モードです。クライアントを終了したり、システムプロキシを解除したりする設定ではありません。
  • allow-lan: false:LAN内のデバイスにプロキシの入口を公開しません。共有が必要な場合に限り、待ち受けアドレス、認証、ファイアウォールを追加設定してください。

dns:上流サーバーとDNS通信の取り込み

dnsブロックでは、コアのドメイン名解決を設定します。ただし、「コアのDNSを有効にすること」と「システムのすべてのDNSリクエストをコアに送ること」は別です。次の例では、ローカルの1053ポートでDNSリクエストを受け付け、Fake-IPモードを有効にして、通常のDNS上流サーバーを指定しています。

dns:
  enable: true
  listen: "127.0.0.1:1053"
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 223.5.5.5
  fake-ip-filter:
    - "*.lan"
    - "localhost"

区別しておきたい4つの項目

  • listenは、コアがDNSクエリを受け付けるアドレスとポートです。上流サーバーのアドレスではありません。通常のシステムDNS設定では、1053のようなカスタムポートを直接指定できないことがほとんどです。
  • nameserverは名前解決に使う上流サーバーです。例では通常のDNSを使用しています。接続できるか、現在のネットワークに適した結果が得られるかは、実際の環境に応じて確認してください。
  • enhanced-mode: fake-ipでは、対応する場合にコアが仮想アドレスを返し、ドメイン名との対応関係を保持します。これらのアドレスは、Webサイトの実際のグローバルIPアドレスではありません。
  • fake-ip-filterでは、Fake-IPを使わずに応答するドメインの範囲を指定します。LAN内のホスト名や、特定の互換性要件に対応するために使用します。

TUNを使う場合は、クライアントまたは設定でDNSハイジャックやルーティングの取り込みなどを行い、リクエストをコアに送る必要があります。dns.enable: trueだけでは、システムのルートは自動的に変更されません。システムプロキシを有効にしても、すべてのアプリのDNSクエリがコアに取り込まれるとは限りません。アプリ内蔵の暗号化DNSが、独自の名前解決経路を使う場合もあります。

上流サーバーをhttps://dns.alidns.com/dns-queryのようなドメイン名を含むDoHアドレスに変更する場合は、上流サーバーのドメイン名自体をどう名前解決するかも考慮してください。mihomoのdefault-nameserverは、このようなブートストラップ用の名前解決に利用できます。proxy-server-nameserverは、プロキシノードのドメイン名解決に使います。これらは同じ意味の項目ではありません。接続経路を把握しないまま、複数段階のDNS転送を重ねないようにしてください。

proxies:ノード定義とサブスクリプションの扱い

proxiesは、ノードオブジェクトを並べたリストです。各ノードには通常、name、type、server、portが含まれます。そのほかの認証情報や転送設定は、使用するプロトコルによって異なります。リモートノードのポートは443や、サーバー側で指定された別の値になる場合があります。ローカルのプロキシ待ち受けポートが7890だからといって、ノード側のポートを7890に変更してはいけません。

ノードを編集するときは、各項目の情報源を確認

  1. まず、typeがサーバー側のプロトコルと一致していることを確認してください。対応プロトコルはコアのバージョンによって異なります。ファイルをインポートできても、すべてのプロトコルで接続できるとは限りません。
  2. サーバーアドレス、パスワード、UUID、暗号化方式などの接続パラメーターは、サービス提供元の設定に従ってください。項目名から値を推測してはいけません。
  3. トランスポート層、TLS、証明書名はサーバー側の設定と一致させる必要があります。証明書エラーが発生した場合は、検証を無効にするのではなく、まずドメイン名とシステム時刻を確認してください。
  4. nameは一意にすることをおすすめします。ポリシーグループはこの名前でノードを参照するため、ノード名を変更した場合は参照先も更新してください。

ノードがなくても、正しい設定ファイルは作成できます。proxies: []は空のリストを意味します。ファイル構造の検証には使えますが、プロキシの出口が自動的に作られるわけではありません。後述の完全な例では空のリストとDIRECTを使っているため、設定の読み込みとルール間の関係を確認する目的に限られます。

proxy-groups:名前による参照とポリシーの選択

ポリシーグループでは、ノード、組み込みポリシー、ほかのポリシーグループをまとめ、参照可能な出口として扱います。以下では、直結と拒否の2つの組み込みメンバーだけを持つ手動選択グループを定義します。ノードの認証情報は必要ありません。

proxy-groups:
  - name: "出口の選択"
    type: select
    proxies:
      - DIRECT
      - REJECT

type: selectは、メンバーを手動で選ぶ設定です。クライアントのプロキシ画面でDIRECTを選ぶと、「出口の選択」を参照するルールは直結を使います。REJECTを選ぶと、該当する接続は拒否されます。ルール自体がなくなるのではなく、グループ内で選択したメンバーによって、同じルールの実際の動作が変わります。

よく使われる3種類のポリシーグループ

種類用途設定時の確認ポイント
selectメンバーを手動で選択メンバーが存在し、現在の選択が意図どおりか
url-test疎通テストの結果に基づいて自動選択テストURL、間隔、候補ノードが利用可能か
fallback候補の順に利用可能なメンバーを選択メンバーの順序とヘルスチェックの設定

自動テストの結果は、指定したテスト先までの測定値であり、すべてのWebサイトでの実際のダウンロード速度を示すものではありません。まず構造を理解するだけなら、selectを使って参照関係を確認するのが簡単です。ポリシーグループを入れ子にする場合は、AがBを参照し、BがAを参照するような循環依存を避けてください。

proxy-providersを使う設定では、ポリシーグループは通常、proxiesリストにプロバイダー名を入れるのではなく、useでプロバイダー名を参照します。2つの項目が参照する対象は異なります。「プロキシが見つからない」というエラーが出たら、参照先がノード、ポリシーグループ、ノードプロバイダーのどれなのかを確認してください。

rules:具体的な条件から照合し、最後にデフォルトを置く

ルールモードでは、接続をリストの上から順に照合し、最初に適用されたルールの転送先を使います。設定内のポリシー名は、大文字・小文字、空白、日本語を含め、定義した名前と完全に一致させる必要があります。以下の4つのルールでは、LAN内のドメイン名、例示用ドメイン、プライベートIPアドレス、その他の接続をそれぞれ処理します。

rules:
  - DOMAIN-SUFFIX,lan,DIRECT
  - DOMAIN-SUFFIX,example.org,出口の選択
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - MATCH,出口の選択
  • DOMAIN-SUFFIX,lan,DIRECTは、lanおよびそのサブドメインに一致します。「lan」を含む任意の文字列に一致するわけではありません。
  • DOMAIN-SUFFIX,example.org,出口の選択は、例示用ドメインとそのサブドメインを「出口の選択」に振り分けます。example.orgはルールの構文を説明するための例です。
  • IP-CIDR,192.168.0.0/16,DIRECT,no-resolveは、このプライベートIPv4ネットワークに一致します。no-resolveは、このルールへの照合を目的としたドメイン名の積極的な名前解決を行わない設定です。
  • MATCH,出口の選択は、前のルールに一致しなかった接続を受け付けます。リストの末尾に配置してください。

no-resolveは、設定全体のDNSを無効にするものでも、接続時に名前解決が一切行われないことを保証するものでもありません。関連するIPルールの照合時に、名前解決を積極的に行うかどうかだけに影響します。接続先のIPアドレスがすでに分かっている場合は、引き続きIPルールの照合対象になります。

MATCH,DIRECTを先頭に置くと、そのルールに一致した接続は以降のルールで処理されません。より細かいドメイン例外を指定する場合は、対象範囲の広いサフィックスルールより前に配置してください。GEOIP、GEOSITE、RULE-SETを使う場合は、対応する地理データベースやルールプロバイダーが利用可能かも確認しましょう。データの参照元を確認せず、ルールだけをコピーしないでください。

設定全体の構造:2スペースのインデントと最小構成

以下の設定には外部ノードが含まれておらず、一致した通信はDIRECTだけをメンバーに持つポリシーグループに渡されます。YAMLの構造、待ち受けポート、グループ名の参照を確認するための例です。リモートプロキシを利用できるサブスクリプションではなく、TUNも有効になっていません。コアのDNSは127.0.0.1:1053で待ち受けますが、システムのDNSクエリを受け取るには、OSまたはクライアント側で別途設定が必要です。

mixed-port: 7890
allow-lan: false
bind-address: "127.0.0.1"
mode: rule
log-level: info
ipv6: false

dns:
  enable: true
  listen: "127.0.0.1:1053"
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 223.5.5.5
  fake-ip-filter:
    - "*.lan"
    - "localhost"

proxies: []

proxy-groups:
  - name: "出口の選択"
    type: select
    proxies:
      - DIRECT

rules:
  - DOMAIN-SUFFIX,lan,DIRECT
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - MATCH,出口の選択

YAMLでよくある4つのミス

  1. インデントにTabを使う。インデントは半角スペースに統一します。上の例では、階層が1つ深くなるごとにスペースを2つ増やしています。同じ階層の項目は位置をそろえてください。
  2. トップレベルの項目を前のブロックの下にインデントする。proxies、proxy-groups、rulesは、いずれも行頭から書き始めます。dnsの下にインデントしてはいけません。
  3. リストのハイフンを忘れる。nameserver、ポリシーグループのメンバー、ルールはいずれもリスト形式です。各項目は- で始めてください。
  4. 同じトップレベルキーを重複して定義する。ファイルの末尾に2つ目のdnsやrulesを追加してはいけません。元の位置に統合してください。キーの重複に対する処理はパーサーによって異なる場合があります。

名前に#やコロンの後の空白などの特殊な文字が含まれる場合は、コメントやマッピング構文として解釈されないよう引用符で囲みます。一般的なルール文字列は、日本語名を含むという理由だけで引用符を付ける必要はありませんが、文字列全体を適切に引用符で囲んでも構いません。Webページの全角コロン「:」を、YAMLで使う半角コロン:と混同しないでください。

読み込みの検証:構文から実際の接続まで

設定を保存できたことは、エディターがファイルを書き込めたことを示すだけです。コアが読み込めても、構造や必須項目のチェックを通過したという意味にとどまります。ノードへの接続、DNSが意図した経路を通るか、アプリがプロキシを使っているかは、個別に確認する必要があります。

4つの手順で確認

  1. 現在使えているファイルをバックアップし、config.yamlのコピーを別に作成して編集します。変更は一度に1つの設定ブロックに絞ると、元に戻しやすくなります。
  2. 実際に起動しているmihomoのバイナリで設定をテストします。LinuxまたはmacOSでバイナリがカレントディレクトリにある場合は、次のコマンドを実行できます。
  3. クライアントで設定を再読み込み、または有効化し、ポートの競合、参照先の名前が見つからない、ルールデータが不足しているといったエラーがログに出ていないか確認します。
  4. プロキシを明示してリクエストを送り、入口をテストします。次にクライアントの接続履歴で、適用されたルールとポリシーの経路を確認し、最後にシステムプロキシやTUNによる全体的な通信の取り込みを検証します。
./mihomo -t -f ./config.yaml

curl --proxy http://127.0.0.1:7890 --head https://example.org/

ルールファイル、ノードプロバイダー、データベースを相対パスで指定している場合は、テスト時の作業ディレクトリも実際の実行環境に合わせてください。コアの-dパラメーターで設定ファイルの作業ディレクトリを指定できます。コマンドが見つからない場合は、YAMLの項目を変更するのではなく、まずバイナリのパスを確認しましょう。上記のcurlリクエストで確認できるのは、指定したHTTPプロキシの入口と接続先へのアクセスだけです。UDP、システムDNS、TUNが正常に動作していることまでは確認できません。

Clash をダウンロードプラットフォームに合ったクライアントを選択