プロキシグループの種類と出口の構成
プロキシグループはルールとノードの間に位置します。ルールが通信の種類を判定し、プロキシグループがその通信に使う出口を決めます。多くのルールにノード名を直接記述すると、ノード名の変更やサブスクリプションの更新が設定全体に影響します。まず用途ごとに安定したグループ名を付け、グループ内のノードを調整すれば、日常的な切り替えとルールの管理を分けられます。接続ログから選択の経緯を追いやすくなる点もメリットです。
手動選択と自動選択の使い分け
selectは、仕事で使うサービス、特定地域のコンテンツ、一時的なトラブルシューティングなど、出口を手動で選びたい場合に適しています。グループのメンバーにはノードだけでなく、別のプロキシグループも指定できます。外側に手動選択グループ、内側に自動テストグループを配置すると、構成を把握しやすくなります。利用者は自動選択か直接接続かを決めるだけで済み、ドメインごとにノードを指定する必要がありません。
url-testは指定したテスト先への接続状況をもとにメンバーを評価し、用途の近いノードから自動選択します。テスト結果が示すのは、ノードからテスト先への接続状況であり、すべてのサービスでの使用感ではありません。テスト先には、安定していてアクセス可能なものを選び、実際の利用環境に近づけてください。一時的に失敗するテスト先だけを判断基準にすると、不必要な切り替えが起きやすくなります。
fallbackは候補を指定順に確認し、利用可能な出口を選ぶ方式です。メイン回線を優先し、障害時に予備回線へ切り替える用途に向いています。load-balanceはポリシーに基づいて接続を振り分ける機能で、1つの接続を複数回線に束ねるものではありません。ログイン状態、接続元IP、地域の一貫性が重要なサービスでは、まず出口を固定し、出口の変化が許容されると確認してから振り分けを検討してください。
proxy-groups:
- name: PROXY
type: select
proxies:
- DIRECT
rules:
- DOMAIN-SUFFIX,github.com,PROXY
- MATCH,DIRECT
上の例は、グループ名とルールの参照関係を確認するためのものです。現在のPROXYにはDIRECTしか含まれていないため、接続は直接行われます。実際に使う場合は、クライアントで既存のノードや別のプロキシグループを追加してください。名前は現在の設定と完全に一致させます。グループ名に「プロキシ」とあっても、必ずリモート出口を経由するとは限りません。メンバーを展開し、最終的な選択先を確認してください。
自動テストの設定とノードプロバイダー
ノードプロバイダーを使う場合、プロキシグループではファイル名ではなく、proxy-providersのキー名をuseで参照します。プロバイダーのヘルスチェックと、プロキシグループの自動選択は目的が異なります。前者はノードの稼働状態を管理し、後者はグループ内の選択に使われます。両方で頻繁にチェックするとリクエストが重複するため、まず間隔を広めに設定し、実際の障害復旧に必要な頻度に合わせて調整してください。
intervalはテスト間隔を秒単位で指定します。toleranceは小さな差による頻繁な切り替えを抑えるための設定です。最低速度を保証する値でも、接続タイムアウトの設定でもありません。自動選択が主に影響するのは新しい接続です。すでに確立したダウンロード、通話、長時間接続は、選択先が変わってもすぐに移行するとは限りません。変更を確認するときは、テスト中の接続を終了してからリクエストを再実行してください。
| 種類 | 主な選択方法 | 適した用途 |
|---|---|---|
select | メンバーを手動で選択 | 出口の固定、トラブル時の比較 |
url-test | テスト結果に基づいて選択 | 用途の近い候補ノード |
fallback | 利用可能なメンバーを順番に選択 | メイン回線と予備回線 |
load-balance | ポリシーに基づいて接続を振り分け | 出口の変更を許容できる通信 |
参照関係と切り替えの確認
グループを入れ子にすることはできますが、循環参照はできません。たとえば、業務グループが自動選択グループを参照し、自動選択グループが業務グループを参照すると、出口を確定できません。変更時はまずグループ名を一覧にし、メンバーを一つずつ確認します。同じノードが複数のグループに含まれていても問題ありません。防ぐべきなのは、グループ名の重複、存在しない名前の参照、入れ子を経由した自己参照です。
確認時は接続ログで、該当したルール、プロキシグループの経路、最終ノードを合わせて確認します。ルールは正しいのに出口が違う場合は、まず外側のグループで保存されている選択を確認し、次に内側の自動選択グループの状態を見ます。グループが空なら、プロバイダーが正常に読み込まれたか、フィルター式ですべてのノードが除外されていないかを確認してください。最初からDNSを変更すると、出口の問題と名前解決の問題が混在します。
サブスクリプションの更新でノードが削除されても、安定した業務グループ名は維持するのがおすすめです。重要なサービスには専用のプロキシグループを作り、汎用グループの自動変更に巻き込まれないようにできます。入れ子を増やし続けるより、検証済みの構成を記録しておく方が管理しやすくなります。複数のサブスクリプションからノードを取り込む方法は、ローカルオーバーライドと複数サブスクリプションのマージをご覧ください。
ルールプロバイダーによる管理とマッチ順
ルールプロバイダーを使うと、頻繁に更新されるドメインやIPアドレス範囲をメイン設定から分離できます。rule-providersで読み込み、RULE-SETでルールチェーンに追加します。メイン設定には分類と出口の関係だけを残せます。ルールプロバイダーはノードのサブスクリプションではなく、プロキシグループも自動作成しません。ファイルが読み込まれても、参照するルールがなければ通信の判定には使われません。
動作タイプとファイル形式を確認する
behaviorはルールの内容と意味を指定します。domainはドメインの一覧、ipcidrはIPアドレス範囲、classicalはタイプ付きのルール項目を格納します。formatはファイルの形式を指定する項目で、両者は互いに置き換えられません。ダウンロードしたファイルがテキストだからといって、特定のbehaviorを選べるとは限りません。実際の項目を開いて確認してください。
ここでは、リモート更新の影響を受けずに構造を確認できるローカルのクラシックルールセットを使います。2つ目の設定をメイン設定のディレクトリにあるrules/work.yamlとして保存し、ディレクトリを読み取れることを確認してから、1つ目の設定を読み込みます。PROXYはあらかじめプロキシグループに定義してください。ルールセットにはマッチ条件だけを記述し、各項目に出口を重複して指定する必要はありません。
rule-providers:
work:
type: file
behavior: classical
format: yaml
path: ./rules/work.yaml
rules:
- RULE-SET,work,PROXY
- GEOIP,CN,DIRECT
- MATCH,PROXY
payload:
- DOMAIN-SUFFIX,github.com
- DOMAIN-SUFFIX,githubusercontent.com
クラシックルールセットでは、DOMAIN-SUFFIXなどのタイプ接頭辞を使います。ドメイン形式のルールセットとは項目の意味が異なるため、上記ファイルのbehaviorだけを変更して流用することはできません。バイナリ形式のルールを使う場合は、現在のコアがその形式に対応しているかも確認してください。エラーが発生したら、キャッシュパスを何度も変更するのではなく、ファイルの内容と宣言が一致しているかを優先して確認します。
リモート更新とキャッシュの役割
リモートルールプロバイダーに切り替える場合は、type: httpを指定し、実在するルールのURL、更新間隔、専用のキャッシュパスを設定します。更新間隔の単位は秒です。URLからは宣言した形式のルールが返される必要があります。ウェブページ、ログイン画面、エラーメッセージが返っても更新成功とはいえません。接続できたという状態だけでは、内容の解析に成功したことにはなりません。
キャッシュがあれば、リモートファイルを一時的に取得できないときも、既存の内容を利用できる場合があります。ただし起動できるかどうかは、キャッシュの有無とコアの読み込み結果にも左右されます。初回利用時はログでダウンロードと解析が完了したことを確認してください。複数のプロバイダーで同じキャッシュファイルを共有しないでください。更新によって別のルールが上書きされ、分類名は正しく見えても内容が異なるという、見つけにくい問題が起こることがあります。
リモートルールの提供元も、設定における信頼境界の一部です。ルールの管理者がドメインの分類を変更すると、接続先の出口も変わる可能性があります。導入前にルールの用途、更新方法、適用範囲を確認し、まずローカルでテストしてからメイン設定に追加してください。動作を安定させたい少数のサービスは、メイン設定に正確なルールを記述して固定できます。広範囲のリモートリストに全面的に依存する必要はありません。
優先順位に沿ってルールを並べる
一般的なルールは上から順に評価され、最初に一致したルールが出口を決めます。そのため、ローカルの例外は通常、汎用ルールセットより前に置きます。対象範囲の広いIPネットワークの判定は後方に置き、最後にMATCHで残りを処理します。最後に適用するルールを前に置くと、後続のルールが評価されません。広範囲の拒否ルールを業務上の例外より前に置くと、例外が無効になります。この順序の誤りはプロキシグループを変更しても解決しません。
IPアドレスに基づく判定では、ドメインの名前解決が必要になる場合があります。一部のIPルールで使用できるno-resolveは、そのルールのために追加の名前解決を行わないようにする設定です。DNSを完全に回避するものではありません。用途に応じて設定してください。既知の接続先IPを使う場合は選択肢になりますが、ドメインを解決して所属するネットワークを判定したい場合は慎重に扱い、意図したマッチ範囲が変わらないようにします。
意図しない振り分けを調べるときは、まず対象のドメインと実際に一致したルールを記録し、該当するプロバイダーまで絞り込みます。一時的に正確なドメインルールを先頭に追加すると、問題がルールの順序にあるのか、出口自体にあるのかを切り分けやすくなります。テスト後は一時的なルールを削除し、用途を明記した正式な例外だけを残してください。互いに上書きし合うルールが増え続けるのを防げます。
ルールが多い場合は、提供元ごとに無造作に並べるのではなく、仕事用サービス、メディアサービス、ローカルネットワークなど、用途別に整理できます。毎回1種類ずつ更新して接続ログを確認すれば、変更の影響元を特定しやすくなります。各フィールドの参照関係についてはconfig.yamlのトップレベルフィールド解説をご覧ください。接続できないときの基本的な確認方法はトラブル対処で紹介しています。
DNS設定の最適化と名前解決の経路
DNSではアドレスを取得するだけでなく、ドメイン名、IPアドレス、その後の出口を一貫させることが重要です。同じドメインでも、利用するDNSサーバーによって異なる結果が返る場合があります。また、プロキシの出口があるネットワークによって、接続先への到達性が変わることもあります。最適化の前に、アプリのリクエストがクライアントのDNSを通っているか、DNSリクエストがどの出口を通るかを確認してから、名前解決サービスを比較してください。サーバー一覧を入れ替えるだけでは不十分です。
待ち受け、上流DNS、ブートストラップを区別する
listenはクライアントのDNSサービスが待ち受ける場所を指定し、nameserverは通常のドメイン検索に使う上流DNSを指定します。設定する階層が異なります。ループバックアドレスで待ち受ける場合、アクセスできるのは同じ端末だけです。設定に記述しただけでは、OSがそのアドレスを使うようにはなりません。OSのDNS設定、TUNによるDNSの捕捉、またはクライアントの機能を通じて、リクエストを実際に待ち受けポートへ送る必要があります。
default-nameserverは主にDNSサーバー自体のドメイン名を解決するために使います。直接アクセスできる、明確なアドレスを指定してください。暗号化DNSの上流をドメイン名で指定する場合は、先にブートストラップの名前解決が必要です。ブートストラップの名前解決が、まだ確立していないプロキシに依存すると、起動時に循環が発生することがあります。その場合、ノードのドメインとDNSサーバーのドメインをどちらも解決できなくなります。
dns:
enable: true
listen: 127.0.0.1:1053
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
default-nameserver:
- 223.5.5.5
nameserver:
- 223.5.5.5
- 1.1.1.1
fake-ip-filter:
- "*.lan"
- "*.local"
この例はフィールドの記述位置を示すものです。記載したパブリックDNSのアドレスは、現在のネットワークから到達できるものを選んでください。システムのポートを自動的に1053へ転送する設定ではなく、すべてのアプリがこのサービスを使うことを保証するものでもありません。導入後は、まずこのポートに直接問い合わせ、待ち受けが動作していることを確認します。その後、OSとアプリの名前解決経路を検証し、OSから接続されていない問題を上流DNSの障害と取り違えないようにしてください。
ノードのドメインとサービスのドメインを分けて扱う
サービスのドメインはプロキシ経由でアクセスできますが、プロキシノード自体のドメインは、通常プロキシが使えるようになる前に解決する必要があります。対応するフィールドがあるコアでは、proxy-server-nameserverを使ってノードのドメイン解決に使うDNSを別途指定できます。変更前に、その上流DNSへ直接アクセスできることを確認してください。ノードのアドレスを解決できない場合、プロキシグループのテストに失敗しても、リモートサービス自体が停止しているとは限りません。
nameserver-policyでは、特定のドメインに使用するDNSサーバーを指定できます。内部ドメイン、スプリットDNS、明確な地域要件があるサービスに適しています。社内ドメインには、社内ネットワークのゾーンにアクセスできるDNSサーバーを使ってください。通常、パブリックDNSでは社内のレコードを解決できません。対象範囲を明確にし、まず1つのサフィックスで確認してから適用範囲を広げます。一般のドメインを、内部ネットワークからしかアクセスできないDNSサーバーへ誤って送らないようにしてください。
respect-rulesを有効にすると、DNS上流への接続にもルールに応じた出口が使われます。ノードのドメイン解決も合わせて整理し、DNSがプロキシに依存し、そのプロキシも同じDNS経路に依存する状態を避けてください。これは万能な高速化スイッチではありません。DNSの出口を変える明確な理由がなければ、まずはシンプルな設定のまま基本接続を安定させてから、必要なポリシーを追加する方が問題を特定しやすくなります。
段階ごとに確認し、ウェブページの表示だけで判断しない
アプリによっては独自のDNSキャッシュを保持したり、暗号化DNSを有効にしたりします。ブラウザー内蔵の名前解決はOSの設定を経由しない場合があり、既存の接続ではDNS問い合わせ自体が発生しないこともあります。設定変更後はクライアント、OS、新規のアプリ接続をそれぞれ確認し、必要に応じて該当するキャッシュを消去してください。既存の接続を終了せずにページを更新するだけでは、新しい設定が反映されたかを確認しにくくなります。
digが使える環境では、以下のコマンドで例にある待ち受けポートへ直接問い合わせられます。Fake-IPのアドレスが返された場合、問い合わせが対応するアドレスマッピングの仕組みに届いたことを示します。接続先サーバーが実際にそのアドレスを使っているわけではありません。コマンドがタイムアウトする場合は、まず待ち受けアドレスとポートの競合を確認してください。応答はあるのにアプリが失敗する場合は、OSからの接続、ルーティング、ルールの適用状況を確認し、すぐにすべての上流DNSを入れ替えないでください。
dig @127.0.0.1 -p 1053 example.com A
一般のドメインは解決できるのに内部ドメインだけ失敗する場合は、検索ドメイン、社内DNSサーバー、VPNのルートを確認します。すべてのドメインが解決できず、IPアドレスへの直接接続は可能な場合は、DNSの捕捉と上流までの経路を重点的に調べてください。ドメインからアドレスを取得できても接続がタイムアウトする場合は、プロキシの経路と接続先への到達性を確認します。DNSの成功だけでは、想定した出口で接続できるとは限りません。
上流DNSを増やせば改善するとは限りません。サーバーが増えると、プライバシーと障害の境界が広がり、返されるアドレスの違いで原因の特定が難しくなる場合もあります。まず信頼できる少数の上流DNSを選び、特殊なドメイン向けのルールと選択理由を記録してください。DNS設定とFake-IPの関係は次の章で解説します。特にアドレスのマッピング、キャッシュの無効化、アプリが保持するアドレスに注意してください。
TUNとFake-IPで制御できる範囲
TUNは、システムのルーティングで送られたIPパケットを受け取る仮想ネットワークインターフェースです。Fake-IPはDNS層でアドレスをマッピングする仕組みです。よく併用されますが、同じ機能ではありません。システムプロキシはプロキシ設定に従うアプリが主な対象です。TUNはより多くのネットワークリクエストを扱えます。すべての接続トラブルに対する標準の修復手段と考えるのではなく、アプリをどこまで制御する必要があるかに応じて有効化してください。
元に戻せる順序でネットワークを制御する
有効化する前に、通常のプロキシ接続でノード、サブスクリプション、プロキシグループが動作することを確認します。そのうえで、クライアントにサービスのインストールや管理者権限が必要かを確認してください。デスクトップOSでは仮想インターフェースやルートの変更に権限が必要なことが多く、モバイルOSではシステムVPNの利用許可が必要です。画面上でスイッチをオンにしただけでは制御が完了したとは限りません。ログでインターフェースの作成、ルートの設定、DNSの捕捉が正常に完了したかを確認してください。
以下は基本的なフィールドの例です。auto-routeはルートの自動設定、auto-detect-interfaceは出口インターフェースの検出、dns-hijackはDNSの捕捉先を設定します。対応状況や動作はOSとコアによって異なります。まずクライアントの標準TUN設定を使い、最終設定と照らし合わせて確認することをおすすめします。画面上の設定とオーバーライドに相反する値を同時に記述しないでください。
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
stackはネットワークスタックの実装を選ぶ設定で、名前だけを見て性能を判断することはできません。実装ごとの対応状況、プロトコル処理、リソース消費はOSによって異なります。特定のアプリで問題が起きた場合は、ほかの設定を変えずに、クライアントが実際に対応しているネットワークスタックだけを切り替えて比較し、OS環境も記録してください。ルート、DNS、MTUを同時に変更しないでください。
Fake-IPのドメインマッピングを理解する
Fake-IPモードでは、アプリにマッピング用のアドレスを返します。その後の接続では、クライアントがこのアドレスからドメインを特定して振り分けます。例に示すアドレス範囲はこの仕組みのためのもので、接続先ウェブサイトの実際のアドレスではありません。接続先IPだけに依存するドメイン判定の難しさを軽減できますが、DNS問い合わせと後続の接続が同じマッピング環境を通ることが前提です。マッピングの経路が途切れると接続に失敗する場合があります。
アプリがアドレスを長時間キャッシュする場合、スリープから復帰した場合、クライアントのインスタンスを切り替えた場合などは、古いマッピングが無効になることがあります。まず再度名前解決を行い、新しい接続を確立してください。必要に応じてアプリとOSのキャッシュを消去します。古いFake-IPアドレスをhostsやサービスの設定に書き込んだり、サーバーアドレスとして他の端末に共有したりしないでください。対応するマッピングテーブルから外れたアドレスには、想定したドメイン名の意味がありません。
fake-ip-filterは、指定したドメインに偽アドレスを返さないようにする設定です。実アドレスが必要な一部のLAN内検出、内部サービス、互換性の問題に利用できます。フィルターは直接接続を指定するルールではありません。実アドレスを取得した後も、接続先の出口はルールで決まります。問題が確認できたドメインを一つずつ追加し、範囲が広すぎてFake-IPの仕組み全体を無効にしないようにしてください。
| 環境 | 主な確認項目 | よくある競合要因 |
|---|---|---|
| デスクトップOS | サービス権限、仮想インターフェース、デフォルトルート | 別のVPN、仮想マシンのネットワーク |
| モバイルOS | VPNの利用許可、バックグラウンド実行状態 | VPNインターフェースを同時に使うアプリ |
| 複数のネットワークインターフェースがある端末 | 実際の出口とインターフェースの識別 | 有線、無線、トンネル間のルート競合 |
ルート競合とLANアクセス
会社のVPN、コンテナネットワーク、仮想マシン、別のプロキシツールがルートを書き換えることがあります。TUNの起動後に内部リソースだけへアクセスできなくなった場合は、該当するネットワークのルートがどこに割り当てられているかを比較し、除外するか従来の経路を残すか確認してください。接続を復旧させるために、すべてのルートをすぐに削除しないでください。管理用の接続が切れる可能性があるため、特にリモート端末では別の復旧手段を確保しておきましょう。
「LAN接続を許可」の有効化とTUNの有効化は別の設定です。前者は通常、ほかの端末からプロキシの待ち受け先に接続できるかどうかを制御し、後者はこの端末のルーティングを制御します。ほかの端末にプロキシを提供する場合は、待ち受けアドレス、ファイアウォール、認証設定も確認してください。この端末でTUNを有効にしても、LAN全体の通信が自動的にクライアントを経由するわけではありません。
TUNによる制御後に全体がインターネットへ接続できなくなった場合は、TUN、システムDNS、システムプロキシの順に復旧状態を確認し、クライアントの終了時にインターフェースとルートが削除されるかも確認してください。まず基本のネットワークを復旧し、その後、制御方式を1つずつテストします。インストーラーと対応プラットフォームについてはダウンロードページをご覧ください。まずClash Plusを選び、具体的な機能の対応状況は使用するクライアントの設定で確認してください。
ドメインスニッフィングとルールの補完
ドメインスニッフィングは、接続の初期段階でプロトコルデータからホスト名を検出し、接続先IPだけでは不足する情報を補います。DNSによるドメインマッピングを補完する機能ですが、名前解決やルーティング全体の設計に代わるものではありません。有効化する前に、実際にドメイン名が失われていることが原因か確認してください。接続ログに正しいドメインと適用ルールがすでに表示されているなら、スニッフィングを追加しても出口の問題は通常解決しません。
検出できる情報と制限
HTTPリクエストからHostヘッダーを取得できる場合があり、TLSハンドシェイクからサーバー名を取得できる場合があります。一部のQUICハンドシェイクからも手がかりを得られます。情報を取得できるかどうかは、プロトコルやハンドシェイクの方式、コアの対応状況によります。スニッフィングはHTTPSを復号する機能ではなく、暗号化されたリクエスト全体を読み取れるようにはなりません。名前情報が保護されている場合やプロトコルに対応していない場合、クライアントがドメイン名を復元することはできません。
アプリが固定アドレスに直接接続したり、独自の名前解決を使ったりすると、接続がクライアントのDNSを経由しないことがあります。このような場合、スニッフィングによってドメインルールが再び適用される可能性があります。ただし、同じIPアドレスで複数のサービスが動作することがあり、アプリのハンドシェイクで検出した名前が、画面に入力したアドレスと一致するとは限りません。実際の接続ログで結果を確認し、ウェブサイトが開くかどうかだけで判断しないでください。
sniffer:
enable: true
sniff:
HTTP:
ports:
- 80
- 8080-8880
override-destination: false
TLS:
ports:
- 443
override-destination: false
skip-domain:
- "*.lan"
- "*.local"
この例では、一般的なHTTPとTLSのポートだけを対象にし、接続先のオーバーライドを無効にして、検出結果を確認しやすくしています。すべてのカスタムポートが自動的に対象になるわけではなく、QUICの検出も有効になっていません。実際のサービスが別のポートを使う場合は、プロトコルを確認してから対象を追加してください。ポートは絞り込み条件であり、プロトコルを証明するものではありません。任意のポートであらゆる解析を試みると、不要な介入が増えます。
ドメインの検出と接続先のオーバーライドを分けて確認する
override-destinationは、検出したドメインに基づいて接続先を上書きするかどうかを制御します。無効のままなら、まずドメインの検出結果とルールの変化を確認できます。有効にすると、その後の名前解決や接続方法が変わる場合があります。2つの動作は分けてテストしてください。まず検出結果の信頼性を確認し、接続先を変更する必要があるかを評価します。一度に有効化すると、異常の原因がどの段階にあるのか切り分けにくくなります。
IPアドレスを指定した接続、内部のリバースプロキシ、接続先に特別な要件がある一部のアプリでは、接続先のオーバーライドが適さない場合があります。特定のサーバーを指定した接続が、ハンドシェイクのドメインに基づいて再度名前解決されると、別のサーバーへ接続される可能性があります。ログイン異常やサービスの応答変化が起きた場合は、意図したプロキシグループに一致したかだけでなく、元のアドレス、検出されたドメイン、最終的な接続先を比較してください。
skip-domainでは、スニッフィングの対象にしたくないドメインを除外できます。まず社内サービスや互換性の問題が確認されているドメインなど、理由が明確なものから追加してください。用途を説明できない大量の除外リストをコピーしないでください。範囲が広すぎると解決したかったドメインの欠落が残り、狭すぎると変更が不要な内部接続に影響する場合があります。項目ごとの確認が重要です。
DNSとアプリの暗号化DNSを含めて切り分ける
ブラウザーの暗号化DNSによって通常の問い合わせがクライアントから見えなくなることはありますが、スニッフィングで必ずドメイン名を復元できるわけではありません。ハンドシェイクの名前も保護されていれば、クライアントに残る情報はIPアドレスなどに限られます。この場合は、アプリにクライアントが制御できる名前解決経路を使わせるか、IPアドレスベースのルールの範囲を受け入れるかを判断してください。効果のないスニッフィングのポート設定を重ねても解決しません。
切り分けには、ドメインが固定され、接続を再現しやすいサービスを1つ選びます。まずスニッフィングを無効にして一致したルールを記録し、次に接続先をオーバーライドせずに検出だけを有効にします。その後、必要に応じてオーバーライドを試してください。毎回古い接続を終了し、プロキシグループの選択は変えずに、ドメインと最終出口を確認します。これにより、名前の検出、ルールの適用、接続先の再設定という3つの変化を切り分けられます。
UDP通信だけに問題がある場合は、ノードが必要な通信方式に対応しているか、TUNが通信を捕捉しているか、該当プロトコルがスニッフィングの対象になっているかを別途確認してください。ブラウザーはQUICの失敗後にTCPへ切り替える場合があります。最終的にページが開いても、両方の経路が正常とは限りません。ルールが正しいことを確認するためにUDPをすべて拒否しないでください。アプリの動作が変わり、元の問題が見えにくくなります。
スニッフィングの設定は対象を絞り、目的を明確にしてください。DNSマッピングが安定していることを確認したうえで、必要なプロトコルに限って有効化し、用途を記録します。再現可能な改善が見られない場合は、よりシンプルな設定に戻すと管理しやすくなります。ルールモード、接続ログ、よくある問題についてはトラブル対処と照らし合わせて確認してください。スニッフィングにすべての振り分けを任せる必要はありません。
ローカルオーバーライドと複数サブスクリプションのマージ
サブスクリプションはリモートから提供される内容を管理し、ローカルオーバーライドは端末や個人の要件を管理します。両者は分けて保存してください。ダウンロードしたサブスクリプションファイルを直接編集すると、次回の更新で上書きされる可能性があります。一方、すべての設定をサブスクリプションに任せると、ポート、DNS、ネットワーク制御の方式がリモートの内容に応じて変わるおそれがあります。リモート側で管理するフィールドと、ローカルで常に管理するフィールドを明確に分けるのが基本です。
クライアントのマージ動作を確認する
クライアントによって、設定のマージ、オーバーライドファイル、ルールのパッチ、スクリプト処理などの機能があります。名称が似ていても動作は同じとは限りません。特に配列フィールドは、全体を置き換えるものもあれば、追加や先頭への挿入に対応するものもあります。使う前に実行順序と適用範囲を確認してください。あるクライアント独自のパッチ構文を、汎用的なmihomo YAMLとして扱わないでください。順序が不明なオーバーライド方式を2つ同時に有効にするのも避けてください。
まずログレベルの変更など、影響が小さいフィールドで動作を確認できます。読み込み後に最終設定を開き、値が変わったことを確認してから、ルールの先頭挿入やリストの置換をテストしてください。画面上で保存できても、最終設定に意図どおりマージされたとは限りません。確認するのは、コアに渡された有効な設定と、コアがそのフィールドを受け入れて読み込んだかどうかです。
ローカルで管理する内容は、端末向けとサービス向けに分けるのがおすすめです。端末向けには待ち受けポート、DNS、TUN、コントローラーを保存し、サービス向けには安定したグループ名、ルールの順序、ローカルの例外を保存します。端末を移行するときに、サービスのルール全体を書き直さず、ネットワーク設定だけを調整できます。スクリプトを使ったオーバーライドは、設定全体を再構成する場合があるため、実行内容を事前に確認してください。
複数サブスクリプションはノードプロバイダーに分ける
2つのサブスクリプションを丸ごとマージする際、よくある競合はノードそのものではなく、同名のプロキシグループ、重複するルール、互換性のないDNS設定です。2つのノードセットを同時に使いたいだけなら、提供元ごとにノードファイルを分け、ローカル設定でプロキシグループをまとめて管理する方が明快です。以下ではローカルファイルでの構成例を示します。ファイルにはノードプロバイダーが読み込めるproxiesリストが必要です。
proxy-providers:
access-a:
type: file
path: ./providers/access-a.yaml
access-b:
type: file
path: ./providers/access-b.yaml
proxy-groups:
- name: PROXY
type: select
use:
- access-a
- access-b
proxies:
- DIRECT
通常、完全なサブスクリプションにはプロキシグループやルールも含まれます。ファイル名を変更しただけで、正規のノードプロバイダーになるわけではありません。ファイル構造と読み込み方法に互換性があること、またはクライアントが明示的に対応する変換機能を使うことを確認してください。リモートプロバイダーを使う場合は、実際のサブスクリプションURLと専用のキャッシュパスを設定します。アクセス情報を含むURLを公開ドキュメントやトラブルシューティングのスクリーンショットに載せないでください。
名前の競合とルール順序の維持
複数の提供元でノード名が重複すると、選択肢を区別しにくくなったり、参照先が曖昧になったりします。可能であればインポートまたは事前処理の段階で、安定した提供元の接頭辞を付けてください。クライアントが対応する名前変更方法を確認してから適用します。表示名だけから地域や用途を判断しないでください。提供元の識別情報は管理元を区別するためのものであり、実際に接続できるかどうかは通常の接続テストで確認します。
ルールをマージするときは、並び順の意味を維持する必要があります。個別の例外は通常先頭に置き、サブスクリプションの汎用ルールを中間に配置し、最後に適用するルールは1つだけ末尾に置きます。2つのルール配列を単純に連結すると、先頭側にあるMATCHが後続のルールをすべて遮ってしまいます。クライアントがルールを末尾に追加する仕様の場合は、先頭挿入に対応しているかを必ず確認してください。項目が存在するだけでは、有効に適用されたとは限りません。
プロキシグループの参照関係にも循環がないか確認してください。マージ後に同名の業務グループが2つ残ったり、グループ名を変更してもルールの出口を更新しなかったりすると、読み込みエラーや意図しない選択が発生します。最小限の確認手順は、まずプロバイダーを読み込み、次に共通のプロキシグループを作成し、最後にルールを追加することです。各段階でログを確認し、ノードの読み込みエラーとルールの参照エラーが同時に最終設定へ持ち込まれないようにしてください。
バックアップ、更新、ロールバック
バックアップには、ローカルオーバーライド、メイン設定、ルールファイル、プロバイダーの構成説明を含めてください。機密性のあるサブスクリプションURLは別に保管します。クライアント画面のスクリーンショットだけでは参照関係を復元できません。更新後の有効設定だけを保存しても、元のオーバーライドの仕組みが失われる場合があります。大きな変更を行う前に、接続可能な状態とその説明を保存し、どのレイヤーを戻すべきか判断できるようにしてください。
サブスクリプションの更新をテストするときは、ローカルの例外が残っているか、ルールの順序が変わっていないか、現在の選択先が削除済みノードではないかを確認します。異常が出た場合は、失敗した設定を続けて修正するのではなく、最新のパッチを無効にしてバックアップを読み込んでください。Profileの切り替えとサブスクリプション更新の違いは複数設定の管理メモをご覧ください。基本的なインポート手順は入門ガイドを参照してください。
外部コントローラーと設定の確認手順
外部コントローラーは、稼働状況の確認、プロキシグループの切り替え、一部の管理操作に使います。コントロールパネルは、その機能を画面から操作するためのものです。パネル自体がプロキシの出口を提供するわけではなく、コアの代わりにもなりません。パネルに接続できない問題とプロキシ接続の問題は別の階層です。管理インターフェースが待ち受けていない、認証情報が一致しない、ブラウザーのセキュリティ制限でアクセスできない場合でも、クライアントが通信を正常に転送していることがあります。
ローカルでの待ち受けとパネルファイル
ローカル端末だけで管理する場合は、external-controllerをループバックアドレスにバインドしてください。external-uiにはローカルのパネルリソースディレクトリを指定します。ディレクトリ内には実際の静的ファイルが必要です。ディレクトリ名を指定しただけでパネルが生成されるわけではありません。以下では待ち受け先とリソースのパスを示します。有効化する前に、コントローラー用の認証キーを別途設定してください。公開例の値を長期利用する認証情報としてコピーしないでください。
external-controller: 127.0.0.1:9090
external-ui: ./ui
認証用フィールドはトップレベルのsecretです。パネルの接続設定と一致する、専用の長いランダム文字列を使ってください。このキーはコントローラーの認証に使うものであり、ノードのパスワードやサブスクリプションURLとは異なります。これらを使い回さないでください。スクリーンショット、共有リンク、公開設定にキーを含めると、管理権限が漏れる範囲も広がります。トラブルシューティングの前に機密情報を削除してください。
待ち受けアドレスをすべてのインターフェースに変更すると、ほかの端末から管理インターフェースへアクセスできるようになる可能性があります。利便性だけを理由に公開しないでください。リモート管理が本当に必要な場合は、管理されたネットワーク、アクセス制限、適切な暗号化経路で接続を保護し、OSのファイアウォールも確認してください。認証を設定していても、ネットワーク分離が不要になるわけではありません。実行時の動作を変更できる管理インターフェースは、管理者権限と同等に扱ってください。
ネットワーク、認証、ブラウザーの制限を分けて確認する
パネルに接続できない場合は、まず現在のコアプロセスがコントローラーの設定を読み込んでいるかを確認し、続けてアドレスとポートを照合します。ブラウザーに表示されるローカルアドレスは、ブラウザーを実行している端末のものです。別の端末でパネルを開く場合、ループバックアドレスはコアが動作しているホストを指しません。この認識違いを解決するために、すぐ待ち受け範囲を広げないでください。まず端末間での管理が本当に必要かを確認します。
ローカルで認証を設定していない段階では、以下のコマンドでインターフェースが応答するか確認できます。認証を設定済みの場合は、対応する認証情報を含むリクエストを使用してください。確認のために認証を削除する必要はありません。接続拒否は、待ち受けがないかアドレスが間違っている可能性を示します。認証エラーは、インターフェースには到達できているものの、認証情報が一致しない状態を示します。別々に対処してください。プロキシノードを何度変更しても結果は変わりません。
curl --fail --silent --show-error http://127.0.0.1:9090/version
リモートのHTTPSページからローカルのHTTPインターフェースへリクエストすると、混合コンテンツ、クロスオリジン、ローカルネットワークへのアクセス制限を受ける場合があります。パネルが空白になる原因は、静的ファイルのパスが間違っているだけかもしれません。まずクライアント内蔵のパネルか、信頼できるローカルパネルを使い、ブラウザーのコンソールを順に確認してください。あらゆる接続元を許可する設定を万能な解決策として使ったり、パネルに接続するためにブラウザーの保護機能をすべて無効にしたりしないでください。
設定の読み込み前後に行う2段階の確認
最初の確認は読み込み前に行います。YAMLのインデント、フィールドの型、参照名、ファイルパスを確認してください。mihomoコマンドを使える環境では設定のテストを実行できます。設定にローカルプロバイダーが含まれる場合は、関連ファイルがすでに所定の場所にあることも確認してください。テストで構文や一部の参照エラーは検出できますが、リモートノードへ接続できるか、OSの権限が付与されているか、すべての業務ルールが想定どおりかまでは保証されません。
mihomo -t -f ./config.yaml
2回目の確認は読み込み後に行います。まず起動ログを見て、コントローラー、プロバイダー、ルールプロバイダーがすべて正常に動作していることを確認します。次に再現しやすいテスト接続を確立し、ドメイン、一致したルール、プロキシグループの経路、最終出口を確認してください。その後、直接接続が必要なサービスとプロキシ経由が必要なサービスをそれぞれテストします。パネルに「稼働中」と表示されるだけでは、設定から実際の接続までを確認したことにはなりません。
パネル上で一時的に切り替えた状態が、サブスクリプションやローカルオーバーライドに保存されるとは限りません。選択状態を長期保存する場合は、クライアントの永続化の仕組みを確認してください。ルールを長期保存する場合は、保守可能な設定レイヤーに追加します。実行中の変更だけを唯一のバックアップにしないでください。再起動、更新、Profileの切り替え後にパネル上の状態が消え、設定が勝手に変わったように見える場合があります。
一度に変更する障害要因は1つだけ
設定の解析、ファイルの読み込み、DNS、出口、ルール、システムによる通信制御の順に調べてください。毎回1つのレイヤーだけを変更し、結果を記録してから次の手順を決めます。更新直後に問題が起きた場合は、嗅ぎ分けを有効にしたりネットワークスタックを変えたりDNSを書き換えたりする前に、直近の正常な設定へ戻して関連性を確認してください。要因を少なくするほど、原因を特定しやすくなります。
起動直後にクラッシュする場合は、エラーを保存し、何度も自動再起動するのをやめて、ログを使った原因特定と設定のロールバック手順を参照してください。起動はするものの特定の機能に問題がある場合は、本ガイドの該当する章を確認します。調整後は最終設定と用途の説明を保存しておけば、次回のサブスクリプション更新や端末移行でも同じ手順で検証できます。