Skip to content

Commit

Permalink
Merge @serverless-dns/dns-operation#v2.3.29
Browse files Browse the repository at this point in the history
This also bumps this dep. for deno from v2.3.21.
  • Loading branch information
amithm7 committed Dec 16, 2021
2 parents 1e3f9ca + a6ee180 commit dbd02b6
Show file tree
Hide file tree
Showing 15 changed files with 1,239 additions and 5 deletions.
1 change: 0 additions & 1 deletion import_map.json
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",
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
},
"homepage": "https://github.com/serverless-dns/serverless-dns#readme",
"dependencies": {
"@serverless-dns/dns-operation": "github:serverless-dns/dns-blocker#v2.3.29",
"@serverless-dns/dns-parser": "github:serverless-dns/dns-parser#v2.1.1",
"@serverless-dns/lfu-cache": "github:serverless-dns/lfu-cache#v2.0.6",
"dotenv": "^10.0.0",
Expand Down
2 changes: 1 addition & 1 deletion src/currentRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { DNSParserWrap as DnsParser } from "@serverless-dns/dns-operation";
import { DNSParserWrap as DnsParser } from "./dns-operation/dnsOperation.js";
import * as log from "./helpers/log.js";

export default class CurrentRequest {
Expand Down
373 changes: 373 additions & 0 deletions src/dns-operation/LICENSE

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions src/dns-operation/README.md
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.
154 changes: 154 additions & 0 deletions src/dns-operation/dnsAggCache.js
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);
}
96 changes: 96 additions & 0 deletions src/dns-operation/dnsBlock.js
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));
}
94 changes: 94 additions & 0 deletions src/dns-operation/dnsBlockOperation.js
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;
}
15 changes: 15 additions & 0 deletions src/dns-operation/dnsOperation.js
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 };
Loading

0 comments on commit dbd02b6

Please sign in to comment.