Awesome
Additional TSIG methods
The github.com/bodgit/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.
:warning: Windows DNS servers don't accept wildcard resource names in dynamic updates.
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/bodgit/tsig"
"github.com/bodgit/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/bodgit/tsig"
"github.com/bodgit/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
}