Files
ShadowsocksX-NG/docs/rule-snapshots.md

5.7 KiB
Raw Permalink Blame History

Bundled Rule Snapshots

Project home | 简体中文

Bundled snapshots used by rule mode are explicitly maintained artifacts:

  • geolocation-cn (issue #63): after manually reviewing the upstream source, run Scripts/update-geolocation-cn.sh. It parses typed entries from the pinned geosite.dat release of Loyalsoldier/domain-list-custom and generates Vendor/rules/geolocation-cn/snapshot.json.
  • china-ipv4 (issue #64): run Scripts/update-china-ipv4.sh to normalize and deduplicate IPv4 CIDRs from the pinned china.txt version of gaoyifan/china-operator-ip, generating Vendor/rules/china-ipv4/snapshot.json.
  • gfwlist (issue #65): run Scripts/update-gfwlist.sh to decode the official Base64 AutoProxy list from a pinned gfwlist.txt version of gfwlist/gfwlist, generating Vendor/rules/gfwlist/snapshot.json. ||host and ||host^ are converted to domain-suffix matches. A |scheme://host rule (optionally with a valid port) is converted to an exact-domain match when its path is empty or /, it has no query, fragment, or user information, and its host is a valid domain without wildcards; the scheme and port are ignored. Only a root path is eligible; rules with a specific path are skipped. @@ retains the direct-routing action. Other URL prefixes, paths, wildcards, regular expressions, single-label prefixes, and IP-literal rules are counted by category in the loss report. A @@ exception completely covered by proxy rules is not written as an ineffective ACL entry (sslocal domain matching gives proxy_list priority over bypass_list). The proxy rule is retained, and the number of shadowed exceptions is included only in absorbedCount. The maintenance script prints per-rule evidence to stdout.

Snapshots use compact JSON with schema 2 / converter 2.0.0: each rule has only action and match; the source appears only in metadata.source; the conversion report retains counts only. Absorbed .cn entries and shadowed GFWList exceptions are not distributed in the snapshot and are not restored after a broad rule is disabled. See ADR-0024. Older snapshot versions are rejected.

Domain values and file DTOs for rules evolve independently. ProxyRule represents both a normalized rule value and rule identity across sources; custom entries also retain a UUID. Custom-rule files use schema 4 and do not store source per rule. Each rule scheme fixes the matched and unmatched actions; custom-rule creation and editing show the matched action as read-only. Schema 1–3 documents remain readable: loading a scheme removes custom rules whose action equals its unmatched action, retaining the remaining UUIDs, order, and all disablement records. Reading leaves the original file intact; the next normal save writes schema 4. Schema 4 documents with reverse-action custom rules are rejected. Older clients cannot read schema 4. Migration can change routing: an old custom direct IP exception in the China-proxy scheme may previously have overridden a built-in proxy range; after removal, that IP follows the scheme's proxy rule. Fixed local targets still bypass the proxy. The bundled snapshot format is unchanged. See ADR-0039 and ADR-0055.

Python is the only upstream conversion implementation. Swift loads, validates, and consumes snapshots; it does not parse upstream input independently. Run the offline regression checks for conversion scripts with PYTHONDONTWRITEBYTECODE=1 python3 Scripts/test-rule-snapshot-converters.py. The default task test also runs both Python checks; run task test:rules for just these checks. Also run PYTHONDONTWRITEBYTECODE=1 python3 Scripts/test-rule-conversion-behavior.py to verify conversion behavior and the fixed snapshot fixtures used by the unit-test bundle. After reviewing a conversion change, add --write-fixtures to the same command to rebuild the fixtures. Fixture timestamps are fixed, and normal tests compare generated output byte for byte. Check snapshot integrity with Scripts/verify-rule-snapshots.sh.

If an update fails, the previous valid snapshot is kept. geolocation-cn conversion fails on unknown syntax or corrupted input. china-ipv4 conversion also fails on abnormal formats (when too many lines are rejected), when all entries are invalid, or when the snapshot size changes abnormally compared with the previous version. gfwlist conversion fails on unknown syntax, corrupted Base64, abnormal size, or an abnormal size change compared with the previous version. Normal builds run Scripts/verify-rule-snapshots.sh offline to check that snapshots exist, their digests match, and schema/converter versions agree; missing or corrupted snapshots fail the build. Distributed artifacts must include each source's NOTICE (license and attribution).

In rule mode, “proxy when unmatched” generates a proxy_all ACL containing both Chinese-domain and Chinese IPv4-CIDR direct-routing candidates, with fixed local bypass taking priority. “Direct when unmatched” generates a bypass_all ACL containing only effective GFWList proxy candidates. The two default actions do not unconditionally union all bundled sources. Unmatched destinations and IP literals that match no available rule go direct. CIDR checks may trigger local DNS queries: when matching an unmatched domain by IP, sslocal may perform a local DNS query. The product does not promise that all DNS queries travel through the remote Shadowsocks server.