New Domestic CDN Hosts Output Support

This commit is contained in:
SukkaW
2026-09-23 02:37:40 +08:00
parent 1baae2ff74
commit 8b5e39525b
7 changed files with 122 additions and 32 deletions

View File

@@ -1,6 +1,7 @@
// @ts-check
import path from 'node:path';
import { DOMESTICS, DOH_BOOTSTRAP, AdGuardHomeDNSMapping } from '../Source/non_ip/domestic';
import { DOMESTIC_CDN } from '../Source/non_ip/domestic_cdn';
import { DIRECTS, HOSTS, LAN } from '../Source/non_ip/direct';
import type { DNSMapping } from '../Source/non_ip/direct';
import { fetchRemoteTextLines, readFileIntoProcessedArray } from './lib/fetch-text-by-line';
@@ -53,6 +54,17 @@ export function createGetDnsMappingRule(allowWildcard: boolean) {
};
}
export const getDomesticCdnDomainsRulesetPromise = once(async () => {
const domesticCdn = await readFileIntoProcessedArray(path.join(SOURCE_DIR, 'non_ip/domestic_cdn.conf'));
const getDnsMappingRuleWithWildcard = createGetDnsMappingRule(true);
Object.values(DOMESTIC_CDN).forEach(({ domains }) => {
appendArrayInPlace(domesticCdn, domains.flatMap(getDnsMappingRuleWithWildcard));
});
return domesticCdn;
});
export const getDomesticAndDirectDomainsRulesetPromise = once(async () => {
const domestics = await readFileIntoProcessedArray(path.join(SOURCE_DIR, 'non_ip/domestic.conf'));
const directs = await readFileIntoProcessedArray(path.resolve(SOURCE_DIR, 'non_ip/direct.conf'));
@@ -66,6 +78,9 @@ export const getDomesticAndDirectDomainsRulesetPromise = once(async () => {
});
});
// Keep legacy subscriptions inclusive of the CDN exceptions.
appendArrayInPlace(domestics, await getDomesticCdnDomainsRulesetPromise());
Object.values(DIRECTS).forEach(({ domains }) => {
appendArrayInPlace(directs, domains.flatMap(getDnsMappingRuleWithWildcard));
});
@@ -81,8 +96,16 @@ export const getDomesticAndDirectDomainsRulesetPromise = once(async () => {
export const buildDomesticRuleset = task(require.main === module, __filename)(async (span) => {
const [domestics, directs, lans] = await getDomesticAndDirectDomainsRulesetPromise();
const domesticCdn = await getDomesticCdnDomainsRulesetPromise();
const dataset: Array<[name: string, DNSMapping]> = ([DOH_BOOTSTRAP, DOMESTICS, DIRECTS, LAN, HOSTS] as const).flatMap(Object.entries);
// Preserve existing provider IDs, and namespace CDN providers so the same
// provider can appear in both sources without overwriting its ruleset or DNS policy.
const domesticMappings = Object.entries(DOMESTIC_CDN).reduce<Record<string, DNSMapping>>((mappings, [name, mapping]) => {
mappings[`DOMESTIC_CDN_${name}`] = mapping;
return mappings;
}, { ...DOMESTICS });
const dataset: Array<[name: string, mapping: DNSMapping]> = ([DOH_BOOTSTRAP, domesticMappings, DIRECTS, LAN, HOSTS] as const).flatMap(Object.entries);
return Promise.all([
new RulesetOutput(span, 'domestic', 'non_ip')
@@ -94,6 +117,17 @@ export const buildDomesticRuleset = task(require.main === module, __filename)(as
)
.addFromRuleset(domestics)
.write(),
new RulesetOutput(span, 'domestic_cdn', 'non_ip')
.withTitle('Sukka\'s Ruleset - Domestic CDN Domains')
.appendDescription(
SHARED_DESCRIPTION,
'',
'This file contains CDN domains of domestic services that should use DIRECT both in China and abroad.',
'Place this ruleset before domestic when routing other domestic traffic back to China.',
'All entries are also included in the domestic ruleset.'
)
.addFromRuleset(domesticCdn)
.write(),
new RulesetOutput(span, 'direct', 'non_ip')
.withTitle('Sukka\'s Ruleset - Direct Rules')
.appendDescription(
@@ -328,7 +362,7 @@ export const buildDomesticRuleset = task(require.main === module, __filename)(as
'https://doh.pub/dns-query',
'https://dns.alidns.com/dns-query',
'[//]udp://10.10.1.1:53',
...(([DOMESTICS, DIRECTS, LAN, HOSTS] as const).flatMap(Object.values) as DNSMapping[]).flatMap(({ domains, dns: _dns }) => domains.flatMap((domain) => {
...(([domesticMappings, DIRECTS, LAN, HOSTS] as const).flatMap(Object.values) as DNSMapping[]).flatMap(({ domains, dns: _dns }) => domains.flatMap((domain) => {
if (!_dns) {
return [];
}

View File

@@ -4,6 +4,7 @@ import { compareAndWriteFile } from './lib/create-file';
import { DIRECTS, LAN } from '../Source/non_ip/direct';
import type { DNSMapping } from '../Source/non_ip/direct';
import { DOMESTICS, DOH_BOOTSTRAP } from '../Source/non_ip/domestic';
import { DOMESTIC_CDN } from '../Source/non_ip/domestic_cdn';
import * as yaml from 'yaml';
import { OUTPUT_INTERNAL_DIR, OUTPUT_MODULES_DIR } from './constants/dir';
import { appendArrayInPlace } from 'foxts/append-array-in-place';
@@ -61,7 +62,7 @@ export const buildAlwaysRealIPModule = task(require.main === module, __filename)
]);
// Intranet, Router Setup, and mant more
const dataset = [DIRECTS, LAN, DOMESTICS, DOH_BOOTSTRAP].reduce<DNSMapping[]>((acc, item) => {
const dataset = [DIRECTS, LAN, DOMESTICS, DOMESTIC_CDN, DOH_BOOTSTRAP].reduce<DNSMapping[]>((acc, item) => {
Object.values(item).forEach((i: DNSMapping) => {
if (i.realip) {
acc.push(i);

View File

@@ -8,6 +8,7 @@ import { HostnameSmolTrie } from 'hntrie/smol';
import { domainToASCII } from 'node:url';
import tldts from 'tldts-experimental';
import { DOMESTICS } from '../Source/non_ip/domestic';
import { DOMESTIC_CDN } from '../Source/non_ip/domestic_cdn';
export async function parseDomesticList() {
const allChinaDomains = new Set<string>(await parseFelixDnsmasqFromResp(await $$fetch('https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf')));
@@ -27,6 +28,10 @@ export async function parseDomesticList() {
const callback = (domain: string, includeAllSubdomain: boolean) => resultTrie.whitelist(includeAllSubdomain ? '.' + domain : domain);
// await Promise.all([
await runAgainstSourceFile(
path.resolve(SOURCE_DIR, 'non_ip/domestic_cdn.conf'),
callback
);
await runAgainstSourceFile(
path.resolve(SOURCE_DIR, 'non_ip/domestic.conf'),
callback
@@ -36,7 +41,7 @@ export async function parseDomesticList() {
callback
);
Object.values(DOMESTICS).forEach(domestic => {
[DOMESTICS, DOMESTIC_CDN].flatMap(item => Object.values(item)).forEach(domestic => {
domestic.domains.forEach(domain => {
switch (domain[0]) {
case '+':

View File

@@ -797,7 +797,65 @@ rules:
- RULE-SET,lan_ip,DIRECT
```
#### Misc
#### 中国大陆常见服务
- 人工维护
**Surge**
```ini
# 中国大陆境内:仅需配置 domestic
# Non IP
RULE-SET,https://ruleset.skk.moe/List/non_ip/domestic.conf,DIRECT
# IP
RULE-SET,https://ruleset.skk.moe/List/ip/domestic.conf,DIRECT
```
```ini
# 其余国家和地区:domestic_cdn 优先直连,domestic 使用代理
# Non IP
RULE-SET,https://ruleset.skk.moe/List/non_ip/domestic_cdn.conf,DIRECT
RULE-SET,https://ruleset.skk.moe/List/non_ip/domestic.conf,Proxy
# IP
RULE-SET,https://ruleset.skk.moe/List/ip/domestic.conf,Proxy
```
**Mihomo**
在下方 `domestic_non_ip` 等 `rule-providers` 的基础上添加:
```yaml
rule-providers:
domestic_cdn_non_ip:
type: http
behavior: classical
format: text
interval: 43200
url: https://ruleset.skk.moe/Clash/non_ip/domestic_cdn.txt
path: ./sukkaw_ruleset/domestic_cdn_non_ip.txt
domestic_ip:
type: http
behavior: classical
format: text
interval: 43200
url: https://ruleset.skk.moe/Clash/ip/domestic.txt
path: ./sukkaw_ruleset/domestic_ip.txt
rules:
- RULE-SET,domestic_cdn_non_ip,DIRECT
- RULE-SET,domestic_non_ip,Back To China Proxy
- MATCH,DIRECT
```
```yaml
# IP
rules:
- RULE-SET,domestic_ip,[Replace with your policy]
```
#### 其他国家和地区常见服务、需直连的服务
- 人工维护
@@ -805,27 +863,15 @@ rules:
```ini
# Non IP
RULE-SET,https://ruleset.skk.moe/List/non_ip/domestic.conf,[Replace with your policy]
RULE-SET,https://ruleset.skk.moe/List/non_ip/direct.conf,[Replace with your policy]
RULE-SET,https://ruleset.skk.moe/List/non_ip/global.conf,[Replace with your policy]
```
```ini
# IP
RULE-SET,https://ruleset.skk.moe/List/ip/domestic.conf,[Replace with your policy]
```
**Mihomo**
```yaml
rule-providers:
domestic_non_ip:
type: http
behavior: classical
format: text
interval: 43200
url: https://ruleset.skk.moe/Clash/non_ip/domestic.txt
path: ./sukkaw_ruleset/domestic_non_ip.txt
direct_non_ip:
type: http
behavior: classical
@@ -840,29 +886,15 @@ rule-providers:
interval: 43200
url: https://ruleset.skk.moe/Clash/non_ip/global.txt
path: ./sukkaw_ruleset/global_non_ip.txt
domestic_ip:
type: http
behavior: classical
format: text
interval: 43200
url: https://ruleset.skk.moe/Clash/ip/domestic.txt
path: ./sukkaw_ruleset/domestic_ip.txt
```
```yaml
# Non IP
rules:
- RULE-SET,domestic_non_ip,[Replace with your policy]
- RULE-SET,direct_non_ip,[Replace with your policy]
- RULE-SET,global_non_ip,[Replace with your policy]
```
```yaml
# IP
rules:
- RULE-SET,domestic_ip,[Replace with your policy]
```
#### chnroute CIDR
- 自动生成

View File

@@ -188,7 +188,6 @@ export const DOMESTICS: Record<string, DNSMapping> = {
'+bilivideo.com',
'+bilivideo.cn',
'+bilivideo.net',
'+hdslb.com',
'+biliimg.com',
'+biliapi.com',
'+biliapi.net',

View File

@@ -0,0 +1,14 @@
# $ custom_build_script
# CDN domains of domestic services that should use DIRECT both in China and abroad.
# Match this ruleset before domestic when routing other domestic traffic back to China.
# The build script also includes these rules in the legacy domestic output.
# >> Bilibili
# Bilibili CDN
DOMAIN-SUFFIX,hdslb.com
# >> NetEase
# NetEase Music CDN
DOMAIN-SUFFIX,music.126.net

View File

@@ -0,0 +1,5 @@
import type { DNSMapping } from './direct';
// CDN domains of domestic services that should use DIRECT both in China and abroad.
// These domains are also included in the legacy domestic output by the build script.
export const DOMESTIC_CDN: Record<string, DNSMapping> = {};