ShadowrocketのREJECTルールとは?ドメイン単位の通信拒否の仕組みと限界

ShadowrocketのREJECTルールの仕組みと、同一ドメイン内のコンテンツ・暗号化DNS・アプリ内リクエストに対する限界を解説します。

この記事の要点

REJECTが拒否するのはルールに一致した通信であり、Webページ内の個々の要素ではありません。この記事では、Shadowrocketで自分の設定を利用している方を対象に、まずConfigモードとルールの順序を確認し、次にドメインを指定してブロックを検証します。最後に、ドメインが見えない場合、接続が再利用される場合、同一ドメイン内に複数のコンテンツがある場合の3つの制約を整理します。

REJECTで拒否される範囲

REJECTはルールの処理ポリシーであり、マッチ条件ではありません。DOMAIN,ads.example.com,REJECTは3つの要素に分けられます。DOMAINはマッチ方法、ads.example.comは対象の値、REJECTは一致した通信を拒否する指定です。DIRECTやプロキシのポリシーで転送を続ける指定ではありません。

アプリからのリクエスト トンネルで捕捉 ルールを照合 REJECTに一致 接続を拒否

この流れが成り立つのは、リクエストがShadowrocketの処理対象になっている場合です。接続がオフになっている、想定した設定が有効になっていない、または現在のルーティング方式で該当ルールを使っていない場合、REJECTを1行追加しただけでは有効になりません。拒否後にアプリが空白画面や読み込みエラーを表示したり、再試行したりすることがあります。画面上の挙動はアプリ側のエラー処理によって異なります。

REJECTはコンテンツを消去する機能ではありません。ページに読み込み済みの画像、ローカルキャッシュ、アプリにあらかじめ用意された広告画面は、ルールを追加してもすぐには消えません。効果を確認するときは、画面に何が残っているかではなく、新しいリクエストが拒否されたかを確認してください。

Configとルールの順序を確認する

HomeでGlobal RoutingをConfigに設定し、Configで現在有効な設定を確認します。ProxyまたはDirectの状態で表示される画面を見て、Configのルールが機能しているか判断しないでください。もともとSceneを使っている場合は、シーンの設定を記録してから、Configを明示的に指定した条件でテストし、自動切り替えの影響を避けます。

  1. Configで元の設定のコピーを保管し、編集対象がこれから有効にするファイルであることを確認します。
  2. 設定の[Rule]セクションにテスト用ルールを追加し、先にマッチする可能性のある広範囲のルールとFINALより前に配置します。
  3. 設定を保存して有効にしたらHomeに戻り、Global Routing → Configになっていることと、接続がオンになっていることを確認します。
  4. 対象アプリに新しい接続を確立させ、接続履歴で接続先、マッチしたルール、処理ポリシーを確認します。ページを一度再読み込みしただけで判断しないでください。

通常のルールは記載順に照合され、最初に一致したルールで処理が決まります。以下は構成例であり、example.com系のドメインは実際のブロック対象一覧ではありません。FINAL,DIRECTも説明用のフォールバックにすぎず、既存設定の最終ルールを上書きしないでください。

[Rule]
DOMAIN,ads.example.com,REJECT
DOMAIN-SUFFIX,metrics.example.com,REJECT
FINAL,DIRECT

DOMAIN-SUFFIX,example.com,DIRECTを先頭に置くと、ads.example.com宛ての通信は先にこのルールに一致し、後続の個別拒否ルールでは処理されません。必要な例外、拒否したい具体的な接続、広範囲のルールを、実際の優先順位に沿って並べてください。「最後に追加したルールが優先される」と考えないようにしましょう。

ドメイン完全一致とサフィックス一致の使い分け

個別の接続を調べるときは、まずDOMAINを使うと対象範囲を絞りやすくなります。サブドメイン全体が同じ用途だと確認できた場合に限り、DOMAIN-SUFFIXへの変更を検討してください。1つのサブドメインで不要な通信が見つかったからといって、親ドメイン全体を拒否しないでください。

完全一致

マッチ条件
DOMAIN
マッチ対象
ads.example.com
ポリシー
REJECT
対象範囲
ads.example.comのみ

img.ads.example.comには一致しません。まず特定の接続を検証する場合に適しています。

サフィックス一致

マッチ条件
DOMAIN-SUFFIX
マッチ対象
metrics.example.com
ポリシー
REJECT
対象範囲
対象ドメインとそのサブドメイン

metrics.example.comとapi.metrics.example.comの両方が対象になるため、用途を事前に確認してください。

DOMAIN-KEYWORDはドメインに含まれるキーワードで照合するため、特定のサフィックスを指定するより対象範囲を絞りにくくなります。たとえばキーワードをadだけにすると、対象サービスとは無関係な多くのドメインにも影響する可能性があります。IP-CIDRはIPアドレスの範囲で、GEOIPはIPアドレスの所在地分類で処理します。いずれも「Webページ内の特定の要素」を指定するものではありません。サーバーやIPアドレスを共有している場合、IP指定で通信を拒否すると他のドメインにも影響することがあります。

要点:まず対象を絞り、確認してから範囲を広げる

まずは DOMAIN ルールを1つ使って、対象の用途とルールの適用結果を確認します。サブドメイン全体を拒否しても問題ないと確認できてから DOMAIN-SUFFIX に変更し、最初のテストでメインドメイン全体を対象にするのは避けてください。

同一ドメイン内のコンテンツはページ上の位置で分けられない

たとえば本文用のAPIがapi.example.com/content、広告用のAPIがapi.example.com/promoにあるとします。どちらも同じドメインを使っているため、通常のDOMAINルールやDOMAIN-SUFFIXルールではURLのパスによって区別できません。api.example.comを拒否すると、広告用APIだけでなく両方の通信が影響を受けます。

HTTPSで一般的に使われる宛先ポートは443ですが、ポート番号だけでは通信の用途はわかりません。通常のドメインルールでは、暗号化されたリクエストのパスや本文を取得できません。アプリ内ブラウザーも同様です。重要なのは、接続先が独立しているか、照合に使えるドメイン情報があるかであり、ブラウザーに表示されるかアプリ内に表示されるかではありません。

暗号化DNSとドメイン情報の見え方

ドメインルールを適用するには、照合に使えるドメイン情報が必要です。システムのDNSを使うアプリでは、名前解決と接続が関連付けられる場合があります。一方、アプリが独自にDoHまたはDoTを使う場合、DNSクエリは別の暗号化接続に含まれます。Shadowrocketが接続先IPだけから、その中で照会されたドメインを特定できるとは限りません。他の接続メタデータを利用できるかどうかも、実際の通信や設定によって異なります。

ケース確認する内容そこから断定できないこと
通常のDNS名前解決との関連、宛先ドメイン、実際にマッチしたルールDNSクエリが確認できても、後続の接続がREJECTに一致するとは限りません
アプリ内DoH独立したDNSエンドポイントに接続しているか、宛先接続にドメイン情報が残っているかDoHでは443がよく使われますが、443の接続がすべてDNSとは限りません
アプリ内DoT宛先ポート853の接続があるか、その用途は何かポート情報だけからクエリ内容を特定することはできません
IPアドレスへ直接接続接続履歴にIPアドレスしか表示されないか、別のドメイン情報と関連付けられているかDOMAINルールがその接続に必ず一致するとは限りません

このような場合は、まずSettingsのDNS設定とアプリ独自の名前解決オプションを確認してください。詳しくはDNS設定ガイドをご覧ください。既知のDNSエンドポイントを拒否すると、アプリの名前解決に失敗したり、別のエンドポイントに切り替わったりすることがあります。これは対象コンテンツをブロックできたことを意味しません。特に「443の接続をすべて拒否する」方法でドメインを調べるのは避けてください。通常のHTTPS通信にも影響します。

再現・確認できるブロックテストを行う

テストでは変更する項目を1つに絞ります。画面上の空白、読み込み時間、エラーメッセージは間接的な兆候です。より確かな確認材料は、接続先、最初に一致したルール、最終的に適用されたポリシーです。以下は自分の設定を確認するための手順であり、接続サービスの入手方法を案内するものではありません。

  1. 変更前の状態を記録:現在の設定を保存し、Global Routingの状態、対象ドメイン、ルール追加前の画面表示を記録します。
  2. ルールを1つだけ追加:確認済みの対象をDOMAIN,ads.example.com,REJECTのような完全なルールとして記述します。実際のテストでは自分で記録したドメインを使用し、例示のドメインを有効な一覧とみなさないでください。
  3. 接続を作り直す:対象アプリを終了してから再起動し、必要に応じてShadowrocketの接続も再確立します。既存の長時間接続が再利用される場合があるため、1回の再読み込みでは新しいルール判定が行われないことがあります。
  4. マッチ結果を確認:新しい接続の宛先、ルール、ポリシーを確認します。処理結果がDIRECTまたはプロキシのままなら、設定が有効か、さらに前のルールが先に一致していないかを確認してください。
  5. 他の機能への影響を確認:ログイン、本文の読み込み、画像表示、送信操作を順にテストします。問題が起きたら追加したルールを元に戻し、同じ操作を再度行って結果を比較します。

自動接続の状態も記録してください。Settings → On Demandは条件に応じた接続動作を管理する機能で、REJECTルールの代わりにはなりません。テスト中にネットワークの変化で接続状態が変わる場合は、リクエスト時に通信がトンネルを通っていたかを先に確認します。On Demand、DNS、ルール一覧を同時に変更すると、どの変更が結果に影響したのか判断しにくくなります。

よくある症状と対処法

REJECTを追加したのに、ページのコンテンツが残るのはなぜ?

まず対象アプリを再起動し、REJECTに一致する新しい接続が発生したか確認します。履歴上で拒否されているのに画面が残る場合は、キャッシュ、ローカルリソース、1つのレスポンスに複数の内容が含まれている可能性を調べてください。すぐに親ドメイン全体へ対象を広げないようにしましょう。

ブロックするとログインできなくなるのはなぜ?

追加したルールをいったん戻し、ログインを再テストしてください。機能が戻る場合は、DOMAIN-SUFFIXを確認済みのDOMAINに絞り、認証用APIと追加リクエストを個別に検証します。同じドメインが複数の用途に使われているなら、必要な通信は許可してください。

接続履歴にIPアドレスしか表示されず、ドメインが見えないのはなぜ?

アプリがIPアドレスへ直接接続していないか、独自の暗号化DNSを使っていないかを確認し、SettingsのDNS設定も確認してください。安易にIPアドレスをネットワーク範囲全体の拒否に広げないでください。共有IPには他のサービスも含まれる可能性があるため、対象と誤ブロックの範囲を先に確かめましょう。

設定を更新したら、手動で追加したルールが消えたのはなぜ?

Configで現在有効なファイルとルールの内容を再確認してください。リモート設定の更新とHomeに登録済みのサブスクリプション内サーバー一覧の更新は、別の操作です。設定を置き換える前にローカルコピーを保存し、更新後にカスタムルールが想定した位置に残っているか確認してください。

最終的な判断基準は「指定した接続が想定どおり拒否され、必要な機能は使えること」です。あらゆるアプリから特定の種類のコンテンツが一切表示されなくなると保証するものではありません。REJECTは個別に識別できる接続の処理に適しています。コンテンツと必要な機能が同じドメイン、接続、レスポンスを共有している場合は、拒否範囲を広げ続けるのではなく、ドメインルールで対応できる範囲を理解してください。

App Storeで正規アプリを確認