gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

doc.go (10725B)


      1 /*
      2 Package dns implements a full featured interface to the Domain Name System.
      3 Both server- and client-side programming is supported. The package allows
      4 complete control over what is sent out to the DNS. The API follows the
      5 less-is-more principle, by presenting a small, clean interface.
      6 
      7 It supports (asynchronous) querying/replying, incoming/outgoing zone transfers,
      8 TSIG, EDNS0, dynamic updates, notifies and DNSSEC validation/signing.
      9 
     10 Note that domain names MUST be fully qualified before sending them, unqualified
     11 names in a message will result in a packing failure.
     12 
     13 Resource records are native types. They are not stored in wire format. Basic
     14 usage pattern for creating a new resource record:
     15 
     16 	r := new(dns.MX)
     17 	r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 3600}
     18 	r.Preference = 10
     19 	r.Mx = "mx.miek.nl."
     20 
     21 Or directly from a string:
     22 
     23 	mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.")
     24 
     25 Or when the default origin (.) and TTL (3600) and class (IN) suit you:
     26 
     27 	mx, err := dns.NewRR("miek.nl MX 10 mx.miek.nl")
     28 
     29 Or even:
     30 
     31 	mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek")
     32 
     33 In the DNS messages are exchanged, these messages contain resource records
     34 (sets). Use pattern for creating a message:
     35 
     36 	m := new(dns.Msg)
     37 	m.SetQuestion("miek.nl.", dns.TypeMX)
     38 
     39 Or when not certain if the domain name is fully qualified:
     40 
     41 	m.SetQuestion(dns.Fqdn("miek.nl"), dns.TypeMX)
     42 
     43 The message m is now a message with the question section set to ask the MX
     44 records for the miek.nl. zone.
     45 
     46 The following is slightly more verbose, but more flexible:
     47 
     48 	m1 := new(dns.Msg)
     49 	m1.Id = dns.Id()
     50 	m1.RecursionDesired = true
     51 	m1.Question = make([]dns.Question, 1)
     52 	m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}
     53 
     54 After creating a message it can be sent. Basic use pattern for synchronous
     55 querying the DNS at a server configured on 127.0.0.1 and port 53:
     56 
     57 	c := new(dns.Client)
     58 	in, rtt, err := c.Exchange(m1, "127.0.0.1:53")
     59 
     60 Suppressing multiple outstanding queries (with the same question, type and
     61 class) is as easy as setting:
     62 
     63 	c.SingleInflight = true
     64 
     65 More advanced options are available using a net.Dialer and the corresponding API.
     66 For example it is possible to set a timeout, or to specify a source IP address
     67 and port to use for the connection:
     68 
     69 	c := new(dns.Client)
     70 	laddr := net.UDPAddr{
     71 		IP: net.ParseIP("[::1]"),
     72 		Port: 12345,
     73 		Zone: "",
     74 	}
     75 	c.Dialer = &net.Dialer{
     76 		Timeout: 200 * time.Millisecond,
     77 		LocalAddr: &laddr,
     78 	}
     79 	in, rtt, err := c.Exchange(m1, "8.8.8.8:53")
     80 
     81 If these "advanced" features are not needed, a simple UDP query can be sent,
     82 with:
     83 
     84 	in, err := dns.Exchange(m1, "127.0.0.1:53")
     85 
     86 When this functions returns you will get DNS message. A DNS message consists
     87 out of four sections.
     88 The question section: in.Question, the answer section: in.Answer,
     89 the authority section: in.Ns and the additional section: in.Extra.
     90 
     91 Each of these sections (except the Question section) contain a []RR. Basic
     92 use pattern for accessing the rdata of a TXT RR as the first RR in
     93 the Answer section:
     94 
     95 	if t, ok := in.Answer[0].(*dns.TXT); ok {
     96 		// do something with t.Txt
     97 	}
     98 
     99 # Domain Name and TXT Character String Representations
    100 
    101 Both domain names and TXT character strings are converted to presentation form
    102 both when unpacked and when converted to strings.
    103 
    104 For TXT character strings, tabs, carriage returns and line feeds will be
    105 converted to \t, \r and \n respectively. Back slashes and quotations marks will
    106 be escaped. Bytes below 32 and above 127 will be converted to \DDD form.
    107 
    108 For domain names, in addition to the above rules brackets, periods, spaces,
    109 semicolons and the at symbol are escaped.
    110 
    111 # DNSSEC
    112 
    113 DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It uses
    114 public key cryptography to sign resource records. The public keys are stored in
    115 DNSKEY records and the signatures in RRSIG records.
    116 
    117 Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK)
    118 bit to a request.
    119 
    120 	m := new(dns.Msg)
    121 	m.SetEdns0(4096, true)
    122 
    123 Signature generation, signature verification and key generation are all supported.
    124 
    125 # DYNAMIC UPDATES
    126 
    127 Dynamic updates reuses the DNS message format, but renames three of the
    128 sections. Question is Zone, Answer is Prerequisite, Authority is Update, only
    129 the Additional is not renamed. See RFC 2136 for the gory details.
    130 
    131 You can set a rather complex set of rules for the existence of absence of
    132 certain resource records or names in a zone to specify if resource records
    133 should be added or removed. The table from RFC 2136 supplemented with the Go
    134 DNS function shows which functions exist to specify the prerequisites.
    135 
    136 	3.2.4 - Table Of Metavalues Used In Prerequisite Section
    137 
    138 	 CLASS    TYPE     RDATA    Meaning                    Function
    139 	 --------------------------------------------------------------
    140 	 ANY      ANY      empty    Name is in use             dns.NameUsed
    141 	 ANY      rrset    empty    RRset exists (value indep) dns.RRsetUsed
    142 	 NONE     ANY      empty    Name is not in use         dns.NameNotUsed
    143 	 NONE     rrset    empty    RRset does not exist       dns.RRsetNotUsed
    144 	 zone     rrset    rr       RRset exists (value dep)   dns.Used
    145 
    146 The prerequisite section can also be left empty. If you have decided on the
    147 prerequisites you can tell what RRs should be added or deleted. The next table
    148 shows the options you have and what functions to call.
    149 
    150 	3.4.2.6 - Table Of Metavalues Used In Update Section
    151 
    152 	 CLASS    TYPE     RDATA    Meaning                     Function
    153 	 ---------------------------------------------------------------
    154 	 ANY      ANY      empty    Delete all RRsets from name dns.RemoveName
    155 	 ANY      rrset    empty    Delete an RRset             dns.RemoveRRset
    156 	 NONE     rrset    rr       Delete an RR from RRset     dns.Remove
    157 	 zone     rrset    rr       Add to an RRset             dns.Insert
    158 
    159 # TRANSACTION SIGNATURE
    160 
    161 An TSIG or transaction signature adds a HMAC TSIG record to each message sent.
    162 The supported algorithms include: HmacSHA1, HmacSHA256 and HmacSHA512.
    163 
    164 Basic use pattern when querying with a TSIG name "axfr." (note that these key names
    165 must be fully qualified - as they are domain names) and the base64 secret
    166 "so6ZGir4GPAqINNh9U5c3A==":
    167 
    168 If an incoming message contains a TSIG record it MUST be the last record in
    169 the additional section (RFC2845 3.2).  This means that you should make the
    170 call to SetTsig last, right before executing the query.  If you make any
    171 changes to the RRset after calling SetTsig() the signature will be incorrect.
    172 
    173 	c := new(dns.Client)
    174 	c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
    175 	m := new(dns.Msg)
    176 	m.SetQuestion("miek.nl.", dns.TypeMX)
    177 	m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix())
    178 	...
    179 	// When sending the TSIG RR is calculated and filled in before sending
    180 
    181 When requesting an zone transfer (almost all TSIG usage is when requesting zone
    182 transfers), with TSIG, this is the basic use pattern. In this example we
    183 request an AXFR for miek.nl. with TSIG key named "axfr." and secret
    184 "so6ZGir4GPAqINNh9U5c3A==" and using the server 176.58.119.54:
    185 
    186 	t := new(dns.Transfer)
    187 	m := new(dns.Msg)
    188 	t.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
    189 	m.SetAxfr("miek.nl.")
    190 	m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix())
    191 	c, err := t.In(m, "176.58.119.54:53")
    192 	for r := range c { ... }
    193 
    194 You can now read the records from the transfer as they come in. Each envelope
    195 is checked with TSIG. If something is not correct an error is returned.
    196 
    197 A custom TSIG implementation can be used. This requires additional code to
    198 perform any session establishment and signature generation/verification. The
    199 client must be configured with an implementation of the TsigProvider interface:
    200 
    201 	type Provider struct{}
    202 
    203 	func (*Provider) Generate(msg []byte, tsig *dns.TSIG) ([]byte, error) {
    204 		// Use tsig.Hdr.Name and tsig.Algorithm in your code to
    205 		// generate the MAC using msg as the payload.
    206 	}
    207 
    208 	func (*Provider) Verify(msg []byte, tsig *dns.TSIG) error {
    209 		// Use tsig.Hdr.Name and tsig.Algorithm in your code to verify
    210 		// that msg matches the value in tsig.MAC.
    211 	}
    212 
    213 	c := new(dns.Client)
    214 	c.TsigProvider = new(Provider)
    215 	m := new(dns.Msg)
    216 	m.SetQuestion("miek.nl.", dns.TypeMX)
    217 	m.SetTsig(keyname, dns.HmacSHA256, 300, time.Now().Unix())
    218 	...
    219 	// TSIG RR is calculated by calling your Generate method
    220 
    221 Basic use pattern validating and replying to a message that has TSIG set.
    222 
    223 	server := &dns.Server{Addr: ":53", Net: "udp"}
    224 	server.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
    225 	go server.ListenAndServe()
    226 	dns.HandleFunc(".", handleRequest)
    227 
    228 	func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
    229 		m := new(dns.Msg)
    230 		m.SetReply(r)
    231 		if r.IsTsig() != nil {
    232 			if w.TsigStatus() == nil {
    233 				// *Msg r has an TSIG record and it was validated
    234 				m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix())
    235 			} else {
    236 				// *Msg r has an TSIG records and it was not validated
    237 			}
    238 		}
    239 		w.WriteMsg(m)
    240 	}
    241 
    242 # PRIVATE RRS
    243 
    244 RFC 6895 sets aside a range of type codes for private use. This range is 65,280
    245 - 65,534 (0xFF00 - 0xFFFE). When experimenting with new Resource Records these
    246 can be used, before requesting an official type code from IANA.
    247 
    248 See https://miek.nl/2014/september/21/idn-and-private-rr-in-go-dns/ for more
    249 information.
    250 
    251 # EDNS0
    252 
    253 EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated by
    254 RFC 6891. It defines a new RR type, the OPT RR, which is then completely
    255 abused.
    256 
    257 Basic use pattern for creating an (empty) OPT RR:
    258 
    259 	o := new(dns.OPT)
    260 	o.Hdr.Name = "." // MUST be the root zone, per definition.
    261 	o.Hdr.Rrtype = dns.TypeOPT
    262 
    263 The rdata of an OPT RR consists out of a slice of EDNS0 (RFC 6891) interfaces.
    264 Currently only a few have been standardized: EDNS0_NSID (RFC 5001) and
    265 EDNS0_SUBNET (RFC 7871). Note that these options may be combined in an OPT RR.
    266 Basic use pattern for a server to check if (and which) options are set:
    267 
    268 	// o is a dns.OPT
    269 	for _, s := range o.Option {
    270 		switch e := s.(type) {
    271 		case *dns.EDNS0_NSID:
    272 			// do stuff with e.Nsid
    273 		case *dns.EDNS0_SUBNET:
    274 			// access e.Family, e.Address, etc.
    275 		}
    276 	}
    277 
    278 SIG(0)
    279 
    280 From RFC 2931:
    281 
    282 	SIG(0) provides protection for DNS transactions and requests ....
    283 	... protection for glue records, DNS requests, protection for message headers
    284 	on requests and responses, and protection of the overall integrity of a response.
    285 
    286 It works like TSIG, except that SIG(0) uses public key cryptography, instead of
    287 the shared secret approach in TSIG. Supported algorithms: ECDSAP256SHA256,
    288 ECDSAP384SHA384, RSASHA1, RSASHA256 and RSASHA512.
    289 
    290 Signing subsequent messages in multi-message sessions is not implemented.
    291 */
    292 package dns