Discussion:
[Dnsmasq-discuss] Feature request: allow to enable/disable --dnssec-check-unsigned per upstream server
Rene Bartsch
2014-08-29 07:59:27 UTC
Permalink
Hi,

I'm running Dnsmasq with DNSSEC-validation and "--dnssec-check-unsigned"
enabled. "server=/onion/127.0.0.1#9053" forwards .onion-queries to the
TOR-resolver. Unfortunately the TOR-resolver provides A-RRs only. So
resolving .onion-domains fails when "--dnssec-check-unsigned" is
enabled.

Please extend "--dnssec-check-unsigned" with an option for the server
address and port.

"dnssec-check-unsigned" would enable for all upstream servers.

"dnssec-check-unsigned=127.0.0.1#9053" would enable only for
127.0.0.1#9053.
--
Best regards,

Renne
Simon Kelley
2014-09-06 16:55:18 UTC
Permalink
Post by Rene Bartsch
Hi,
I'm running Dnsmasq with DNSSEC-validation and "--dnssec-check-unsigned"
enabled. "server=/onion/127.0.0.1#9053" forwards .onion-queries to the
TOR-resolver. Unfortunately the TOR-resolver provides A-RRs only. So
resolving .onion-domains fails when "--dnssec-check-unsigned" is enabled.
Please extend "--dnssec-check-unsigned" with an option for the server
address and port.
"dnssec-check-unsigned" would enable for all upstream servers.
"dnssec-check-unsigned=127.0.0.1#9053" would enable only for
127.0.0.1#9053.
This ties in with something I was considering, which is to be able to
disable DNSSEC checking for particular upstream servers. I guess it's
better to associate it with the the server than enable-dnssec or
dnssec-check-unsigned, so we could have

server-no-dnssec=/onion/127.0.0.1#9053

or

server-no-dnssec-unsigned=/onion/127.0.0.1#9053

What does the team think?

Cheers,

Simon.
Andre Heider
2016-01-08 14:18:01 UTC
Permalink
Hi,
Post by Simon Kelley
Post by Rene Bartsch
Hi,
I'm running Dnsmasq with DNSSEC-validation and "--dnssec-check-unsigned"
enabled. "server=/onion/127.0.0.1#9053" forwards .onion-queries to the
TOR-resolver. Unfortunately the TOR-resolver provides A-RRs only. So
resolving .onion-domains fails when "--dnssec-check-unsigned" is enabled.
Please extend "--dnssec-check-unsigned" with an option for the server
address and port.
"dnssec-check-unsigned" would enable for all upstream servers.
"dnssec-check-unsigned=127.0.0.1#9053" would enable only for
127.0.0.1#9053.
This ties in with something I was considering, which is to be able to
disable DNSSEC checking for particular upstream servers. I guess it's
better to associate it with the the server than enable-dnssec or
dnssec-check-unsigned, so we could have
server-no-dnssec=/onion/127.0.0.1#9053
or
server-no-dnssec-unsigned=/onion/127.0.0.1#9053
I just ran into this, was anything implemented to allow disabling
dnssec for selected servers?

Regards,
Andre
Simon Kelley
2016-01-09 18:25:04 UTC
Permalink
Hi,
On Sat, Sep 6, 2014 at 6:55 PM, Simon Kelley
Post by Simon Kelley
Post by Rene Bartsch
Hi,
I'm running Dnsmasq with DNSSEC-validation and
"--dnssec-check-unsigned" enabled.
"server=/onion/127.0.0.1#9053" forwards .onion-queries to the
TOR-resolver. Unfortunately the TOR-resolver provides A-RRs
only. So resolving .onion-domains fails when
"--dnssec-check-unsigned" is enabled.
Please extend "--dnssec-check-unsigned" with an option for the
server address and port.
"dnssec-check-unsigned" would enable for all upstream servers.
"dnssec-check-unsigned=127.0.0.1#9053" would enable only for
127.0.0.1#9053.
This ties in with something I was considering, which is to be
able to disable DNSSEC checking for particular upstream servers.
I guess it's better to associate it with the the server than
enable-dnssec or dnssec-check-unsigned, so we could have
server-no-dnssec=/onion/127.0.0.1#9053
or
server-no-dnssec-unsigned=/onion/127.0.0.1#9053
I just ran into this, was anything implemented to allow disabling
dnssec for selected servers?
Regards, Andre
No that one slipped though the net. Thinking about that some more,
there are likely fundamental problems with doing ant DNSSEC on
servers handling subdomains, since the chain-of-trust isn't going to wor
k.

EG. you run dnsmasq with

server=/example.com/<ip-of-server>

This is likely because that server knows about stuff under example.com
which is not known about by the "global" DNS server which dnsmasq is
forwarding to. Even if the example.com server is signing DNSSEC, it's
highly unlikely that dnsmasq will be able to validate its output,
since the chain-of-trust won't reach to it. If you're going to the
trouble of getting the DS record for example.com signed by the .com
administrators, then you may as well have them serve the delegation as
well, and make example.com globally visible.

It therefore makes sense to turn off DNSSEC validation for any domains
handled by such servers.

The next stage would be to turn it back on if there's a trust-anchor
supplied for the domain. That would allow DNS servers for private
domains to work with DNSSEC. Doing that is predicated on making the
dnsmasq validation code work with non-root trust anchors. I don't
think it does at the moment.

So, that's a plan.

1) disable validation when forwarding to servers for a domain.

and longer term

2) make non-root trust anchors work and turn it back on is one is
provided.


Comments?

Simon.
Andre Heider
2016-01-10 14:46:19 UTC
Permalink
Hi,
Post by Simon Kelley
No that one slipped though the net. Thinking about that some more,
there are likely fundamental problems with doing ant DNSSEC on
servers handling subdomains, since the chain-of-trust isn't going to wor
k.
EG. you run dnsmasq with
server=/example.com/<ip-of-server>
This is likely because that server knows about stuff under example.com
which is not known about by the "global" DNS server which dnsmasq is
forwarding to. Even if the example.com server is signing DNSSEC, it's
highly unlikely that dnsmasq will be able to validate its output,
since the chain-of-trust won't reach to it. If you're going to the
trouble of getting the DS record for example.com signed by the .com
administrators, then you may as well have them serve the delegation as
well, and make example.com globally visible.
It therefore makes sense to turn off DNSSEC validation for any domains
handled by such servers.
The next stage would be to turn it back on if there's a trust-anchor
supplied for the domain. That would allow DNS servers for private
domains to work with DNSSEC. Doing that is predicated on making the
dnsmasq validation code work with non-root trust anchors. I don't
think it does at the moment.
So, that's a plan.
1) disable validation when forwarding to servers for a domain.
and longer term
2) make non-root trust anchors work and turn it back on is one is
provided.
Comments?
It would be solving the .onion problem without the security issue of
disabling dnsseccheckunsigned.

But there are already non IANA TLDs using DNSSEC out there, like
opennic, see [0].

Right now I can make use of that, e.g. with their .free TLD:
* dig +tcp +multi +noall +answer DS free @5.9.49.12
* trust-anchor=free,<output from earlier step>
* server=/free/5.9.49.12

and make dnsmasq resolve e.g. reg.for.free with dnssec enabled (next
to all the IANA TLDs). Your plan would break that until 2) is
implemented.

Having that that, this example isn't a clear solution either. It
fishes out the .free DS record since it's the only way I could find to
tell dnsmasq about it (using the trust-anchor "domain" field).

Maybe "named" trust-anchors are the most flexible solution. Something like this:
* trust-anchor=iana,...
* trust-anchor=opennic,...
* server=x.x.x.x/iana
* server=/free/x.x.x.x/opennic
* server=/indy/x.x.x.x/opennic
* server=/onion/x.x.x.x/none

But whatever 2) will be, having 1) so we don't have to disable
dnsseccheckunsigned would be a first step.

Thanks,
Andre

[0] http://wiki.opennicproject.org/dnssecroot
Simon Kelley
2016-01-11 21:27:02 UTC
Permalink
Hi,
On Sat, Jan 9, 2016 at 7:25 PM, Simon Kelley
Post by Simon Kelley
No that one slipped though the net. Thinking about that some
more, there are likely fundamental problems with doing ant DNSSEC
on servers handling subdomains, since the chain-of-trust isn't
going to wor k.
EG. you run dnsmasq with
server=/example.com/<ip-of-server>
This is likely because that server knows about stuff under
example.com which is not known about by the "global" DNS server
which dnsmasq is forwarding to. Even if the example.com server is
signing DNSSEC, it's highly unlikely that dnsmasq will be able to
validate its output, since the chain-of-trust won't reach to it.
If you're going to the trouble of getting the DS record for
example.com signed by the .com administrators, then you may as
well have them serve the delegation as well, and make example.com
globally visible.
It therefore makes sense to turn off DNSSEC validation for any
domains handled by such servers.
The next stage would be to turn it back on if there's a
trust-anchor supplied for the domain. That would allow DNS
servers for private domains to work with DNSSEC. Doing that is
predicated on making the dnsmasq validation code work with
non-root trust anchors. I don't think it does at the moment.
So, that's a plan.
1) disable validation when forwarding to servers for a domain.
and longer term
2) make non-root trust anchors work and turn it back on is one
is provided.
Comments?
It would be solving the .onion problem without the security issue
of disabling dnsseccheckunsigned.
But there are already non IANA TLDs using DNSSEC out there, like
opennic, see [0].
Right now I can make use of that, e.g. with their .free TLD: * dig
trust-anchor=free,<output from earlier step> *
server=/free/5.9.49.12
and make dnsmasq resolve e.g. reg.for.free with dnssec enabled
(next to all the IANA TLDs). Your plan would break that until 2)
is implemented.
Having that that, this example isn't a clear solution either. It
fishes out the .free DS record since it's the only way I could find
to tell dnsmasq about it (using the trust-anchor "domain" field).
Maybe "named" trust-anchors are the most flexible solution.
Something like this: * trust-anchor=iana,... *
trust-anchor=opennic,... * server=x.x.x.x/iana *
server=/free/x.x.x.x/opennic * server=/indy/x.x.x.x/opennic *
server=/onion/x.x.x.x/none
But whatever 2) will be, having 1) so we don't have to disable
dnsseccheckunsigned would be a first step.
Thanks, Andre
[0] http://wiki.opennicproject.org/dnssecroot
Your opennic example is interesting. The opennic nameservers provide
an alternative root, and delegate all the IANA TLDs (or at least all
the ones which existed before ICANN started whoring them out to
whoever would pay.....) The solution, therefore is to send all the
queries to opennic, they'll get the answers from the conventional TLDs
and return them just fine.

The clever bit is that opennic has signed the root zone with their own
key - they have to to be able to add .free and friends, since the
ICANN private key isn't available to them. The Opennic website doesn't
provide this key in easy to use form, as far as I can see, but we can
easily get it.

dig @5.9.49.12 dnskey .

will us the key (actually three keys, two zone-signing keys and a key
signing key - that's the one we're interested in - it has flags field
== 257.

; <<>> DiG 9.9.5-3ubuntu0.6-Ubuntu <<>> @5.9.49.12 dnskey .
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35573
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;. IN DNSKEY

;; ANSWER SECTION:
. 86400 IN DNSKEY 256 3 8
AwEAAbBeOAxco/hOn+ENrbiIW8s4YMZXRGmNAx58Oy8PQBWSf9G5JDyQ
owOLQLQlrVX7S2qmtF8OOUgX3inM+IUm6g+Nbjh1fYrdFYHMKD+T13fw
aYT6gUJJKtLrfjznDfZ3+ViRoywd4riLA/xMR1+B+2lZqdCW1mN9z+7J
gsBJs5tuKqUaLLj89fF+80DPicbQyKm/VFsXIFve2foM0YiK9+x0QYS7
yYkpgMRd2OyCfpCMf8dipYnVWwxGIBtT8FE10///M+OAedCLfWyScqWV
xHnf6G3fH0+Lxh5Kp+xa7szf80wO7xAoMcRWctCq8DoKQZJ41MJhlIVe Xq7ng21lKws=
. 86400 IN DNSKEY 257 3 8
AwEAAe2SqWzJDU5l8IiTdWIEi4gG0fNGXzX3ISbU1a6JAsUPFl7rCWDe
9f5J67xGSAkbwS2doYzvPL72AmI077wFapBtNFCgUT4KruO+f0j0pO74
QFM6dFlIRbVJBUuTReRcikiqP8e1wWvLXd4PknSkAi6k+TQpl48YOEYC
rf1jqWqPTJVZuJlMMdYyHSXndRhN5QF7+kP7FmulpDhLCNLFVHWCXXxH
td6AgF6OyuTMr1iQd44tBz2e8sNK9qJ9fsCvF2iRRUlePh1q2WKzC6DG
J5PJgeHKefSE515+hdyBWhGId2u7yOTNMxcbAOq17KOmf/fct1nvlqOM
cLZ55oKPy0t9nU/niQaYhU0P+F8rmdyCkK29ri4hbBHgOO7INw2ElYxA
B/uihgC+7ErTkQg5iZiIrGvAMXIeV0tXsB+QNgAFqAHpuNjiyaXBnNkN
YUKKcnHr54lJ2grXXSIgK/et2vPgeQK9TWNX7yiLwRcE6Nw8jK0ZdpfO
ujGgVnvVfOtJaTVkT2qyXp0M3FSQG8Se0C0x17Pvu9Jrs44P6cDwcA5n
QPMjEZOyHdk+LeYrk41qhWubVF3D1MeJdxwgL8ZtW8Rk5J55SlQZU8cm
bd8cklpiRYA/60G++wvatfKQs24zB/rlC0yXKWZ/IuRGN/p96Fes8O+s YAWFOHq/kA43fpg
J
. 86400 IN DNSKEY 256 3 8
AwEAAa50Y7yGoWrBHwj8apK12S1bu/esUB/2XdWlJAxi5Ab8xKAaHX2g
m9UR9OKfu2rzVLrtFgye85EFQqkYswZNYySNMLFuifaCPE9uJcK6ygDa
gc5IP1OjGD27KT+xMLPl6zWjCcmyxIwoZpFJKnZ9RxMWViApKMSdohOK
hLMED8dRDDy665aS8xgvZm8bCl8g0eRTrMAq9jVovQ53uADWhZt/fIQK
iNfrKWLk8WeHmjP+mIVEKL6bRzzYI+mB7sQAAYz/fePFBMsbqBBLkMsJ
gQQBdum/b25w6Jf8FDkwpkcBHHziR4DGxyc/d5yQIXZCyeG0IEkCD1sx 98VGerH5CR8=

;; Query time: 906 msec
;; SERVER: 5.9.49.12#53(5.9.49.12)
;; WHEN: Mon Jan 11 21:08:36 GMT 2016
;; MSG SIZE rcvd: 1109

The trust anchor we need is not the key, it's a DS record, which is
simply a SHA1 or SHA256 hash of the key in question - all the
information needed is on the RRset above, but it needs to be
reformated. The following pipeline does it for BIND-format config

dig @5.9.49.12 dnskey . | dnssec-dsfromkey -2 -f - .

The -2 flag tells dsfromkey to make the SHA256 hash

. IN DS 7372 8 2
14A2B8CAF58BFAAE0BD7C257488A341FCC542F9F88F0B678D620324CE7B55285


A quick re-format into dnsmasq config format gives us

trust-anchor=.,7372,8,2,14A2B8CAF58BFAAE0BD7C257488A341FCC542F9F88F0B678
D620324CE7B55285


Putting that in the config file and _just_ using 5.9.49.12 (and other
opennic servers) gives DNSSEC for all domains fine.


I didn't verify that key out-of-band in any way. In theory there could
be a man-in-the-middle intercepting DNS queries from my network, and
substituting his own key so that I set up trust to it. It would be
good for opennic to publish their key widely, so it can be checked
rather than trusting an insecure DNS query. Even a web page would help
- - it's much more difficult to substitute a key buried in HTML that one
in a DNS packet.

Assuming that I have the genuine opennic key, I'm now trusting
opennic. They can give me bad data for _any_ domain if they wish, by
providing an alternative chain-of-trust to the data. Of course the
same is true for 99% of the internet who blindly trust their ISPs
recursive resolver because they're no doing DNSEC validation.

If you trust opennic more that ICANN is an interesting question: ICANN
does elaborate key ceremonies and hold the private key in multiple
HSMs spread around the world. Opennic, as far as I can see, keeps it
in a mode 700 directory on their master nameserver machine. Presumably
the NSA could take it any time they wanted, but the same is probably
true for the ICANN private key. It will take more effort, but it's
worth more....


Cheers,

Simon.
Andre Heider
2016-01-12 10:16:18 UTC
Permalink
Post by Simon Kelley
The -2 flag tells dsfromkey to make the SHA256 hash
. IN DS 7372 8 2
14A2B8CAF58BFAAE0BD7C257488A341FCC542F9F88F0B678D620324CE7B55285
A quick re-format into dnsmasq config format gives us
trust-anchor=.,7372,8,2,14A2B8CAF58BFAAE0BD7C257488A341FCC542F9F88F0B678
D620324CE7B55285
I knew it was just a hash, but I was too lazy to look up how to get it
into a compatible format :)
dnssec-dsfromkey is the solution, thanks for that info.

Thanks,
Andre
Simon Kelley
2016-01-14 20:25:32 UTC
Permalink
I've got the code I described into dnsmasq.

server=/domain/<ip-address>

now disables DNSSEC for queries sent to that server, unless there's
a corresponding

trust-anchor=domain,.......

That all seems to work well, I can delegate to opennic at the TLD-level,
rather than the root level.

I realised that there's a fundamental problem that all DNSSEC queries to
validate a query get send to the same server as the original query. That
would break, eg a domain under .free which held a CNAME to another TLD.
Fixing that needs some long-overdue code re-writing, which is now in
progress.


Cheers,

Simon.
Post by Andre Heider
Post by Simon Kelley
The -2 flag tells dsfromkey to make the SHA256 hash
. IN DS 7372 8 2
14A2B8CAF58BFAAE0BD7C257488A341FCC542F9F88F0B678D620324CE7B55285
A quick re-format into dnsmasq config format gives us
trust-anchor=.,7372,8,2,14A2B8CAF58BFAAE0BD7C257488A341FCC542F9F88F0B678
D620324CE7B55285
I knew it was just a hash, but I was too lazy to look up how to get it
into a compatible format :)
dnssec-dsfromkey is the solution, thanks for that info.
Thanks,
Andre
Andre Heider
2016-01-14 21:32:46 UTC
Permalink
Hi,
Post by Simon Kelley
I've got the code I described into dnsmasq.
server=/domain/<ip-address>
now disables DNSSEC for queries sent to that server, unless there's
a corresponding
trust-anchor=domain,.......
That all seems to work well, I can delegate to opennic at the TLD-level,
rather than the root level.
neat, thanks for the quick solution!

I just gave it a quick spin:
started, version 2.76test5 cachesize 150
...
using nameserver 5.9.49.12#53 for domain free
using nameserver 5.9.49.12#53 for domain bit (no DNSSEC)
using nameserver x.x.x.x#9053 for domain onion (no DNSSEC)
using nameserver y.y.y.y#53

with reenabled dnsseccheckunsigned it now works as advertised :)
Post by Simon Kelley
I realised that there's a fundamental problem that all DNSSEC queries to
validate a query get send to the same server as the original query. That
would break, eg a domain under .free which held a CNAME to another TLD.
Fixing that needs some long-overdue code re-writing, which is now in
progress.
Sorry for exposing that :P

Thanks,
Andre
Andre Heider
2016-01-15 10:48:37 UTC
Permalink
Post by Andre Heider
I knew it was just a hash, but I was too lazy to look up how to get it
random note: `drill -s` does that too:
"-s When encountering a DNSKEY print the equivalent DS also."

drill -t -s free dnskey
...
;; ANSWER SECTION:
free. 86400 IN DNSKEY 256 3 8
AwEAAbhd9S94l+8MmCBGgh5UvJ0MBmHFmQMln2kZ3+8ygMBJ/LCsGQuwJNeHKs1yTCeiaIdz/XpDc5dqXP/bWzjE2PpX6Jeds7Ub3j8xJ+VfKINwdHPYoyjsG2lCnVhtUKtRDfPOpFhEvOq8wzwJBXHFxK7Z5jPcSmAaUQlBIPTDI+As6C2dccB4I0mN+4XB7V1VfD3QwdgvCXdAW6yh3V9XZPDEkZeI3yu2CTzu2wT00wKZB7iPUhmqB/UCu0iOuEccYQpZ5Lp1FIf6wYQ4cfHYBhEv5S5cILXMnMtJ9L4PTHRcbQ3px32BtniEX1g4lQj/SNgSQNyG4F7NtFKfxqCXaAU=
;{id = 43806 (zsk), size = 2048b}

free. 86400 IN DNSKEY 257 3 8
AwEAAcwvNG8OQAlDpQVo7yuspxG2QeKjtPJQynADPElT6t8HwnqgY8rHCzJ8asd3+OSn5WSsgRlIqpwXGZoOJD3ULQ5IabyHpreDqDU3hEAMwK/nUVb25wV1klKC6OdOU2B/XGtqJVFcPNnXvNVtL7xu7ss6D43mfXZYwgrqKMb5Rb/vOLo6m43IbIUIpni3QePhyX4vi4tgx7rUXbpIdrRQsBaqnylZeO5JpLkxW+VkL1XtV4/sc8DJh/QlXpsW8+G3WYZ3tBqI3ojLlK11/6ORnu0vhWqqUPorOsxIqGq6xso0fiwfOFUbWDICcUX2R42hHeIqlSw4F831cBlk6IE1Uot8e8fCovYSDNO+e06wBqEmsygv0iYL/qBs1ABbkf+QshggTN6M+XKUCweH1965PWISIEzfEd5lTIR0fOKcIq3t1aozOOHEakPiCYa3UWN3lkebmyHAjEUJa7/aAlEXR/uCzdyiShm5FYjmid5hEX1MtP/VOR9BcY5aYkAED6Xdi/YZWtJw+W27ufWH0jMWMq89ZBwWTWkB24E9O40ecImSG6x8hY7BYNx4Vyroh2S3LNaa/M6zpE543t3gr7jFGLbxGohuWhpIQW9LTOFlWUTxRc1CqQRwJi/ZGyFH5OU0KRpxQwKcCnzvPTosxy6EkdoyUlgPcwIO7XUYTa7yidCH
;{id = 43336 (ksk), size = 4096b}
...
; equivalent DS records for key 43806:
; sha1: free. 86400 IN DS 43806 8 1
9ba8d3af79d783e7168d04b066b8348bcbbee7e9
; sha256: free. 86400 IN DS 43806 8 2
72a7e6a65775d2c96b460af2429605bc402ecf0b4eaff99bdcb6ff570b4b0586
;
; equivalent DS records for key 43336:
; sha1: free. 86400 IN DS 43336 8 1
8f568552cd5744047a241763d33ae0379de1ed72
; sha256: free. 86400 IN DS 43336 8 2
9518ec9290f40e43e8cce6044ff9216bc5099b12620774d394666856e9106377

Regards,
Andre

Loading...