getssl icon indicating copy to clipboard operation
getssl copied to clipboard

DNS validation using drill broken on FreeBSD (maybe others)

Open pk1048 opened this issue 7 years ago • 5 comments

OS: FreeBSD 11.1-RELEASE-p4 drill version 1.6.17 (ldns version 1.6.17) getssl ver. 2.10

When nslookup is not installed getssl picks drill for DNS validation. drill is called with the SOA flag which fails to return the server name, so the DNS validation fails. Removing the SOA flag permits the DNS validation of the server name for which the certificate is requested.

Line number 393 is the problem. Bad line that does not work:

        if [[ "$($DNS_CHECK_FUNC "${d}" SOA|grep -c "^${d}")" -ge 1 ]]; then
             debug "found IP for ${d}"

Changed line that does work:

        if [[ "$($DNS_CHECK_FUNC "${d}" |grep -c "^${d}")" -ge 1 ]]; then
             debug "found IP for ${d}"

Server name I am trying to get a certificate for: svc-05.aim.hosting

Bad drill command:

drill svc-05.aim.hosting SOA
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 58518
;; flags: qr aa rd ra ; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0 
;; QUESTION SECTION:
;; svc-05.aim.hosting.	IN	SOA

;; ANSWER SECTION:

;; AUTHORITY SECTION:
aim.hosting.	300	IN	SOA	ns-04.aim.hosting. root.advancedinfomanagement.com.aim.hosting. 228 86400 3600 604800 300

;; ADDITIONAL SECTION:

;; Query time: 0 msec
;; SERVER: 172.16.3.15
;; WHEN: Mon Feb 26 17:23:50 2018
;; MSG SIZE  rcvd: 110

Note no occurrence of the server name in the response in the first column.

Correct drill command:

drill svc-05.aim.hosting    
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 828
;; flags: qr aa rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 1 
;; QUESTION SECTION:
;; svc-05.aim.hosting.	IN	A

;; ANSWER SECTION:
svc-05.aim.hosting.	3600	IN	A	172.16.3.17

;; AUTHORITY SECTION:
aim.hosting.	3600	IN	NS	ns02.advancedinfomanagement.com.
aim.hosting.	3600	IN	NS	ns-04.aim.hosting.

;; ADDITIONAL SECTION:
ns-04.aim.hosting.	3600	IN	A	172.16.3.15

;; Query time: 0 msec
;; SERVER: 172.16.3.15
;; WHEN: Mon Feb 26 17:25:12 2018
;; MSG SIZE  rcvd: 133

pk1048 avatar Feb 26 '18 22:02 pk1048

There's no 'correct drill command', it just needs to be configurable. The case above will fail on IPv6 only host.

Another potential (common) example - a CNAME to www - in this case again record type is different. Making ANY is not an option as it may return not really valid cases (similar to SOA actually).

Although in the way SOA is validated - ANY could be usable substitute (any record type with exact match to domain name regardless whether it is actually resolvable to IP address or not). But ANY may fail due to exceeding datagram size and syntax for edns/tcp query is different for drill/dig, and ANY meta-type query is now being deprecated. Something like this allows me to overcome this by a) using ANY type record and b) pinning queries to server which supports the meta-type

diff --git a/getssl b/getssl
index 7f3713e..0b14dd8 100755
--- a/getssl
+++ b/getssl
@@ -390,7 +390,7 @@ check_config() { # check the config files for all obvious errors
       fi
       # check domain exist
       if [[ "$DNS_CHECK_FUNC" == "drill" ]] || [[ "$DNS_CHECK_FUNC" == "dig" ]]; then
-        if [[ "$($DNS_CHECK_FUNC "${d}" SOA|grep -c "^${d}")" -ge 1 ]]; then
+        if [[ "$($DNS_CHECK_FUNC "${d}" ANY $([ "x$PUBLIC_DNS_SERVER" = "x" ] || echo -n "@$PUBLIC_DNS_SERVER")|grep -c "^${d}")" -ge 1 ]]; then
           debug "found IP for ${d}"
         else
           info "${DOMAIN}: DNS lookup failed for ${d}"

rufferson avatar Apr 28 '18 06:04 rufferson

Is there a reason that the SOA has to be queried? Even with AUTH_DNS_SERVER added, my (name server for my) domain simply doesn't provide a SOA record:

$ dig foo.example.org SOA | grep example
;; foo.example.org.   IN  SOA
example.org.   900    IN  SOA  ns.provider.net. ns2.provider.de. 2017102603 10800 3600 604800 86400

Thus, I had to adjust the current getssl version (v2.13) like this to get it past the DNS lookup failed for... error:

--- /usr/local/sbin/getssl.orig 2019-10-16 04:23:14.646093583 +0200
+++ /usr/local/sbin/getssl      2019-10-16 04:57:52.790080260 +0200
@@ -393,7 +393,7 @@
       fi
       # check domain exist
       if [[ "$DNS_CHECK_FUNC" == "drill" ]] || [[ "$DNS_CHECK_FUNC" == "dig" ]]; then
-        if [[ "$($DNS_CHECK_FUNC "${d}" SOA|grep -c "^${d}")" -ge 1 ]]; then
+        if [[ "$($DNS_CHECK_FUNC "${d}" A|grep -c "^${d}")" -ge 1 ]]; then
           debug "found IP for ${d}"
         else
           info "${DOMAIN}: DNS lookup failed for ${d}"

ckujau avatar Oct 16 '19 03:10 ckujau

Wait. Your server never returns a SOA record? IMHO this doesn't conform to the RFC.

QuingKhaos avatar Oct 16 '19 12:10 QuingKhaos

Maybe I'm dense, but again - why do we need the SOA record here? It's being used for zone information, but why do we care about this here? In many hosting environments I don't control the zone (example.org), I only control a hostname (foo.example.org) and I don't control its nameserver either.

$ for d in github.com freebsd.org kame.net; do dig www.${d} SOA | grep -v ^\;; done | cut -c-80
www.github.com.         1163    IN      CNAME   github.com.
github.com.             548     IN      SOA     ns-1707.awsdns-21.co.uk. awsdns-hostmaster.amazon.com. 1

www.freebsd.org.        13      IN      CNAME   wfe0.nyi.freebsd.org.
freebsd.org.            3600    IN      SOA     ns0.freebsd.org. hostmaster.freebsd.org. 2019101616 36

www.kame.net.           10407   IN      CNAME   orange.kame.net.
kame.net.               1153    IN      SOA     orange.kame.net. root.orange.kame.net. 2012070903 3600 30

ckujau avatar Oct 16 '19 17:10 ckujau

I think this can be closed as this was fixed in commit # 0c7390d to remove the SOA flag.

scott-42 avatar Feb 23 '20 17:02 scott-42