この記事は、Shadowrocketで自分の設定を読み込み、通信の振り分けを調整したいユーザー向けです。リクエストがどのルールにマッチするか、具体的なルールと広範なルールの順序、PROXY・DIRECT・REJECTの使い分け、FINALで未マッチのリクエストを受ける方法を説明します。
ルール優先順位の基本:最初にマッチした時点で停止
Shadowrocketのルールリストは、すべてを同時に評価して「最も具体的な」ルールを選ぶ仕組みではありません。設定に記述された順序に従い、上から1行ずつ確認します。あるルールが現在のリクエストにマッチすると、その後のルールは今回の判定に使われません。つまり、優先順位は位置で決まり、ルール名や文字数、策略の種類によって自動的に決まるものではありません。
たとえば、同じドメインが完全一致のDOMAINルールと、サフィックス全体を対象にするDOMAIN-SUFFIXルールの両方にマッチする場合があります。DOMAIN-SUFFIXが先に書かれていると、より具体的なDOMAINでも適用されません。設定では例外を広範なルールより前に置き、最も広い範囲を対象にするフォールバックを最後に配置します。
典型的な判定は5段階に分けられます。アプリが接続を開始する、Shadowrocketが対象のドメインまたはIPを取得する、[Rule]の1行目から確認する、最初にマッチしたルールで停止する、その行末の策略に従って処理する、という流れです。具体的なルールに1つもマッチしなければ、FINALへ進みます。
[Rule]
DOMAIN,api.example.com,DIRECT
DOMAIN-SUFFIX,example.com,PROXY
IP-CIDR,192.168.0.0/16,DIRECT
GEOIP,CN,DIRECT
FINAL,PROXY
api.example.comへアクセスすると、1行目にマッチしてDIRECTが適用されます。www.example.comへアクセスした場合は1行目にマッチせず、その後DOMAIN-SUFFIXにマッチしてPROXYが適用されます。対象がプライベートアドレス帯192.168.0.0/16にある場合はDIRECTとなり、それ以外のリクエストはGEOIPで判定された後、なおマッチしないものがFINALに渡されます。
DOMAIN、DOMAIN-SUFFIX、IP-CIDR、GEOIPの並べ方
ルールは「範囲が狭く、意図が明確」なものから「範囲が広く、対象が多い」ものへ並べます。DOMAINは完全な1つのドメインだけにマッチするため、個別の例外に適しています。DOMAIN-SUFFIXは指定ドメインとサブドメインを対象にします。IP-CIDRはアドレス帯で判定し、GEOIPは対象IPを地理データベースの分類に基づいて判定します。FINALは特定の対象を確認せず、前のルールにマッチしなかったリクエストを受け取ります。
推奨する配置レベル
- ローカルおよび予約アドレス:まずLANアドレスと、DIRECTを明示的に適用する対象を処理し、内部機器へのリクエストが別の策略に入らないようにします。
- 完全一致のドメイン:DOMAINを使って、1台のホストに対する特別な処理を指定します。たとえば、1つのAPIドメインを後続のサフィックスルールより優先させます。
- ドメインサフィックス:DOMAIN-SUFFIXを使って、1つのメインドメインとすべてのサブドメインを処理します。
- アドレス帯:IP-CIDRを使って、明確なIPv4ネットワークをマッチさせます。通常、プレフィックス長が大きいほど対象範囲は狭くなります。
- 地理的分類:GEOIPは具体的なドメインルールやアドレスルールの後に置き、広範な分類が例外リクエストを先に取り込まないようにします。
- 最終フォールバック:FINALを最後に置き、残りすべての通信をどう処理するか明確にします。
具体的なルール
- DOMAIN
- api.example.com,DIRECT
- DOMAIN-SUFFIX
- example.com,PROXY
- IP-CIDR
- 192.168.0.0/16,DIRECT
例外は、対象範囲が広いルールより前に記述します。
広範なルール
- GEOIP
- CN,DIRECT
- FINAL
- PROXY
- 位置
- [Rule]の末尾
具体的なマッチングを終えてから、地理判定と最終フォールバックへ進みます。
DOMAIN-SUFFIXの値にはドメインだけを記述し、https://、パス、クエリパラメータは付けません。ルールが判定するのは完全なURLではなくホスト名です。cdn.example.comを処理する場合はDOMAIN,cdn.example.com,DIRECTと記述できます。example.comとすべてのサブドメインを対象にする場合はDOMAIN-SUFFIX,example.com,PROXYと記述します。
IP-CIDRのプレフィックス長は対象ネットワークに合わせる必要があります。192.168.0.0/16は192.168.0.0から192.168.255.255までを対象にします。誤って/24と記述すると、範囲は1つの末端ネットワークまで狭まり、同じ種類のほかのLANアドレスにはマッチしません。
結論:例外が具体的であるほど前に置く
汎用ルールより優先させたい単一ドメイン、単一アドレス帯、LANの例外は、DOMAIN-SUFFIX、GEOIP、FINALより前に置きます。ルールを具体的に書くだけで、自動的に高い優先順位が与えられるわけではありません。
PROXY、DIRECT、REJECTで変わる処理
ルール末尾の策略によって、マッチ後のリクエスト処理が決まります。PROXYは現在の設定で指定されたプロキシ策略に渡します。DIRECTは対象へ直接接続します。REJECTはリクエストを拒否します。3つは処理方法であり、ルールキーワードではありません。前半のDOMAIN-SUFFIX、GEOIP、IP-CIDRなどが「何にマッチするか」を判定し、末尾の策略が「どう処理するか」を決めます。
| 策略 | 処理結果 | 適したルールの意図 | 確認ポイント |
|---|---|---|---|
| PROXY | 設定内のプロキシ策略に渡して処理 | プロキシ経由でアクセスする必要があるドメイン、またはFINALのフォールバック | 現在選択している策略が利用可能で、Global RoutingがConfigになっていることを確認 |
| DIRECT | 現在のネットワークから対象へ直接接続 | LANアドレス、明示的な直接接続ドメイン、GEOIP分類 | ローカルネットワークから対象へ到達できることを確認 |
| REJECT | マッチしたリクエストを直ちに拒否 | ブロック対象として明確なドメインまたはアドレス範囲 | 広すぎるサフィックスを誤ってREJECTにしない |
PROXYは、どのリクエストも必ず成功させるものではありません。現在選択しているプロキシ策略にリクエストを渡し、その後の処理を任せるだけです。最終結果は、ユーザーが用意した設定、該当プロトコルのパラメータ、ネットワーク状態によって変わります。Shadowrocketの設定には、Shadowsocks、VMess、VLESS、Trojan、Hysteria2、WireGuardなどのプロトコルを含められますが、ルールの順序と個別プロトコルは別の要素です。プロトコルを変更しても、[Rule]を上から順に判定する方式は変わりません。
DIRECTも「Shadowrocketを無視する」ものではありません。リクエストはまずルール判定を通り、マッチした後に直接接続が選ばれます。LAN機器へアクセスできない場合は、プライベートアドレスのルールがFINALより前にあるかを確認し、Global RoutingがProxyのままになっていないことも確認してください。
REJECTは対象範囲が明確な場合だけ使用します。DOMAIN-SUFFIX,example.com,REJECTを前に置くと、そのメインドメインとすべてのサブドメインが拒否され、後ろにDOMAIN,api.example.com,DIRECTがあっても適用されません。正しくは、許可する例外を先に書き、その後に範囲の広い拒否ルールを置きます。
許可する例外
- 1行目
- DOMAIN,api.example.com,DIRECT
- 2行目
- DOMAIN-SUFFIX,example.com,REJECT
- 結果
- APIは直接接続、その他のサフィックスは拒否
完全一致のDOMAINが先にマッチするため、後続のサフィックスルールより優先されます。
ルーティングモード
- Config
- ルールリストに従って振り分け
- Proxy
- グローバルプロキシモードを使用
- Direct
- グローバル直接接続モードを使用
- Scene
- 設定したSceneに応じてモードを選択
カスタムルールを確認するときは、まずHomeでGlobal Routingを確認します。
FINALをルール末尾に置く必要がある理由
FINALは、マッチしなかったリクエストの共通出口です。ドメイン、IP、アドレス範囲を限定しないため、途中に置くと、それまでにマッチしなかったすべてのリクエストを受け取り、後続ルールに実行機会がなくなります。設定上はFINALの後に行を追加できても、すでに最初のマッチが成立した結果を後続行で変えることはできません。
# 推奨順序
DOMAIN,internal.example.com,DIRECT
DOMAIN-SUFFIX,example.com,PROXY
GEOIP,CN,DIRECT
FINAL,PROXY
# 誤った順序
FINAL,PROXY
DOMAIN,internal.example.com,DIRECT
1つ目の順序では、完全一致のドメイン、サフィックス、GEOIPを先に確認し、最後にPROXYで残りのリクエストを処理します。2つ目は1行目で全リクエストをFINALにマッチさせているため、2行目が適用されることはありません。「ルールを追加してもまったく反映されない」場合は、まずFINALの後ろに記述していないか確認します。
FINALの策略は設定の目的に合わせて決め、特定の値に機械的に固定しないでください。「直接接続の例外だけを列挙し、それ以外はプロキシを使う」構成ならFINAL,PROXYを使用できます。「プロキシが必要な対象だけを列挙し、それ以外は直接接続する」構成ならFINAL,DIRECTを使用できます。どちらも有効ですが、前のルールはフォールバックの方向と一致させる必要があります。
結論:デフォルトの動作を決めてから例外を書く
まず、未マッチのリクエストを最終的にPROXYとDIRECTのどちらで処理するか決めます。そのうえで、デフォルトと逆の動作をさせる例外をFINALより前に記述します。重複したルールを追加し続けるより確認しやすく、同じドメインに相反する処理を設定するミスも防げます。
変更後は決まった手順で確認
- Configで現在使用している設定を開き、実際に有効な設定を変更していることを確認します。同名の別設定や予備設定を変更していないか注意してください。
- [Rule]に最終フォールバックを担うFINALが1つだけあり、ルールリストの末尾に置かれていることを確認します。
- Homeに戻り、Global RoutingをConfigに設定します。ProxyまたはDirectの状態では、カスタムルールによる期待どおりの振り分けをConfigモードで検証できません。
- DIRECTにマッチするはずの対象と、PROXYにマッチするはずの対象を1つずつテストします。すべてのルールを1つのサイトだけで判断しないでください。
- 結果が期待と異なる場合は、追加したばかりの行だけでなく、ルール上部からDOMAIN、DOMAIN-SUFFIX、IP-CIDR、GEOIPのうち最初にマッチしそうな行を探します。
設定更新、On Demand、ルールが反映されない場合の主な原因
自分で用意したサービスやサブスクリプションを利用している場合、設定の更新によってリモート側のルール内容が再書き込みされることがあります。更新で上書きされる設定を直接編集すると、更新後にリモート側の内容へ戻る可能性があります。変更前に、その設定が手動管理なのかサブスクリプションに合わせて更新されるのかを確認し、更新後は[Rule]の順序とFINALの位置を再確認してください。
On Demandとルールの優先順位は、異なる段階を扱います。入口はSettings → On Demandで、設定済みのネットワーク条件に応じて接続するタイミングを決めます。接続確立後のリクエストの振り分けは、Global Routingと現在の設定ルールによって決まります。On Demandで接続が確立していない場合、[Rule]だけを調整しても接続条件の確認にはなりません。
ルール実行
- 入口の確認
- Home → Global Routing
- テストモード
- Config
- 設定場所
- 現在のConfigの[Rule]
- 終点
- FINALが最終行にある
まず有効な設定対象を確認し、その後でルール内容が正しいか判断します。
自動接続
- 入口
- Settings → On Demand
- 役割
- ネットワーク条件に応じて接続を制御
- ルールとの関係
- [Rule]の順序は変更しない
- 確認
- 接続と振り分けを分けて確認
接続するタイミングとリクエスト策略は、2つの段階として確認します。
別のよくある原因は、ルール内容にURLを含めていることです。DOMAINとDOMAIN-SUFFIXが受け付けるのはドメイン部分だけです。スキーム、ポート、パスまで記述すると、マッチ対象が正しくなりません。たとえばhttps://api.example.com:443/v1/statusのホストをマッチさせる場合、DOMAINの値はapi.example.comとします。ポート443とパス/v1/statusは、このドメインルールの値には含めません。
ルール名と策略名も英語の原文を使用し、フィールドは半角の英語カンマで区切ります。全角カンマ、フィールドの不足、余分な空白による見えにくい差異が、1行の設定を期待どおりに解析できなくする場合があります。ルールをコピーした後は、まず3つのフィールド構造を保ち、キーワード、マッチ値、策略を順に確認してください。
DOMAINを追加したのに、なぜPROXYのままですか?
上にすでにマッチするDOMAIN-SUFFIXがないか確認し、FINALの後ろに記述していないことも確認します。例外にする完全一致のDOMAINは、広範なサフィックスルールより前に移し、HomeでGlobal RoutingをConfigに設定してから再テストします。
DIRECTを記述したのに、LAN機器へ接続できません。
対象の実際のIPが、記述したIP-CIDRの範囲内にあるか確認します。たとえば192.168.1.20は192.168.0.0/16にマッチしますが、192.168.2.0/24にはマッチしません。その後、ローカルWi-Fiからその機器へアクセスできることを確認してください。
サブスクリプション更新後にカスタムルールが消えました。
更新によって現在の設定内容が再書き込みされた可能性があります。まずConfigで有効な設定とその取得元を確認し、[Rule]が更新後の内容に戻っていないか確認します。長期間保持したい変更は、その設定の管理方法に合ったルール管理方法を使用してください。
On Demandを有効にすると、FINALは変わりますか?
変わりません。On DemandはSettings → On Demandにあり、接続するタイミングを管理します。FINALは引き続き[Rule]末尾のフォールバックです。まず接続が確立していることを確認し、その後リクエストがConfigモードでルールにマッチしているか確認します。
REJECTの範囲が広すぎるかどうかを素早く判断するには?
REJECTの前にあるマッチキーワードを確認します。DOMAINは完全な1つのドメインだけに影響し、DOMAIN-SUFFIXはメインドメインとすべてのサブドメインに影響します。単一ホストだけを拒否したい場合は完全一致のDOMAINを使用し、広範なREJECTを必要な例外より前に置かないでください。
保存前のルール確認リスト
保守しやすい設定は、通常、明確な階層を持ちます。LANと完全一致の例外を前に置き、ドメインサフィックスとアドレス帯を中央に置き、GEOIPを後ろ、FINALを最後にします。同じ対象を複数箇所に記述して相反する策略にしないでください。例外が必要な場合は「具体的なルールを前、汎用ルールを後」という順序で表現し、後続ルールが前のルールを上書きすると期待しないでください。
- 現在使用中のConfigを変更しており、別の未有効設定ではない。
- Home → Global RoutingがConfigになっており、テスト中にProxyまたはDirectのままになっていない。
- DOMAINとDOMAIN-SUFFIXの値にスキーム、ポート、パス、クエリパラメータが含まれていない。
- ルールのフィールドを英語カンマで区切り、キーワードと策略は英語原文のままにしている。
- 完全一致のDOMAINが、それを対象に含める可能性のあるDOMAIN-SUFFIXより前にある。
- IP-CIDRのプレフィックス長を明確にし、
/16と/24の対象範囲を混同していない。 - GEOIPが、優先処理するドメインおよびアドレスルールの後にある。
- FINALがフォールバックだけを担い、[Rule]の最後に置かれている。
- サブスクリプション更新後に、カスタム内容が残っているか再確認する。
- Settings → On Demandは接続するタイミングだけを制御し、Global Routingやルール確認の代わりにはならない。
確認後は、少なくとも反対方向の2つのサンプルで検証します。1つはDIRECT、もう1つはPROXYを想定した対象です。設定にREJECTが含まれる場合は、明確に拒否する対象も1つ追加します。各サンプルについてルールの先頭から最初のマッチを追うほうが、接続スイッチや1回の読み込み速度だけを見るより問題を特定しやすくなります。
ShadowrocketはAppleプラットフォーム向けのクローズドソースの商用アプリです。主な利用端末はiPhoneとiPadで、Mac、Apple TV、Apple Visionの互換性およびシステム要件はApp Storeページの記載に従います。入手先はApp Storeのみです。開発者名はShadow Launch Technology Limited、アプリIDは932747118、購入方式は買い切りです。アプリの購入と回線サービスは別のものであり、設定とサブスクリプションはユーザー自身が用意・管理します。