Hacker News new | ask | show | jobs
by gregmac 1880 days ago
At work we have a service built on powerdns-backend (http). The biggest pain there was lack of docs. There's circumstances where powerdns would make multiple requests to the backend app server, and figuring out how to answer its first direct queries in a way to satisfy it on the first query took some trial and error (this was a few years ago, so I don't remember specifics). I seem to remember it asking the backend for ANY records and then a bunch of metadata stuff, which meant having to spend time understanding not just how to answer the simple DNS TXT and A queries we were trying to do, but understanding how powerdns would interpret the client query, pass it to the backend, and interpret the result (which was quite different from straight DNS).

That also made it really hard to test, short of setting up a full end-to-end integration test including running powerdns (which I think we have, but isn't fully automated).

If I was building that service again, I'd definitely have a serious look into building it directly as a standalone DNS server rather than a backend for something else.

1 comments

Hello! PowerDNS developer here. Did you spot https://doc.powerdns.com/authoritative/appendices/internals.... and https://doc.powerdns.com/authoritative/appendices/backend-wr... ?

And if not (or also if you did), can you suggest documentation additions that would have helped you here?

I think that page would have been incredibly useful, but doesn't look like it existed.

I was just looking through the source history of the project a bit as I wasn't the original developer (I've just done some fixes; most recently fixing some things going from 4.2 to 4.4). The original code was written in 2016, when the documentation was a lot more sparse [1]. Kudos for the improvements!

I just filed a PR [2] fixing the doc issues I ran into (probably should have done that at the time).

To enumerate some things I see right now (using remote http backend):

* pdns always queries /lookup/example.com./SOA, /getAllDomainMetadata/example.com. /lookup/example.com./ANY -- in my case that seems a bit wasteful: there's no metadata, and SOA is returned in the /ANY request anyway. I'm unclear if there's a misconfiguration, something we're doing wrong, or this is just "how it works".

* If I query `some.domain.example.com.` (and we aren't serving requests for any part of that), the backend returns `{result:false}` -- and then pdns proceeds to query `domain.example.com.`, `example.com.`, `com.`, and `.` before finally returning SERVFAIL. It would be nice if (1) it didn't have to run so many queries, but also (2) my understanding is the appropriate response should be REFUSED (as this is not a general DNS resolver) -- but I don't know how to get PowerDNS to do that.

That last bit is what I've found most frustrating about working with pdns: everything feels like "just do what pdns asks and it'll sort out what it wants to do as a result" and I can't just tell it "returned REFUSED for that query". Maybe some examples would help with this?

[1] https://web.archive.org/web/20170615183449/https://doc.power...

[2] https://github.com/PowerDNS/pdns/pull/10345

Hey, thanks for the PR, love that!

The wasteful SOA query is a result of our internal code flow. You can reduce wasteful queries a bit with the new `consistent-backends` setting, but the SOA query will remain.

We (no longer) have a knob to disable metadata, but there's a cache that should also remember your empty response (the default value for `domain-metadata-cache-ttl` is 60 seconds).

If you have a SOA for example.com, pdns will never return REFUSED for anything inside example.com. The zone is there, so an answer must be present - either a name with records, a name with no records for that type, or the name does not exist. (The distinction between the latter two is why you mostly see ANY queries instead of the type the client asked for).

As far as I can tell, you should never be returning 'false' to anything, as that indicates failure, which is different than 'I know I do not have what you are asking for'. Think of it like this: your SQL database does not go 'oh no' when it has zero rows for you; it just gives you zero rows. A pdns remote backend should behave the same. If you return 'empty' for those lookups into domains you have nothing for, instead of false, I expect REFUSED will come out instead of SERVFAIL.

(And, if I'm correct in the previous paragraph, your PR is correct too :-) )