package nscheck import ( "context" "net" "net/netip" "testing" "time" "github.com/miekg/dns" ) // A query to this host's own address is signed with LocalKey, so a server // with views answers from the view that key selects. func TestLocalKey(t *testing.T) { zone := "example.com." key := &Key{Name: "jarl-view-external.", Algorithm: "hmac-sha256", Secret: "c2VjcmV0LXNlY3JldC1zZWNyZXQtc2VjcmV0LXNlY3I="} pc, err := net.ListenPacket("udp", "127.0.0.1:0") if err != nil { t.Skip(err) } _, port, _ := net.SplitHostPort(pc.LocalAddr().String()) srv := &dns.Server{PacketConn: pc, TsigSecret: map[string]string{key.Name: key.Secret}, Handler: dns.HandlerFunc(func(w dns.ResponseWriter, req *dns.Msg) { // Signed with the view key: the "external" view's serial. serial := "1" signed := req.IsTsig() != nil && w.TsigStatus() == nil if signed { serial = "2" } m := new(dns.Msg) m.SetReply(req) m.Authoritative = true m.Answer = []dns.RR{rr(zone + " 3600 IN SOA ns1." + zone + " admin." + zone + " " + serial + " 3600 900 1209600 300")} if signed { m.SetTsig(key.Name, dns.HmacSHA256, 300, time.Now().Unix()) } w.WriteMsg(m) })} go srv.ActivateAndServe() t.Cleanup(func() { srv.Shutdown() }) ref := uint32(2) c := &Checker{Timeout: time.Second, Port: port, IsLocal: func(netip.Addr) bool { return false }} if res := c.Serials(context.Background(), zone, &ref, []Target{{Addresses: []string{"127.0.0.1"}}}); res[0].Status != "behind" { t.Errorf("unsigned: %+v (want the other view's serial)", res[0]) } c.LocalKey = key if res := c.Serials(context.Background(), zone, &ref, []Target{{Addresses: []string{"127.0.0.1"}}}); res[0].Status != "in_sync" { t.Errorf("signed with the view key: %+v", res[0]) } }