From 93eac0e766afdcea4c89e5bd8cb7b28b1a9029d6 Mon Sep 17 00:00:00 2001 From: ZLX Date: Thu, 10 Sep 2026 13:11:11 +0800 Subject: [PATCH] =?UTF-8?q?feat(clash):=20=E6=96=B0=E5=A2=9E=20?= =?UTF-8?q?=F0=9F=90=99=20Github=20=E5=88=86=E7=BB=84=EF=BC=8CGitHub=20?= =?UTF-8?q?=E6=B5=81=E9=87=8F=E7=8B=AC=E7=AB=8B=E5=88=86=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原先 GitHub 流量被切成三份:api.github.com 和 Copilot 系域名被 ai.list 带进 OpenAI&Anthropic,其余靠 ProxyGFWlist 的 DOMAIN-KEYWORD,github 落到 🌍 海外访问,kgithub.com 走 ChinaOnly 直连。现在把后两类收拢成独立分组。 - 新增 Rules/GitHub.list:30 条 DOMAIN-SUFFIX + 69 条 IP-CIDR + 2 条 IP-CIDR6 - 新增 generate_github_rules.py:从 api.github.com/meta 生成 IP 段, 用标记块只重写 IP 部分,手工补充的域名不会被覆盖 几个取舍: - ruleset 排在 ai.list 之后,Copilot 与 api.github.com 继续跟 Cursor/OpenAI 同出口,AI 体验不受影响 - 移除 DOMAIN-KEYWORD,github,否则会抢走 ChinaOnly.list 里的 kgithub.com - IP 段只取 git/web/api/packages/pages,排除 actions(6980 条)/codespaces, 那是 Azure 大段,会把非 GitHub 流量误判进代理组 - IP 规则全部带 no-resolve,用途仅是兜住 SSH 推拉(redir-host 下 sniffer 嗅探不到 SSH 域名);全为纯 IP-CIDR,不含 IP-ASN,避免 OpenClash 启动死锁 - 节点候选不放家宽:clone/release 属带宽消耗型,与 AI 组的防风控诉求相反 via [HAPI](https://hapi.run) Co-Authored-By: HAPI Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01GNghjXGrjt64G32W7t6Bhu --- ACL4SSR_Online_Full_Mannix.ini | 7 ++ Rules/GitHub.list | 116 ++++++++++++++++++++++++++ generate_github_rules.py | 146 +++++++++++++++++++++++++++++++++ 3 files changed, 269 insertions(+) create mode 100644 Rules/GitHub.list create mode 100644 generate_github_rules.py diff --git a/ACL4SSR_Online_Full_Mannix.ini b/ACL4SSR_Online_Full_Mannix.ini index 02b31ac..9f34b25 100644 --- a/ACL4SSR_Online_Full_Mannix.ini +++ b/ACL4SSR_Online_Full_Mannix.ini @@ -55,6 +55,8 @@ ;💃 Tiktok(简化为 指定/沙特/DIRECT) ;👥 Facebook ;🦖 Google服务(合并 YouTube/FCM/Google) +;🐙 Github(日本/新加坡/美国 自动 + 指定 + 海外访问 + DIRECT,不含家宽:clone/release 属带宽消耗型,家宽按量贵) +; 规则顺序在 ai.list 之后,故 api.github.com 与 Copilot 系域名仍归 AI 分组 ;url-test ;延迟测试链接 http://www.gstatic.com/generate_204 -> https://i.ytimg.com/generate_204 @@ -290,6 +292,7 @@ custom_proxy_group=全部-手动`select`[🇦-🇿]{2}|^(?!.*(Data Left|Traffic| custom_proxy_group=💩 ‍广告`select`[]DIRECT`[]REJECT`[]🌍 ‍海外访问 custom_proxy_group=OpenAI&Anthropic`select`[]全部-手动`[]🇸🇬 ‍新加坡-手动`[]🇺🇸 ‍美国-手动`[]🇸🇬 ‍新加坡-自动`[]🇸🇬 ‍新加坡家宽-自动`[]🇺🇸 ‍美国家宽-自动`[]🇺🇸 ‍美国-自动`[]DIRECT custom_proxy_group=Gemini&Cursor&Grok`select`[]全部-手动`[]🇸🇬 ‍新加坡-手动`[]🇺🇸 ‍美国-手动`[]🇸🇬 ‍新加坡-自动`[]🇸🇬 ‍新加坡家宽-自动`[]🇺🇸 ‍美国家宽-自动`[]🇺🇸 ‍美国-自动`[]DIRECT +custom_proxy_group=🐙 Github`select`[]全部-手动`[]🇯🇵 ‍日本-自动`[]🇸🇬 ‍新加坡-自动`[]🇺🇸 ‍美国-自动`[]🎏 ‍其他-自动`[]🌍 ‍海外访问`[]DIRECT custom_proxy_group=🌐 ‍未知站点`select`[]🌍 ‍海外访问`[]🏠 ‍国内直连 ; custom_proxy_group=⚡ ‍低延迟`url-test`[🇦-🇿]{2}|^(?!.*(Data Left|Traffic|Expir[ey]|剩[余餘]流量|[到过過效]期|[时時][间間]|重置|官.?网|官方|产品|平台|勿连|修复|恢复|更新|地址|网站|网址|售后|客服|联系|使用|购买|公告|版本|出现|没网|情况|开通|数量|分割线|推荐|注[::]))`https://i.ytimg.com/generate_204`30,,50 @@ -333,6 +336,10 @@ ruleset=Gemini&Cursor&Grok,https://gitea.178494.xyz/zhanglixing/ACL4SSR/raw/bran ruleset=Gemini&Cursor&Grok,https://gitea.178494.xyz/zhanglixing/ACL4SSR/raw/branch/main/Rules/Grok.list ruleset=OpenAI&Anthropic,https://raw.githubusercontent.com/QuixoticHeart/rule-set/refs/heads/ruleset/surge/ai.list +; 必须排在 ai.list 之后:api.github.com 与 copilot 系域名由 ai.list 先命中,归 AI 分组 +; 本 list 已移除 DOMAIN-KEYWORD,github,故不会抢走后面 ChinaOnly.list 里的 kgithub.com +ruleset=🐙 Github,https://gitea.178494.xyz/zhanglixing/ACL4SSR/raw/branch/main/Rules/GitHub.list + ruleset=💰 ‍券商,https://raw.githubusercontent.com/Arthur-vx/broker-rules/main/Broker.list ruleset=💃 Tiktok,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/Ruleset/TikTok.list diff --git a/Rules/GitHub.list b/Rules/GitHub.list new file mode 100644 index 0000000..45bbcec --- /dev/null +++ b/Rules/GitHub.list @@ -0,0 +1,116 @@ +# GitHub 全站规则 +# 域名部分基于 https://github.com/blackmatrix7/ios_rule_script rule/Clash/GitHub/GitHub.list +# 本地改动: +# - 移除 DOMAIN-KEYWORD,github —— 会抢走 ChinaOnly.list 里的 kgithub.com 等国内镜像 +# - githubcopilot.com / githubnext.com 保留作兜底, 实际由更靠前的 ai.list 命中并归入 AI 分组 +# IP 部分由 generate_github_rules.py 从 https://api.github.com/meta 生成, 见文件末尾标记块 + +DOMAIN-SUFFIX,atom.io +DOMAIN-SUFFIX,dependabot.com +DOMAIN-SUFFIX,ghcr.io +DOMAIN-SUFFIX,git.io +DOMAIN-SUFFIX,github-atom-io-herokuapp-com.freetls.fastly.net +DOMAIN-SUFFIX,github-avatars.oss-cn-hongkong.aliyuncs.com +DOMAIN-SUFFIX,github-cloud.s3.amazonaws.com +DOMAIN-SUFFIX,github.blog +DOMAIN-SUFFIX,github.com +DOMAIN-SUFFIX,github.community +DOMAIN-SUFFIX,github.dev +DOMAIN-SUFFIX,github.io +DOMAIN-SUFFIX,githubapp.com +DOMAIN-SUFFIX,githubassets.com +DOMAIN-SUFFIX,githubcopilot.com +DOMAIN-SUFFIX,githubhackathon.com +DOMAIN-SUFFIX,githubnext.com +DOMAIN-SUFFIX,githubpreview.dev +DOMAIN-SUFFIX,githubstatus.com +DOMAIN-SUFFIX,githubuniverse.com +DOMAIN-SUFFIX,githubusercontent.com +DOMAIN-SUFFIX,myoctocat.com +DOMAIN-SUFFIX,npm.community +DOMAIN-SUFFIX,npmjs.com +DOMAIN-SUFFIX,npmjs.org +DOMAIN-SUFFIX,opensource.guide +DOMAIN-SUFFIX,rawgit.com +DOMAIN-SUFFIX,rawgithub.com +DOMAIN-SUFFIX,repo.new +DOMAIN-SUFFIX,thegithubshop.com + +# === BEGIN AUTO-GENERATED IP RULES (generate_github_rules.py) === +# 来源: https://api.github.com/meta 的 git / web / api / packages / pages 字段 +# 请勿手工编辑本块, 运行 python3 generate_github_rules.py 重新生成 + +IP-CIDR,4.208.26.196/31,no-resolve +IP-CIDR,4.208.26.198/32,no-resolve +IP-CIDR,4.208.26.200/32,no-resolve +IP-CIDR,4.225.11.194/32,no-resolve +IP-CIDR,4.225.11.196/32,no-resolve +IP-CIDR,4.225.11.200/31,no-resolve +IP-CIDR,4.228.31.145/32,no-resolve +IP-CIDR,4.228.31.149/32,no-resolve +IP-CIDR,4.228.31.150/32,no-resolve +IP-CIDR,4.228.31.152/32,no-resolve +IP-CIDR,4.237.22.32/32,no-resolve +IP-CIDR,4.237.22.34/32,no-resolve +IP-CIDR,4.237.22.38/32,no-resolve +IP-CIDR,4.237.22.40/32,no-resolve +IP-CIDR,4.249.131.163/32,no-resolve +IP-CIDR,4.249.131.164/32,no-resolve +IP-CIDR,4.249.131.166/31,no-resolve +IP-CIDR,20.26.156.210/31,no-resolve +IP-CIDR,20.26.156.214/31,no-resolve +IP-CIDR,20.27.177.113/32,no-resolve +IP-CIDR,20.27.177.116/31,no-resolve +IP-CIDR,20.27.177.118/32,no-resolve +IP-CIDR,20.29.134.17/32,no-resolve +IP-CIDR,20.29.134.18/31,no-resolve +IP-CIDR,20.29.134.23/32,no-resolve +IP-CIDR,20.87.245.0/31,no-resolve +IP-CIDR,20.87.245.4/32,no-resolve +IP-CIDR,20.87.245.6/32,no-resolve +IP-CIDR,20.175.192.146/31,no-resolve +IP-CIDR,20.175.192.149/32,no-resolve +IP-CIDR,20.175.192.150/32,no-resolve +IP-CIDR,20.199.39.227/32,no-resolve +IP-CIDR,20.199.39.228/32,no-resolve +IP-CIDR,20.199.39.231/32,no-resolve +IP-CIDR,20.199.39.232/32,no-resolve +IP-CIDR,20.200.245.241/32,no-resolve +IP-CIDR,20.200.245.245/32,no-resolve +IP-CIDR,20.200.245.247/32,no-resolve +IP-CIDR,20.200.245.248/32,no-resolve +IP-CIDR,20.201.28.144/32,no-resolve +IP-CIDR,20.201.28.148/32,no-resolve +IP-CIDR,20.201.28.151/32,no-resolve +IP-CIDR,20.201.28.152/32,no-resolve +IP-CIDR,20.205.243.160/32,no-resolve +IP-CIDR,20.205.243.164/32,no-resolve +IP-CIDR,20.205.243.166/32,no-resolve +IP-CIDR,20.205.243.168/32,no-resolve +IP-CIDR,20.207.73.82/31,no-resolve +IP-CIDR,20.207.73.85/32,no-resolve +IP-CIDR,20.207.73.86/32,no-resolve +IP-CIDR,20.217.135.0/31,no-resolve +IP-CIDR,20.217.135.4/31,no-resolve +IP-CIDR,20.233.83.145/32,no-resolve +IP-CIDR,20.233.83.146/31,no-resolve +IP-CIDR,20.233.83.149/32,no-resolve +IP-CIDR,48.202.248.34/32,no-resolve +IP-CIDR,48.202.248.38/31,no-resolve +IP-CIDR,48.202.248.40/32,no-resolve +IP-CIDR,48.204.201.2/32,no-resolve +IP-CIDR,48.204.201.5/32,no-resolve +IP-CIDR,48.204.201.6/32,no-resolve +IP-CIDR,48.204.201.9/32,no-resolve +IP-CIDR,140.82.112.0/20,no-resolve +IP-CIDR,143.55.64.0/20,no-resolve +IP-CIDR,172.182.252.133/32,no-resolve +IP-CIDR,172.182.252.135/32,no-resolve +IP-CIDR,172.182.252.136/31,no-resolve +IP-CIDR,185.199.108.0/22,no-resolve +IP-CIDR,192.30.252.0/22,no-resolve + +IP-CIDR6,2606:50c0::/32,no-resolve +IP-CIDR6,2a0a:a440::/29,no-resolve + +# === END AUTO-GENERATED IP RULES === diff --git a/generate_github_rules.py b/generate_github_rules.py new file mode 100644 index 0000000..01be6be --- /dev/null +++ b/generate_github_rules.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python3 +""" +从 GitHub 官方 meta API (https://api.github.com/meta) 拉取 IP 段, +生成/更新 Rules/GitHub.list 中的 IP-CIDR 规则块。 + +域名规则由人工维护在标记块之外, 本脚本只重写标记块内的 IP 规则, +不会覆盖手工补充的域名条目。 +""" + +import ipaddress +import json +import urllib.request +from pathlib import Path + +META_URL = "https://api.github.com/meta" +OUTPUT_FILE = Path("Rules/GitHub.list") + +BEGIN_MARK = "# === BEGIN AUTO-GENERATED IP RULES (generate_github_rules.py) ===" +END_MARK = "# === END AUTO-GENERATED IP RULES ===" + +# 只取这几个服务的网段。 +# 刻意排除: +# actions / actions_macos / codespaces —— 是 Azure 大段(actions 近 7000 条), +# 会把大量非 GitHub 流量误判进代理组 +# copilot —— Copilot 归 AI 分组, 见 ACL4SSR_Online_Full_Mannix.ini 规则顺序 +# hooks / importer / github_enterprise_importer —— 入站或企业迁移用, 客户端不需要 +INCLUDED_KEYS = ["git", "web", "api", "packages", "pages"] + +# 域名骨架, 仅在 Rules/GitHub.list 不存在时写入 +DEFAULT_DOMAIN_SECTION = """\ +# GitHub 全站规则 +# 域名部分基于 https://github.com/blackmatrix7/ios_rule_script rule/Clash/GitHub/GitHub.list +# 本地改动: +# - 移除 DOMAIN-KEYWORD,github —— 会抢走 ChinaOnly.list 里的 kgithub.com 等国内镜像 +# - githubcopilot.com / githubnext.com 保留作兜底, 实际由更靠前的 ai.list 命中并归入 AI 分组 +# IP 部分由 generate_github_rules.py 从 https://api.github.com/meta 生成, 见文件末尾标记块 + +DOMAIN-SUFFIX,atom.io +DOMAIN-SUFFIX,dependabot.com +DOMAIN-SUFFIX,ghcr.io +DOMAIN-SUFFIX,git.io +DOMAIN-SUFFIX,github-atom-io-herokuapp-com.freetls.fastly.net +DOMAIN-SUFFIX,github-avatars.oss-cn-hongkong.aliyuncs.com +DOMAIN-SUFFIX,github-cloud.s3.amazonaws.com +DOMAIN-SUFFIX,github.blog +DOMAIN-SUFFIX,github.com +DOMAIN-SUFFIX,github.community +DOMAIN-SUFFIX,github.dev +DOMAIN-SUFFIX,github.io +DOMAIN-SUFFIX,githubapp.com +DOMAIN-SUFFIX,githubassets.com +DOMAIN-SUFFIX,githubcopilot.com +DOMAIN-SUFFIX,githubhackathon.com +DOMAIN-SUFFIX,githubnext.com +DOMAIN-SUFFIX,githubpreview.dev +DOMAIN-SUFFIX,githubstatus.com +DOMAIN-SUFFIX,githubuniverse.com +DOMAIN-SUFFIX,githubusercontent.com +DOMAIN-SUFFIX,myoctocat.com +DOMAIN-SUFFIX,npm.community +DOMAIN-SUFFIX,npmjs.com +DOMAIN-SUFFIX,npmjs.org +DOMAIN-SUFFIX,opensource.guide +DOMAIN-SUFFIX,rawgit.com +DOMAIN-SUFFIX,rawgithub.com +DOMAIN-SUFFIX,repo.new +DOMAIN-SUFFIX,thegithubshop.com + +""" + + +def fetch_meta(): + """拉取 GitHub meta API""" + req = urllib.request.Request(META_URL, headers={"User-Agent": "curl/8"}) + with urllib.request.urlopen(req, timeout=30) as resp: + return json.load(resp) + + +def extract_networks(meta): + """按 INCLUDED_KEYS 取网段并去重, IPv4 / IPv6 分开返回""" + v4, v6 = set(), set() + + for key in INCLUDED_KEYS: + for cidr in meta.get(key, []): + try: + net = ipaddress.ip_network(cidr, strict=False) + except ValueError: + print(f"跳过无法解析的网段: {key} -> {cidr}") + continue + (v4 if net.version == 4 else v6).add(net) + + # collapse_addresses 会合并相邻/包含关系的网段, git/web/api 高度重叠 + return ( + sorted(ipaddress.collapse_addresses(v4)), + sorted(ipaddress.collapse_addresses(v6)), + ) + + +def build_ip_block(v4, v6): + """生成标记块内容。no-resolve 必须保留: 没有它, 每条 IP 规则都会触发一次 + DNS 解析, 拖慢整条规则链, 且这些规则的用途只是兜住已经是 IP 的连接 + (git@github.com 的 SSH 推拉在 redir-host 模式下嗅探不到域名)。""" + lines = [ + BEGIN_MARK, + f"# 来源: {META_URL} 的 {' / '.join(INCLUDED_KEYS)} 字段", + "# 请勿手工编辑本块, 运行 python3 generate_github_rules.py 重新生成", + "", + ] + lines += [f"IP-CIDR,{net},no-resolve" for net in v4] + if v6: + lines.append("") + lines += [f"IP-CIDR6,{net},no-resolve" for net in v6] + lines += ["", END_MARK] + return "\n".join(lines) + "\n" + + +def write_rules(ip_block, output_file): + """保留域名部分, 只替换标记块""" + if output_file.exists(): + text = output_file.read_text(encoding="utf-8") + else: + text = DEFAULT_DOMAIN_SECTION + + if BEGIN_MARK in text and END_MARK in text: + head = text.split(BEGIN_MARK)[0] + tail = text.split(END_MARK, 1)[1] + text = head + ip_block + tail.lstrip("\n") + else: + text = text.rstrip("\n") + "\n\n" + ip_block + + output_file.parent.mkdir(exist_ok=True) + output_file.write_text(text, encoding="utf-8") + + +def main(): + meta = fetch_meta() + v4, v6 = extract_networks(meta) + + print(f"合并后 IPv4 网段 {len(v4)} 条, IPv6 网段 {len(v6)} 条") + + write_rules(build_ip_block(v4, v6), OUTPUT_FILE) + print(f"已更新 {OUTPUT_FILE}") + + +if __name__ == "__main__": + main()