forked from mrrfv/cloudflare-gateway-pihole-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cf_list_create.js
147 lines (120 loc) · 4.07 KB
/
cf_list_create.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import { existsSync } from "node:fs";
import { resolve } from "node:path";
import {
createZeroTrustListsAtOnce,
createZeroTrustListsOneByOne,
} from "./lib/api.js";
import {
DEBUG,
DRY_RUN,
FAST_MODE,
LIST_ITEM_LIMIT,
LIST_ITEM_SIZE,
PROCESSING_FILENAME,
} from "./lib/constants.js";
import { normalizeDomain, notifyWebhook } from "./lib/helpers.js";
import {
extractDomain,
isComment,
isValidDomain,
memoize,
readFile,
} from "./lib/utils.js";
const allowlistFilename = existsSync(PROCESSING_FILENAME.OLD_ALLOWLIST)
? PROCESSING_FILENAME.OLD_ALLOWLIST
: PROCESSING_FILENAME.ALLOWLIST;
const blocklistFilename = existsSync(PROCESSING_FILENAME.OLD_BLOCKLIST)
? PROCESSING_FILENAME.OLD_BLOCKLIST
: PROCESSING_FILENAME.BLOCKLIST;
const allowlist = new Map();
const blocklist = new Map();
const domains = [];
let processedDomainCount = 0;
let unnecessaryDomainCount = 0;
let duplicateDomainCount = 0;
let allowedDomainCount = 0;
const memoizedNormalizeDomain = memoize(normalizeDomain);
// Read allowlist
console.log(`Processing ${allowlistFilename}`);
await readFile(resolve(`./${allowlistFilename}`), (line) => {
const _line = line.trim();
if (!_line) return;
if (isComment(_line)) return;
const domain = memoizedNormalizeDomain(_line, true);
if (!isValidDomain(domain)) return;
allowlist.set(domain, 1);
});
// Read blocklist
console.log(`Processing ${blocklistFilename}`);
await readFile(resolve(`./${blocklistFilename}`), (line, rl) => {
if (domains.length === LIST_ITEM_LIMIT) {
return;
}
const _line = line.trim();
if (!_line) return;
// Check if the current line is a comment in any format
if (isComment(_line)) return;
// Remove prefixes and suffixes in hosts, wildcard or adblock format
const domain = memoizedNormalizeDomain(_line);
// Check if it is a valid domain which is not a URL or does not contain
// characters like * in the middle of the domain
if (!isValidDomain(domain)) return;
processedDomainCount++;
if (allowlist.has(domain)) {
if (DEBUG) console.log(`Found ${domain} in allowlist - Skipping`);
allowedDomainCount++;
return;
}
if (blocklist.has(domain)) {
if (DEBUG) console.log(`Found ${domain} in blocklist already - Skipping`);
duplicateDomainCount++;
return;
}
// Get all the levels of the domain and check from the highest
// because we are blocking all subdomains
// Example: fourth.third.example.com => ["example.com", "third.example.com", "fourth.third.example.com"]
for (const item of extractDomain(domain).slice(1)) {
if (!blocklist.has(item)) continue;
// The higher-level domain is already blocked
// so it's not necessary to block this domain
if (DEBUG) console.log(`Found ${item} in blocklist already - Skipping ${domain}`);
unnecessaryDomainCount++;
return;
}
blocklist.set(domain, 1);
domains.push(domain);
if (domains.length === LIST_ITEM_LIMIT) {
console.log(
"Maximum number of blocked domains reached - Stopping processing blocklist..."
);
rl.close();
}
});
const numberOfLists = Math.ceil(domains.length / LIST_ITEM_SIZE);
console.log("\n\n");
console.log(`Number of processed domains: ${processedDomainCount}`);
console.log(`Number of duplicate domains: ${duplicateDomainCount}`);
console.log(`Number of unnecessary domains: ${unnecessaryDomainCount}`);
console.log(`Number of allowed domains: ${allowedDomainCount}`);
console.log(`Number of blocked domains: ${domains.length}`);
console.log(`Number of lists to be created: ${numberOfLists}`);
console.log("\n\n");
(async () => {
if (DRY_RUN) {
console.log(
"Dry run complete - no lists were created. If this was not intended, please remove the DRY_RUN environment variable and try again."
);
return;
}
console.log(
`Creating ${numberOfLists} lists for ${domains.length} domains...`
);
if (FAST_MODE) {
await createZeroTrustListsAtOnce(domains);
} else {
await createZeroTrustListsOneByOne(domains);
}
await notifyWebhook(
`CF List Create script finished running (${domains.length} domains, ${numberOfLists} lists)`
);
})();