ShadowrocketのREJECTとは?ルールでブロックできる範囲とできない範囲

REJECTは接続確立前に、ルールに一致したリクエストを拒否します。ドメイン・IPによる判定、ルールの優先順位、ブロックできないケースを解説します。

この記事の要点

ShadowrocketのREJECTは接続を振り分けるポリシーであり、Webページのコンテンツをフィルタリングする機能ではありません。接続が正常に動作し、ルールを編集する段階の方向けに、Global RoutingをConfigに設定する方法、ドメインまたはIPで範囲を絞ったルールを追加する手順、リクエストログでの確認方法を解説します。ルールの漏れ、キャッシュ、同一ドメイン上のコンテンツによる制限も整理します。

REJECTが拒否するのは接続であり、ページ内の特定要素ではありません

アプリがネットワークにアクセスすると、Shadowrocketは処理対象となる接続にルールを照合します。REJECTに一致すると、そのリクエストについてDIRECTやPROXYを使った通常の宛先向け接続は確立されません。ここでいう「接続確立前」とは宛先への出方向の接続段階を指します。アプリがリクエストを送信する前という意味でも、照合前にDNSクエリが必ず発生しないという意味でもありません。

アプリからリクエスト トンネルで受信 ルールを照合 一致して拒否 アプリにエラー

アプリ上の表示は、アプリ独自のエラー処理によって異なります。画像の読み込みに失敗したり、独立した計測リクエストが終了したりするほか、再試行やタイムアウトが表示されることもあります。REJECTは正常なページを代わりに生成せず、ページ内の空白領域を自動で折りたたむこともありません。そのため、「リクエストは拒否されたが、ページの見た目は変わらない」という状況は起こり得ます。

これらのポリシーは、使用するプロキシプロトコルとは別の階層です。Shadowsocks、VMess、VLESS、Trojan、Hysteria2、WireGuardは、プロキシの通信方式やトンネル方式を表します。プロキシプロトコルを変更しても、REJECTでHTTPSページ内のコンテンツを識別できるようにはなりません。

ドメインルールとIPルールで判定できること

照合時に宛先ドメインを取得できる場合は、DOMAINまたはDOMAIN-SUFFIXを使用できます。前者は完全一致するホスト名、後者は指定したドメインとそのサブドメインに一致します。独立したリクエスト先だけを拒否したい場合は、最初からドメイン全体に範囲を広げず、完全なホスト名を指定してください。

ドメインの照合範囲

DOMAIN
metrics.example.com,REJECT
DOMAIN-SUFFIX
example.com,REJECT
照合対象
宛先のホスト名(URLのパスではありません)

example.comとそのサブドメインは構文の説明用です。そのまま使えるブロックリストではありません。

IPの照合範囲

IP-CIDR
192.0.2.10/32,REJECT,no-resolve
GEOIP
CN,DIRECT
照合対象
宛先IP、ネットワーク範囲、またはIP位置情報データベース

192.0.2.10はドキュメント用の例示アドレスです。GEOIPの例は許可する設定を示すもので、ブロックを推奨するものではありません。

/32は単一のIPv4アドレスを表し、曖昧な範囲を意味しません。no-resolveは、このIPルールのためだけに追加のドメイン解決を行わないようにする設定です。「すべてのリクエストでDNSを使わなくなる」という意味ではありません。アプリがIPアドレスに直接アクセスし、利用可能なドメイン関連情報もない場合、ドメインルールだけでは一致しないことがあります。

IPルールにも限界があります。複数のドメインが同じCDNアドレスを共有する場合があり、同じドメインでも地域、ネットワーク、時間によって異なるIPアドレスが返ることがあります。ある時点で解決されたIPをすべて拒否すると、新しいアドレスを見逃す一方で、同じアドレスを共有する別のサービスに影響するおそれがあります。GEOIPもアドレスの位置情報データベースに基づく判定であり、Webサイトの実際のコンテンツや運営主体を識別するものではありません。

範囲を広げる前に依存関係を確認してください。ログイン、認証コード、画像、本文で、同じドメインの異なるサブドメインが使われることがあります。DOMAINをDOMAIN-SUFFIXに変更すると、単一の接続先の拒否が、必要なリクエスト一式の拒否に広がる可能性があります。

ルールは記載順に照合され、REJECTに特別な優先権はありません

Configによるルーティングでは、ルールを上から順に確認し、最初に一致したルールのポリシーを適用します。拒否を意味するREJECTだからといって、前にあるDIRECTやPROXYを自動的に上書きするわけではありません。具体的な例外は範囲の広いルールより前に置き、FINALはルール群の最後に配置して、それまで一致しなかった接続を処理します。

[Rule]
DOMAIN,login.example.com,DIRECT
DOMAIN,metrics.example.com,REJECT
DOMAIN-SUFFIX,example.com,PROXY
GEOIP,CN,DIRECT
FINAL,PROXY

この例は順序の説明用です。login.example.comは先にDIRECTに一致し、metrics.example.comは先にREJECTに一致します。それ以外のexample.comに属するリクエストは、その後PROXYに一致します。DOMAIN-SUFFIXを先頭に移すと、前の2つのホスト名も先にそのルールで処理され、後続の個別ルールが機能しなくなります。

設定例結果修正方法
広い範囲の許可ルールがREJECTより前宛先が先に許可ルールに一致対象となる広い範囲のルールより前に、ホスト名を指定したREJECTを配置する
REJECTがFINALより後リクエストはすでにFINALで処理済みFINALはルール群の最後に配置する
同じホスト名に複数のポリシーが設定されている先に一致したルールが適用されるREJECTだけでなく、ルール全体の順序を確認する

判断のポイント:実際に一致したルールを確認してから、ブロック範囲を広げる

リクエストログにDIRECTまたはPROXYと表示される場合は、後続ルールを増やす前に、前段のルールまたは現在のルーティング設定を見直してください。同じリクエストがすでに別のルールに一致している状態では、似たREJECTルールを追加しても解決しません。

Configの適用を確認し、範囲を絞ってテストする

ルールファイルがConfigにあっても、現在のリクエストがそのファイルで処理されるとは限りません。まずHomeでGlobal Routingを確認してください。ProxyとDirectは全体の通信経路を決める設定です。ルールをテストするときは、Configを明示的に選択します。Sceneは状況に応じたルーティング設定です。Sceneと表示されているだけで、現在のConfigにあるルールが適用されるとは判断できません。

  1. 設定のコピーを保存します。Configで現在使用中の設定を確認し、編集前に復元用のコピーを保存してください。内容を把握していないルール一式を、そのまま上書きしないでください。
  2. ホスト名を指定したルールを1つだけ追加します。リクエストログに実際に表示されたホスト名を使い、DOMAIN,ホスト名,REJECTの形式で記述します。ここでの「ホスト名」は入力欄の説明であり、そのまま貼り付けて使えるルールではありません。
  3. 設定の適用状態を確認します。変更を保存し、編集した設定が選択されていることを確認します。HomeでGlobal RoutingをConfigに設定し、接続スイッチがオンになっていることも確認してください。
  4. 新しいリクエストを発生させます。対象ページを閉じてから再度開きます。必要に応じて対象アプリを終了して起動し直してください。読み込み済みの画像や古いタブだけを見て判断しないでください。
  5. ログを確認します。リクエストログで対象のホスト名またはIPを探し、実際に一致したルールとポリシーを確認してください。新しいリクエストにREJECTと表示されて初めて、テストで拒否処理が行われたと確認できます。
  6. ルールを戻して比較します。追加したルールを一時的に削除し、同じ手順でリクエストを発生させます。削除前後の接続結果や機能の変化を比べ、影響がそのルールによるものか確認してください。

Settings → On Demandは、条件に応じた自動接続を制御する設定であり、REJECTのオン・オフではありません。テスト中にトンネルが切断されると、その後のリクエストが同じ処理経路を通らない可能性があります。「ルールが効かない」と判断する前に接続状態を確認してください。また、ルールを変更しても既存のセッションがすべて切断されるわけではありません。テストでは新しい接続を発生させる必要があります。

記録するのは検証条件であり、速度の評価ではありません。対象のホスト名、Global Routingの設定、適用されたポリシー、アプリを再起動したかの4点を記録してください。これらが分からない状態では、「ページを開ける」というだけでREJECTの適用を判断できません。

HTTPS、キャッシュ、同一ドメイン上のコンテンツによる制限

ドメインルールとIPルールが処理するのは接続先です。たとえば通常のコンテンツがhttps://example.com/articleにあり、別のコンテンツがhttps://example.com/promoにあっても、ホスト名は同じです。DOMAINやDOMAIN-SUFFIXだけでは2つのパスを区別できません。このホスト名を拒否すると、通常の記事も同時にブロックされる可能性があります。

443
HTTPSで一般的に使われるデフォルトポートであり、コンテンツの種類を示すものではありません
53
従来のDNSで一般的に使われるポートであり、すべてのDNS通信方式をカバーするものではありません
4項目
Global Routing:Proxy / Direct / Config / Scene

ポート番号から分かるのは、通信の用途に関する手がかりだけです。通常のWebページもその他のHTTPSリクエストも443を使う場合があるため、ポート全体を拒否して細かく選別することはできません。宛先ドメインを取得できても、暗号化された接続内のURLパス、リクエスト本文、応答内容を読み取れるとは限りません。REJECT自体に復号機能はありません。

URL Rewriteは別種のリクエスト書き換え機能であり、その機能をREJECTのものとして扱ってはいけません。接続ルールだけで特定のコンテンツを切り分けられない場合は、必要な機能を維持して対象範囲を絞ってください。ページ要素を消そうとしてネットワーク範囲を際限なく広げるのは避けましょう。

よくある症状と復旧手順

REJECTを追加したのに、ページが表示されるのはなぜですか?

まずHomeでGlobal RoutingがConfigになっていることを確認します。リクエストを再発生させてログを確認してください。新しいリクエストにREJECTと表示されているのに以前の画像が残っている場合は、アプリのキャッシュを確認します。新しいログがまったくない場合、表示中のページだけではルールの結果を判断できません。

ブロックしたらログインできなくなったのはなぜですか?

まず、最近追加したDOMAIN-SUFFIXまたはIP-CIDRルールを削除し、アプリを開き直してログインを確認します。正常に戻った場合は、ログイン先と対象コンテンツがドメインまたはIPアドレスを共有していないか確認してください。区別できる場合はホスト名を指定したDOMAINに変更し、区別できない場合はログインに必要な接続を許可してください。

サブスクリプション更新後、追加したルールが効かなくなったのはなぜですか?

Configに戻り、現在有効なファイルとRuleセクションにローカルの変更が残っているか確認します。サーバー上のサブスクリプション情報を更新する操作と、リモート設定を置き換える操作は別です。更新時に設定全体が置き換えられた場合、ローカルルールが上書きされた可能性があります。保存したコピーから復元し、ルールの順序をもう一度確認してください。

大量のIPアドレスをそのままコピーしてブロックできますか?

いきなり一括で追加するのは避けてください。実際の接続先を1つ記録し、CDNアドレスを共有しているか、別のIPアドレスが返されることがあるかを確認してから、IP-CIDRを使うか判断します。関連するルールを一度に1組だけ変更し、復元用コピーも保存してください。どのルールが機能の不具合を招いたのか分からなくなるのを防げます。

この記事では、ユーザーが自身のサービス提供元とサブスクリプションを利用していることを前提としています。接続情報は利用中のサービス提供元から取得してください。サービス提供元が案内する接続パラメータは接続設定に関するもので、REJECTは現在の設定における照合と拒否を処理します。両者は代替できません。検証後は、用途が分からないルールを増やし続けるより、範囲が明確で説明でき、元に戻せるルールを保つほうが管理しやすくなります。

Shadowrocketの入手と基本設定ガイド

iPhone / iPad版はApp Storeで2.99米ドルの買い切りです。Mac(Appleシリコン / Intel)、Windows、Android、Linux版は無料です。iPhone / iPadのシステム要件はApp Storeの掲載内容をご確認ください。アプリの買い切り料金と通信サービスの料金は別です。アプリを入手した後、ご自身の接続設定が必要です。

Shadowrocketを全プラットフォーム向けにダウンロード