接続が正常に使えており、Configにドメインブロックのルールを追加したい方向けの記事です。まずマッチ条件とREJECTポリシーを区別し、ルールを追加して接続ログを確認します。そのうえで、同一ドメインのリソース、キャッシュ、アプリ内コンテンツがドメインルールで処理できる範囲を超えていないかを判断します。ドメイン名とアドレスは構文説明用の例であり、実際のブロックリストとしては使えません。
1. REJECTはマッチ後の処理ポリシーであり、コンテンツ識別機能ではない
Shadowrocketのルールでは、「どの条件に一致する接続か」と「一致した後にどう処理するか」を分けて考えます。DOMAIN-SUFFIX、DOMAIN、IP-CIDRはマッチ条件で、REJECTは処理ポリシーです。ドメインをルールに記述しても、Webページ内の広告や解析コード、動画の一部を識別するわけではありません。条件に一致した接続を拒否するだけです。
この流れは、実際にShadowrocketを経由し、現在のルール設定で処理される通信が対象です。通信がトンネルに入らなければ、ルールは適用されません。トンネルに入っていても、ルーティングが全体的な直接接続またはプロキシになっている場合、Configの個別ルールが有効かどうかは判断できません。トラブルシューティングでは、まずHomeで接続状態を確認し、次にGlobal Routingを確認してください。
- Config:現在の構成に設定されたルールに基づいて接続ポリシーを決定します。この記事のルール例を検証する際に使用します。
- Proxy:すべての通信をプロキシ経由にするルーティング設定です。Configの振り分けルールを検証する基準にはなりません。
- Direct:すべての通信を直接接続するルーティング設定です。ページが開けるというだけで、拒否ルールが機能していないとは判断できません。
- Scene:シーンで実際に使用されている構成とルーティング設定を確認してください。テスト時はConfigに固定して、変数を減らします。
拒否されたときの表示はアプリによって異なります。リソースの読み込みエラーや空白のプレースホルダーが表示されたり、再試行を繰り返したりすることがあります。REJECTはページレイアウトを削除する機能ではなく、読み込みを速くする保証もありません。また、リモートコンテンツを別の内容に書き換える機能でもありません。
2. DOMAINとDOMAIN-SUFFIXの書き方と適用範囲
ドメインルールにはホスト名だけを記述し、https://、ポート、パス、クエリパラメーターは含めません。対象のリクエストがhttps://ads.example.com:443/banner?id=1の場合、確認するのはads.example.comです。443は接続ポート、/bannerはパスであり、どちらもDOMAIN-SUFFIXのドメイン引数ではありません。
DOMAIN,ads.example.com,REJECT
DOMAIN-SUFFIX,metrics.example.com,REJECT
ホスト名の完全一致
- キーワード
- DOMAIN
- パラメーター
- ads.example.com
- ポリシー
- REJECT
- マッチ範囲
- ads.example.comのみ。img.ads.example.comは含まない
最初の検証では、影響範囲を限定できるホスト名の完全一致を優先します。
ドメインサフィックス一致
- キーワード
- DOMAIN-SUFFIX
- パラメーター
- metrics.example.com
- ポリシー
- REJECT
- マッチ範囲
- metrics.example.comとそのサブドメイン
ドメイン階層全体の用途が同じだと確認してから、サフィックスの範囲に広げます。
DOMAIN-SUFFIX,example.com,REJECTは、example.comやapi.example.comなどのサブドメインにも一致します。ただし、任意の文字列を含むかどうかで判定するものではないため、notexample.comは一致しません。また、サフィックスの指定を*.example.comで代用しないでください。ルール構文に従って、ドメイン名だけを指定します。
3. ルールは上から順にマッチ:例外を先に、FINALを最後に
ルールの順序によって結果は変わります。同じ接続では、最初に一致した有効なルールが処理ポリシーを決めます。後ろにある、より具体的なルールが自動的に優先されることはありません。そのため、アクセスを許可する例外は、それを対象とする拒否ルールより前に置きます。広範なIPルールや地域ルール、FINALは通常、関連するドメインルールの後に置きます。
[Rule]
DOMAIN,keep.metrics.example.com,DIRECT
DOMAIN-SUFFIX,metrics.example.com,REJECT
GEOIP,CN,DIRECT
FINAL,DIRECT
この例は順序の説明用です。keep.metrics.example.comは先に完全一致の例外にマッチし、それ以外のmetrics.example.comのドメイン階層は拒否されます。FINAL,DIRECTは例を成立させるための設定です。実際の構成では既存の最終処理ポリシーを維持し、ブロックルールを追加するためだけに、未マッチの通信をすべて直接接続に変更しないでください。
| ルールの位置 | よくある問題 | 修正方法 |
|---|---|---|
| 拒否ルールがFINALの後にある | 通信がすでに最終処理ルールに適用されている | 拒否ルールをFINALより前に移動する |
| 例外ルールがサフィックス拒否ルールより後にある | 例外対象のホストが先にREJECTに一致する | 完全一致の例外をサフィックスルールより前に移動する |
| 広範な許可ルールが拒否ルールより前にある | 対象が先に許可ポリシーに一致する | マッチ記録を確認し、重複するルールの順序を調整する |
まとめ:最初に一致したルールを確認してから、新しいルールを追加
対象の接続がすでに前のルールで処理されている場合、同じREJECTを重ねて追加しても結果は変わりません。まず現在の構成とマッチした位置を確認し、ルールの移動または条件の絞り込みを行ってください。
対象がIPアドレスの場合は、IP-CIDR,192.0.2.0/24,REJECT,no-resolveのような構文でアドレス範囲のマッチを設定できます。ここに記載したアドレス範囲は説明用の例です。no-resolveは、このIPルールのためにドメイン名の名前解決を積極的に行わない指定であり、端末のDNSを無効にするものではありません。共有IPには無関係な複数のドメインが割り当てられていることがあるため、ドメインブロックが効かないからといって、アドレス範囲全体を拒否しないでください。
4. ドメイン単位のブロックでは、同一ドメイン内のパスやアプリ内の表示を区別できない
本文用APIがapi.example.com/article、プロモーション用APIがapi.example.com/promotionだとします。どちらも同じホスト名を使っているため、DOMAINやDOMAIN-SUFFIXでは後者のパスだけを拒否できません。api.example.comをREJECTにすると、本文やログイン状態、コメント用APIまで遮断される可能性があります。
| コンテンツの配信方法 | ドメインルールでできること | 保証できないこと |
|---|---|---|
| 別ホストから素材を読み込む | そのホストへの新しい接続を拒否する | アプリが空白のプレースホルダーを削除するとは限らない |
| 同じホストの異なるパス | ホスト単位で処理する | ドメインルールで特定のパスだけを選ぶことはできない |
| プロモーションと本文が同じレスポンスに含まれる | 接続全体を拒否する | レスポンスから一部だけを選び出すことはできない |
| ローカルキャッシュまたはアプリ内蔵素材 | 新しい接続がなければマッチできない | すでに表示された内容がすぐ消えるとは限らない |
HTTPSでは通常、URLのパスやレスポンス本文は隠されています。ルールが接続先のドメインを取得できても、暗号化された接続内のすべてのリソースを読み取れるわけではありません。ホストを拒否するドメイン単位のREJECTに、コンテンツの復号は必要ありませんが、処理できる範囲は該当する接続に限られます。パス処理、レスポンスの書き換え、ページ要素の非表示を、ドメインルールの機能と混同しないでください。
- 動画とプロモーション部分がすでに同じメディアストリームに結合されている場合、メディアホストを拒否すると動画全体を再生できなくなることがあります。
- アプリ内の埋め込みページもネットワーク接続を開始しますが、埋め込みページだからといって、素材が必ず独立したドメインから配信されるとは限りません。
- アプリが別のホストに切り替えて再試行する場合、元のルールには引き続き一致していても、新しいリクエスト先がルールの対象外である可能性があります。
- IPアドレスへの直接接続で利用可能なドメイン情報がない場合、単一のドメインルールですべてのケースをカバーできるとは限りません。
5. 追加と検証:一度に変更するのは1つだけにして、元に戻せる状態を保つ
テストには、正常に利用できている構成を使ってください。この記事では、ユーザーがすでに自身のプロバイダーやサブスクリプションを利用していることを前提とし、接続サービスの提供や推奨は行いません。対象がもともと直接アクセスできるリソースであれば、接続方法はそのままにして、新しいルールによる違いだけを確認できます。
- 現在の構成をバックアップします。Configで現在選択されているファイルを確認し、コピーを保存するか、元の内容を記録してください。例のルールを既存ファイル全体に上書きしないでください。
- ルーティング設定を固定します。Homeで接続が有効になっていることを確認し、Global RoutingをConfigに設定します。編集した構成が選択されていることも確認してください。
- 完全一致のルールを追加します。対象の構成の
[Rule]セクションに、まずDOMAIN,ads.example.com,REJECT形式のルールを1つ追加します。例のホスト名を記録した対象ホストに置き換え、関連する広範なルールとFINALより前に配置してください。 - 保存してリクエストを再実行します。対象のページまたはアプリを開き直してください。必要に応じて接続を再確立し、新しいリクエストに新しい構成を適用します。すでに確立された長時間接続やローカルキャッシュだけを、検証の根拠にしないでください。
- 接続ログを確認します。対象ホストの新しいリクエストを探し、実際のポリシーがREJECTになっているかを確認します。同時に、ログイン、本文、画像、再生などの必要な機能も確認してください。
- 問題が起きたら、まず元に戻します。追加したルールを削除または無効にして、もう一度テストしてください。機能が復旧した場合は、完全一致の例外を追加するか、DOMAINに条件を絞るか、そのドメイン全体のブロックをやめるかを判断します。
端末で自動接続を有効にしている場合は、Settings → On Demandも確認してください。テスト中に接続が自動で復旧したり、状態が切り替わったりしても気づかないことがあります。On Demandは接続を開始するタイミングを決める機能で、REJECTのマッチ優先順位は変更しません。両者は分けて確認してください。
6. よくある質問:ルールに一致しない、コンテンツが表示される、誤って遮断したときの復旧
REJECTを設定したのに、なぜWebページを開けるのですか?
まず、拒否した対象がページのホストなのか、付随するリソースのホストなのかを確認してください。素材のドメインだけを拒否した場合、本文を引き続き開けるのは想定どおりの動作かもしれません。次に、HomeのGlobal RoutingがConfigになっているか、正しい構成が選択されているか、ルールがFINALより前にあるかを確認します。ページ全体が開くかどうかだけでなく、新しい接続に実際に適用されたポリシーを確認してください。
ログではREJECTになっているのに、なぜアプリに元の内容が表示されるのですか?
対象のページを開き直し、新しいリクエストが発生しているか確認してください。ダウンロード済みの画像、事前読み込みされたコンテンツ、アプリ内蔵素材は表示され続けることがあります。また、アプリが別のホストに切り替えている可能性もあります。画面にまだ内容が表示されているという理由だけで拒否範囲を広げず、リクエスト時刻と対象ドメインを照合してください。
ルールを追加したらログインできなくなりました。どうすれば元に戻せますか?
まず直近に追加したルールを取り消し、ログインをやり直してください。ログインできるようになった場合、そのルールが必要なAPIまで対象にしていた可能性があります。ログイン前後のホスト記録を比較し、サフィックスルールをホスト名の完全一致に絞ってください。特定のホストを許可すべきだと確認できた場合に限り、拒否ルールより前に対応する完全一致の例外を追加します。
別のプロキシプロトコルに切り替えると、REJECTの精度は上がりますか?
Shadowsocks、VMess、VLESS、Trojan、Hysteria2、WireGuardのいずれに切り替えても、コンテンツを識別できるようにはなりません。REJECTの適用は、ルール処理に入る通信、利用可能な接続先情報、ルールの順序によって決まります。原因を切り分けられなくなるのを防ぐため、接続方法は変えずにルールを検証してください。
ルールを残すかどうかは、次の3つをすべて満たすかで判断します。対象の新しいリクエストが実際に一致すること、意図したリソースが制限されること、必要な機能に影響しないことです。ドメイン単位で必要なコンテンツと拒否したいコンテンツを分けられない場合は、広範な拒否ルールを追加し続けるのではなく、ドメイン単位で処理できる範囲に限界があると判断してください。