diff --git a/_worker.js b/_worker.js index 66d04f82e..8beac6e51 100644 --- a/_worker.js +++ b/_worker.js @@ -5142,6 +5142,8 @@ async function updateDataset(env, newSettings, resetSettings) { customCdnHost: validateField("customCdnHost")?.trim() ?? currentSettings?.customCdnHost ?? "", customCdnSni: validateField("customCdnSni")?.trim() ?? currentSettings?.customCdnSni ?? "", bestVLESSTrojanInterval: validateField("bestVLESSTrojanInterval") ?? currentSettings?.bestVLESSTrojanInterval ?? "30", + customRuleBlockSites: validateField("customRuleBlockSites")?.trim() ?? currentSettings?.customRuleBlockSites ?? "", + customRuleBypassSites: validateField("customRuleBypassSites")?.trim() ?? currentSettings?.customRuleBypassSites ?? "", vlessConfigs: validateField("vlessConfigs") ?? currentSettings?.vlessConfigs ?? true, trojanConfigs: validateField("trojanConfigs") ?? currentSettings?.trojanConfigs ?? false, ports: validateField("ports")?.split(",") ?? currentSettings?.ports ?? ["443"], @@ -5272,6 +5274,8 @@ function renderHomePage(request, proxySettings, hostName, isPassSet) { customCdnHost, customCdnSni, bestVLESSTrojanInterval, + customRuleBlockSites, + customRuleBypassSites, vlessConfigs, trojanConfigs, ports, @@ -5687,6 +5691,14 @@ function renderHomePage(request, proxySettings, hostName, isPassSet) { +
+ + +
+
+ + +
@@ -6590,6 +6602,8 @@ function renderHomePage(request, proxySettings, hostName, isPassSet) { const customCdnHost = document.getElementById('customCdnHost').value; const customCdnSni = document.getElementById('customCdnSni').value; const isCustomCdn = customCdnAddrs.length > 0 || customCdnHost !== '' || customCdnSni !== ''; + const customRuleBlockSites = document.getElementById('customRuleBlockSites').value?.split(',').filter(addr => addr !== ''); + const customRuleBypassSites = document.getElementById('customRuleBypassSites').value?.split(',').filter(addr => addr !== ''); const warpEndpoints = document.getElementById('warpEndpoints').value?.replaceAll(' ', '').split(','); const noiseCountMin = getValue('noiseCountMin'); const noiseCountMax = getValue('noiseCountMax'); @@ -7161,7 +7175,9 @@ function buildXrayRoutingRules(proxySettings, outboundAddrs, isChain, isBalancer bypassRussia, blockAds, blockPorn, - blockUDP443 + blockUDP443, + customRuleBlockSites, + customRuleBypassSites } = proxySettings; const isBlock = blockAds || blockPorn; const isBypass = bypassIran || bypassChina || bypassRussia; @@ -7200,30 +7216,46 @@ function buildXrayRoutingRules(proxySettings, outboundAddrs, isChain, isBalancer outboundTag: "direct", type: "field" }); - if (isBypass || isBlock) { + if (isBypass || isBlock || customRuleBlockSites || customRuleBypassSites) { const createRule = /* @__PURE__ */ __name((type, outbound) => ({ [type]: [], outboundTag: outbound, type: "field" }), "createRule"); - let geositeDirectRule, geoipDirectRule; - if (!isWorkerLess) { - geositeDirectRule = createRule("domain", "direct"); - geoipDirectRule = createRule("ip", "direct"); + if (customRuleBlockSites) { + let customSiteBlockRule = createRule("domain", "block"); + customRuleBlockSites.split(",").forEach( + (domainName) => customSiteBlockRule.domain.push(domainName.trim()) + ); + rules.push(customSiteBlockRule); } - let geositeBlockRule = createRule("domain", "block"); - geoRules.forEach(({ rule, type, domain, ip }) => { - if (rule) { - if (type === "direct") { - geositeDirectRule?.domain.push(domain); - geoipDirectRule?.ip?.push(ip); - } else { - geositeBlockRule.domain.push(domain); - } + if (customRuleBypassSites) { + let customSiteBypassRule = createRule("domain", "direct"); + customRuleBypassSites.split(",").forEach( + (domainName) => customSiteBypassRule.domain.push(domainName.trim()) + ); + rules.push(customSiteBypassRule); + } + if (isBypass || isBlock) { + let geositeDirectRule, geoipDirectRule; + if (!isWorkerLess) { + geositeDirectRule = createRule("domain", "direct"); + geoipDirectRule = createRule("ip", "direct"); } - }); - !isWorkerLess && isBypass && rules.push(geositeDirectRule, geoipDirectRule); - isBlock && rules.push(geositeBlockRule); + let geositeBlockRule = createRule("domain", "block"); + geoRules.forEach(({ rule, type, domain, ip }) => { + if (rule) { + if (type === "direct") { + geositeDirectRule?.domain.push(domain); + geoipDirectRule?.ip?.push(ip); + } else { + geositeBlockRule.domain.push(domain); + } + } + }); + !isWorkerLess && isBypass && rules.push(geositeDirectRule, geoipDirectRule); + isBlock && rules.push(geositeBlockRule); + } } blockUDP443 && rules.push({ network: "udp", @@ -7843,10 +7875,23 @@ function buildClashRoutingRules(proxySettings) { bypassRussia, blockAds, blockPorn, - blockUDP443 + blockUDP443, + customRuleBlockSites, + customRuleBypassSites } = proxySettings; const isBypass = bypassIran || bypassChina || bypassLAN || bypassRussia; const isBlock = blockAds || blockPorn; + let customSiteBlockRules = [], customSiteBypassRules = []; + if (customRuleBlockSites) { + customRuleBlockSites.split(",").forEach( + (domainName) => customSiteBlockRules.push(`DOMAIN-SUFFIX,${domainName},REJECT`) + ); + } + if (customRuleBypassSites) { + customRuleBypassSites.split(",").forEach( + (domainName) => customSiteBypassRules.push(`DOMAIN-SUFFIX,${domainName},DIRECT`) + ); + } let geositeDirectRules = [], geoipDirectRules = [], geositeBlockRules = []; const geoRules = [ { rule: bypassLAN, type: "direct", geosite: "private", geoip: "private" }, @@ -7871,6 +7916,8 @@ function buildClashRoutingRules(proxySettings) { } let rules = [ `AND,((IP-CIDR,${localDNS}/32),(DST-PORT,53)),DIRECT`, + ...customSiteBlockRules, + ...customSiteBypassRules, ...geositeDirectRules, ...geoipDirectRules, ...geositeBlockRules @@ -8283,7 +8330,9 @@ function buildSingBoxRoutingRules(proxySettings) { bypassRussia, blockAds, blockPorn, - blockUDP443 + blockUDP443, + customRuleBlockSites, + customRuleBypassSites } = proxySettings; const isBypass = bypassIran || bypassChina || bypassRussia; let rules = [ @@ -8389,6 +8438,14 @@ function buildSingBoxRoutingRules(proxySettings) { ip_is_private: true, outbound: "direct" }); + customRuleBlockSites && rules.push({ + domain_suffix: customRuleBlockSites.split(",").map((item) => item.trim()), + outbound: "block" + }); + customRuleBypassSites && rules.push({ + domain_suffix: customRuleBypassSites.split(",").map((item) => item.trim()), + outbound: "direct" + }); const createRule = /* @__PURE__ */ __name((outbound) => ({ rule_set: [], outbound diff --git a/src/worker.js b/src/worker.js index ab5d3d4e4..eba0a3f74 100644 --- a/src/worker.js +++ b/src/worker.js @@ -1227,6 +1227,8 @@ async function updateDataset (env, newSettings, resetSettings) { customCdnHost: validateField('customCdnHost')?.trim() ?? currentSettings?.customCdnHost ?? '', customCdnSni: validateField('customCdnSni')?.trim() ?? currentSettings?.customCdnSni ?? '', bestVLESSTrojanInterval: validateField('bestVLESSTrojanInterval') ?? currentSettings?.bestVLESSTrojanInterval ?? '30', + customRuleBlockSites: validateField("customRuleBlockSites")?.trim() ?? currentSettings?.customRuleBlockSites ?? "", + customRuleBypassSites: validateField("customRuleBypassSites")?.trim() ?? currentSettings?.customRuleBypassSites ?? "", vlessConfigs: validateField('vlessConfigs') ?? currentSettings?.vlessConfigs ?? true, trojanConfigs: validateField('trojanConfigs') ?? currentSettings?.trojanConfigs ?? false, ports: validateField('ports')?.split(',') ?? currentSettings?.ports ?? ['443'], @@ -1373,6 +1375,8 @@ function renderHomePage (request, proxySettings, hostName, isPassSet) { customCdnHost, customCdnSni, bestVLESSTrojanInterval, + customRuleBlockSites, + customRuleBypassSites, vlessConfigs, trojanConfigs, ports, @@ -1791,6 +1795,14 @@ function renderHomePage (request, proxySettings, hostName, isPassSet) {
+
+ + +
+
+ + +
@@ -2694,6 +2706,8 @@ function renderHomePage (request, proxySettings, hostName, isPassSet) { const customCdnHost = document.getElementById('customCdnHost').value; const customCdnSni = document.getElementById('customCdnSni').value; const isCustomCdn = customCdnAddrs.length > 0 || customCdnHost !== '' || customCdnSni !== ''; + const customRuleBlockSites = document.getElementById('customRuleBlockSites').value?.split(',').filter(addr => addr !== ''); + const customRuleBypassSites = document.getElementById('customRuleBypassSites').value?.split(',').filter(addr => addr !== ''); const warpEndpoints = document.getElementById('warpEndpoints').value?.replaceAll(' ', '').split(','); const noiseCountMin = getValue('noiseCountMin'); const noiseCountMax = getValue('noiseCountMax'); @@ -3290,7 +3304,9 @@ function buildXrayRoutingRules (proxySettings, outboundAddrs, isChain, isBalance bypassRussia, blockAds, blockPorn, - blockUDP443 + blockUDP443, + customRuleBlockSites, + customRuleBypassSites } = proxySettings; const isBlock = blockAds || blockPorn; @@ -3331,33 +3347,51 @@ function buildXrayRoutingRules (proxySettings, outboundAddrs, isChain, isBalance type: "field" }); - if (isBypass || isBlock) { + if (isBypass || isBlock || customRuleBlockSites || customRuleBypassSites) { const createRule = (type, outbound) => ({ [type]: [], outboundTag: outbound, type: "field" }); - let geositeDirectRule, geoipDirectRule; - if (!isWorkerLess) { - geositeDirectRule = createRule("domain", "direct"); - geoipDirectRule = createRule("ip", "direct"); + if (customRuleBlockSites) { + let customSiteBlockRule = createRule("domain", "block"); + customRuleBlockSites.split(",").forEach( + domainName => customSiteBlockRule.domain.push(domainName.trim()) + ); + rules.push(customSiteBlockRule); } - let geositeBlockRule = createRule("domain", "block"); - geoRules.forEach(({ rule, type, domain, ip }) => { - if (rule) { - if (type === 'direct') { - geositeDirectRule?.domain.push(domain); - geoipDirectRule?.ip?.push(ip); - } else { - geositeBlockRule.domain.push(domain); - } + if (customRuleBypassSites) { + let customSiteBypassRule = createRule("domain", "direct"); + customRuleBypassSites.split(",").forEach( + domainName => customSiteBypassRule.domain.push(domainName.trim()) + ); + rules.push(customSiteBypassRule); + } + + if (isBypass || isBlock) { + let geositeDirectRule, geoipDirectRule; + if (!isWorkerLess) { + geositeDirectRule = createRule("domain", "direct"); + geoipDirectRule = createRule("ip", "direct"); } - }); - - !isWorkerLess && isBypass && rules.push(geositeDirectRule, geoipDirectRule); - isBlock && rules.push(geositeBlockRule); + + let geositeBlockRule = createRule("domain", "block"); + geoRules.forEach(({ rule, type, domain, ip }) => { + if (rule) { + if (type === 'direct') { + geositeDirectRule?.domain.push(domain); + geoipDirectRule?.ip?.push(ip); + } else { + geositeBlockRule.domain.push(domain); + } + } + }); + + !isWorkerLess && isBypass && rules.push(geositeDirectRule, geoipDirectRule); + isBlock && rules.push(geositeBlockRule); + } } blockUDP443 && rules.push({ @@ -4007,11 +4041,26 @@ function buildClashRoutingRules (proxySettings) { bypassRussia, blockAds, blockPorn, - blockUDP443 + blockUDP443, + customRuleBlockSites, + customRuleBypassSites } = proxySettings; const isBypass = bypassIran || bypassChina || bypassLAN || bypassRussia; const isBlock = blockAds || blockPorn; + + let customSiteBlockRules = [], customSiteBypassRules = []; + if (customRuleBlockSites) { + customRuleBlockSites.split(",").forEach( + domainName => customSiteBlockRules.push(`DOMAIN-SUFFIX,${domainName},REJECT`) + ); + } + if (customRuleBypassSites) { + customRuleBypassSites.split(",").forEach( + domainName => customSiteBypassRules.push(`DOMAIN-SUFFIX,${domainName},DIRECT`) + ); + } + let geositeDirectRules = [], geoipDirectRules = [], geositeBlockRules = []; const geoRules = [ { rule: bypassLAN, type: 'direct', geosite: "private", geoip: "private" }, @@ -4038,6 +4087,8 @@ function buildClashRoutingRules (proxySettings) { let rules = [ `AND,((IP-CIDR,${localDNS}/32),(DST-PORT,53)),DIRECT`, + ...customSiteBlockRules, + ...customSiteBypassRules, ...geositeDirectRules, ...geoipDirectRules, ...geositeBlockRules @@ -4478,7 +4529,9 @@ function buildSingBoxRoutingRules (proxySettings) { bypassRussia, blockAds, blockPorn, - blockUDP443 + blockUDP443, + customRuleBlockSites, + customRuleBypassSites } = proxySettings; const isBypass = bypassIran || bypassChina || bypassRussia; @@ -4588,6 +4641,16 @@ function buildSingBoxRoutingRules (proxySettings) { outbound: "direct" }); + customRuleBlockSites && rules.push({ + domain_suffix: customRuleBlockSites.split(',').map(item => item.trim()), + outbound: "block" + }); + + customRuleBypassSites && rules.push({ + domain_suffix: customRuleBypassSites.split(',').map(item => item.trim()), + outbound: "direct" + }); + const createRule = (outbound) => ({ rule_set: [], outbound