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

20 lines
5.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Bundled Rule Snapshots
[Project home](../ShadowsocksX-NG2/README.md) | [简体中文](rule-snapshots.zh.md)
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](https://github.com/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](https://github.com/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](https://github.com/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](adr/0024-snapshot-drops-absorbed-and-forensics.md). 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](adr/0039-rule-values-and-independent-storage-models.md) and [ADR-0055](adr/0055-preset-owned-custom-rule-actions.md).
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.