Give every view a TSIG key that selects it
Each view's match-clients starts with "key jarl-view-NAME" (after
"!key" for the views listed after it), so a query signed with a view's
key lands in that view from any address. The secrets are derived from a
random seed in Jarl's database. The delegation check signs its queries
to this server's own addresses with the key of the zone's view: before,
they got whichever view matched the server's address, usually internal.
jarl view key / GET /views/{id}/key show a key for dig -k (tsig:write,
audited). jarl-view- key names are reserved; the importer drops view
keys from a configuration Jarl wrote.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c696d02513
commit
384f6b3060
26 files changed
+463
-16
No files matched your search
@@ -0,0 +1,52 @@
|
||||
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])
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user