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 // @ts-check
import path from 'node:path'; import path from 'node:path';
import { DOMESTICS, DOH_BOOTSTRAP, AdGuardHomeDNSMapping } from '../Source/non_ip/domestic'; 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 { DIRECTS, HOSTS, LAN } from '../Source/non_ip/direct';
import type { DNSMapping } from '../Source/non_ip/direct'; import type { DNSMapping } from '../Source/non_ip/direct';
import { fetchRemoteTextLines, readFileIntoProcessedArray } from './lib/fetch-text-by-line'; 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 () => { export const getDomesticAndDirectDomainsRulesetPromise = once(async () => {
const domestics = await readFileIntoProcessedArray(path.join(SOURCE_DIR, 'non_ip/domestic.conf')); const domestics = await readFileIntoProcessedArray(path.join(SOURCE_DIR, 'non_ip/domestic.conf'));
const directs = await readFileIntoProcessedArray(path.resolve(SOURCE_DIR, 'non_ip/direct.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 }) => { Object.values(DIRECTS).forEach(({ domains }) => {
appendArrayInPlace(directs, domains.flatMap(getDnsMappingRuleWithWildcard)); appendArrayInPlace(directs, domains.flatMap(getDnsMappingRuleWithWildcard));
}); });
@@ -81,8 +96,16 @@ export const getDomesticAndDirectDomainsRulesetPromise = once(async () => {
export const buildDomesticRuleset = task(require.main === module, __filename)(async (span) => { export const buildDomesticRuleset = task(require.main === module, __filename)(async (span) => {
const [domestics, directs, lans] = await getDomesticAndDirectDomainsRulesetPromise(); 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([ return Promise.all([
new RulesetOutput(span, 'domestic', 'non_ip') new RulesetOutput(span, 'domestic', 'non_ip')
@@ -94,6 +117,17 @@ export const buildDomesticRuleset = task(require.main === module, __filename)(as
) )
.addFromRuleset(domestics) .addFromRuleset(domestics)
.write(), .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') new RulesetOutput(span, 'direct', 'non_ip')
.withTitle('Sukka\'s Ruleset - Direct Rules') .withTitle('Sukka\'s Ruleset - Direct Rules')
.appendDescription( .appendDescription(
@@ -328,7 +362,7 @@ export const buildDomesticRuleset = task(require.main === module, __filename)(as
'https://doh.pub/dns-query', 'https://doh.pub/dns-query',
'https://dns.alidns.com/dns-query', 'https://dns.alidns.com/dns-query',
'[//]udp://10.10.1.1:53', '[//]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) { if (!_dns) {
return []; return [];
} }

View File

@@ -4,6 +4,7 @@ import { compareAndWriteFile } from './lib/create-file';
import { DIRECTS, LAN } from '../Source/non_ip/direct'; import { DIRECTS, LAN } from '../Source/non_ip/direct';
import type { DNSMapping } from '../Source/non_ip/direct'; import type { DNSMapping } from '../Source/non_ip/direct';
import { DOMESTICS, DOH_BOOTSTRAP } from '../Source/non_ip/domestic'; import { DOMESTICS, DOH_BOOTSTRAP } from '../Source/non_ip/domestic';
import { DOMESTIC_CDN } from '../Source/non_ip/domestic_cdn';
import * as yaml from 'yaml'; import * as yaml from 'yaml';
import { OUTPUT_INTERNAL_DIR, OUTPUT_MODULES_DIR } from './constants/dir'; import { OUTPUT_INTERNAL_DIR, OUTPUT_MODULES_DIR } from './constants/dir';
import { appendArrayInPlace } from 'foxts/append-array-in-place'; 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 // 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) => { Object.values(item).forEach((i: DNSMapping) => {
if (i.realip) { if (i.realip) {
acc.push(i); acc.push(i);

View File

@@ -8,6 +8,7 @@ import { HostnameSmolTrie } from 'hntrie/smol';
import { domainToASCII } from 'node:url'; import { domainToASCII } from 'node:url';
import tldts from 'tldts-experimental'; import tldts from 'tldts-experimental';
import { DOMESTICS } from '../Source/non_ip/domestic'; import { DOMESTICS } from '../Source/non_ip/domestic';
import { DOMESTIC_CDN } from '../Source/non_ip/domestic_cdn';
export async function parseDomesticList() { 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'))); 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); const callback = (domain: string, includeAllSubdomain: boolean) => resultTrie.whitelist(includeAllSubdomain ? '.' + domain : domain);
// await Promise.all([ // await Promise.all([
await runAgainstSourceFile(
path.resolve(SOURCE_DIR, 'non_ip/domestic_cdn.conf'),
callback
);
await runAgainstSourceFile( await runAgainstSourceFile(
path.resolve(SOURCE_DIR, 'non_ip/domestic.conf'), path.resolve(SOURCE_DIR, 'non_ip/domestic.conf'),
callback callback
@@ -36,7 +41,7 @@ export async function parseDomesticList() {
callback callback
); );
Object.values(DOMESTICS).forEach(domestic => { [DOMESTICS, DOMESTIC_CDN].flatMap(item => Object.values(item)).forEach(domestic => {
domestic.domains.forEach(domain => { domestic.domains.forEach(domain => {
switch (domain[0]) { switch (domain[0]) {
case '+': case '+':

View File

@@ -797,7 +797,65 @@ rules:
- RULE-SET,lan_ip,DIRECT - 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 ```ini
# Non IP # 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/direct.conf,[Replace with your policy]
RULE-SET,https://ruleset.skk.moe/List/non_ip/global.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** **Mihomo**
```yaml ```yaml
rule-providers: rule-providers:
domestic_non_ip: 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: direct_non_ip:
type: http type: http
behavior: classical behavior: classical
@@ -840,29 +886,15 @@ rule-providers:
interval: 43200 interval: 43200
url: https://ruleset.skk.moe/Clash/non_ip/global.txt url: https://ruleset.skk.moe/Clash/non_ip/global.txt
path: ./sukkaw_ruleset/global_non_ip.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 ```yaml
# Non IP # Non IP
rules: rules:
- RULE-SET,domestic_non_ip,[Replace with your policy]
- RULE-SET,direct_non_ip,[Replace with your policy] - RULE-SET,direct_non_ip,[Replace with your policy]
- RULE-SET,global_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 #### chnroute CIDR
- 自动生成 - 自动生成

View File

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