Skip to content

Instantly share code, notes, and snippets.

@johannrichard
Last active November 20, 2021 15:11
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save johannrichard/f2a26f9f14d85a7e06ce1b2751443413 to your computer and use it in GitHub Desktop.
Save johannrichard/f2a26f9f14d85a7e06ce1b2751443413 to your computer and use it in GitHub Desktop.
Serverless Worker Function for ASN prefix parsing for OPNsense and pfSense
/***
* Worker Function for ASN prefix parsing
* Will query the BigIP API for a given ASN and return a plain-text representation of the ASN prefixes
* (IP ranges) that can be used in either OPNsense or pfSense URL Tables (Firewall alias).
*
* See https://docs.opnsense.org/manual/aliases.html (OPNsense) and https://docs.netgate.com/pfsense/en/latest/firewall/aliases.html (pfSense) for details of their use.
*
* You can deploy this worker for example on the free tier of CloudFlare (Up to 100'000 requests a day) or
* any other serverless platform that supports JavaScript
*
* See https://workers.cloudflare.com/
*
* Inspired by http://asn.blawk.net/
* Use: https://my-asn-worker.example.com/?asn=2906
*/
async function handleRequest(request) {
const init = {
headers: {
'content-type': 'text/plain;charset=UTF-8',
},
}
const url = request.url
const bgpViewUrl = "https://api.bgpview.io/asn/" // API: https://bgpview.docs.apiary.io/
// Function to parse query strings
function getParameterByName(name) {
name = name.replace(/[\[\]]/g, '\\$&')
name = name.replace(/\//g, '')
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
results = regex.exec(url)
if (!results) return null
else if (!results[2]) return ''
else if (results[2]) {
results[2] = results[2].replace(/\//g, '')
}
return decodeURIComponent(results[2].replace(/\+/g, ' '));
}
// Usage example
var asn = getParameterByName('asn')
if(asn) {
const response = await fetch(bgpViewUrl + asn + "/prefixes", init);
const results = await gatherResponse(response);
if(results.status == "ok" ) {
var prefixes = "; BGP View Sources list of ASN prefixes\n; https://bgpview.io\n; Generated by CloudFlare Worker " + url + "\n; Last-Modified: " + new Date();
results.data.ipv4_prefixes.forEach(obj => {
prefixes = prefixes + "\n" + obj.prefix + " ; " + obj.description + "(" + obj.country_code + ")"
});
return new Response(prefixes, init)
} else {
return new Response("ASN Prefix Error.\nPlease verify your ASN is correct.\nParsed ASN: " + asn, {status: 500})
}
} else {
return new Response('', init)
}
}
addEventListener('fetch', event => {
return event.respondWith(handleRequest(event.request))
})
/**
* gatherResponse awaits and returns a response body as a string.
* Use await gatherResponse(..) in an async function to get the response body
* @param {Response} response
*/
async function gatherResponse(response) {
const { headers } = response
const contentType = headers.get('content-type')
if (contentType.includes('application/json')) {
return await response.json()
} else if (contentType.includes('application/text')) {
return await response.text()
} else if (contentType.includes('text/html')) {
return await response.text()
} else {
return await response.text()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment