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[] = { "tho...@habets.se <tho...@habets.pp.se>" }; 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;