mapper, state: deliver nodeAttrs through MapResponse and harden nextdns DoH rewrite
WithSelfNode and buildTailPeers merge each node's policy CapMap
into the tailcfg.Node.CapMap they emit. State.NodeCapMap and
State.NodeCapMaps wrap the policy manager: NodeCapMap returns a
defensive clone per call; NodeCapMaps snapshots the full per-node
map once for batched callers, amortising pm.mu acquisition across
a peer build.
generateDNSConfig grew a per-node CapMap argument so it can apply
nodeAttr-driven DNS overlays. The nextdns DoH rewrite hardens against
policy-controlled inputs:
- nextDNSDoHHost anchors the prefix match instead of substring,
so a hostile resolver URL cannot smuggle a nextdns hostname in
a path or query.
- nextDNSProfileFromCapMap accepts only profile names matching
[A-Za-z0-9._-]{1,64} and picks the lexicographically first when
multiple are granted -- deterministic, no shell metacharacters
or URL fragments through.
- addNextDNSMetadata composes the rewritten URL via url.Parse +
url.Values rather than fmt.Sprintf, so existing query strings
on the resolver URL survive and metadata cannot inject a new
component.
WithTaildropEnabled in servertest controls cfg.Taildrop.Enabled per
test so cap/file-sharing emission can be toggled in tests that need
to verify the off path.
This commit is contained in:
parent
a4f05b0962
commit
6fcff9e352
5 changed files with 312 additions and 19 deletions
|
|
@ -42,6 +42,7 @@ type serverConfig struct {
|
|||
ephemeralTimeout time.Duration
|
||||
nodeExpiry time.Duration
|
||||
batcherWorkers int
|
||||
taildropEnabled bool
|
||||
}
|
||||
|
||||
func defaultServerConfig() *serverConfig {
|
||||
|
|
@ -50,6 +51,7 @@ func defaultServerConfig() *serverConfig {
|
|||
bufferedChanSize: 30,
|
||||
batcherWorkers: 1,
|
||||
ephemeralTimeout: 30 * time.Second,
|
||||
taildropEnabled: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -73,6 +75,15 @@ func WithNodeExpiry(d time.Duration) ServerOption {
|
|||
return func(c *serverConfig) { c.nodeExpiry = d }
|
||||
}
|
||||
|
||||
// WithTaildropEnabled toggles the Taildrop file-sharing feature.
|
||||
// Defaults to true to match production. Pass false to verify
|
||||
// behaviour when an operator has switched the toggle off — e.g.
|
||||
// that [tailcfg.CapabilityFileSharing] is withheld from the
|
||||
// always-on baseline.
|
||||
func WithTaildropEnabled(enabled bool) ServerOption {
|
||||
return func(c *serverConfig) { c.taildropEnabled = enabled }
|
||||
}
|
||||
|
||||
// NewServer creates and starts a Headscale test server.
|
||||
// The server is fully functional and accepts real Tailscale control
|
||||
// protocol connections over Noise.
|
||||
|
|
@ -111,6 +122,7 @@ func NewServer(tb testing.TB, opts ...ServerOption) *TestServer {
|
|||
Policy: types.PolicyConfig{
|
||||
Mode: types.PolicyModeDB,
|
||||
},
|
||||
Taildrop: types.TaildropConfig{Enabled: sc.taildropEnabled},
|
||||
Tuning: types.Tuning{
|
||||
BatchChangeDelay: sc.batchDelay,
|
||||
BatcherWorkers: sc.batcherWorkers,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue