ルール

順序付きのリスト。先に当たった 1 行が決める。

ルールファイルが問われるのは、グローバルポリシーが Config のときだけです。Proxy と Direct はファイル全体をスキップします。ホームのテスターは見本リストでドメインを照合し、端末が使っているファイルとは別です。

  1. 01いつ走るか
  2. 021 行は三つの部分
  3. 03照合順
  4. 04ドメイン条件
  5. 05アドレスと地理ライブラリ
  6. 06DIRECT · PROXY · REJECT
  7. 07ホスト名はどこから来るか
  8. 08三つの要求の歩き読み
  9. 09複数構成と外部リスト

01

エンジンのスイッチはポリシーにあり、ファイルにはない

どれほど揃ったルールでも、ポリシーが Proxy なら送信はすべて現在のレコードへ入り、Direct ならすべて元経路です。ファイルが「自分で開く」ことはありません。ポリシーを Config に戻して初めて、今選んでいる構成が 1 行ずつ照合を始めます。ポリシー 3 項の意味は トンネル にあります。

構成ファイルは複数持てます。接続時に使うのは今選んでいる 1 つだけです。サーバーレコードは別のオブジェクトです。ハイライト行を替えてもファイルは替わらず、ファイルを替えてもハイライト行は替わりません。構成に何が書いてあるかと、一覧で今ハイライトされている出口は、独立した二件です。オブジェクトConfig を見てください。

だから「ルールが効かない」にはまったく違う二義があります。ひとつは、エンジンがそもそも問われていない(ポリシーが Config ではない、または選ばれているのが思っていたファイルではない)。もうひとつは、問われたが、先に当たった行が思っていた行ではない。切り分けでは前者を先に確認し、それから後者を直します。

ホームのテスターは端末上のファイルではない

製品ページのドメインテスターは、書き込み済みの見本リストです。「上から、先に当たった 1 行が効く」だけを示します。GEOIP はウェブでは模擬できません。テスターの結果を自分の端末の振り分けだと思うと、誤った結論になります。

02

1 行は三つの部分

よくある書き方は、条件タイプ、引数、動作です。カンマ区切りです。タイプと引数が「この行が誰を扱うか」を決め、動作が「扱ったあとどうするか」を決めます。行頭が # の行はコメントで、エンジンは飛ばし、照合に参加しません。

# コメントは照合されない
DOMAIN,api.example.com,PROXY
DOMAIN-SUFFIX,example.com,DIRECT
IP-CIDR,10.0.0.0/8,DIRECT
GEOIP,CN,DIRECT
FINAL,PROXY

送信を本当に変える動作は三つだけです。DIRECT(元経路)、PROXY(今ハイライトされているレコード)、REJECT(止め、送らない)。ファイルによってはポリシーグループ名が書いてあり、動作を別の選択論理へ向けます。本ページが扱うのはこの三つの直接動作だけです。タイプを間違え、カンマを書き落とし、URI を丸ごとルール行に貼ると、その行は期待どおり動かず、要求は下へ落ち続けます。

同じファイルにドメイン条件とアドレス条件を混ぜられます。エンジンは接続ごとにリストを一度だけ歩き、「ドメインで一度当たり、IP でもう一度当たって和集合」にはしません。先に当たった行がすでに動作を出しており、後ろの行は見ません。

03

狭い条件を、広い条件より上に書く

Shadowrocket の default.conf:Rule 289 件
ルールは設定ファイルにあります。ポリシーが Config のときだけ問われます。App Store 掲載画面。端末の版に従ってください。

照合は上からです。ある行が当たったあと、後ろの行は見ません。だから例外は通則より前に書きます。FINAL をファイルの途中に置くと、それより下の行はすべて無効です。ファイルには残っていますが、問われることはありません。

下の二つのリストは行がまったく同じで、順番だけ逆であり、結果は逆です。

# A: 先にホストを指名し、そのあとサフィックス
DOMAIN,api.example.com,PROXY
DOMAIN-SUFFIX,example.com,DIRECT
FINAL,PROXY

# B: 先にサフィックス。api の行には永遠に到達しない
DOMAIN-SUFFIX,example.com,DIRECT
DOMAIN,api.example.com,PROXY
FINAL,PROXY

api.example.com では、リスト A は 1 行目に当たりレコードへ、リスト B はサフィックスに当たり直通です。www.example.com では、どちらもサフィックスで直通です。unrelated.org では、どちらも FINAL に落ち、レコードへ行きます。

KEYWORD は SUFFIX より広く、GEOIP はほとんどのドメイン行より広く、FINAL が最も広いです。安定した順は、具体ホスト → サフィックス / キーワード → 網段 → GEOIP → FINAL です。構文の要求ではなく、例外が見えるための置き方です。

04

ドメイン条件: 誰が誰に当たるか

DOMAIN
ホスト名は完全一致である必要があります。DOMAIN,example.com,PROXY は example.com に当たり、www.example.com にも api.example.com にも当たりません。正確な名前一つを扱うときに使い、サフィックスの代わりにしないでください。
DOMAIN-SUFFIX
ホスト名がそのサフィックスと等しいか、「.サフィックス」で終わります。apple.com は apple.com と www.apple.com に当たり、icloud.com はその中にありません。notapple.com には当たりません。後者は apple.com という文字で終わるだけで、間にその点がありません。
DOMAIN-KEYWORD
ホスト名がその文字列を含めば当たります。KEYWORD,google は google.com にも googlevideo.com にも、名前に google が挟まったホストにも当たります。範囲が最大で、誤爆も最も起きやすいです。サフィックスに直せるなら使わないでください。

サフィックス行は、そのサフィックスのサブドメイン以外の名前を自動では覆いません。DOMAIN-SUFFIX,google.com,PROXY を書いても gstatic.com、youtube.com、googleapis.com は対象になりません。それらは別の登録ドメインです。それぞれ書くか、後ろの GEOIP / FINAL に落ちるのを受け入れます。

大文字小文字はドメインの慣例どおり区別しません。国際ドメインがルールに Unicode で出て、実際の要求が punycode(xn--)だと、両側が合わず、その行は当たりません。切り分けでは、ルールファイルに実際に書いたバイトを基準にしてください。

05

アドレス、ポート、地理ライブラリ

IP-CIDR
宛先 IPv4 網段です。例: 10.0.0.0/8172.16.0.0/12192.168.0.0/16 はよく DIRECT と書き、LAN がトンネルに出入りしないようにします。この 1 行だけのとき、IPv6 の宛先は当たらず、要求は下へ落ち続けます。
IP-CIDR6
IPv6 網段です。二つのアドレス族を同時に扱うなら両方書き、または使わないほうを設定で切ってください。IPv4 の私網だけ足して、端末が同じサービスを IPv6 で取ると、ルールが「ときどき効く」ように見えます。
GEOIP
宛先 IP の地理ライブラリ上の分類であり、ドメインの登録地でも、サイトの言語でもありません。GEOIP,CN,DIRECT の意味は、この宛先がライブラリで CN と印されたとき直通、です。ライブラリ版は端末上にあり、ウェブのテスターでは模擬できません。CDN が同じホスト名を別の国のアドレスに指すと、GEOIP の結果も動きます。
DEST-PORT
宛先ポートです。ある種の出口(たとえば 443 だけレコードへ入れたい)を他のポートから分けるために使います。ホスト名は見えません。ドメイン行と一緒に書くときも、先に当たったほうが決まります。
USER-AGENT
クライアントが宣言する UA 文字列です。要求にこの項が出るときだけ意味があります。多くのアプリは HTTP ヘッダを通さず、UA を空のままにし、この行は彼らには存在しません。
FINAL
最後に置くべきです。前が誰も当たらないときに、ここの動作を使います。省略せず、「書かなければデフォルト PROXY」という推測にも頼らないでください。FINAL が PROXY か DIRECT かが、指名されていないトラフィックすべての運命を決め、ドメイン行を百行足すより効きます。

一部の IP 行は no-resolve などの印を付け、この行の照合のためにドメインをアドレスへ解決しない、という意味です。解決方針は DNS ページの DNS 設定とも互いに影響します。ルールがホスト名だけ見てアドレスを見えないと、アドレス行はすべて外れます。アドレスだけ見てホスト名を見えないと、ドメイン行はすべて外れます。

06

三つの動作は「繋がりの度合い」ではない

直通であるべきシステムサービスを PROXY にすると、プッシュ、写真同期、ストア更新が遅くなったり失敗したりしがちです。それら向けではない出口に送られるからです。レコードへ入れるべきホストを DIRECT にすると、Data は Direct だけ増え、ページは「プロキシを開いていない」ように見えます。ホストを REJECT にすると、アプリがネットワークエラーを出し、ノードが壊れたと誤読されやすいです。

動作を変える前に、その行が本当に当たるかを確認してください。一度も到達しないルールを直しても、画面は何も変わりません。Data でカウンタがどちら側に立つかを見るほうが、スイッチのオンオフを繰り返すより効きます。

07

ルールが見る名前は、アドレスバーの文字列とは限らない

ドメイン条件は解決結果、HTTP の Host、または TLS の Server Name Indication に依ります。アプリが IP に直接繋ぐ、または SNI を付けないなら、ルールはアドレスしか見えず、ドメイン行はすべて外れ、最後は IP-CIDR、GEOIP、FINAL に落ちます。

それが「同じサイトが、あるときはプロキシ、あるときは直通」の一因です。ホスト名を持つ要求と、IP だけ残る要求があります。ブラウザのアドレスバーは www.example.com でも、下層は先に CDN のアドレスに繋ぐことがあります。GEOIP が見るのはその CDN のライブラリであり、その名前の印象ではありません。

システム DNS とアプリ内 DNS をそれぞれ設定し、互いに矛盾すると、ルールが見るホスト名と本当の宛先が食い違います。解決に異常がないとき、二箇所を同時に直さないでください。詳細は DNS です。

リライト は要求が見えたあとに起き、ルールの代わりにどの道を通るかを決められません。先に振り分け、それからリライトです。HTTPS 本文レベルのリライトには追加の復号許可が要ります。システム を見てください。

08

同じリストで三つの要求を歩き読む

現在のポリシーが Config、ファイルが下、今ハイライトされているのが使えるレコード 1 本だとします。

DOMAIN-SUFFIX,apple.com,DIRECT
DOMAIN-SUFFIX,icloud.com,DIRECT
DOMAIN-SUFFIX,github.com,PROXY
IP-CIDR,10.0.0.0/8,DIRECT
GEOIP,CN,DIRECT
FINAL,PROXY

www.apple.com

ホスト名が .apple.com で終わり、1 行目に当たり、DIRECT です。github も GEOIP も問いません。Data は Direct が増えるはずです。これは Apple のサーバがどこにあるかとは無関係で、この行に何が書いてあるかだけに関係します。

github.com

前の二行は外れ、三行目が当たり、PROXY です。GEOIP は後ろにあり、このアドレスがライブラリである国と印されていても、もう問われません。Data は Proxy が増えるはずです。ここで Proxy が動かずページが失敗するなら、github ルールをもう 1 行足す前にレコードを調べてください。

宛先 10.1.2.3 だけが分かり、ホスト名がない

すべてのドメイン行が外れ、IP-CIDR に当たり、DIRECT です。同じサービスが名前で来ることも、アドレスで来ることもあると、まったく違う二つの動作が見えます。エンジンが無作為なのではなく、二回の要求がエンジンに渡した情報が違います。

指名されておらず、宛先 IP がライブラリで CN と印されたホスト

ドメイン行はどれも外れ、網段も外れ、GEOIP,CN に当たり、DIRECT です。ライブラリがこのアドレスを別の国と印すと FINAL に落ち、PROXY です。解決を一度替える、CDN ノードを替えると、同じ名前はこの二行の間を跳ねます。

09

複数構成、外部リスト

アプリは複数の構成を保存でき、接続時に走るのは今選んでいる 1 つだけです。一つからもう一つへ切るのは、リスト全体の置換であり、「二つの FINAL が重なる」ではありません。他人のリストを取り込む前に、その FINAL と GEOIP を見つけてください。この二行が、指名されていない大半のトラフィックの運命を決めます。

レコードが、いま普通に届くサイトの多くと同じ側にあり、少数のホストだけ通したいのに FINAL を PROXY にすると、無関係な要求が大量にノードへ入ります。レコードが別の側にあり、指名されていないものも通したいのに FINAL を DIRECT にすると、大半のサイトはノードに入りません。外部リストの著者は自分の出口に合わせて書いており、あなたの出口に合わせて書いてはいません。

リストは期限切れになります。購読型ルールの更新と、サーバーコンテナの更新は、別オブジェクト上の同種の動作です。保存するのは URL、取得が成功してからローカルファイルを置き換え、失敗時は直前に成功したファイルを残し、失敗のためにルールを空にはしません。更新はそのときのネットワーク経路を通り、スイッチが失効したレコードに繋がっていると、ルール購読自体も更新失敗し得ます。オブジェクトConfig を見てください。

一度に直す条件は一つです。直したあと、固定した 1 レコードでポリシーだけ切り替えて対照します。Data です。レコードもファイルも FINAL も同時に替えると、画面上の変化は帰属できません。