Извлечение всех записей TXT определенного домена - PullRequest
1 голос
/ 06 марта 2019

Я хочу извлечь записи TXT определенного домена в Go. Я посмотрел на кучу блогов и попробовал следующий код:

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)
        }

}

Когда я выполняю эту программу, я получаю следующий вывод.

docusign=05958488-4752-4ef2-95eb-aa7ba8a3bd0e
facebook-domain-verification=22rm551cu4k0ab0bxsw536tlds4h95
globalsign-smime-dv=CDYX+XFHUw2wml6/Gb8+59BsH31KzUr6c1l2BPvqKX8=
v=spf1 include:_spf.google.com ~all

Это работает в соответствии с моим требованием, поскольку я следую https://www.kitterman.com/spf/validate.html, чтобы проверить, правильно ли я получаю вывод.

Теперь, когда я меняю свой входной домен на geckoboard.com (скажем), я получаю следующую ошибку:

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

Я понимаю, что это исключение тайм-аута. Однако, когда я выполняю тот же запрос на https://www.kitterman.com/spf/validate.html,, я получаю ожидаемый результат в течение доли секунды.

Есть ли лучший способ извлечь записи TXT, кроме использования net.LookupTXT("google.com")? Если нет, может кто-нибудь предложить мне хороший механизм повторения для того же кода с более высоким значением времени ожидания?

Обновление 1: Пробовал ответ, предоставленный @Florian Weimer, но все еще получал тайм-аут.

$ 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

Обновление 2: Как подсказывает @ThunderCat, я установил намного большее значение времени ожидания. Я добавил options timeout:30 в resolver.conf. Оба запроса, dig и моя программа, выполняются в течение более 30 секунд перед получением тайм-аута.

Ответы [ 2 ]

2 голосов
/ 06 марта 2019

Вероятно, ваш рекурсивный распознаватель неправильно настроен или просто неисправен. Вероятно, он неправильно обрабатывает EDNS или вообще не обрабатывает TCP-запросы. (Некоторые решения для виртуализации клиентов имеют встроенные серверы пересылки DNS с этими проблемами.)

Причина, по которой требуется TCP, заключается в том, что размер ответа превышает 512 байт:

$ 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

Флаг tc означает, что клиент должен повторить попытку через TCP. (Обычно dig делает это автоматически, но флаг +ignore подавляет это.)

Это похоже на ошибку в вашей среде. Также возможно, что сам рекурсивный распознаватель не может получить данные из глобальной DNS. Тот факт, что запрос dig приводит к таймауту, а не к ответу с tc, указывает на последнее. Дальнейшая отладка требует перехвата пакетов.

0 голосов
/ 08 марта 2019

Спасибо, @Florian Weimer за вашу помощь.У меня это работает с небольшим расширением вашей dig команды.

$ 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"

Мой код Голанга для этого же:

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)
}
...