[wishlist] unbound vs djbdns

Hello list,

After having used DJB's dnscache for many years, I switched to Unbound.
Unbound works fine, but there's something I miss: djbdns' configuration
simplicity. Wouldn't it be nice if Unbound had dir like:

/etc/unbound/stub-zones/

in which one could easily:

echo "dns1.domain.tld" > /etc/unbound/stub-zones/subdomain.domain.tld

restart unbound and then all queries for "subdomain.domain.tld" are
forwarded to "dns1.domain.tld" (that's the way djbdns is working).

Now I need to enter:

stub-zone:
        name: "subdomain.domain.tld"
        stub-host: dns1.domain.tld

Into the config file. This is not so much work, but if there are many of
these entries...

Another question: I'd like to have a simple logfile which will show me:

<timestamp> <source> <query>

e.g.:

2011-06-13 21:25:54 10.0.0.3 www.example.com

This can be done by grep/sed/awk-ing the logfile, but I miss the source
address of the machine that is sending the query. Setting the verbosity
to something higher than "1" produces al lot of debug noise, but not
the address that is querying the resolver. Or did I miss something
crucial somewhere?

Just my 2 newbee cents,

R.

Then you just use a shell script to generate the config? I don't think
that unbound needs a feature which can be accomplished by simple shell
or awk script:

cd /etc/unbound/stub-zones;
for domain in *; do < $domain awk 'BEGIN { print "stub-zone:\n\tname:
\"'${domain}'\""; } { print "\tstub-host: \""$0"\""; } END { print "";
}'; done > /etc/unbound/stub-zones.conf

and add

include: "/etc/unbound/stub-zones.conf"

to your unbound.conf

O.

Hi Richard, Ondrej,

Hello list,

[...]
Into the config file. This is not so much work, but if there are many of
these entries...

Then you just use a shell script to generate the config? I don't think
that unbound needs a feature which can be accomplished by simple shell
or awk script:

cd /etc/unbound/stub-zones;
for domain in *; do < $domain awk 'BEGIN { print "stub-zone:\n\tname:
\"'${domain}'\""; } { print "\tstub-host: \""$0"\""; } END { print "";
}'; done > /etc/unbound/stub-zones.conf

and add

include: "/etc/unbound/stub-zones.conf"

to your unbound.conf

Yes, you can also do echo "stub-zone: name: $name stub-host: $svr" >>
/etc/unbound/stub-zones.conf and then include that file in
unbound.conf. So, it can be on one line without quotes (no spaces in
names) and that is a very simple shellscript line.

For the log file with queries have you thought about this:
tcpdump -i xl0 dst port domain and "(" dst host [your-resolver-IP] or
dst host [your-resolver-IP6] ")"
(and with -f or -m to make it print numerically, otherwise it will
perform (reverse) DNS lookups to log your DNS lookups ... )

tcpdump has options, but if you want more, then perhaps dnstop (tcpdump
with some nicer statistics output):
http://dns.measurement-factory.com/tools/dnstop/index.html (and there
are a lot of other tools).

Since you like to keep up, have you seen that unbound has a munin (and
cacti) plugin for statistics gathering?

Best regards,
   Wouter

For security reasons, you shouldn't really parse traffic on a production
system, though you could write the logfile and do so offline.

...which would be a good reason for unbound to do the logging itself. Unbound has already parsed the DNS packet, by necessity.

Could you elaborate? What does parsing offline buy you security wise
that a live system cannot? Privilege separation/dropping is straight
forward in the case of tcpdump/libpcap and input validation is
approximately /[a-z0-9_.]+/i and would be a problem in both the live and
offline case.

Another method is to physically decouple the collector from the parser.
Although traffic/cpu intensive, syslog'ing the output to another box
live and having it parsed (say via a syslog-ng pipe() destination) as it
appears would be perfectly feasible.

I personally would not use tcpdump and cook my own using libpcap and
probably learn how to use a DNS decoding library, but the problem space
is the same.

Cheers

Of course a simple shell script can do the job (I already did that),
but to get back to the original thing: I just suggested the the djbdns
system is simpler, so why not copy it? :wink: I now wrote a shell script
that converts the djbdns way to an include file. I did not say that
Unbound is broken or so, I just suggest that things can be done in a
simpler way :wink:

And as far as the source addresses in the logfiles are concerned: I
know I can use tcpdump, but is a source address in the logfiles not an
essential item? IMHO it is...

R.

...logging in the 'fast path', not advisable.

Plus assuming part of the reason you might be logging is to catch
unbound-kill packets, not great.

Using a specific logging/recording tool means it becomes independent on
the DNS server you use.

Cheers

What does parsing offline buy you security wise
that a live system cannot? Privilege separation/dropping is straight
forward in the case of tcpdump/libpcap and input validation is
approximately /[a-z0-9_.]+/i and would be a problem in both the live and
offline case.

I meant a seperate permanently offline machine, any exploit/attack has
almost nowhere to go. The point is, parsing online is not best
practice.

Another method is to physically decouple the collector from the parser.
Although traffic/cpu intensive, syslog'ing the output to another box
live and having it parsed (say via a syslog-ng pipe() destination) as it
appears would be perfectly feasible.

Yep and a one way cable as per snort.org would be best practice giving
realtime functionality and be safe though your parser and so logging
could potentially still be attacked or damaged/prevented. Though an
attacker would likely struggle to know he succeeded.

For the log file with queries have you thought about this:
tcpdump -i xl0 dst port domain and "(" dst host [your-resolver-IP] or
dst host [your-resolver-IP6] ")"

For security reasons, you shouldn't really parse traffic on a production
system, though you could write the logfile and do so offline.

...which would be a good reason for unbound to do the logging itself.
Unbound has already parsed the DNS packet, by necessity.

...logging in the 'fast path', not advisable.

Says who?

Bind 9 manages this just fine at our site, at excessively high loads.

Plus assuming part of the reason you might be logging is to catch
unbound-kill packets, not great.

I think it would be better to have packets no kill unbound personally...

Using a specific logging/recording tool means it becomes independent on
the DNS server you use.

It's also another bit of software to install, update, configure and manage. It's another independent DNS parser, which may or may not be as robust as the DNS parser in a high-volume recursive resolver. And it lacks access to internal resolver state, which the logging may or may not want to record e.g.

date name class type flags from-cache=yes|no

But hey - since unbound already doesn't log, you've got what you want, so why worry?

...logging in the 'fast path', not advisable.

Says who?

We all have our own rules-of-thumb that we have empirically built up
over the years, this just so happens to be one of mine.

Bind 9 manages this just fine at our site, at excessively high loads.

Curious, whats the ceiling PPS rate with and without logging?

Cheers

    > For security reasons, you shouldn't really parse traffic on a production
    > system, though you could write the logfile and do so offline.
    
    ...which would be a good reason for unbound to do the logging itself.
    Unbound has already parsed the DNS packet, by necessity.

I don't understand this logic. For "security reason" one should not parse
traffic on the production box, but it is OK that unbound
(that is in prduction on this box) does parse it?

Confused,

  jaap

Unbound has already parsed the DNS payload so the security reason is
probably moot at that point. I think $poster[-2] was hinting more
towards a seperate stat analysis tool might have insecurity woes and
that should not be run on the production box.

I prefer[1] to have a seperator collector daemon, Phil's preference is
to get unbound to do it as it argubly has already done 80% of the leg
work.

Cheers

[1] BIND9 was all the rage, then djbdns, now unbound, tomorrow?

Unbound is chrooted and has very limited parsing requirements. OpenBSD's
PF with no serious bugs at all and Snort which has had many serious
parsing bugs would be the extremes.

Bind 9 manages this just fine at our site, at excessively high loads.

But we know unbound is far quicker and more secure than bind, of course
so was djbs code.

>
> Plus assuming part of the reason you might be logging is to catch
> unbound-kill packets, not great.

I think it would be better to have packets no kill unbound personally...

What are these, do you mean dnssec dos. Googling hasn't turned
much up.

>
> Using a specific logging/recording tool means it becomes independent on
> the DNS server you use.

It's also another bit of software to install, update, configure and
manage. It's another independent DNS parser, which may or may not be as
robust as the DNS parser in a high-volume recursive resolver. And it
lacks access to internal resolver state, which the logging may or may
not want to record e.g.

I agree here, but I have a couple of thoughts ignoring performance which
as stated is why it won't happen.

It will likely be more secure than the tcpdump incarnation but will it
reduce security of unbound without tcpdump at all. Hardly I guess,
there's no deep packet inspection, but many have some sort of NOC
anyway.

     >
     > For security reasons, you shouldn't really parse traffic on a production
     > system, though you could write the logfile and do so offline.

     ...which would be a good reason for unbound to do the logging itself.
     Unbound has already parsed the DNS packet, by necessity.

I don't understand this logic. For "security reason" one should not parse
traffic on the production box, but it is OK that unbound

Someone else said "you shouldn't parse on a production box". I don't agree with that. What I'm saying is that...

(that is in prduction on this box) does parse it?

...since Unbound MUST parse the packet (obviously) and MUST be hardened against malformed DNS requests, there is no significant additional security risk in having unbound (optionally) perform the logging.

There *may* be a security risk in having a separate application doing the parsing and logging; it depends on how it's written, whether parsing DNS packets is it's primary goal, and so on. It seems pretty clear that tcpdump isn't the ideal tool.

Hello,

I also miss the logging feature.

I also know, I could "tcpdump --foo --voodoo".
But I do not want read tcpdump's interpretation of a dns packet.
I like to see what unbound thinks about it.

I also dislike running tcpdump as a parser with root privileges.
Yes, I could capture as root and parse as nobody, but that's not comfortable!

The suggested logging may be switched on/off via unbound-control.
So the "fast path" is less involved.

I simply want sometimes know, what questions a specific system
asks. Without voodoo ...

Anyway, as a postmaster, I would throw away any mailer which could not tell me
who is sending/receiving mail. And I would not using tcpdump.

As a webmaster, I would not use a webserver unable to to usual logging.
And also nobody uses tcpdump.

Why I am advised to do so as dnsmaster ?

For security reasons, you shouldn't really parse traffic on a production
system, though you could write the logfile and do so offline.

...which would be a good reason for unbound to do the logging itself.
Unbound has already parsed the DNS packet, by necessity.

+1

For security reasons, you shouldn't really parse traffic on a
production system, though you could write the logfile and do so
offline.
   
...which would be a good reason for unbound to do the logging
itself. Unbound has already parsed the DNS packet, by necessity.

I don't understand this logic. For "security reason" one should not
parse traffic on the production box, but it is OK that unbound (that
is in prduction on this box) does parse it?

Unbound has already parsed the DNS payload so the security reason is
probably moot at that point. I think $poster[-2] was hinting more
towards a seperate stat analysis tool might have insecurity woes and
that should not be run on the production box.

I prefer[1] to have a seperator collector daemon, Phil's preference is
to get unbound to do it as it argubly has already done 80% of the leg
work.

Can't we have unbound push logging information to a seperate process
or something like that which handles the logging (which does no parsing).

That is what djbdns with deamontools probably does too I would expect.

Hi Andreas,

Hello,

I also miss the logging feature.

Why I am advised to do so as dnsmaster ?

...which would be a good reason for unbound to do the logging itself.
Unbound has already parsed the DNS packet, by necessity.

+1

Once it has parsed the query, I could print it, the simplest way:
Jun 15 10:03:05 unbound[25547:0] info: ::1 <www.nlnetlabs.nl. A IN>
Jun 15 10:03:10 unbound[25547:0] info: ::1 <www.nlnetlabs.com. A IN>
Jun 15 10:03:12 unbound[25547:0] info: ::1 <www.nlnetlabs.com. MX IN>

Here I perform a couple of queries from ::1.

But it is very simple:
It would be printed for cache response and for non-cache-response.
It would not do escaping, weird characters become '?' (not \123).
It is logged to the regular log channel. (at LOG_INFO level).
I can change the format a little, remove the <>

Patch that does this is:
- --- daemon/worker.c (revision 2428)
+++ daemon/worker.c (working copy)
@@ -775,6 +775,11 @@
                server_stats_insrcode(&worker->stats, c->buffer);
                return 1;
        }
+ if(1) {
+ char ip[128];
+ addr_to_str(&repinfo->addr, repinfo->addrlen, ip,
sizeof(ip));
+ log_nametypeclass(0, ip, qinfo.qname, qinfo.qtype,
qinfo.qclass);
+ }
        if(qinfo.qtype == LDNS_RR_TYPE_AXFR ||
                qinfo.qtype == LDNS_RR_TYPE_IXFR) {
                verbose(VERB_ALGO, "worker request: refused zone
transfer.");

So, most of the work would be for the option to turn it on and off, and
the cost is again, the if statement that tests for this option. This
would be an if statement that is tested for every query, hence slowing
down when it is not turned on. Not sure if this is worth it.

Best regards,
   Wouter

Once it has parsed the query, I could print it, the simplest way:
Jun 15 10:03:05 unbound[25547:0] info: ::1 <www.nlnetlabs.nl. A IN>
Jun 15 10:03:10 unbound[25547:0] info: ::1 <www.nlnetlabs.com. A IN>
Jun 15 10:03:12 unbound[25547:0] info: ::1 <www.nlnetlabs.com. MX IN>

perfect!

It would be printed for cache response and for non-cache-response.

yep, I'll see queries!

It would not do escaping, weird characters become '?' (not \123).

most ot the time this information is enough.

It is logged to the regular log channel. (at LOG_INFO level).

in my case it's stderr connected to a circular buffer file in /dev/shm

Not sure if this is worth it.

I am. The fastest application is not usefull until one can see what's going on.

Thanks.
I will try the patch and report. But it may take some time ...
Andreas