Reputation: 2587
I want to extract the TXT Records of a particular domain in Go. I looked at a bunch of blogs and tried the following code:
package main
import (
"fmt"
"net"
)
func main() {
txts, err := net.LookupTXT("google.com")
if err != nil {
panic(err)
}
if len(txts) == 0 {
fmt.Printf("no record")
}
for _, txt := range txts {
fmt.Printf("%s\n", txt)
}
}
When I execute this program, I get the following output.
docusign=05958488-4752-4ef2-95eb-aa7ba8a3bd0e
facebook-domain-verification=22rm551cu4k0ab0bxsw536tlds4h95
globalsign-smime-dv=CDYX+XFHUw2wml6/Gb8+59BsH31KzUr6c1l2BPvqKX8=
v=spf1 include:_spf.google.com ~all
This is working according to my requirement as I follow https://www.kitterman.com/spf/validate.html to validate if I am getting the correct output.
Now, whenever I change my Input Domain to geckoboard.com (say), I get the following error:
panic: lookup geckoboard.com on 127.0.0.53:53: read udp 127.0.0.1:38440->127.0.0.53:53: i/o timeout
goroutine 1 [running]:
main.main()
/home/maruthi/emailheader.go:11
+0x190 exit status 2
I get the fact that this is a Timeout Exception. However, when I run the same query on https://www.kitterman.com/spf/validate.html, I get the expected result within a fraction of seconds.
Is there any better way for extracting TXT Records other than using net.LookupTXT("google.com")
? If not, can someone suggest me a good retry mechanism for the same code with a higher timeout value?
Update 1: Tried the answer provided by @Florian Weimer but still getting a timeout.
$ dig +ignore +bufsize=512 geckoboard.com txt
; <<>> DiG 9.11.3-1ubuntu1.5-Ubuntu <<>> +ignore +bufsize=512 geckoboard.com txt
;; global options: +cmd
;; connection timed out; no servers could be reached
Update 2: As suggested by @ThunderCat, I set the timeout to a much higher value. I added options timeout:30
in resolver.conf . Both queries, the dig
and my program run for a period over 30 seconds before getting a timeout.
Upvotes: 1
Views: 2051
Reputation: 2587
Thanks, @Florian Weimer for your help. I have got this working with a small extension your dig
command.
$ dig @8.8.8.8 +ignore +short +bufsize=1024 geckoboard.com txt
"MS=ms20890953"
"facebook-domain-verification=uh1r0ebrc3sig0h2za0djoj4mhkn3g"
"google-site-verification=I6OUOqinHxPNuD8YBb3-c8GQA7YkbeHdx0xwUeeGLqI"
"google-site-verification=PWaSMmjvCe_daQC2-b7cZ9UW4rFt6Y8ZWQ7YoRbhMDw"
"google-site-verification=lSxvRgW-oP91yihSZ1kNv57EfgT97tmErxAjv5HFi2Q"
"spf2.0/pra include:spf.recurly.com ~all"
"status-page-domain-verification=8963fbq9nrjx"
"v=spf1 include:_spf.google.com include:sendgrid.net include:spf.recurly.com include:mail.zendesk.com include:servers.mcsv.net ~all"
My Golang code for the same is:
package main
import (
"fmt"
"os/exec"
)
func main() {
out, err := exec.Command("bash", "-c", "dig @8.8.8.8 +ignore +short +bufsize=1024 geckoboard.com txt").Output()
s := string(out[:])
if err != nil {
fmt.Println("Unexpected Error Occured ", err)
}
fmt.Printf(s)
}
Upvotes: 0
Reputation: 33757
It is likely that your recursive resolver is misconfigured or just broken. It probably does not handle EDNS correctly, or does not process TCP queries at all. (Some client virtualization solutions have built-in DNS forwarders with these problems.)
The reason why TCP is needed is that the response size is larger than 512 bytes:
$ dig +ignore +bufsize=512 geckoboard.com txt
; <<>> DiG 9.10.3-P4-Debian <<>> +ignore +bufsize=512 geckoboard.com txt
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60761
;; flags: qr tc rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1200
;; QUESTION SECTION:
;geckoboard.com. IN TXT
;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Mar 06 20:39:31 CET 2019
;; MSG SIZE rcvd: 43
The tc
flag means that the client is supposed to retry over TCP. (Normally, dig
will do this automatically, but the +ignore
flag suppresses this.)
This appears to fail in your environment. It is also possible that the recursive resolver itself cannot obtain the data from the global DNS. The fact that the dig
query results in a timeout and not a response with tc
suggests the latter. Further debugging requires packet captures.
Upvotes: 2