On Thu, Nov 18, 2021 at 07:22:27AM +0100, Otto Moerbeek wrote:
> On Wed, Nov 17, 2021 at 01:05:05PM -0800, [email protected] wrote:
>
> > On Wed, 17 Nov 2021 20:46:46 +0000, Otto Moerbeek <[email protected]> said:
> > > Well, I should have been more clear as well, dig sets both the AD bit
> > > (by default) and the DO bit (on +dnssec). More clienst do this. This
> > > is part of the can of worms.
> >
> > Right, yeah. I misunderstood the AD bit in the query being the
> > trigger, but as you say it's the DO, and as the RFC says, queries
> > shouldn't set the AD.
>
> I wasn't comlete and not right, as Florian is saying, a more recent
> RFC does define the AD bit for queries. Sorry about that oversight.
> Sometimes it's hard to keep track of all the relevant RFCs.
>
> So AD bit in a query gets you a potential AD bits set in the reply,
> but without the records needed to validate the signature, you have to
> trust the resolver. Setting the DO bit does get you the DNSSEC records
> in addition to the AD bit in the reply if valiudation succeeded. That
> is also a reason setting the DO bit is a can of worms, it grows the
> response sizes and not all equipment handles tat properly.
>
> >
> > > You are forcing *all* clients resolving to use dnssec. Only a solution
> > > that limits the scope to the the smallest case (ssh doing an
> > > getrrsetbyname() for DNS_RDATATYPE_SSHFP is likely acceptable. Sadly
> > > the context used by resolving is program-wide, so setting a flag in
> > > _res is also not going to work.
> >
> > Yeah. For the machine I'm on I actually want all DNS requests system
> > wide to use DNSSEC. So personally that's working as intended. But I
> > see your point.
> >
> > Currently there's no way to get a signed response, right?
> >
> > With my patch for a per-program level option I just successfully
> > tested:
> >
> > RES_OPTIONS=dnssec ssh foo.example.com
> >
> > But of course it doesn't limit to just getrrsetbyname().
> >
> > Is the asr_ctx (where flags look like they live) program-wide, or just
> > thread wide? I can basically hear you cringing already, so maybe the
> > only real solution is to have getrrsetbyname_async_run() pass in flags
> > to _res_query_async_ctx()->setup_query() to OR in the option?
> >
> > And then maybe have getrrsetbyname() call that stack twice, once with
> > and once without RES_USE_DNSSEC, in case DNSSEC is broken?
>
> After sleeping on it, likely setting the DO bit for a single query can
> be done like ntpd is doing for the CD bit, see probe_root_ns() in
> ntp_dns.c
>
> But I agree with Florian that setting the AD bit on the query is
> better, although afaik, there is no way of doing that yet.
>
> -Otto
>
A diff setting the DO bit for just the SSHFP query could look like this.
Setting the AD bit is not possible atm, but I might take a look how to
do that.
-Otto
Index: dns.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/dns.c,v
retrieving revision 1.41
diff -u -p -r1.41 dns.c
--- dns.c 19 Jul 2021 03:13:28 -0000 1.41
+++ dns.c 18 Nov 2021 06:38:13 -0000
@@ -29,6 +29,7 @@
#include <sys/socket.h>
#include <netdb.h>
+#include <resolv.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
@@ -195,7 +196,7 @@ verify_host_key_dns(const char *hostname
struct sshkey *hostkey, int *flags)
{
u_int counter;
- int result;
+ int result, old_options;
struct rrsetinfo *fingerprints = NULL;
u_int8_t hostkey_algorithm;
@@ -218,8 +219,12 @@ verify_host_key_dns(const char *hostname
return -1;
}
+ old_options = _res.options;
+ _res.options |= RES_USE_DNSSEC;
result = getrrsetbyname(hostname, DNS_RDATACLASS_IN,
DNS_RDATATYPE_SSHFP, 0, &fingerprints);
+ _res.options = old_options;
+
if (result) {
verbose("DNS lookup error: %s", dns_result_totext(result));
return -1;