Go: how to get the DNS records of a domain

Go: how to get the DNS records of a domain

In this article we will see how to get the DNS records of a domain with Go.

In this article we will see how to get the DNS records of a domain with Go.

Let's start by importing the required packages:


import (
    "fmt"
    "net"
)

We imported two standard Go packages: "fmt" for output formatting and "net" for accessing network functions, including DNS queries.

We then define a struct to store the host (the domain name) and the type of DNS record we want to search (A, CNAME, NS, MX or TXT).


type DNSQuery struct {
	Host string
	Type string
}

Now let's create the main function of the program that performs DNS queries. It takes as input an object of type DNSQuery and returns an array of strings (DNS records) and an error, if any.


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)

	}
}

Within the getRecord function, a check is made on the specified record type. Depending on the record type, the following actions are performed:

  1. For type "A" (IPv4 address), the net.LookupIP function is used to look up the IP addresses associated with the domain.

  2. For the type "CNAME" (canonical name), the net.LookupCNAME function is used to look up the canonical name associated with the domain.

  3. For the "NS" (nameserver) type, the net.LookupNS function is used to look up the nameservers associated with the domain.

  4. For the "MX" (mail record) type, the net.LookupMX function is used to look up the MX records associated with the domain.

  5. For the "TXT" type (text record), the net.LookupTXT function is used to look up the TXT records associated with the domain.

Each result obtained is added to the records array, which is finally returned as a result of the function together with any error.

Finally, the main function:


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

The main function creates a DNSQuery object with the domain "gabrieleromanato.com" and the record of type "A". Then it calls the getRecord function to get the associated DNS records and handle any errors. If there are no errors, it simply prints the DNS records one by one.