forked from serverless-dns/serverless-dns
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge @serverless-dns/dns-operation#v2.3.29
This also bumps this dep. for deno from v2.3.21.
- Loading branch information
Showing
15 changed files
with
1,239 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
{ | ||
"imports": { | ||
"@serverless-dns/dns-operation": "https://github.com/serverless-dns/dns-blocker/raw/v2.3.21/dnsOperation.js", | ||
"@serverless-dns/dns-parser": "https://github.com/serverless-dns/dns-parser/raw/v2.1.1/index.js", | ||
"@serverless-dns/lfu-cache": "https://github.com/serverless-dns/lfu-cache/raw/v2.0.6/lfu.js", | ||
"buffer": "https://deno.land/[email protected]/node/buffer.ts", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
This is a rethink plugin repository for rethink serverless dns. | ||
1. Dns resolver plugin | ||
This plugin forwards dns request to upstream resolver which is configurable at worker's environment variable. | ||
2. Dns block plugin | ||
This plugin checks for requested domain should be blocked or further process to upstream resolver. | ||
3. Dns cname block plugin | ||
This plugin checks whether dns response from upstream resolver should be blocked or send back to user. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
/* | ||
* Copyright (c) 2021 RethinkDNS and its authors. | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
import DNSParserWrap from "./dnsParserWrap.js"; | ||
import DNSBlockOperation from "./dnsBlockOperation.js"; | ||
import { BlocklistFilter } from "../blocklist-wrapper/blocklistWrapper.js"; | ||
let debug = false; | ||
export default class DNSAggCache { | ||
constructor() { | ||
this.dnsParser = new DNSParserWrap(); | ||
this.dnsBlockOperation = new DNSBlockOperation(); | ||
this.blocklistFilter = new BlocklistFilter(); | ||
this.wCache = null; | ||
} | ||
/** | ||
* @param {*} param | ||
* @param {*} param.userBlocklistInfo | ||
* @param {*} param.request | ||
* @param {*} param.requestBodyBuffer | ||
* @param {*} param.isAggCacheReq | ||
* @param {*} param.isDnsMsg | ||
* @returns | ||
*/ | ||
async RethinkModule(param) { | ||
let response = {}; | ||
response.isException = false; | ||
response.exceptionStack = ""; | ||
response.exceptionFrom = ""; | ||
response.data = null; | ||
try { | ||
if (!param.isDnsMsg) { | ||
return response; | ||
} | ||
response.data = await this.aggCache(param); | ||
} catch (e) { | ||
response.isException = true; | ||
response.exceptionStack = e.stack; | ||
response.exceptionFrom = "DNSAggCache RethinkModule"; | ||
console.error("Error At : DNSAggCache -> RethinkModule"); | ||
console.error(e.stack); | ||
} | ||
return response; | ||
} | ||
|
||
async aggCache(param) { | ||
let response = {}; | ||
response.reqDecodedDnsPacket = this.dnsParser.Decode( | ||
param.requestBodyBuffer, | ||
); | ||
response.aggCacheResponse = {}; | ||
response.aggCacheResponse.type = "none"; | ||
|
||
if (param.isAggCacheReq && this.wCache === null) { | ||
this.wCache = caches.default; | ||
} | ||
|
||
if (param.isAggCacheReq) { | ||
const dn = (response.reqDecodedDnsPacket.questions.length > 0 | ||
? response.reqDecodedDnsPacket.questions[0].name | ||
: "").trim().toLowerCase() + | ||
":" + response.reqDecodedDnsPacket.questions[0].type; | ||
let cacheResponse = await getCacheapi(this.wCache, param.request.url, dn); | ||
if (debug) { | ||
console.log("Cache Api Response"); | ||
console.log(cacheResponse); | ||
} | ||
if (cacheResponse) { | ||
response.aggCacheResponse = await parseCacheapiResponse( | ||
cacheResponse, | ||
this.dnsParser, | ||
this.dnsBlockOperation, | ||
this.blocklistFilter, | ||
param.userBlocklistInfo, | ||
response.reqDecodedDnsPacket, | ||
); | ||
} | ||
} | ||
return response; | ||
} | ||
} | ||
async function parseCacheapiResponse( | ||
cacheResponse, | ||
dnsParser, | ||
dnsBlockOperation, | ||
blocklistFilter, | ||
userBlocklistInfo, | ||
reqDecodedDnsPacket, | ||
) { | ||
let response = {}; | ||
response.type = "none"; | ||
response.data = {}; | ||
let metaData = JSON.parse(cacheResponse.headers.get("x-rethink-metadata")); | ||
|
||
if (debug) { | ||
console.log("Response Found at CacheApi"); | ||
console.log(JSON.stringify(metaData)); | ||
} | ||
//check whether incoming request should be blocked by blocklist filter | ||
if ( | ||
(reqDecodedDnsPacket.questions[0].type == "A" || | ||
reqDecodedDnsPacket.questions[0].type == "AAAA" || | ||
reqDecodedDnsPacket.questions[0].type == "CNAME" || | ||
reqDecodedDnsPacket.questions[0].type == "HTTPS" || | ||
reqDecodedDnsPacket.questions[0].type == "SVCB") && | ||
metaData.blocklistInfo && | ||
userBlocklistInfo.userBlocklistFlagUint !== "" | ||
) { | ||
metaData.blocklistInfo = new Map(Object.entries(metaData.blocklistInfo)); | ||
let blockResponse = dnsBlockOperation.checkDomainBlocking( | ||
userBlocklistInfo.userBlocklistFlagUint, | ||
userBlocklistInfo.userServiceListUint, | ||
userBlocklistInfo.flagVersion, | ||
metaData.blocklistInfo, | ||
blocklistFilter, | ||
reqDecodedDnsPacket.questions[0].name.trim().toLowerCase(), | ||
); | ||
if (blockResponse.isBlocked) { | ||
response.type = "blocked"; | ||
response.data = blockResponse; | ||
return response; | ||
} | ||
} | ||
if (metaData.bodyUsed) { | ||
const now = Date.now(); | ||
if (now <= (metaData.ttlEndTime)) { | ||
response.type = "response"; | ||
response.data.decodedDnsPacket = dnsParser.Decode( | ||
await cacheResponse.arrayBuffer(), | ||
); | ||
const outttl = Math.max( | ||
Math.floor((metaData.ttlEndTime - now) / 1000), | ||
1, | ||
); // to verify ttl is not set to 0sec | ||
for (let answer of response.data.decodedDnsPacket.answers) { | ||
answer.ttl = outttl; | ||
} | ||
response.data.bodyBuffer = dnsParser.Encode( | ||
response.data.decodedDnsPacket, | ||
); | ||
} | ||
} | ||
|
||
return response; | ||
} | ||
|
||
async function getCacheapi(wCache, reqUrl, key) { | ||
let wCacheUrl = new URL((new URL(reqUrl)).origin + "/" + key); | ||
return await wCache.match(wCacheUrl); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* | ||
* Copyright (c) 2021 RethinkDNS and its authors. | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
import DNSParserWrap from "./dnsParserWrap.js"; | ||
import DNSBlockOperation from "./dnsBlockOperation.js"; | ||
|
||
export default class DNSBlock { | ||
constructor() { | ||
this.dnsParser = new DNSParserWrap(); | ||
this.dnsBlockOperation = new DNSBlockOperation(); | ||
this.wCache = null; | ||
} | ||
/** | ||
* @param {*} param | ||
* @param {*} param.userBlocklistInfo | ||
* @param {*} param.blocklistFilter | ||
* @param {*} param.requestDecodedDnsPacket | ||
* @param {*} param.isAggCacheReq | ||
* @param {*} param.event | ||
* @param {*} param.request | ||
* @returns | ||
*/ | ||
async RethinkModule(param) { | ||
let response = {}; | ||
response.isException = false; | ||
response.exceptionStack = ""; | ||
response.exceptionFrom = ""; | ||
response.data = {}; | ||
response.data.isBlocked = false; | ||
response.data.blockedB64Flag = ""; | ||
try { | ||
if (param.userBlocklistInfo.userBlocklistFlagUint.length !== "") { | ||
let domainNameBlocklistInfo; | ||
// FIXME: handle HTTPS/SVCB | ||
if ( | ||
(param.requestDecodedDnsPacket.questions.length >= 1) && | ||
(param.requestDecodedDnsPacket.questions[0].type == "A" || | ||
param.requestDecodedDnsPacket.questions[0].type == "AAAA" || | ||
param.requestDecodedDnsPacket.questions[0].type == "CNAME" || | ||
param.requestDecodedDnsPacket.questions[0].type == "HTTPS" || | ||
param.requestDecodedDnsPacket.questions[0].type == "SVCB") | ||
) { | ||
domainNameBlocklistInfo = param.blocklistFilter.getDomainInfo( | ||
param.requestDecodedDnsPacket.questions[0].name, | ||
); | ||
if (domainNameBlocklistInfo.searchResult) { | ||
response.data = this.dnsBlockOperation.checkDomainBlocking( | ||
param.userBlocklistInfo.userBlocklistFlagUint, | ||
param.userBlocklistInfo.userServiceListUint, | ||
param.userBlocklistInfo.flagVersion, | ||
domainNameBlocklistInfo.searchResult, | ||
param.blocklistFilter, | ||
param.requestDecodedDnsPacket.questions[0].name, | ||
); | ||
if (response.data.isBlocked && param.isAggCacheReq) { | ||
if (this.wCache === null) { | ||
this.wCache = caches.default; | ||
} | ||
toCacheApi(param, this.wCache, domainNameBlocklistInfo); | ||
} | ||
} | ||
} | ||
} | ||
} catch (e) { | ||
response.isException = true; | ||
response.exceptionStack = e.stack; | ||
response.exceptionFrom = "DNSBlock RethinkModule"; | ||
console.error("Error At : DNSBlock -> RethinkModule"); | ||
console.error(e.stack); | ||
} | ||
return response; | ||
} | ||
} | ||
|
||
function toCacheApi(param, wCache, domainNameBlocklistInfo) { | ||
const dn = | ||
param.requestDecodedDnsPacket.questions[0].name.trim().toLowerCase() + ":" + | ||
param.requestDecodedDnsPacket.questions[0].type; | ||
let wCacheUrl = new URL((new URL(param.request.url)).origin + "/" + dn); | ||
let response = new Response("", { | ||
headers: { | ||
"x-rethink-metadata": JSON.stringify({ | ||
ttlEndTime: 0, | ||
bodyUsed: false, | ||
blocklistInfo: Object.fromEntries(domainNameBlocklistInfo.searchResult), | ||
}), | ||
}, | ||
cf: { cacheTtl: 604800 }, //setting ttl to 7days 60*60*24*7 | ||
}); | ||
param.event.waitUntil(wCache.put(wCacheUrl, response)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* | ||
* Copyright (c) 2021 RethinkDNS and its authors. | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
export default class DNSBlockOperation { | ||
checkDomainBlocking( | ||
userBlocklistFlagUint, | ||
userServiceListUint, | ||
flagVersion, | ||
blocklistMap, | ||
blocklistFilter, | ||
domainName, | ||
) { | ||
let response; | ||
try { | ||
response = checkDomainNameUserFlagIntersection( | ||
userBlocklistFlagUint, | ||
flagVersion, | ||
blocklistMap, | ||
blocklistFilter, | ||
domainName, | ||
); | ||
if (response.isBlocked) { | ||
return response; | ||
} | ||
|
||
if (userServiceListUint) { | ||
let dnSplit = domainName.split("."); | ||
let dnJoin = ""; | ||
let wildCardResponse; | ||
while (dnSplit.shift() != undefined) { | ||
dnJoin = dnSplit.join("."); | ||
wildCardResponse = checkDomainNameUserFlagIntersection( | ||
userServiceListUint, | ||
flagVersion, | ||
blocklistMap, | ||
blocklistFilter, | ||
dnJoin, | ||
); | ||
if (wildCardResponse.isBlocked) { | ||
return wildCardResponse; | ||
} | ||
} | ||
} | ||
} catch (e) { | ||
throw e; | ||
} | ||
|
||
return response; | ||
} | ||
} | ||
|
||
function checkDomainNameUserFlagIntersection( | ||
userBlocklistFlagUint, | ||
flagVersion, | ||
blocklistMap, | ||
blocklistFilter, | ||
domainName, | ||
) { | ||
let response = {}; | ||
try { | ||
response.isBlocked = false; | ||
response.blockedB64Flag = ""; | ||
response.blockedTag = []; | ||
if (blocklistMap.has(domainName)) { | ||
let domainNameInBlocklistUint = blocklistMap.get(domainName); | ||
let blockedUint = blocklistFilter.flagIntersection( | ||
userBlocklistFlagUint, | ||
domainNameInBlocklistUint, | ||
); | ||
if (blockedUint) { | ||
response.isBlocked = true; | ||
response.blockedB64Flag = blocklistFilter.getB64FlagFromUint16( | ||
blockedUint, | ||
flagVersion, | ||
); | ||
} else { | ||
blockedUint = new Uint16Array(domainNameInBlocklistUint); | ||
response.blockedB64Flag = blocklistFilter.getB64FlagFromUint16( | ||
blockedUint, | ||
flagVersion, | ||
); | ||
} | ||
//response.blockedTag = blocklistFilter.getTag(blockedUint); | ||
} | ||
} catch (e) { | ||
throw e; | ||
} | ||
return response; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* Copyright (c) 2021 RethinkDNS and its authors. | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
import DNSParserWrap from "./dnsParserWrap.js"; | ||
import DNSBlock from "./dnsBlock.js"; | ||
import DNSResponseBlock from "./dnsResponseBlock.js"; | ||
import DNSResolver from "./dnsResolver.js"; | ||
import DNSBlockOperation from "./dnsBlockOperation.js" | ||
import DNSAggCache from "./dnsAggCache.js" | ||
export { DNSBlock, DNSParserWrap, DNSResolver, DNSResponseBlock, DNSBlockOperation, DNSAggCache }; |
Oops, something went wrong.