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