Additional TSIG methods
The github.com/skunkie/tsig package
adds support for additional TSIG methods used in DNS queries. It is designed
to be used alongside the github.com/miekg/dns
package which is used to construct and parse DNS queries and responses.
This is most useful for allowing
RFC 3645 GSS-TSIG which is necessary
for dealing with Windows DNS servers that require 'Secure only' updates or
BIND if it has been configured to use Kerberos.
Here is an example client, it is necessary that your Kerberos or Active
Directory environment is configured and functional:
package main
import (
"fmt"
"time"
"github.com/skunkie/tsig"
"github.com/skunkie/tsig/gss"
"github.com/miekg/dns"
)
func main() {
dnsClient := new(dns.Client)
dnsClient.Net = "tcp"
gssClient, err := gss.NewClient(dnsClient)
if err != nil {
panic(err)
}
defer gssClient.Close()
host := "ns.example.com:53"
// Negotiate a context with the chosen server using the
// current user. See also gssClient.NegotiateContextWithCredentials()
// and gssClient.NegotiateContextWithKeytab() for alternatives
keyname, _, err := gssClient.NegotiateContext(host)
if err != nil {
panic(err)
}
dnsClient.TsigProvider = gssClient
// Use the DNS client as normal
msg := new(dns.Msg)
msg.SetUpdate(dns.Fqdn("example.com"))
insert, err := dns.NewRR("test.example.com. 300 A 192.0.2.1")
if err != nil {
panic(err)
}
msg.Insert([]dns.RR{insert})
msg.SetTsig(keyname, tsig.GSS, 300, time.Now().Unix())
rr, _, err := dnsClient.Exchange(msg, host)
if err != nil {
panic(err)
}
if rr.Rcode != dns.RcodeSuccess {
fmt.Printf("DNS error: %s (%d)\n", dns.RcodeToString[rr.Rcode], rr.Rcode)
}
// Cleanup the context
err = gssClient.DeleteContext(keyname)
if err != nil {
panic(err)
}
}
If you need to deal with both regular TSIG and GSS-TSIG together then this
package also exports an HMAC TSIG implementation. To use both together set
your client up something like this:
package main
import (
"github.com/skunkie/tsig"
"github.com/skunkie/tsig/gss"
"github.com/miekg/dns"
)
func main() {
dnsClient := new(dns.Client)
dnsClient.Net = "tcp"
// Create HMAC TSIG provider
hmac := tsig.HMAC{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
// Create GSS-TSIG provider
gssClient, err := gss.NewClient(dnsClient)
if err != nil {
panic(err)
}
defer gssClient.Close()
// Configure DNS client with both providers
dnsClient.TsigProvider = tsig.MultiProvider(hmac, gssClient)
// Use the DNS client as normal
}