OpenSSH calls getrrsetbyname() in dns.c:verify_host_key_dns().
It then checks for RRSET_VALIDATED, which is only set if the DNS response
has the 'ad' attribute set.
getrrsetbyname() in turn uses res_.* to do DNS requests, but doesn't set
RES_USE_DNSSEC when doing so.
Thus the DNS query that goes out does not have the 'ad' bit set, causing
the response too to not have 'ad' set.
>From my looking at the call stack there's actually no way for OpenSSH, or
the user via env or /etc/resolv.conf, to set RES_USE_DNSSEC.
It seems the unwind DNS server *unconditionally* returns with 'ad' set, so
it works if (and only if?) unwind is the server queried. This seems like a
bug, and it should probably work with all DNS servers (e.g. 8.8.8.8[3]).
I believe that the fix here should be:
else if (!strcmp(tok[i], "dnssec"))
ac->ac_options |= RES_USE_DNSSEC;
else if (!strcmp(tok[i], "edns0"))
ac->ac_options |= RES_USE_EDNS0;
[1]
https://cvsweb.openbsd.org/src/usr.bin/ssh/dns.c?rev=1.41&content-type=text/x-cvsweb-markup
[2]
https://cvsweb.openbsd.org/src/lib/libc/asr/asr.c?rev=1.66&content-type=text/x-cvsweb-markup
[3] I realize that the path from the recursive resolver to the machine must
be secure. I'm using 8.8.8.8 as an example.
https://serverfault.com/questions/1063853/sshfp-not-working
--
typedef struct me_s {
char name[] = { "Thomas Habets" };
char email[] = { "[email protected] <[email protected]>" };
char kernel[] = { "Linux" };
char *pgpKey[] = { "http://www.habets.pp.se/pubkey.txt" };
char pgp[] = { "9907 8698 8A24 F52F 1C2E 87F6 39A4 9EEA 460A 0169" };
char coolcmd[] = { "echo '. ./_&. ./_'>_;. ./_" };
} me_t;