Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 26 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
<a href="https://github.com/KuGouGo/Rules/actions/workflows/build.yml"><img alt="Sync Rules" src="https://github.com/KuGouGo/Rules/actions/workflows/build.yml/badge.svg?branch=main"></a>
<a href="https://github.com/KuGouGo/Rules/actions/workflows/pull-request.yml"><img alt="Pull Request Validation" src="https://github.com/KuGouGo/Rules/actions/workflows/pull-request.yml/badge.svg?branch=main"></a>
<img alt="Platforms" src="https://img.shields.io/badge/platforms-Surge%20%7C%20Quantumult%20X%20%7C%20Egern%20%7C%20sing--box%20%7C%20mihomo-2f6f6f">
<img alt="License" src="https://img.shields.io/badge/license-MIT-4b5563">
<img alt="Repository code license" src="https://img.shields.io/badge/repository%20code-MIT-4b5563">
</p>

面向 Surge、Quantumult X、Egern、sing-box mihomo 的规则构建仓库。`main` 保存稳定源码并触发发布,客户端产物位于对应平台分支
本仓库从配置的上游和本地维护源生成 Surge、Quantumult X、Egern、sing-box mihomo 规则。`main` 保存构建源码、配置和工作流;可直接使用的文件位于对应平台分支

> [!IMPORTANT]
> 客户端不要引用 `main`。第三方规则不因格式转换而自动适用 MIT,来源和许可边界见 [`NOTICE`](NOTICE) 与 [`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md)。
> 客户端不要引用 `main`。规则名称和区域分类沿用上游定义,不构成准确性、完整性或适用性保证。第三方内容不因格式转换而自动适用本仓库的 MIT 许可,详见 [`NOTICE`](NOTICE) 与 [`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md)。

## 使用规则
## 获取产物

稳定 URL 格式:
分支 URL 格式:

```text
https://raw.githubusercontent.com/KuGouGo/Rules/{branch}/{type}/{name}.{extension}
Expand All @@ -38,43 +38,42 @@ https://raw.githubusercontent.com/KuGouGo/Rules/sing-box/domain/cn.srs
https://raw.githubusercontent.com/KuGouGo/Rules/mihomo/ip/google.mrs
```

各平台的接入方式和最小配置示例位于对应产物分支的 `README.md`。分支 URL 始终指向最新产物;需要固定内容时,将分支名替换为具体提交 SHA。
各平台的接入方式和最小配置示例位于对应产物分支的 `README.md`。分支 URL 会随成功发布变化,不适合作为不可变版本标识;需要固定内容时,应将分支名替换为产物分支的提交 SHA。

## 常用规则
## 规则说明

| 名称 | 类型 | 用途 |
| 名称 | 类型 | 当前生成方式 |
| --- | --- | --- |
| `cn` | domain / ip | 中国大陆域名或合并后的中国大陆 CIDR |
| `geolocation-cn` | domain | 上游定义的中国大陆区域域名 |
| `geolocation-!cn` | domain | 上游定义的非中国大陆区域域名 |
| `google` / `telegram` | ip | 对应服务的 CIDR;Telegram 额外合并 ASN 前缀 |
| `emby-cn` | domain | Emby 中国大陆细分规则 |
| `emby` | domain | 通用 Emby 规则 |
| `fakeip-filter` | domain | 本仓库维护的 Fake-IP 排除规则 |
| `cn` | domain | v2fly/domain-list-community 的 `cn` 集合及其派生结果 |
| `cn` | ip | 配置的中国大陆 IP 上游经规范化、去重和 CIDR 合并后的结果 |
| `geolocation-cn` / `geolocation-!cn` | domain | 上游提供的区域集合名称与内容 |
| `google` / `telegram` | ip | 配置的服务地址源;Telegram 结果还合并配置的 ASN 前缀 |
| `emby-cn` / `emby` | domain | 本仓库维护的两个 Emby 规则集合 |
| `fakeip-filter` | domain | 本仓库维护的 Fake-IP 排除集合 |

`emby-cn` 必须放在 `emby` 前面。规则名称来自上游,不同名称即使内容相近也不视为别名;使用前请在目标分支确认文件存在
在按首条命中处理的客户端中,如果同时使用 `emby-cn` `emby`,应先加载范围较窄的 `emby-cn`。规则文件会随上游增加、删除或改变;使用前应在目标分支确认文件存在并检查内容

## 平台能力
## 转换行为

| 平台 | 精确域名 | 后缀 | 关键词 | 正则 | IP CIDR |
| 产物平台 | 精确域名 | 后缀 | 关键词 | 正则 | IP CIDR |
| --- | :---: | :---: | :---: | :---: | :---: |
| Surge | ✓ | ✓ | ✓ | — | ✓ |
| Quantumult X | ✓ | ✓ | ✓ | — | ✓ |
| Egern | ✓ | ✓ | ✓ | ✓ | ✓ |
| sing-box | ✓ | ✓ | ✓ | ✓ | ✓ |
| mihomo | ✓ | ✓ | — | — | ✓ |

`—` 表示当前转换链不保留该类型,不代表客户端本身不支持。列表只包含不受支持的规则类型时,对应平台不会发布空产物
`✓` 表示当前转换器会保留并输出该类型,`—` 表示当前转换链会省略该类型;该表不判断客户端自身的全部能力。一个列表在目标平台没有可保留条目时,不发布空文件

属性与区域名称沿用上游语义:

- `name@cn`、`name@!cn`、`name@ads` 是属性派生集合,`@!cn` 不是布尔取反。
- `*-cn`、`*-!cn` 是区域列表名称;明显冗余的属性派生不会发布。
- `official`、`registry`、`community` 仅表示采集来源分类,不代表质量或许可等级
- `official`、`registry`、`community` 是仓库配置中的来源分类,不代表质量、可信度或许可等级

## 本地维护

要求 Bash 5+、GNU Make、Git 和 Python 3。macOS 可使用 Homebrew Bash 完成验证与文本构建;sing-box mihomo 的完整二进制构建仅支持 lock 文件声明的 Linux 平台。
本地命令要求 Bash 5+、GNU Make、Git 和 Python 3。macOS 可使用 Homebrew Bash 运行检查和文本构建;需要下载 sing-box mihomo 的二进制构建只支持 lock 文件声明的 Linux 平台。

```bash
make check-runtime
Expand All @@ -84,21 +83,22 @@ make preflight
make clean
```

- `make validate`:运行 Shell、Python、配置、规则质量和测试检查
- `make validate`:运行 Shell、Python、配置、自定义规则和测试检查
- `make build-custom-text`:生成自定义文本产物,不下载二进制工具。
- `make preflight`:执行完整验证和文本构建,适合提交前检查
- `make clean`:删除生成产物和临时文件,保留可信工具缓存
- `make preflight`:执行 `make validate` 和自定义文本构建;不执行上游完整同步、二进制构建或发布
- `make clean`:删除生成产物和临时文件,保留已校验的工具缓存

完整环境、构建事务和调试命令见 [开发指南](docs/DEVELOPMENT.md)。

## 仓库边界

- 长期分支只保留 `main` 与 `surge`、`quanx`、`egern`、`sing-box`、`mihomo` 五个产物分支。
- 代码、文档和依赖更新通过临时分支向 `main` 提交 Pull Request;验证通过并合并后才构建和发布,临时分支自动删除。
- 变更通过临时分支向 `main` 提交 Pull Request;PR 运行静态检查和不发布的完整候选构建,临时分支在合并后删除。
- `main` 在构建相关路径变化、定时任务运行或人工触发时执行发布工作流;产物内容没有变化时不会创建新的产物分支提交。
- Dependabot 每月向 `main` 集中提交一个 GitHub Actions minor/patch 更新 PR;major 与安全告警单独人工评估。
- `fakeip-filter` 是本仓库维护的文本源,不下载第三方预编译文件。
- 构建摘要、manifest 和 CI 通过都不是第三方许可证明。
- 规则按现状提供,部署前应检查内容并保留回滚方案
- 规则按现状提供。使用者需自行判断策略、顺序和更新带来的影响,并保留可回退版本

## 文档

Expand Down
4 changes: 2 additions & 2 deletions scripts/tests/test-custom-build-atomic.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ assert_injected_failure_preserves_output() {

# Change a maintained source so staging contains output different from the
# restored controlled artifact. A late text failure must still publish nothing.
printf '\nDOMAIN-SUFFIX,atomic-stage.example\n' >> "$REPO/sources/custom/domain/emby.list"
printf '\nDOMAIN-SUFFIX,atomic-stage.example.com\n' >> "$REPO/sources/custom/domain/emby.list"
assert_injected_failure_preserves_output late-text RULES_BUILD_CUSTOM_TEXT_ONLY=1

# Avoid network/tool-lock behavior only inside this disposable test copy. The
Expand Down Expand Up @@ -100,7 +100,7 @@ assert_injected_failure_preserves_output late-binary
printf 'restored binary\n' > "$REPO/.output/domain/surge/unrelated.list"
RULES_CONFLICT_BASE_SHA="$BASE_SHA" RULES_BUILD_CUSTOM_TEXT_ONLY=1 \
"$REPO/scripts/commands/build-custom.sh" >/dev/null
grep -Fx 'DOMAIN-SUFFIX,atomic-stage.example' "$REPO/.output/domain/surge/emby.list" >/dev/null
grep -Fx 'DOMAIN-SUFFIX,atomic-stage.example.com' "$REPO/.output/domain/surge/emby.list" >/dev/null
grep -Fx 'restored upstream' "$REPO/.output/unrelated/upstream.txt" >/dev/null
grep -Fx 'restored binary' "$REPO/.output/domain/surge/unrelated.list" >/dev/null

Expand Down
15 changes: 15 additions & 0 deletions scripts/tests/test-custom-rule-quality.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,21 @@ IP-CIDR6,fc00::/7
EOF
assert_lint_passes "pass" "$TMP_DIR/pass/domain" "$TMP_DIR/pass/ip"

make_case_dirs "$TMP_DIR/fakeip-single-label"
printf '%s\n' 'DOMAIN-SUFFIX,lan' > "$TMP_DIR/fakeip-single-label/domain/fakeip-filter.list"
assert_lint_passes \
"fakeip-single-label" \
"$TMP_DIR/fakeip-single-label/domain" \
"$TMP_DIR/fakeip-single-label/ip"

make_case_dirs "$TMP_DIR/non-fakeip-single-label"
printf '%s\n' 'DOMAIN-SUFFIX,lan' > "$TMP_DIR/non-fakeip-single-label/domain/example.list"
assert_lint_fails_with \
"non-fakeip-single-label" \
"DOMAIN-SUFFIX value is too broad" \
"$TMP_DIR/non-fakeip-single-label/domain" \
"$TMP_DIR/non-fakeip-single-label/ip"

make_case_dirs "$TMP_DIR/domain-coverage"
cat > "$TMP_DIR/domain-coverage/domain/example.list" <<'EOF'
DOMAIN-SUFFIX,example.com
Expand Down
21 changes: 15 additions & 6 deletions scripts/tests/test-fakeip-migration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,21 @@ git -C "$RENDER_REPO" commit -m add-fakeip >/dev/null
RULES_BUILD_CUSTOM_TEXT_ONLY=1 "$RENDER_REPO/scripts/commands/build-custom.sh" >/dev/null
RULES_BUILD_CUSTOM_TEXT_ONLY=1 "$RENDER_REPO/scripts/commands/build-custom.sh" >/dev/null

grep -Fx 'DOMAIN-SUFFIX,in-addr.arpa' "$RENDER_REPO/.output/domain/surge/fakeip-filter.list" >/dev/null
grep -Fx 'DOMAIN,localhost.localdomain' "$RENDER_REPO/.output/domain/surge/fakeip-filter.list" >/dev/null
grep -Fx 'HOST-SUFFIX,in-addr.arpa,fakeip-filter' "$RENDER_REPO/.output/domain/quanx/fakeip-filter.list" >/dev/null
grep -Fx 'HOST,localhost.localdomain,fakeip-filter' "$RENDER_REPO/.output/domain/quanx/fakeip-filter.list" >/dev/null
grep -Fx " - 'in-addr.arpa'" "$RENDER_REPO/.output/domain/egern/fakeip-filter.yaml" >/dev/null
grep -Fx " - 'localhost.localdomain'" "$RENDER_REPO/.output/domain/egern/fakeip-filter.yaml" >/dev/null
if grep -Fx '*' "$ROOT/sources/custom/domain/fakeip-filter.list" >/dev/null; then
echo "test failed: universal Fake-IP bypass must not be published" >&2
exit 1
fi
grep -Fx 'DOMAIN-SUFFIX,lan' "$RENDER_REPO/.output/domain/surge/fakeip-filter.list" >/dev/null
grep -Fx 'DOMAIN,proxy.golang.org' "$RENDER_REPO/.output/domain/surge/fakeip-filter.list" >/dev/null
if grep -F 'DOMAIN-REGEX,' "$RENDER_REPO/.output/domain/surge/fakeip-filter.list" >/dev/null; then
echo "test failed: Surge output retained unsupported regex rules" >&2
exit 1
fi
grep -Fx 'HOST-SUFFIX,lan,fakeip-filter' "$RENDER_REPO/.output/domain/quanx/fakeip-filter.list" >/dev/null
grep -Fx 'HOST,proxy.golang.org,fakeip-filter' "$RENDER_REPO/.output/domain/quanx/fakeip-filter.list" >/dev/null
grep -Fx " - 'lan'" "$RENDER_REPO/.output/domain/egern/fakeip-filter.yaml" >/dev/null
grep -Fx " - 'proxy.golang.org'" "$RENDER_REPO/.output/domain/egern/fakeip-filter.yaml" >/dev/null
grep -Fx " - '^time\\.[^.]+\\.com$'" "$RENDER_REPO/.output/domain/egern/fakeip-filter.yaml" >/dev/null

prepare_collision_repo() {
local repo="$1"
Expand Down
6 changes: 5 additions & 1 deletion scripts/tools/lint-custom-rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,11 @@ def load_domain_rules(directory: Path, reporter: Reporter) -> list[LocatedRule]:
result: list[LocatedRule] = []
for path in iter_rule_files(directory):
validate_rule_file_name(path, reporter)
rules, errors = parse_classical_domain_file(path, require_canonical=True)
rules, errors = parse_classical_domain_file(
path,
require_canonical=True,
allow_single_label_suffix=path.name == "fakeip-filter.list",
)
reporter.errors.extend(errors)
if not rules:
reporter.error(f"{path}:0 has no effective rules")
Expand Down
131 changes: 119 additions & 12 deletions sources/custom/domain/fakeip-filter.list
Original file line number Diff line number Diff line change
@@ -1,13 +1,120 @@
# KuGouGo-maintained conservative Fake-IP exclusions.
#
# Reverse DNS namespaces must retain address semantics instead of receiving a
# synthetic address. See RFC 3172 and RFC 3596.
DOMAIN-SUFFIX,in-addr.arpa
DOMAIN-SUFFIX,ip6.arpa

# Special-use names used for local resolution and protocol discovery.
# See RFC 6761, RFC 7050, RFC 8375, and RFC 9462.
DOMAIN,localhost.localdomain
DOMAIN-SUFFIX,ipv4only.arpa
# KuGouGo-maintained Fake-IP exclusions.
# A universal wildcard is intentionally omitted because it disables Fake-IP
# for every domain and makes the remaining entries ineffective.

# LAN and special-use names
DOMAIN-SUFFIX,lan
DOMAIN-SUFFIX,localdomain
DOMAIN-SUFFIX,example
DOMAIN-SUFFIX,invalid
DOMAIN-SUFFIX,localhost
DOMAIN-SUFFIX,test
DOMAIN-SUFFIX,local
DOMAIN-SUFFIX,home.arpa
DOMAIN-SUFFIX,resolver.arpa
DOMAIN-SUFFIX,direct

# NTP services
DOMAIN-REGEX,^time\.[^.]+\.com$
DOMAIN-REGEX,^time\.[^.]+\.gov$
DOMAIN-REGEX,^time\.[^.]+\.edu\.cn$
DOMAIN-REGEX,^time\.[^.]+\.apple\.com$
DOMAIN,time-ios.apple.com
DOMAIN-REGEX,^time[1-7]\.[^.]+\.com$
DOMAIN-REGEX,^ntp\.[^.]+\.com$
DOMAIN-REGEX,^ntp[1-7]\.[^.]+\.com$
DOMAIN-SUFFIX,time.edu.cn
DOMAIN-SUFFIX,ntp.org.cn
DOMAIN-SUFFIX,pool.ntp.org
DOMAIN,time1.cloud.tencent.com

# Music services
DOMAIN-SUFFIX,music.163.com
DOMAIN-SUFFIX,126.net
DOMAIN,musicapi.taihe.com
DOMAIN,music.taihe.com
DOMAIN,songsearch.kugou.com
DOMAIN,trackercdn.kugou.com
DOMAIN-SUFFIX,kuwo.cn
DOMAIN,api-jooxtt.sanook.com
DOMAIN,api.joox.com
DOMAIN,joox.com
DOMAIN-SUFFIX,y.qq.com
DOMAIN,streamoc.music.tc.qq.com
DOMAIN,mobileoc.music.tc.qq.com
DOMAIN,isure.stream.qqmusic.qq.com
DOMAIN,dl.stream.qqmusic.qq.com
DOMAIN,aqqmusic.tc.qq.com
DOMAIN,amobile.music.tc.qq.com
DOMAIN-SUFFIX,xiami.com
DOMAIN-SUFFIX,music.migu.cn

# Connectivity checks and local login endpoints
DOMAIN-SUFFIX,msftconnecttest.com
DOMAIN-SUFFIX,msftncsi.com
DOMAIN,localhost.ptlogin2.qq.com
DOMAIN,localhost.sec.qq.com
DOMAIN-REGEX,^localhost\.[^.]+\.weixin\.qq\.com$
DOMAIN-SUFFIX,kk-rays.com

# Games
DOMAIN-SUFFIX,steamcontent.com
DOMAIN-SUFFIX,srv.nintendo.net
DOMAIN-SUFFIX,cdn.nintendo.net
DOMAIN-REGEX,^xbox\.[^.]+\.[^.]+\.microsoft\.com$
DOMAIN-REGEX,^(?:[^.]+\.){2}xboxlive\.com$
DOMAIN-REGEX,^xbox\.[^.]+\.microsoft\.com$
DOMAIN,xnotify.xboxlive.com
DOMAIN-SUFFIX,battle.net
DOMAIN-SUFFIX,battlenet.com.cn
DOMAIN-SUFFIX,wotgame.cn
DOMAIN-SUFFIX,wggames.cn
DOMAIN-SUFFIX,wowsgame.cn
DOMAIN-SUFFIX,wargaming.net

# Development and STUN
DOMAIN,proxy.golang.org
DOMAIN-REGEX,^(?:.+\.)?stun(?:\.[^.]+){2,5}$

# Routers
DOMAIN,heartbeat.belkin.com
DOMAIN-SUFFIX,linksys.com
DOMAIN-SUFFIX,linksyssmartwifi.com
DOMAIN-SUFFIX,router.asus.com

# Apple software updates
DOMAIN,mesu.apple.com
DOMAIN,swscan.apple.com
DOMAIN,swquery.apple.com
DOMAIN,swdownload.apple.com
DOMAIN,swcdn.apple.com
DOMAIN,swdist.apple.com

# Services and applications
DOMAIN,lens.l.google.com
DOMAIN,na.b.g-tun.com
DOMAIN-SUFFIX,square-enix.com
DOMAIN-SUFFIX,finalfantasyxiv.com
DOMAIN-SUFFIX,ffxiv.com
DOMAIN-SUFFIX,ff14.sdo.com
DOMAIN,ff.dorado.sdo.com
DOMAIN-SUFFIX,mcdn.bilivideo.cn
DOMAIN-SUFFIX,media.dssott.com
DOMAIN,shark007.net
DOMAIN-SUFFIX,market.xiaomi.com
DOMAIN-SUFFIX,cmbchina.com
DOMAIN-SUFFIX,cmbimg.com
DOMAIN,adguardteam.github.io
DOMAIN,adrules.top
DOMAIN,anti-ad.net
DOMAIN,local.adguard.org
DOMAIN,static.adtidy.org
DOMAIN-SUFFIX,sandai.net
DOMAIN-SUFFIX,n0808.com
DOMAIN-SUFFIX,3gppnetwork.org
DOMAIN-SUFFIX,uu.163.com
DOMAIN,ps.res.netease.com
DOMAIN-SUFFIX,oray.com
DOMAIN-SUFFIX,orayimg.com
DOMAIN-SUFFIX,gcloudcs.com
DOMAIN-SUFFIX,gcloudsdk.com
DOMAIN-SUFFIX,dynv6.net