まず、設定が処理される流れを押さえましょう。アプリからのリクエストはローカルポートに渡され、コアが現在のモードに応じて処理します。ルールモードでは rules が適用するポリシーを決め、proxy-groups が実際の接続先を選びます。dns は名前解決を担い、TUNはトラフィックをコアに取り込む方法を変えます。それぞれ関連はありますが、同じ設定項目ではありません。

この記事では、設定ファイルでよく使われる順に各項目を解説します。基本項目はClashの設定体系に共通しますが、TUNやDNSの拡張機能、新しいプロトコルは使用するコアによって対応状況が異なります。Clash Metaの後継はmihomoという名称で、クライアントの画面上の名称とコアの名称も異なる場合があります。クライアント名に「Clash」とあるだけで、すべての項目が使えるとは限りません。

1. 編集前に設定ファイルと読み込み先を確認する

config.yamlが、クライアントで現在読み込まれている設定全体とは限りません。GUIクライアントでは、購読元の設定、ユーザー設定、オーバーライド用の設定、実際に動作する設定を別々に保存することがあります。実行時に生成されるファイルを直接編集すると、次回の購読切り替えや再起動で再生成される可能性があります。

  1. クライアントの「設定」または「Profiles」ページを開き、最近インポートした項目ではなく、現在有効な項目を確認します。
  2. 該当項目の「編集」または「ファイルを開く」から開き、編集前の内容を別名で保存します。ボタン名はクライアントのバージョンによって異なります。
  3. クライアントに「オーバーライド」「マージ」またはMerge機能があるか確認します。長期的に使うローカルルールは、こうした機能から追加するのがおすすめです。
  4. 保存後、「設定を再読み込み」を実行するか、設定を有効にし直して、ログに解析エラーが出ていないか確認します。

まずYAMLの構文エラーを確認する

  • インデントにはスペースを使い、Tabは使いません。この記事では1階層を半角スペース2つで表記します。
  • キーと値の間にはスペースを入れます。たとえば mode: rule のように書き、mode:rule とはしません。
  • リスト項目は - で始めます。同じ階層のノード、プロキシグループ、ルールはインデントをそろえます。
  • 真偽値は true または false と記述します。特殊記号を含む名前、パスワード、アドレスは引用符で囲むのがおすすめです。

yaml: line 12: mapping values are not allowed in this context と表示された場合は、まず12行目とその前の行のコロン、引用符、インデントを確認します。この段階ではまだネットワーク接続処理に進んでいないため、ノードを何度も切り替えても解決にはつながりません。

2. ポートと動作モード:リクエストの入口

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
ipv6: false

mixed-portはHTTPプロキシとSOCKS5プロキシの両方のリクエストを受け付けます。上の例では、アプリのプロキシサーバーに127.0.0.1、ポートに7890を設定できます。これらは例示用の値です。クライアントに別のポートが表示される場合は、実際の動作値を使用してください。

設定項目用途間違えやすい点
portHTTPプロキシの待ち受けポートDNSポートでも、ノード側のポートでもありません。
socks-portSOCKSプロキシの待ち受けポートアプリ側で対応するプロキシプロトコルを選ぶ必要があります。
mixed-portHTTPとSOCKSで共通の入口ほかの待ち受け設定と同じアドレス・ポートを重複して割り当てる必要はありません。
external-controllerコントロールAPIの待ち受けアドレス画面からコアを操作するためのものです。ブラウザーに設定するプロキシの接続先ではありません。

mode: ruleはルールに基づく振り分け、globalはグローバルポリシー、directは直接接続を意味します。rulesを編集しても変化がない場合は、画面上のモードが「グローバル」または「直接接続」になっていないか確認してください。

allow-lan: falseは、LAN内のデバイスからの接続を制限します。同じネットワーク内のほかのデバイスでも使う場合は、待ち受けアドレス、OSのファイアウォール、認証設定を確認してください。スマートフォンから接続するために、コントロールAPIをインターネットに公開するのは避けてください。

log-level: infoは、通常のトラブルシューティングに適した設定です。一時的にdebugを使った場合は、早めに元に戻してください。ログにアクセス先のドメインが記録されることがあります。ここでのipv6: falseはOSのIPv6を無効にする設定ではなく、システムのネットワーク設定の代わりにはなりません。

3. dns:待ち受け、上流DNS、fake-ipの役割

dns:
  enable: true
  listen: 127.0.0.1:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - https://dns.alidns.com/dns-query

enableはコアのDNS機能を有効にし、listenはDNSサーバーの待ち受け先を指定します。127.0.0.1:1053と設定しても、ローカルにDNSの接続口ができるだけで、システムからのすべてのDNSリクエストがそこに送られるわけではありません。通常のシステムDNS設定では1053のような任意のポートを直接指定できないことが多く、クライアント側のDNS転送や横取り、TUNとの連携設定も必要です。

default-nameserverは一般的な予備DNS一覧ではない

nameserverにドメイン名を使う暗号化DNSのアドレスを指定すると、コアはまずDNSサーバー自体のドメイン名を解決する必要があります。default-nameserverは主にこの初期の名前解決を担い、通常の問い合わせ先にはnameserverを使います。すべてのアドレスを同じリストに無造作に入れると、問題の切り分けが難しくなります。

fake-ipが返すのはドメインに対応付けたアドレス

fake-ipモードでは、ドメインに対応する仮想アドレスを割り当て、コアが接続先とドメインを対応付けられるようにします。198.18.0.0/16の範囲のアドレスが表示されても、すぐにDNS汚染だと判断する必要はありません。これらは内部マッピング用であり、接続先サイトの実際のグローバルIPではありません。

LAN内のサービス、プリンター、特定のアプリで問題が起きる場合は、既存のdnsセクションに適切なfake-ip-filter項目を追加できます。まず問題のドメインを特定し、使用中のコアが対応するマッチ方法で記述してください。すべてのドメインを除外すると、DNS全体の動作が変わってしまいます。

4. proxiesとproxy-providers:ノードの取得元

proxiesには、設定ファイルに直接記述するノード一覧を指定します。各ノードのtypeに応じて必要な項目が異なります。よく使う項目はname、server、portですが、パスワード、UUID、TLS、通信方式の設定はサーバー側に合わせる必要があります。別のプロトコルの項目をそのまま流用しないでください。

proxy-providersはノードプロバイダーを定義し、リモートURLやローカルファイルからノード一覧を読み込みます。任意の購読URLを設定すれば必ず使えるわけではありません。プロバイダーファイルの形式、購読先が返す内容、コアの対応状況を確認してください。rulesやdnsを含む完全な設定ファイルを、ノード一覧だけを想定する場所にそのまま指定することもできません。

  • 直接定義したノードは、proxy-groups内のproxiesで名前を指定して参照します。
  • プロバイダー内のノードは通常、プロキシグループのuseでプロバイダー名を指定して参照します。
  • 名前は完全一致が必要です。スペース、大文字・小文字、記号も名前の一部です。
  • 購読URL、パスワード、UUID、コントロールAPIのキーは、公開画像や公開ログに含めないでください。

ログに存在しないプロキシ名が表示された場合は、まず参照関係を確認し、次に購読が正常に更新されたかを調べます。ノードの削除や名前の変更後に、プロキシグループが古い名前を参照したままだと、設定の検証に失敗します。

5. proxy-groups:ノードをまとめて接続先を選ぶ

proxy-groups:
  - name: 手動選択
    type: select
    proxies:
      - DIRECT
  - name: デフォルト接続先
    type: select
    proxies:
      - 手動選択
      - DIRECT

この例は参照関係だけを示しています。DIRECTは組み込みの直接接続ポリシーで、プロキシノードではありません。そのため、例をそのまま使ってもリモートプロキシには接続できません。実際に使うときは、設定内に存在するノード名やプロバイダーをプロキシグループに追加してください。

「デフォルト接続先」というグループ名はルールから参照でき、グループ内で「手動選択」を参照することもできます。この階層構成なら、ルールと個々のノードを分けて管理できます。ルールでは安定したグループ名を指定し、ノードを切り替えるときはプロキシ画面でグループ内の選択を変えるだけで済みます。ルールを一つずつ編集する必要はありません。

種類主な動作設定時の注意
select候補から接続先を手動で選択します。候補にはノードのほか、別のプロキシグループも指定できます。
url-test接続テストの結果に応じて、接続先を自動選択します。テスト用URL、実行間隔、切り替えの許容値を適切に設定します。
fallback候補の順に、利用可能な接続先を選択します。重視するのは優先順位と障害時の切り替えであり、最低遅延の選択ではありません。
load-balance指定したポリシーに従って接続を振り分けます。複数ノードの帯域をまとめて、1つのダウンロード接続に使う機能ではありません。

自動選択グループに表示されるテスト時間は、その時点でテスト先に接続した結果を示すにすぎず、すべてのWebサイトの通信速度を表すものではありません。テスト間隔は短ければよいわけでもありません。たとえばinterval: 300は300秒を意味します。設定前にサービス提供元の制限と実際の必要性を確認してください。

グループの循環参照にも注意してください。たとえば、AグループにBグループを含め、BグループにもAグループを含めるケースです。階層が整っているように見えても、コアが最終的な接続先を決められなくなります。

6. rules:上から順に評価し、最初に一致したルールを適用

rules:
  - DOMAIN,example.com,デフォルト接続先
  - DOMAIN-SUFFIX,example.org,DIRECT
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
  - MATCH,デフォルト接続先

上の例では、構文の説明に予約済みのサンプルドメインを使っています。実際の用途に推奨するルールではありません。DOMAINはドメイン名に完全一致し、DOMAIN-SUFFIXはそのドメインとサブドメインに一致します。IP-CIDRは接続先IPが属するネットワークに一致します。3つ目の項目には適用するポリシーを指定し、グループ名のほかDIRECTやREJECTなどの組み込みポリシーも指定できます。

MATCHは最後のフォールバックとして配置する

MATCHは、それまでのルールに一致しなかったリクエストを受け持ちます。先頭に置くと、その後のドメインやネットワークのルールは評価されません。特定のドメインを新たに直接接続にする場合は、ファイル末尾に機械的に追加するのではなく、そのドメインより先に一致する広範なルールの前に置いてください。

no-resolveはDNS全体を無効にする設定ではない

IP-CIDRの後に付けるno-resolveは、そのIPルールの判定だけを目的としたドメインの自動名前解決を行わない、という意味です。接続先IPがすでに分かっていれば、引き続きIPで照合できます。DNS機能を無効にする設定ではなく、ドメイン名の解決が必要なアプリの接続を自動で復旧させるものでもありません。

GEOIPや地理情報に基づくルールを使う場合は、関連するデータファイルが利用可能か、コアがその形式に対応しているかも確認してください。詳しくはトラブル対処のGeoIPに関する項目を参照してください。ルールセットを使う場合は、rule-providersの種類と内容の形式に加えて、RULE-SETで指定する参照名も確認します。

7. TUNとクライアントのオーバーライド:設定を書いた後に通信が取り込まれているか確認

TUNは仮想ネットワークデバイスを使った通信の入口であり、別のプロキシノード一覧ではありません。以下はmihomoでよく使われる項目の組み合わせです。有効にする前に、クライアントのサービス権限、システムのルーティング、ほかのVPNの状態を確認してください。

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53

auto-routeはルートの自動設定に、auto-detect-interfaceは送信インターフェースの自動選択に使います。対応状況はOSやコアのバージョンによって異なります。仮想ネットワークアダプターを作成できない場合は、まずクライアントのサービスモードや認証手順を確認してください。権限エラーに対処するために、DNSアドレスを適当に追加・削除するのは避けてください。

dns-hijackの例は、通信の取り込み経路に入った従来型の53番ポートのDNS通信を対象としています。すべての暗号化DNSを横取りするわけではありません。ブラウザー組み込みのDoH、ほかのVPNのルーティング、アプリ独自のネットワーク処理によっても、実際の通信経路は変わります。

クライアントの画面設定によって、ファイル内のmixed-port、mode、dns、tunが上書きされることもあります。保存後に値が元に戻る場合は、クライアントの「実行中の設定」などを開き、実際に適用されている内容と購読元の設定を比較してください。どの設定がどの層を上書きしているのか分からなくなるため、複数のファイルを続けて編集するのは避けましょう。

8. 保存後の確認手順:構文、読み込み、通信、ルール

  1. まず設定を解析できるか確認します。mihomoのコマンドライン版を使っている場合は、以下の検証コマンドを実行できます。GUIクライアントでは、まずクライアント内蔵の設定チェック機能を使ってください。
  2. 再読み込みが成功したか確認します。ログに古いエラーが残っていないか、待ち受けポートと現在のモードが合っているかを確認してください。ファイルを保存しただけでは、設定が再読み込みされないことがあります。
  3. 1つのリクエストで入口を確認します。TUNを無効にした状態で、ローカルHTTPプロキシを明示してテストします。システムプロキシの有効・無効を同時に確認する必要がなくなり、原因を切り分けやすくなります。
  4. 接続の詳細を確認します。接続先ドメイン、適用されたルール、プロキシグループ、最終的なノードを確認してください。グループ名が正しくても、グループ内でDIRECTが選ばれていれば直接接続になります。
  5. 最後に設定が維持されるか確認します。クライアントを再起動し、さらに購読を更新して、オーバーライドが残るか確認してください。設定が失われる場合は、手動で何度も追記するのではなく、マージ方法を見直します。
# 設定ファイルのあるディレクトリで実行。mihomoをコマンド検索パスに追加しておくこと
mihomo -t -f config.yaml

# ローカルの7890番ポートを使い、HTTPプロキシ経由で明示的にリクエスト
curl -I --proxy http://127.0.0.1:7890 https://example.com

コマンドラインで検証する際は、クライアントと同じバージョンのコアを使い、相対パスへの依存にも注意してください。設定チェックに合格したことから分かるのは、そのコアで設定を読み込めるということだけです。ノードへの接続、購読の更新、Webサイトへのアクセスが成功する保証にはなりません。上記のcurlリクエストで確認できるのも、そのリクエスト1つのプロキシ経路だけで、すべてのアプリの通信が取り込まれているわけではありません。

bind: address already in useが表示された場合は、まずポートを使用しているプロセスを特定するか、待ち受けポートとアプリ側のプロキシポートを合わせて変更してください。ノードへの接続がタイムアウトする場合は、ノードのアドレス、ネットワーク到達性、サービスの状態を確認します。詳しくは接続タイムアウトの対処方法を参照してください。

安全に設定を変更するには、一度に変更する層を1つに絞ります。まずポートとモード、次にDNS、その後にプロキシグループとルール、最後にTUNによる通信の取り込みを検討してください。変更のたびに動作する設定を保存しておけば、問題が起きても元に戻せます。購読の有効化、モード切り替え、ローカルポートを確認するには、はじめにの手順に沿って確認してください。