In questo articolo vedremo come ottenere i record DNS di un dominio con Go.
Iniziamo importando i package richiesti:
import (
    "fmt"
    "net"
)
Abbiamo importato due package standard di Go: "fmt" per la formattazione dell'output e "net" per l'accesso alle funzioni di rete, comprese le query DNS.
Definiamo quindi una struct per memorizzare l'host (il nome del dominio) e il tipo di record DNS che si vogliamo cercare (A, CNAME, NS, MX o TXT).
type DNSQuery struct {
	Host string
	Type string
}
Creiamo ora la funzione principale del programma che esegue le query DNS. Prende in input un oggetto di tipo DNSQuery e restituisce un array di stringhe (record DNS) e un errore, se ce n'รจ uno.
func getRecord(record DNSQuery) ([]string, error) {
	var records []string
	recordType := record.Type
	domain := record.Host
	switch recordType {
	case "A":
		ips, err := net.LookupIP(domain)
		if err != nil {
			return records, err
		}
		for _, ip := range ips {
			records = append(records, ip.String())
		}
		return records, nil
	case "CNAME":
		name, err := net.LookupCNAME(domain)
		if err != nil {
			return records, err
		}
		records = append(records, name)
		return records, nil
	case "NS":
		ns, err := net.LookupNS(domain)
		if err != nil {
			return records, err
		}
		for _, n := range ns {
			records = append(records, n.Host)
		}
		return records, nil
	case "MX":
		mxs, err := net.LookupMX(domain)
		if err != nil {
			return records, err
		}
		for _, mx := range mxs {
			pref := string(mx.Pref)
			r := fmt.Sprintf("%s %s", mx.Host, pref)
			records = append(records, r)
		}
		return records, nil
	case "TXT":
		txts, err := net.LookupTXT(domain)
		if err != nil {
			return records, err
		}
		for _, txt := range txts {
			records = append(records, txt)
		}
		return records, nil
	default:
		return records, fmt.Errorf("Unknown record type %s", recordType)
	}
}
All'interno della funzione getRecord, viene effettuato un controllo sul tipo di record specificato. In base al tipo di record, vengono eseguite le seguenti azioni:
- Per il tipo "A" (indirizzo IPv4), viene utilizzata la funzione - net.LookupIPper cercare gli indirizzi IP associati al dominio.
- Per il tipo "CNAME" (nome canonico), viene utilizzata la funzione - net.LookupCNAMEper cercare il nome canonico associato al dominio.
- Per il tipo "NS" (server dei nomi), viene utilizzata la funzione - net.LookupNSper cercare i server dei nomi associati al dominio.
- Per il tipo "MX" (record di posta), viene utilizzata la funzione - net.LookupMXper cercare i record MX associati al dominio.
- Per il tipo "TXT" (record di testo), viene utilizzata la funzione - net.LookupTXTper cercare i record TXT associati al dominio.
Ogni risultato ottenuto viene aggiunto all'array records, che alla fine viene restituito come risultato della funzione insieme a un eventuale errore.
Giungiamo infine alla funzione main:
func main() {
	record := DNSQuery{"gabrieleromanato.com", "A"}
	records, err := getRecord(record)
	if err != nil {
		fmt.Println(err)
	} else {
		for _, r := range records {
			fmt.Println(r)
		}
	}
}
La funzione main crea un oggetto DNSQuery con il dominio "gabrieleromanato.com" e il tipo di record "A". Poi chiama la funzione getRecord per ottenere i record DNS associati e gestisce eventuali errori. Se non ci sono errori, stampa i record DNS ottenuti uno per uno.