Skip to content

Instantly share code, notes, and snippets.

@shagamemnon
Last active January 8, 2021 07:38
Show Gist options
  • Save shagamemnon/5f8506a40be2fc37a3328cef02bac9c9 to your computer and use it in GitHub Desktop.
Save shagamemnon/5f8506a40be2fc37a3328cef02bac9c9 to your computer and use it in GitHub Desktop.
## Sample / prototype Worker snippet for bot management + KV + rate limiting
### Requires:
* Wrangler (https://github.com/cloudflare/wrangler)
* API key with Workers, and Workers KV write Permissions
```js
const CIDR = require('cidr-js')
const cidr = new CIDR()
/*
* Keys will be returned as JSON objects in the following format:
* { "35.245.72.112": "customer" }
*/
const NAMESPACE = EJP_CUSTOMER_DB
const API_TOKEN = 'c2547eb745079dac9320b638f5e225cf483cc5cfdda41'
addEventListener('fetch', event =>
event.respondWith(handleRequest(event.request)),
)
async function handleRequest (request) {
if (request.url.endsWith('admin')) {
return updateCustomerList(request)
}
return inspectRequest(request)
}
/* Tests requests against KV store, and add response headers accordingly */
async function inspectRequest (request) {
let opts = {
botManagement: {
score: 100,
},
ip: '0.0.0.0',
}
let response
try {
if (request.cf) {
opts.botManagement = request.cf.botManagement
}
if (request.headers.has('cf-connecting-ip')) {
opts.ip = request.headers.get('cf-connecting-ip')
}
response = await fetch(request)
/* example response from KV { "35.245.72.112": "customer" } */
let isVerifiedCustomerIp = await NAMESPACE.get(opts.ip)
response = new Response(response.body, response)
if (isVerifiedCustomerIp || score > 50) {
response.headers.set('x-ejp-status', 'clean')
} else {
response.headers.set('x-ejp-status', 'suspicious')
}
} catch (e) {
response = await fetch(request)
response = new Response(response.body, response)
response.headers.set('x-workers-err', e.toString())
}
return response
}
/* TODO: Finish interface for adding and removing customers from KV */
async function updateCustomerList (request) {
let body = await request.text()
let ips = cidr.list(body)
for (let i = 0; i < ips.length; i++) {
ips[i] = {
key: ips[i],
value: 'customer',
}
}
return fetch(
'https://api.cloudflare.com/client/v4/accounts/:account_identifier/storage/kv/namespaces/:namespace_identifier/bulk',
{
method: 'PUT',
headers: {
Authorization: 'c2547eb745079dac9320b638f5e225cf483cc5cfdda41',
'Content-Type': 'application/json',
},
body: JSON.stringify(ips),
},
)
}
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment