From ac535c927aa7b6e8887639dae944df685b67bf34 Mon Sep 17 00:00:00 2001 From: Viet Huynh Date: Thu, 2 Nov 2023 02:42:28 +0700 Subject: [PATCH 1/5] updated logging for API calls --- cf_gateway_rule_create.js | 1 + cf_gateway_rule_delete.js | 2 +- cf_list_create.js | 10 +++++--- cf_list_delete.js | 2 ++ lib/api.js | 53 ++++++++++++++++++++++++--------------- 5 files changed, 44 insertions(+), 24 deletions(-) diff --git a/cf_gateway_rule_create.js b/cf_gateway_rule_create.js index d069a00..9bf8f34 100644 --- a/cf_gateway_rule_create.js +++ b/cf_gateway_rule_create.js @@ -7,5 +7,6 @@ const wirefilterExpression = lists.reduce((previous, current) => { return `${previous} any(dns.domains[*] in \$${current.id}) or `; }, ""); +console.log("Creating rule..."); // Remove the trailing ' or ' await createZeroTrustRule(wirefilterExpression.slice(0, -4)); diff --git a/cf_gateway_rule_delete.js b/cf_gateway_rule_delete.js index e8aedf5..a0e08f4 100644 --- a/cf_gateway_rule_delete.js +++ b/cf_gateway_rule_delete.js @@ -11,6 +11,6 @@ const cgpsRule = rules.find(({ name }) => name === "CGPS Filter Lists"); return; } - console.log(`Deleting rule ${cgpsRule.name}`); + console.log(`Deleting rule ${cgpsRule.name}...`); await deleteZeroTrustRule(cgpsRule.id); })(); diff --git a/cf_list_create.js b/cf_list_create.js index 61e906c..52a8b0b 100644 --- a/cf_list_create.js +++ b/cf_list_create.js @@ -118,15 +118,15 @@ await readFile(resolve(`./${blocklistFilename}`), (line, rl) => { } }); +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 blocked domains: ${domains.length}`); console.log(`Number of allowed domains: ${allowedDomainCount}`); -console.log( - `Number of lists to be created: ${Math.ceil(domains.length / LIST_ITEM_SIZE)}` -); +console.log(`Number of lists to be created: ${numberOfLists}`); console.log("\n\n"); (async () => { @@ -137,6 +137,10 @@ console.log("\n\n"); return; } + console.log( + `Creating ${numberOfLists} lists for ${domains.length} domains...` + ); + if (FAST_MODE) { await createZeroTrustListsAtOnce(domains); return; diff --git a/cf_list_delete.js b/cf_list_delete.js index e9d3cb6..f8be9e4 100644 --- a/cf_list_delete.js +++ b/cf_list_delete.js @@ -28,6 +28,8 @@ import { FAST_MODE } from "./lib/constants.js"; `Got ${lists.length} lists, ${cgpsLists.length} of which are CGPS lists that will be deleted.` ); + console.log(`Deleting ${cgpsLists.length} lists...`); + if (FAST_MODE) { await deleteZeroTrustListsAtOnce(cgpsLists); return; diff --git a/lib/api.js b/lib/api.js index 2764a4f..a647fa0 100644 --- a/lib/api.js +++ b/lib/api.js @@ -62,7 +62,6 @@ export const createZeroTrustListsOneByOne = async (items) => { * @param {string[]} items The domains. */ export const createZeroTrustListsAtOnce = async (items) => { - const totalListNumber = Math.ceil(items.length / LIST_ITEM_SIZE); const requests = []; for (let i = 0, listNumber = 1; i < items.length; i += LIST_ITEM_SIZE) { @@ -77,7 +76,7 @@ export const createZeroTrustListsAtOnce = async (items) => { try { await Promise.all(requests); - console.log(`Created ${totalListNumber} lists`); + console.log("Created lists successfully"); } catch (err) { console.error(`Error occurred while creating lists - ${err.toString()}`); } @@ -125,7 +124,7 @@ export const deleteZeroTrustListsAtOnce = async (lists) => { try { await Promise.all(requests); - console.log(`Deleted ${lists.length} lists`); + console.log("Deleted lists successfully"); } catch (err) { console.error(`Error occurred while deleting lists - ${err.toString()}`); } @@ -147,19 +146,26 @@ export const getZeroTrustRules = () => * @param {string} wirefilterExpression The expression to be used for the rule. * @returns {Promise} */ -export const createZeroTrustRule = (wirefilterExpression) => - requestGateway("/rules", { - method: "POST", - body: JSON.stringify({ - name: "CGPS Filter Lists", - description: - "Filter lists created by Cloudflare Gateway Pi-hole Scripts. Avoid editing this rule. Changing the name of this rule will break the script.", - enabled: true, - action: "block", - filters: ["dns"], - traffic: wirefilterExpression, - }), - }); +export const createZeroTrustRule = async (wirefilterExpression) => { + try { + await requestGateway("/rules", { + method: "POST", + body: JSON.stringify({ + name: "CGPS Filter Lists", + description: + "Filter lists created by Cloudflare Gateway Pi-hole Scripts. Avoid editing this rule. Changing the name of this rule will break the script.", + enabled: true, + action: "block", + filters: ["dns"], + traffic: wirefilterExpression, + }), + }); + + console.log("Created rule successfully"); + } catch (err) { + console.error(`Error occurred while creating rule - ${err.toString()}`); + } +}; /** * Deletes a Zero Trust rule. @@ -168,7 +174,14 @@ export const createZeroTrustRule = (wirefilterExpression) => * @param {number} id The ID of the rule to be deleted. * @returns {Promise} */ -export const deleteZeroTrustRule = (id) => - requestGateway(`/rules/${id}`, { - method: "DELETE", - }); +export const deleteZeroTrustRule = async (id) => { + try { + await requestGateway(`/rules/${id}`, { + method: "DELETE", + }); + + console.log("Deleted rule successfully"); + } catch (err) { + console.error(`Error occurred while deleting rule - ${err.toString()}`); + } +}; From 4f97b35b74e2ef03168f98dcf796ff821a4f492d Mon Sep 17 00:00:00 2001 From: Viet Huynh Date: Thu, 2 Nov 2023 02:56:56 +0700 Subject: [PATCH 2/5] use API Token in favour of API Key for better security --- .env.example | 3 +-- .github/images/create_api_token.png | Bin 0 -> 36167 bytes README.md | 3 +-- auto_update_github_action.yml | 6 ++--- extended_guide.md | 12 ++++++---- lib/constants.js | 15 ++++++++---- lib/helpers.js | 36 +++++++++++++++++++--------- 7 files changed, 48 insertions(+), 27 deletions(-) create mode 100644 .github/images/create_api_token.png diff --git a/.env.example b/.env.example index 83fcadf..a9fb3ae 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,5 @@ -CLOUDFLARE_API_KEY= +CLOUDFLARE_API_TOKEN= CLOUDFLARE_ACCOUNT_ID= -CLOUDFLARE_ACCOUNT_EMAIL= CLOUDFLARE_LIST_ITEM_LIMIT=300000 DRY_RUN=0 FAST_MODE=0 diff --git a/.github/images/create_api_token.png b/.github/images/create_api_token.png new file mode 100644 index 0000000000000000000000000000000000000000..19350e484afbc67a3d8cee9d283e91339b61ca77 GIT binary patch literal 36167 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 B&yoND literal 0 HcmV?d00001 diff --git a/README.md b/README.md index 2b728e0..cb3ac46 100644 --- a/README.md +++ b/README.md @@ -51,9 +51,8 @@ Please note that the GitHub Action downloads the recommended blocklists and whit 1. Create a new empty, private repository. Forking or public repositories are discouraged, but supported - although the script never leaks your API keys and GitHub Actions secrets are automatically redacted from the logs, it's better to be safe than sorry. 2. Create the following GitHub Actions secrets in your repository settings: -- `CLOUDFLARE_API_KEY`: Your Cloudflare API key +- `CLOUDFLARE_API_TOKEN`: Your Cloudflare API Token with Zero Trust read and write permissions - `CLOUDFLARE_ACCOUNT_ID`: Your Cloudflare account ID -- `CLOUDFLARE_ACCOUNT_EMAIL`: Your Cloudflare account email - `CLOUDFLARE_LIST_ITEM_LIMIT`: The maximum number of blocked domains allowed for your Cloudflare Zero Trust plan. Use 300000 for the free plan or if you're unsure. - `PING_URL`: /Optional/ The HTTP(S) URL to ping (using curl) after the GitHub Action has successfully updated your filters. Useful for monitoring. diff --git a/auto_update_github_action.yml b/auto_update_github_action.yml index 8223210..47a4311 100644 --- a/auto_update_github_action.yml +++ b/auto_update_github_action.yml @@ -46,8 +46,7 @@ jobs: - name: Delete old rules and lists run: npm run cloudflare-delete env: - CLOUDFLARE_API_KEY: ${{ secrets.CLOUDFLARE_API_KEY }} - CLOUDFLARE_ACCOUNT_EMAIL: ${{ secrets.CLOUDFLARE_ACCOUNT_EMAIL }} + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_LIST_ITEM_LIMIT: ${{ secrets.CLOUDFLARE_LIST_ITEM_LIMIT }} FAST_MODE: ${{ vars.FAST_MODE }} @@ -55,8 +54,7 @@ jobs: - name: Create new rules and lists run: npm run cloudflare-create env: - CLOUDFLARE_API_KEY: ${{ secrets.CLOUDFLARE_API_KEY }} - CLOUDFLARE_ACCOUNT_EMAIL: ${{ secrets.CLOUDFLARE_ACCOUNT_EMAIL }} + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_LIST_ITEM_LIMIT: ${{ secrets.CLOUDFLARE_LIST_ITEM_LIMIT }} FAST_MODE: ${{ vars.FAST_MODE }} diff --git a/extended_guide.md b/extended_guide.md index 3d43c3e..8b22a19 100644 --- a/extended_guide.md +++ b/extended_guide.md @@ -16,13 +16,17 @@ https://dash.cloudflare.com/1234567890abcdef1234567890abcdef In this example, `1234567890abcdef1234567890abcdef` is the account ID. -### `CLOUDFLARE_API_KEY` +### `CLOUDFLARE_API_TOKEN` -The Cloudflare API key can be found in the [Cloudflare dashboard](https://dash.cloudflare.com/) too. Click on your profile picture (or user icon) in the top right corner, then click on "API Tokens" in the sidebar. Scroll down to the "API Keys" section and click on "View" next to the Global API Key. +Cloudflare API Token can be created in your [Cloudflare profile](https://dash.cloudflare.com/profile/api-tokens): -### `CLOUDFLARE_ACCOUNT_EMAIL` +1. Click "Create Token" and click "Get Started" in the "Create Custom Token" row. +2. Enter any name for your token +3. Add Zero Trust Read and Edit permissions for your account +4. Click "Continue to summary" and click "Create Token" +5. You will see the created API Token -The Cloudflare account email is the email address you use to log in to the Cloudflare dashboard. +![Creating API Token](.github/images/create_api_token.png) ### `CLOUDFLARE_LIST_ITEM_LIMIT` diff --git a/lib/constants.js b/lib/constants.js index 9567b91..5ed46e1 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -2,7 +2,15 @@ import dotenv from "dotenv"; dotenv.config(); -export const API_TOKEN = process.env.CLOUDFLARE_API_KEY; +if (process.env.CLOUDFLARE_API_KEY) { + console.warn( + "Using Global API Key is very risky for your Cloudflare account. It is strongly recommended to create an API Token with scoped permissions instead." + ); +} + +export const API_KEY = process.env.CLOUDFLARE_API_KEY; + +export const API_TOKEN = process.env.CLOUDFLARE_API_TOKEN; export const ACCOUNT_ID = process.env.CLOUDFLARE_ACCOUNT_ID; @@ -33,12 +41,11 @@ export const LIST_TYPE = { }; export const USER_DEFINED_ALLOWLIST_URLS = process.env.ALLOWLIST_URLS - // .filter(x => x) removes empty items from the URL arrays - ? process.env.ALLOWLIST_URLS.split("\n").filter(x => x) + ? process.env.ALLOWLIST_URLS.split("\n").filter((x) => x) : undefined; export const USER_DEFINED_BLOCKLIST_URLS = process.env.BLOCKLIST_URLS - ? process.env.BLOCKLIST_URLS.split("\n").filter(x => x) + ? process.env.BLOCKLIST_URLS.split("\n").filter((x) => x) : undefined; export const RECOMMENDED_ALLOWLIST_URLS = [ diff --git a/lib/helpers.js b/lib/helpers.js index 84b4e8f..7c92111 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -1,4 +1,10 @@ -import { ACCOUNT_EMAIL, ACCOUNT_ID, API_HOST, API_TOKEN } from "./constants.js"; +import { + ACCOUNT_EMAIL, + ACCOUNT_ID, + API_HOST, + API_KEY, + API_TOKEN, +} from "./constants.js"; if (!globalThis.fetch) { console.warn( @@ -20,20 +26,30 @@ if (!globalThis.fetch) { * @returns {Promise} */ const request = async (url, options) => { - if (!API_TOKEN || !ACCOUNT_ID || !ACCOUNT_EMAIL) { + if (!(API_TOKEN || API_KEY) || !ACCOUNT_ID) { throw new Error( - "One or more required secrets have not been added: CLOUDFLARE_API_KEY, CLOUDFLARE_ACCOUNT_ID, and CLOUDFLARE_ACCOUNT_EMAIL" + "The following secrets are required: CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID" ); } + const headers = API_TOKEN + ? { + Authorization: `Bearer ${API_TOKEN}`, + "Content-Type": "application/json", + } + : { + Authorization: `Bearer ${API_KEY}`, + "Content-Type": "application/json", + "X-Auth-Email": ACCOUNT_EMAIL, + "X-Auth-Key": API_KEY, + }; + const response = await fetch(url, { - headers: { - Authorization: `Bearer ${API_TOKEN}`, - "Content-Type": "application/json", - "X-Auth-Email": ACCOUNT_EMAIL, - "X-Auth-Key": API_TOKEN, - }, ...options, + headers: { + ...options.headers, + ...headers, + }, }); if (!response.ok) { @@ -42,8 +58,6 @@ const request = async (url, options) => { const data = await response.json(); - console.log(`HTTP request succeeded: ${data.success}`); - return data; }; From cdcce5a939c88cc256df17aedae8d16b5c44b697 Mon Sep 17 00:00:00 2001 From: Viet Huynh Date: Thu, 2 Nov 2023 02:58:24 +0700 Subject: [PATCH 3/5] remove sleep function --- lib/api.js | 3 --- lib/utils.js | 7 ------- 2 files changed, 10 deletions(-) diff --git a/lib/api.js b/lib/api.js index a647fa0..ef4c138 100644 --- a/lib/api.js +++ b/lib/api.js @@ -1,6 +1,5 @@ import { LIST_ITEM_SIZE } from "./constants.js"; import { requestGateway } from "./helpers.js"; -import { sleep } from "./utils.js"; /** * Gets Zero Trust lists. @@ -47,7 +46,6 @@ export const createZeroTrustListsOneByOne = async (items) => { try { await createZeroTrustList(listName, chunk); - await sleep(); totalListNumber--; listNumber++; console.log(`Created "${listName}" list - ${totalListNumber} left`); @@ -104,7 +102,6 @@ export const deleteZeroTrustListsOneByOne = async (lists) => { for (const { id, name } of lists) { try { await deleteZeroTrustList(id); - await sleep(); totalListNumber--; console.log(`Deleted ${name} list - ${totalListNumber} left`); } catch (err) { diff --git a/lib/utils.js b/lib/utils.js index 607be0f..79ad4ea 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -7,13 +7,6 @@ if (!globalThis.fetch) { globalThis.fetch = (await import("node-fetch")).default; } -/** - * Sleeps for a specified amount of time. - * @param {number} [ms=350] The amount of time in ms. - */ -export const sleep = (ms = 350) => - new Promise((resolve) => setTimeout(resolve, ms)); - /** * Checks if the value is a valid domain. * @param {string} value The value to be checked. From 4552ea77b360de073576427c1d1a772991bef7c6 Mon Sep 17 00:00:00 2001 From: Viet Huynh Date: Thu, 2 Nov 2023 02:59:35 +0700 Subject: [PATCH 4/5] fix wording --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cb3ac46..bebafde 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Please note that the GitHub Action downloads the recommended blocklists and whit 1. Create a new empty, private repository. Forking or public repositories are discouraged, but supported - although the script never leaks your API keys and GitHub Actions secrets are automatically redacted from the logs, it's better to be safe than sorry. 2. Create the following GitHub Actions secrets in your repository settings: -- `CLOUDFLARE_API_TOKEN`: Your Cloudflare API Token with Zero Trust read and write permissions +- `CLOUDFLARE_API_TOKEN`: Your Cloudflare API Token with Zero Trust read and edit permissions - `CLOUDFLARE_ACCOUNT_ID`: Your Cloudflare account ID - `CLOUDFLARE_LIST_ITEM_LIMIT`: The maximum number of blocked domains allowed for your Cloudflare Zero Trust plan. Use 300000 for the free plan or if you're unsure. - `PING_URL`: /Optional/ The HTTP(S) URL to ping (using curl) after the GitHub Action has successfully updated your filters. Useful for monitoring. From 06ecfe490bc969671bb02ae8be08209c46e208e1 Mon Sep 17 00:00:00 2001 From: Viet Huynh Date: Thu, 2 Nov 2023 03:10:46 +0700 Subject: [PATCH 5/5] update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bebafde..001b478 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Please note that the GitHub Action downloads the recommended blocklists and whit - `CLOUDFLARE_API_TOKEN`: Your Cloudflare API Token with Zero Trust read and edit permissions - `CLOUDFLARE_ACCOUNT_ID`: Your Cloudflare account ID -- `CLOUDFLARE_LIST_ITEM_LIMIT`: The maximum number of blocked domains allowed for your Cloudflare Zero Trust plan. Use 300000 for the free plan or if you're unsure. +- `CLOUDFLARE_LIST_ITEM_LIMIT`: The maximum number of blocked domains allowed for your Cloudflare Zero Trust plan. Default to 300,000. Optional if you are using the free plan. - `PING_URL`: /Optional/ The HTTP(S) URL to ping (using curl) after the GitHub Action has successfully updated your filters. Useful for monitoring. 3. Create the following GitHub Actions variables in your repository settings if you desire: