Skip to content

Commit

Permalink
Merge pull request #143 from bsyk/upsert_rule
Browse files Browse the repository at this point in the history
Update existing rule
  • Loading branch information
mrrfv authored Nov 29, 2024
2 parents 9e9fc1e + a5de303 commit 17b34b6
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 4 deletions.
6 changes: 3 additions & 3 deletions cf_gateway_rule_create.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createZeroTrustRule, getZeroTrustLists } from "./lib/api.js";
import { getZeroTrustLists, upsertZeroTrustRule } from "./lib/api.js";
import { BLOCK_BASED_ON_SNI } from "./lib/constants.js";
import { notifyWebhook } from "./lib/helpers.js";

Expand All @@ -13,7 +13,7 @@ const wirefilterDNSExpression = lists.reduce((previous, current) => {

console.log("Creating DNS rule...");
// .slice removes the trailing ' or '
await createZeroTrustRule(wirefilterDNSExpression.slice(0, -4), "CGPS Filter Lists", ["dns"]);
await upsertZeroTrustRule(wirefilterDNSExpression.slice(0, -4), "CGPS Filter Lists", ["dns"]);

// Optionally create a rule that matches the SNI.
// This only works for users who proxy their traffic through Cloudflare.
Expand All @@ -26,7 +26,7 @@ if (BLOCK_BASED_ON_SNI) {

console.log("Creating SNI rule...");
// .slice removes the trailing ' or '
await createZeroTrustRule(wirefilterSNIExpression.slice(0, -4), "CGPS Filter Lists - SNI Based Filtering", ["l4"]);
await upsertZeroTrustRule(wirefilterSNIExpression.slice(0, -4), "CGPS Filter Lists - SNI Based Filtering", ["l4"]);
}

// Send a notification to the webhook
Expand Down
54 changes: 53 additions & 1 deletion lib/api.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BLOCK_PAGE_ENABLED, LIST_ITEM_SIZE } from "./constants.js";
import { BLOCK_PAGE_ENABLED, DEBUG, LIST_ITEM_SIZE } from "./constants.js";
import { requestGateway } from "./helpers.js";

/**
Expand Down Expand Up @@ -140,6 +140,25 @@ export const deleteZeroTrustListsAtOnce = async (lists) => {
export const getZeroTrustRules = () =>
requestGateway("/rules", { method: "GET" });

/**
* Upserts a Zero Trust rule.
* If a rule with the same name exists, will update it. Otherwise create a new rule.
* @param {string} wirefilterExpression The expression to be used for the rule.
* @param {string} name The name of the rule.
* @param {string[]} filters The filters to be used for the rule. Default is ["dns"]. Possible values are ["dns", "http", "l4", "egress"].
* @returns {Promise<Object>}
*/
export const upsertZeroTrustRule = async (wirefilterExpression, name = "CGPS Filter Lists", filters = ["dns"]) => {
const { result: existingRules} = await getZeroTrustRules();
const existingRule = existingRules.find(rule => rule.name === name);
if (existingRule) {
if (DEBUG) console.log(`Found "${existingRule.name}" in rules, updating...`);
return updateZeroTrustRule(existingRule.id, wirefilterExpression, name, filters);
}
if (DEBUG) console.log(`No existing rule named "${existingRule.name}", creating...`);
return createZeroTrustRule(wirefilterExpression, name, filters);
}

/**
* Creates a Zero Trust rule.
*
Expand Down Expand Up @@ -172,6 +191,39 @@ export const createZeroTrustRule = async (wirefilterExpression, name = "CGPS Fil
}
};

/**
* Updates a Zero Trust rule.
*
* API docs: https://developers.cloudflare.com/api/operations/zero-trust-gateway-rules-update-zero-trust-gateway-rule
* @param {number} id The ID of the rule to be updated.
* @param {string} wirefilterExpression The expression to be used for the rule.
* @param {string} name The name of the rule.
* @param {string[]} filters The filters to be used for the rule.
* @returns {Promise<Object>}
*/
export const updateZeroTrustRule = async (id, wirefilterExpression, name = "CGPS Filter Lists", filters = ["dns"]) => {
try {
await requestGateway(`/rules/${id}`, {
method: "PUT",
body: JSON.stringify({
// Name and action are required fields, even if they haven't changed.
// And enabled must always be set to true, otherwise the rule will be disabled if omitted.
name,
action: "block",
enabled: true,
rule_settings: { "block_page_enabled": BLOCK_PAGE_ENABLED, "block_reason": "Blocked by CGPS, check your filter lists if this was a mistake." },
filters,
traffic: wirefilterExpression,
}),
});

console.log("Updated existing rule successfully");
} catch (err) {
console.error(`Error occurred while updating rule - ${err.toString()}`);
throw err;
}
};

/**
* Deletes a Zero Trust rule.
*
Expand Down

0 comments on commit 17b34b6

Please sign in to comment.