mirror of
https://github.com/slackhq/nebula.git
synced 2026-05-16 12:57:38 +02:00
Reset static host list addresses on change
This commit is contained in:
@@ -303,6 +303,132 @@ func TestLighthouse_reload(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// TestLighthouse_reloadStaticHostMap verifies that reloading static_host_map applies the new
|
||||
// config rather than appending to it. See issue #718.
|
||||
func TestLighthouse_reloadStaticHostMap(t *testing.T) {
|
||||
l := test.NewLogger()
|
||||
c := config.NewC(l)
|
||||
c.Settings["lighthouse"] = map[string]any{"am_lighthouse": true}
|
||||
c.Settings["listen"] = map[string]any{"port": 4242}
|
||||
c.Settings["static_host_map"] = map[string]any{
|
||||
"10.128.0.2": []any{"1.1.1.1:4242"},
|
||||
}
|
||||
|
||||
myVpnNet := netip.MustParsePrefix("10.128.0.1/24")
|
||||
nt := new(bart.Lite)
|
||||
nt.Insert(myVpnNet)
|
||||
cs := &CertState{
|
||||
myVpnNetworks: []netip.Prefix{myVpnNet},
|
||||
myVpnNetworksTable: nt,
|
||||
}
|
||||
|
||||
lh, err := NewLightHouseFromConfig(t.Context(), l, c, cs, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
staticHost := netip.MustParseAddr("10.128.0.2")
|
||||
otherHost := netip.MustParseAddr("10.128.0.3")
|
||||
|
||||
// Capture the RemoteList pointer up front; an in-flight handshake would hold the same one
|
||||
// on hostinfo.remotes, so it must reflect every reload below.
|
||||
pinned := lh.Query(staticHost)
|
||||
require.NotNil(t, pinned)
|
||||
assert.Equal(t, []netip.AddrPort{netip.MustParseAddrPort("1.1.1.1:4242")}, pinned.CopyAddrs([]netip.Prefix{}))
|
||||
|
||||
// Replace the remote address. The new address should be the only entry.
|
||||
nc := map[string]any{
|
||||
"static_host_map": map[string]any{
|
||||
"10.128.0.2": []any{"2.2.2.2:4242"},
|
||||
},
|
||||
}
|
||||
rc, err := yaml.Marshal(nc)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, c.ReloadConfigString(string(rc)))
|
||||
|
||||
rl := lh.Query(staticHost)
|
||||
require.NotNil(t, rl)
|
||||
assert.Same(t, pinned, rl, "RemoteList pointer must stay stable so in-flight handshakes pick up the change")
|
||||
assert.Equal(t, []netip.AddrPort{netip.MustParseAddrPort("2.2.2.2:4242")}, rl.CopyAddrs([]netip.Prefix{}))
|
||||
|
||||
// Reload back to the original IP. Mirrors the round-trip in issue #718 step 6-8 where
|
||||
// the buggy reload produced [1.1.1.1, 2.2.2.2, 1.1.1.1] instead of [1.1.1.1].
|
||||
nc = map[string]any{
|
||||
"static_host_map": map[string]any{
|
||||
"10.128.0.2": []any{"1.1.1.1:4242"},
|
||||
},
|
||||
}
|
||||
rc, err = yaml.Marshal(nc)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, c.ReloadConfigString(string(rc)))
|
||||
|
||||
rl = lh.Query(staticHost)
|
||||
require.NotNil(t, rl)
|
||||
assert.Same(t, pinned, rl)
|
||||
assert.Equal(t, []netip.AddrPort{netip.MustParseAddrPort("1.1.1.1:4242")}, rl.CopyAddrs([]netip.Prefix{}))
|
||||
|
||||
// Reload with the same config. An unchanged entry must not duplicate.
|
||||
require.NoError(t, c.ReloadConfigString(string(rc)))
|
||||
|
||||
rl = lh.Query(staticHost)
|
||||
require.NotNil(t, rl)
|
||||
assert.Same(t, pinned, rl)
|
||||
assert.Equal(t, []netip.AddrPort{netip.MustParseAddrPort("1.1.1.1:4242")}, rl.CopyAddrs([]netip.Prefix{}))
|
||||
|
||||
// Switch back to 2.2.2.2 so the rest of the test continues against a known address.
|
||||
nc = map[string]any{
|
||||
"static_host_map": map[string]any{
|
||||
"10.128.0.2": []any{"2.2.2.2:4242"},
|
||||
},
|
||||
}
|
||||
rc, err = yaml.Marshal(nc)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, c.ReloadConfigString(string(rc)))
|
||||
|
||||
// Add a second host alongside the first. Both should be present, neither duplicated.
|
||||
nc = map[string]any{
|
||||
"static_host_map": map[string]any{
|
||||
"10.128.0.2": []any{"2.2.2.2:4242"},
|
||||
"10.128.0.3": []any{"3.3.3.3:4242"},
|
||||
},
|
||||
}
|
||||
rc, err = yaml.Marshal(nc)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, c.ReloadConfigString(string(rc)))
|
||||
|
||||
rl = lh.Query(staticHost)
|
||||
require.NotNil(t, rl)
|
||||
assert.Same(t, pinned, rl, "adding a sibling entry must not displace the existing RemoteList")
|
||||
assert.Equal(t, []netip.AddrPort{netip.MustParseAddrPort("2.2.2.2:4242")}, rl.CopyAddrs([]netip.Prefix{}))
|
||||
|
||||
rl = lh.Query(otherHost)
|
||||
require.NotNil(t, rl)
|
||||
assert.Equal(t, []netip.AddrPort{netip.MustParseAddrPort("3.3.3.3:4242")}, rl.CopyAddrs([]netip.Prefix{}))
|
||||
|
||||
// Drop the first host entirely. The vpnAddr is no longer marked static, our owner
|
||||
// contribution is cleared, but the addrMap entry stays in place so non-static cache
|
||||
// data (from lighthouse queries) on the same RemoteList isn't lost. In-flight handshakes
|
||||
// that already had the pointer see an empty address list rather than retrying stale ones.
|
||||
nc = map[string]any{
|
||||
"static_host_map": map[string]any{
|
||||
"10.128.0.3": []any{"3.3.3.3:4242"},
|
||||
},
|
||||
}
|
||||
rc, err = yaml.Marshal(nc)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, c.ReloadConfigString(string(rc)))
|
||||
|
||||
_, isStatic := lh.GetStaticHostList()[staticHost]
|
||||
assert.False(t, isStatic)
|
||||
|
||||
rl = lh.Query(staticHost)
|
||||
require.NotNil(t, rl)
|
||||
assert.Same(t, pinned, rl)
|
||||
assert.Empty(t, rl.CopyAddrs([]netip.Prefix{}))
|
||||
|
||||
rl = lh.Query(otherHost)
|
||||
require.NotNil(t, rl)
|
||||
assert.Equal(t, []netip.AddrPort{netip.MustParseAddrPort("3.3.3.3:4242")}, rl.CopyAddrs([]netip.Prefix{}))
|
||||
}
|
||||
|
||||
func newLHHostRequest(fromAddr netip.AddrPort, myVpnIp, queryVpnIp netip.Addr, lhh *LightHouseHandler) testLhReply {
|
||||
req := &NebulaMeta{
|
||||
Type: NebulaMeta_HostQuery,
|
||||
|
||||
Reference in New Issue
Block a user