doc.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*
  2. Package dns implements a full featured interface to the Domain Name System.
  3. Server- and client-side programming is supported.
  4. The package allows complete control over what is send out to the DNS. The package
  5. API follows the less-is-more principle, by presenting a small, clean interface.
  6. The package dns supports (asynchronous) querying/replying, incoming/outgoing zone transfers,
  7. TSIG, EDNS0, dynamic updates, notifies and DNSSEC validation/signing.
  8. Note that domain names MUST be fully qualified, before sending them, unqualified
  9. names in a message will result in a packing failure.
  10. Resource records are native types. They are not stored in wire format.
  11. Basic usage pattern for creating a new resource record:
  12. r := new(dns.MX)
  13. r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX,
  14. Class: dns.ClassINET, Ttl: 3600}
  15. r.Preference = 10
  16. r.Mx = "mx.miek.nl."
  17. Or directly from a string:
  18. mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.")
  19. Or when the default TTL (3600) and class (IN) suit you:
  20. mx, err := dns.NewRR("miek.nl. MX 10 mx.miek.nl.")
  21. Or even:
  22. mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek")
  23. In the DNS messages are exchanged, these messages contain resource
  24. records (sets). Use pattern for creating a message:
  25. m := new(dns.Msg)
  26. m.SetQuestion("miek.nl.", dns.TypeMX)
  27. Or when not certain if the domain name is fully qualified:
  28. m.SetQuestion(dns.Fqdn("miek.nl"), dns.TypeMX)
  29. The message m is now a message with the question section set to ask
  30. the MX records for the miek.nl. zone.
  31. The following is slightly more verbose, but more flexible:
  32. m1 := new(dns.Msg)
  33. m1.Id = dns.Id()
  34. m1.RecursionDesired = true
  35. m1.Question = make([]dns.Question, 1)
  36. m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}
  37. After creating a message it can be send.
  38. Basic use pattern for synchronous querying the DNS at a
  39. server configured on 127.0.0.1 and port 53:
  40. c := new(dns.Client)
  41. in, rtt, err := c.Exchange(m1, "127.0.0.1:53")
  42. Suppressing multiple outstanding queries (with the same question, type and
  43. class) is as easy as setting:
  44. c.SingleInflight = true
  45. If these "advanced" features are not needed, a simple UDP query can be send,
  46. with:
  47. in, err := dns.Exchange(m1, "127.0.0.1:53")
  48. When this functions returns you will get dns message. A dns message consists
  49. out of four sections.
  50. The question section: in.Question, the answer section: in.Answer,
  51. the authority section: in.Ns and the additional section: in.Extra.
  52. Each of these sections (except the Question section) contain a []RR. Basic
  53. use pattern for accessing the rdata of a TXT RR as the first RR in
  54. the Answer section:
  55. if t, ok := in.Answer[0].(*dns.TXT); ok {
  56. // do something with t.Txt
  57. }
  58. Domain Name and TXT Character String Representations
  59. Both domain names and TXT character strings are converted to presentation
  60. form both when unpacked and when converted to strings.
  61. For TXT character strings, tabs, carriage returns and line feeds will be
  62. converted to \t, \r and \n respectively. Back slashes and quotations marks
  63. will be escaped. Bytes below 32 and above 127 will be converted to \DDD
  64. form.
  65. For domain names, in addition to the above rules brackets, periods,
  66. spaces, semicolons and the at symbol are escaped.
  67. DNSSEC
  68. DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It
  69. uses public key cryptography to sign resource records. The
  70. public keys are stored in DNSKEY records and the signatures in RRSIG records.
  71. Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK) bit
  72. to a request.
  73. m := new(dns.Msg)
  74. m.SetEdns0(4096, true)
  75. Signature generation, signature verification and key generation are all supported.
  76. DYNAMIC UPDATES
  77. Dynamic updates reuses the DNS message format, but renames three of
  78. the sections. Question is Zone, Answer is Prerequisite, Authority is
  79. Update, only the Additional is not renamed. See RFC 2136 for the gory details.
  80. You can set a rather complex set of rules for the existence of absence of
  81. certain resource records or names in a zone to specify if resource records
  82. should be added or removed. The table from RFC 2136 supplemented with the Go
  83. DNS function shows which functions exist to specify the prerequisites.
  84. 3.2.4 - Table Of Metavalues Used In Prerequisite Section
  85. CLASS TYPE RDATA Meaning Function
  86. --------------------------------------------------------------
  87. ANY ANY empty Name is in use dns.NameUsed
  88. ANY rrset empty RRset exists (value indep) dns.RRsetUsed
  89. NONE ANY empty Name is not in use dns.NameNotUsed
  90. NONE rrset empty RRset does not exist dns.RRsetNotUsed
  91. zone rrset rr RRset exists (value dep) dns.Used
  92. The prerequisite section can also be left empty.
  93. If you have decided on the prerequisites you can tell what RRs should
  94. be added or deleted. The next table shows the options you have and
  95. what functions to call.
  96. 3.4.2.6 - Table Of Metavalues Used In Update Section
  97. CLASS TYPE RDATA Meaning Function
  98. ---------------------------------------------------------------
  99. ANY ANY empty Delete all RRsets from name dns.RemoveName
  100. ANY rrset empty Delete an RRset dns.RemoveRRset
  101. NONE rrset rr Delete an RR from RRset dns.Remove
  102. zone rrset rr Add to an RRset dns.Insert
  103. TRANSACTION SIGNATURE
  104. An TSIG or transaction signature adds a HMAC TSIG record to each message sent.
  105. The supported algorithms include: HmacMD5, HmacSHA1, HmacSHA256 and HmacSHA512.
  106. Basic use pattern when querying with a TSIG name "axfr." (note that these key names
  107. must be fully qualified - as they are domain names) and the base64 secret
  108. "so6ZGir4GPAqINNh9U5c3A==":
  109. c := new(dns.Client)
  110. c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
  111. m := new(dns.Msg)
  112. m.SetQuestion("miek.nl.", dns.TypeMX)
  113. m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
  114. ...
  115. // When sending the TSIG RR is calculated and filled in before sending
  116. When requesting an zone transfer (almost all TSIG usage is when requesting zone transfers), with
  117. TSIG, this is the basic use pattern. In this example we request an AXFR for
  118. miek.nl. with TSIG key named "axfr." and secret "so6ZGir4GPAqINNh9U5c3A=="
  119. and using the server 176.58.119.54:
  120. t := new(dns.Transfer)
  121. m := new(dns.Msg)
  122. t.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
  123. m.SetAxfr("miek.nl.")
  124. m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
  125. c, err := t.In(m, "176.58.119.54:53")
  126. for r := range c { ... }
  127. You can now read the records from the transfer as they come in. Each envelope is checked with TSIG.
  128. If something is not correct an error is returned.
  129. Basic use pattern validating and replying to a message that has TSIG set.
  130. server := &dns.Server{Addr: ":53", Net: "udp"}
  131. server.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
  132. go server.ListenAndServe()
  133. dns.HandleFunc(".", handleRequest)
  134. func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
  135. m := new(dns.Msg)
  136. m.SetReply(r)
  137. if r.IsTsig() != nil {
  138. if w.TsigStatus() == nil {
  139. // *Msg r has an TSIG record and it was validated
  140. m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
  141. } else {
  142. // *Msg r has an TSIG records and it was not valided
  143. }
  144. }
  145. w.WriteMsg(m)
  146. }
  147. PRIVATE RRS
  148. RFC 6895 sets aside a range of type codes for private use. This range
  149. is 65,280 - 65,534 (0xFF00 - 0xFFFE). When experimenting with new Resource Records these
  150. can be used, before requesting an official type code from IANA.
  151. see http://miek.nl/posts/2014/Sep/21/Private%20RRs%20and%20IDN%20in%20Go%20DNS/ for more
  152. information.
  153. EDNS0
  154. EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated
  155. by RFC 6891. It defines an new RR type, the OPT RR, which is then completely
  156. abused.
  157. Basic use pattern for creating an (empty) OPT RR:
  158. o := new(dns.OPT)
  159. o.Hdr.Name = "." // MUST be the root zone, per definition.
  160. o.Hdr.Rrtype = dns.TypeOPT
  161. The rdata of an OPT RR consists out of a slice of EDNS0 (RFC 6891)
  162. interfaces. Currently only a few have been standardized: EDNS0_NSID
  163. (RFC 5001) and EDNS0_SUBNET (draft-vandergaast-edns-client-subnet-02). Note
  164. that these options may be combined in an OPT RR.
  165. Basic use pattern for a server to check if (and which) options are set:
  166. // o is a dns.OPT
  167. for _, s := range o.Option {
  168. switch e := s.(type) {
  169. case *dns.EDNS0_NSID:
  170. // do stuff with e.Nsid
  171. case *dns.EDNS0_SUBNET:
  172. // access e.Family, e.Address, etc.
  173. }
  174. }
  175. SIG(0)
  176. From RFC 2931:
  177. SIG(0) provides protection for DNS transactions and requests ....
  178. ... protection for glue records, DNS requests, protection for message headers
  179. on requests and responses, and protection of the overall integrity of a response.
  180. It works like TSIG, except that SIG(0) uses public key cryptography, instead of the shared
  181. secret approach in TSIG.
  182. Supported algorithms: DSA, ECDSAP256SHA256, ECDSAP384SHA384, RSASHA1, RSASHA256 and
  183. RSASHA512.
  184. Signing subsequent messages in multi-message sessions is not implemented.
  185. */
  186. package dns