Skip to content

Commit

Permalink
prefilter: do not resolve undelegated domains
Browse files Browse the repository at this point in the history
  • Loading branch information
ignoramous committed Nov 10, 2022
1 parent f0cd10c commit 74498e3
Show file tree
Hide file tree
Showing 5 changed files with 314 additions and 6 deletions.
62 changes: 61 additions & 1 deletion src/core/io-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,32 @@ export default class IOState {
}
}

dnsNxDomainResponse() {
this.initDecodedDnsPacketIfNeeded();
this.stopProcessing = true;
this.isDnsBlock = true;

try {
this.assignNxDomainResponse();
const b = dnsutil.encode(this.decodedDnsPacket);
this.httpResponse = new Response(b, {
headers: this.headers(b),
});
} catch (e) {
this.log.e("nxdomain", JSON.stringify(this.decodedDnsPacket), e.stack);
this.isException = true;
this.exceptionStack = e.stack;
this.exceptionFrom = "IOState:dnsNxDomainResponse";
this.httpResponse = new Response(null, {
headers: util.concatHeaders(
this.headers(),
this.additionalHeader(JSON.stringify(this.exceptionStack))
),
status: 503,
});
}
}

headers(b = null) {
const xNileFlags = this.isDnsBlock ? { "x-nile-flags": this.flag } : null;
const xNileFlagsOk = !xNileFlags ? { "x-nile-flags-dn": this.flag } : null;
Expand Down Expand Up @@ -202,14 +228,48 @@ export default class IOState {
return done;
}

// builds nxdomain response only for undelegated domains
// like .internal / .local .lan
assignNxDomainResponse() {
if (util.emptyObj(this.decodedDnsPacket.questions)) {
this.log.e("decoded dns-packet missing question");
return false;
}

this.decodedDnsPacket.type = "response";
this.decodedDnsPacket.rcode = "NXDOMAIN";
// TODO: what is flag(387) 0b_0_000_0000_1100_00011?
this.decodedDnsPacket.flags = 387;
this.decodedDnsPacket.flag_qr = true;
this.decodedDnsPacket.answers = [];
this.decodedDnsPacket.authorities = [
{
name: ".",
type: "SOA",
ttl: 86400,
class: "IN",
flush: false,
data: {
mname: "a.root-servers.net",
rname: "nstld.verisign-grs.com",
serial: 2022111001,
refresh: 1800,
retry: 900,
expire: 604800,
minimum: 86400,
},
},
];
}

initFlagsAndAnswers(ttlsec = 300) {
if (util.emptyObj(this.decodedDnsPacket.questions)) {
this.log.e("decoded dns-packet missing question");
return false;
}
this.decodedDnsPacket.type = "response";
this.decodedDnsPacket.rcode = "NOERROR";
// TODO: what is flag(384) 0b_0000_0000_1100_0000?
// TODO: what is flag(384) 0b0_0000_0000_1100_0000?
this.decodedDnsPacket.flags = 384;
this.decodedDnsPacket.flag_qr = true;
this.decodedDnsPacket.answers = [];
Expand Down
34 changes: 34 additions & 0 deletions src/core/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import * as bufutil from "../commons/bufutil.js";
import * as dnsutil from "../commons/dnsutil.js";
import * as envutil from "../commons/envutil.js";
import * as util from "../commons/util.js";
import IOState from "./io-state.js";

export default class RethinkPlugin {
/**
Expand Down Expand Up @@ -49,6 +50,14 @@ export default class RethinkPlugin {
false
);

this.registerPlugin(
"prefilter",
services.prefilter,
["rxid", "requestDecodedDnsPacket"],
this.prefilterCallBack,
false
);

this.registerPlugin(
"cacheOnlyResolver",
services.dnsCacheHandler,
Expand Down Expand Up @@ -173,6 +182,27 @@ export default class RethinkPlugin {
}
}

/**
* @param {Response} response
* @param {IOState} io
*/
prefilterCallBack(response, io) {
const rxid = this.parameter.get("rxid");
const r = response.data;
const deny = r.isBlocked;
const err = response.isException;
this.log.d(rxid, "prefilter deny?", deny, "err?", err);

if (err) {
this.log.w(rxid, "prefilter: error", r);
this.loadException(rxid, response, io);
} else if (deny) {
io.dnsNxDomainResponse(r.flag);
} else {
this.log.d(rxid, "prefilter no-op");
}
}

dnsCacheCallBack(response, io) {
const rxid = this.parameter.get("rxid");
const r = response.data;
Expand Down Expand Up @@ -232,6 +262,10 @@ export default class RethinkPlugin {
io.dnsExceptionResponse(response);
}

/**
* @param {IOState} io
* @returns
*/
async initIoState(io) {
this.io = io;

Expand Down
6 changes: 6 additions & 0 deletions src/core/svc.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { BlocklistWrapper } from "../plugins/rethinkdns/main.js";
import { CommandControl } from "../plugins/command-control/cc.js";
import { UserOp } from "../plugins/users/user-op.js";
import {
DNSPrefilter,
DNSCacheResponder,
DNSResolver,
DnsCache,
Expand Down Expand Up @@ -39,6 +40,10 @@ export const services = {
* @type {?UserOp} userOp
*/
userOp: null,
/**
* @type {?DNSPrefilter} prefilter
*/
prefilter: null,
/**
* @type {?CommandControl} commandControl
*/
Expand Down Expand Up @@ -70,6 +75,7 @@ async function systemReady() {

services.blocklistWrapper = bw;
services.userOp = new UserOp();
services.prefilter = new DNSPrefilter();
services.dnsCacheHandler = new DNSCacheResponder(bw, cache);
services.commandControl = new CommandControl(bw);
services.dnsResolver = new DNSResolver(bw, cache);
Expand Down
8 changes: 3 additions & 5 deletions src/plugins/cache-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function determineCacheExpiry(packet) {
let ttl = someVeryHighTtl;

// TODO: nxdomain ttls are in the authority section
// FIXME: OPT answers do not have a ttl field
// TODO: OPT answers need not set a ttl field
// set min(ttl) among all answers, but at least minTtlSec
for (const a of packet.answers) ttl = Math.min(a.ttl || minTtlSec, ttl);

Expand Down Expand Up @@ -91,10 +91,8 @@ function makeId(packet) {
// multiple questions are kind of an undefined behaviour
// stackoverflow.com/a/55093896
if (!dnsutil.hasSingleQuestion(packet)) return null;

const name = dnsutil.normalizeName(packet.questions[0].name);
const type = packet.questions[0].type;
return name + ":" + type;
const q = packet.questions[0];
return dnsutil.normalizeName(q.name) + ":" + q.type;
}

export function makeLocalCacheValue(b, metadata) {
Expand Down
Loading

0 comments on commit 74498e3

Please sign in to comment.