| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | package nebula | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2021-11-02 14:14:26 -04:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | 	"crypto/ed25519" | 
					
						
							|  |  |  | 	"crypto/rand" | 
					
						
							| 
									
										
										
										
											2024-07-31 10:18:56 -05:00
										 |  |  | 	"net/netip" | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/flynn/noise" | 
					
						
							|  |  |  | 	"github.com/slackhq/nebula/cert" | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 	"github.com/slackhq/nebula/config" | 
					
						
							| 
									
										
										
										
											2021-11-10 21:47:38 -06:00
										 |  |  | 	"github.com/slackhq/nebula/test" | 
					
						
							| 
									
										
										
										
											2021-11-03 20:54:04 -05:00
										 |  |  | 	"github.com/slackhq/nebula/udp" | 
					
						
							| 
									
										
										
										
											2019-12-09 16:53:56 -08:00
										 |  |  | 	"github.com/stretchr/testify/assert" | 
					
						
							| 
									
										
										
										
											2025-03-10 17:38:14 -05:00
										 |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-31 13:37:41 -04:00
										 |  |  | func newTestLighthouse() *LightHouse { | 
					
						
							|  |  |  | 	lh := &LightHouse{ | 
					
						
							| 
									
										
										
										
											2023-12-19 11:58:31 -06:00
										 |  |  | 		l:         test.NewLogger(), | 
					
						
							| 
									
										
										
										
											2024-07-31 10:18:56 -05:00
										 |  |  | 		addrMap:   map[netip.Addr]*RemoteList{}, | 
					
						
							|  |  |  | 		queryChan: make(chan netip.Addr, 10), | 
					
						
							| 
									
										
										
										
											2022-10-31 13:37:41 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-07-31 10:18:56 -05:00
										 |  |  | 	lighthouses := map[netip.Addr]struct{}{} | 
					
						
							|  |  |  | 	staticList := map[netip.Addr]struct{}{} | 
					
						
							| 
									
										
										
										
											2022-10-31 13:37:41 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	lh.lighthouses.Store(&lighthouses) | 
					
						
							|  |  |  | 	lh.staticList.Store(&staticList) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return lh | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | func Test_NewConnectionManagerTest(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2021-11-10 21:47:38 -06:00
										 |  |  | 	l := test.NewLogger() | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	//_, tuncidr, _ := net.ParseCIDR("1.1.1.1/24") | 
					
						
							| 
									
										
										
										
											2024-07-31 10:18:56 -05:00
										 |  |  | 	localrange := netip.MustParsePrefix("10.1.1.1/24") | 
					
						
							|  |  |  | 	vpnIp := netip.MustParseAddr("172.1.1.2") | 
					
						
							|  |  |  | 	preferredRanges := []netip.Prefix{localrange} | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Very incomplete mock objects | 
					
						
							| 
									
										
										
										
											2025-03-06 11:28:26 -06:00
										 |  |  | 	hostMap := newHostMap(l) | 
					
						
							| 
									
										
										
										
											2024-04-03 22:14:51 -05:00
										 |  |  | 	hostMap.preferredRanges.Store(&preferredRanges) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	cs := &CertState{ | 
					
						
							| 
									
										
										
										
											2025-04-07 18:08:29 -04:00
										 |  |  | 		initiatingVersion: cert.Version1, | 
					
						
							|  |  |  | 		privateKey:        []byte{}, | 
					
						
							|  |  |  | 		v1Cert:            &dummyCert{version: cert.Version1}, | 
					
						
							|  |  |  | 		v1HandshakeBytes:  []byte{}, | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-31 13:37:41 -04:00
										 |  |  | 	lh := newTestLighthouse() | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	ifce := &Interface{ | 
					
						
							|  |  |  | 		hostMap:          hostMap, | 
					
						
							| 
									
										
										
										
											2021-11-12 10:47:36 -06:00
										 |  |  | 		inside:           &test.NoopTun{}, | 
					
						
							| 
									
										
										
										
											2023-06-14 10:48:52 -05:00
										 |  |  | 		outside:          &udp.NoopConn{}, | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 		firewall:         &Firewall{}, | 
					
						
							|  |  |  | 		lightHouse:       lh, | 
					
						
							| 
									
										
										
										
											2023-08-14 21:32:40 -05:00
										 |  |  | 		pki:              &PKI{}, | 
					
						
							| 
									
										
										
										
											2023-08-21 18:51:45 -05:00
										 |  |  | 		handshakeManager: NewHandshakeManager(l, hostMap, lh, &udp.NoopConn{}, defaultHandshakeConfig), | 
					
						
							| 
									
										
										
										
											2021-03-26 09:46:30 -05:00
										 |  |  | 		l:                l, | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-08-14 21:32:40 -05:00
										 |  |  | 	ifce.pki.cs.Store(cs) | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Create manager | 
					
						
							| 
									
										
										
										
											2021-11-02 14:14:26 -04:00
										 |  |  | 	ctx, cancel := context.WithCancel(context.Background()) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 	punchy := NewPunchyFromConfig(l, config.NewC(l)) | 
					
						
							|  |  |  | 	nc := newConnectionManager(ctx, l, ifce, 5, 10, punchy) | 
					
						
							| 
									
										
										
										
											2020-11-19 15:44:05 -08:00
										 |  |  | 	p := []byte("") | 
					
						
							|  |  |  | 	nb := make([]byte, 12, 12) | 
					
						
							|  |  |  | 	out := make([]byte, mtu) | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	// Add an ip we have established a connection w/ to hostmap | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 	hostinfo := &HostInfo{ | 
					
						
							| 
									
										
										
										
											2025-03-06 11:28:26 -06:00
										 |  |  | 		vpnAddrs:      []netip.Addr{vpnIp}, | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 		localIndexId:  1099, | 
					
						
							|  |  |  | 		remoteIndexId: 9901, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	hostinfo.ConnectionState = &ConnectionState{ | 
					
						
							| 
									
										
										
										
											2025-03-06 11:28:26 -06:00
										 |  |  | 		myCert: &dummyCert{version: cert.Version1}, | 
					
						
							| 
									
										
										
										
											2023-08-21 14:11:06 -05:00
										 |  |  | 		H:      &noise.HandshakeState{}, | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-03-13 12:35:14 -05:00
										 |  |  | 	nc.hostMap.unlockedAddHostInfo(hostinfo, ifce) | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-03 20:54:04 -05:00
										 |  |  | 	// We saw traffic out to vpnIp | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 	nc.Out(hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 	nc.In(hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 	assert.NotContains(t, nc.pendingDeletion, hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2025-03-06 11:28:26 -06:00
										 |  |  | 	assert.Contains(t, nc.hostMap.Hosts, hostinfo.vpnAddrs[0]) | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 	assert.Contains(t, nc.hostMap.Indexes, hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 	assert.Contains(t, nc.out, hostinfo.localIndexId) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Do a traffic check tick, should not be pending deletion but should not have any in/out packets recorded | 
					
						
							|  |  |  | 	nc.doTrafficCheck(hostinfo.localIndexId, p, nb, out, time.Now()) | 
					
						
							|  |  |  | 	assert.NotContains(t, nc.pendingDeletion, hostinfo.localIndexId) | 
					
						
							|  |  |  | 	assert.NotContains(t, nc.out, hostinfo.localIndexId) | 
					
						
							|  |  |  | 	assert.NotContains(t, nc.in, hostinfo.localIndexId) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Do another traffic check tick, this host should be pending deletion now | 
					
						
							| 
									
										
										
										
											2023-04-04 13:42:24 -05:00
										 |  |  | 	nc.Out(hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 	nc.doTrafficCheck(hostinfo.localIndexId, p, nb, out, time.Now()) | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 	assert.Contains(t, nc.pendingDeletion, hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 	assert.NotContains(t, nc.out, hostinfo.localIndexId) | 
					
						
							|  |  |  | 	assert.NotContains(t, nc.in, hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 	assert.Contains(t, nc.hostMap.Indexes, hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2025-03-06 11:28:26 -06:00
										 |  |  | 	assert.Contains(t, nc.hostMap.Hosts, hostinfo.vpnAddrs[0]) | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Do a final traffic check tick, the host should now be removed | 
					
						
							|  |  |  | 	nc.doTrafficCheck(hostinfo.localIndexId, p, nb, out, time.Now()) | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 	assert.NotContains(t, nc.pendingDeletion, hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2025-03-06 11:28:26 -06:00
										 |  |  | 	assert.NotContains(t, nc.hostMap.Hosts, hostinfo.vpnAddrs[0]) | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 	assert.NotContains(t, nc.hostMap.Indexes, hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func Test_NewConnectionManagerTest2(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2021-11-10 21:47:38 -06:00
										 |  |  | 	l := test.NewLogger() | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	//_, tuncidr, _ := net.ParseCIDR("1.1.1.1/24") | 
					
						
							| 
									
										
										
										
											2024-07-31 10:18:56 -05:00
										 |  |  | 	localrange := netip.MustParsePrefix("10.1.1.1/24") | 
					
						
							|  |  |  | 	vpnIp := netip.MustParseAddr("172.1.1.2") | 
					
						
							|  |  |  | 	preferredRanges := []netip.Prefix{localrange} | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Very incomplete mock objects | 
					
						
							| 
									
										
										
										
											2025-03-06 11:28:26 -06:00
										 |  |  | 	hostMap := newHostMap(l) | 
					
						
							| 
									
										
										
										
											2024-04-03 22:14:51 -05:00
										 |  |  | 	hostMap.preferredRanges.Store(&preferredRanges) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	cs := &CertState{ | 
					
						
							| 
									
										
										
										
											2025-04-07 18:08:29 -04:00
										 |  |  | 		initiatingVersion: cert.Version1, | 
					
						
							|  |  |  | 		privateKey:        []byte{}, | 
					
						
							|  |  |  | 		v1Cert:            &dummyCert{version: cert.Version1}, | 
					
						
							|  |  |  | 		v1HandshakeBytes:  []byte{}, | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-31 13:37:41 -04:00
										 |  |  | 	lh := newTestLighthouse() | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	ifce := &Interface{ | 
					
						
							|  |  |  | 		hostMap:          hostMap, | 
					
						
							| 
									
										
										
										
											2021-11-12 10:47:36 -06:00
										 |  |  | 		inside:           &test.NoopTun{}, | 
					
						
							| 
									
										
										
										
											2023-06-14 10:48:52 -05:00
										 |  |  | 		outside:          &udp.NoopConn{}, | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 		firewall:         &Firewall{}, | 
					
						
							|  |  |  | 		lightHouse:       lh, | 
					
						
							| 
									
										
										
										
											2023-08-14 21:32:40 -05:00
										 |  |  | 		pki:              &PKI{}, | 
					
						
							| 
									
										
										
										
											2023-08-21 18:51:45 -05:00
										 |  |  | 		handshakeManager: NewHandshakeManager(l, hostMap, lh, &udp.NoopConn{}, defaultHandshakeConfig), | 
					
						
							| 
									
										
										
										
											2021-03-26 09:46:30 -05:00
										 |  |  | 		l:                l, | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-08-14 21:32:40 -05:00
										 |  |  | 	ifce.pki.cs.Store(cs) | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Create manager | 
					
						
							| 
									
										
										
										
											2021-11-02 14:14:26 -04:00
										 |  |  | 	ctx, cancel := context.WithCancel(context.Background()) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 	punchy := NewPunchyFromConfig(l, config.NewC(l)) | 
					
						
							|  |  |  | 	nc := newConnectionManager(ctx, l, ifce, 5, 10, punchy) | 
					
						
							| 
									
										
										
										
											2020-11-19 15:44:05 -08:00
										 |  |  | 	p := []byte("") | 
					
						
							|  |  |  | 	nb := make([]byte, 12, 12) | 
					
						
							|  |  |  | 	out := make([]byte, mtu) | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	// Add an ip we have established a connection w/ to hostmap | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 	hostinfo := &HostInfo{ | 
					
						
							| 
									
										
										
										
											2025-03-06 11:28:26 -06:00
										 |  |  | 		vpnAddrs:      []netip.Addr{vpnIp}, | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 		localIndexId:  1099, | 
					
						
							|  |  |  | 		remoteIndexId: 9901, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	hostinfo.ConnectionState = &ConnectionState{ | 
					
						
							| 
									
										
										
										
											2025-03-06 11:28:26 -06:00
										 |  |  | 		myCert: &dummyCert{version: cert.Version1}, | 
					
						
							| 
									
										
										
										
											2023-08-21 14:11:06 -05:00
										 |  |  | 		H:      &noise.HandshakeState{}, | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-03-13 12:35:14 -05:00
										 |  |  | 	nc.hostMap.unlockedAddHostInfo(hostinfo, ifce) | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-03 20:54:04 -05:00
										 |  |  | 	// We saw traffic out to vpnIp | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 	nc.Out(hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 	nc.In(hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2025-03-06 11:28:26 -06:00
										 |  |  | 	assert.NotContains(t, nc.pendingDeletion, hostinfo.vpnAddrs[0]) | 
					
						
							|  |  |  | 	assert.Contains(t, nc.hostMap.Hosts, hostinfo.vpnAddrs[0]) | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 	assert.Contains(t, nc.hostMap.Indexes, hostinfo.localIndexId) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Do a traffic check tick, should not be pending deletion but should not have any in/out packets recorded | 
					
						
							|  |  |  | 	nc.doTrafficCheck(hostinfo.localIndexId, p, nb, out, time.Now()) | 
					
						
							|  |  |  | 	assert.NotContains(t, nc.pendingDeletion, hostinfo.localIndexId) | 
					
						
							|  |  |  | 	assert.NotContains(t, nc.out, hostinfo.localIndexId) | 
					
						
							|  |  |  | 	assert.NotContains(t, nc.in, hostinfo.localIndexId) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Do another traffic check tick, this host should be pending deletion now | 
					
						
							| 
									
										
										
										
											2023-04-04 13:42:24 -05:00
										 |  |  | 	nc.Out(hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 	nc.doTrafficCheck(hostinfo.localIndexId, p, nb, out, time.Now()) | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 	assert.Contains(t, nc.pendingDeletion, hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 	assert.NotContains(t, nc.out, hostinfo.localIndexId) | 
					
						
							|  |  |  | 	assert.NotContains(t, nc.in, hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 	assert.Contains(t, nc.hostMap.Indexes, hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2025-03-06 11:28:26 -06:00
										 |  |  | 	assert.Contains(t, nc.hostMap.Hosts, hostinfo.vpnAddrs[0]) | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// We saw traffic, should no longer be pending deletion | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 	nc.In(hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 	nc.doTrafficCheck(hostinfo.localIndexId, p, nb, out, time.Now()) | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 	assert.NotContains(t, nc.pendingDeletion, hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 	assert.NotContains(t, nc.out, hostinfo.localIndexId) | 
					
						
							|  |  |  | 	assert.NotContains(t, nc.in, hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2023-02-13 14:41:05 -06:00
										 |  |  | 	assert.Contains(t, nc.hostMap.Indexes, hostinfo.localIndexId) | 
					
						
							| 
									
										
										
										
											2025-03-06 11:28:26 -06:00
										 |  |  | 	assert.Contains(t, nc.hostMap.Hosts, hostinfo.vpnAddrs[0]) | 
					
						
							| 
									
										
										
										
											2019-11-19 17:00:20 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Check if we can disconnect the peer. | 
					
						
							|  |  |  | // Validate if the peer's certificate is invalid (expired, etc.) | 
					
						
							|  |  |  | // Disconnect only if disconnectInvalid: true is set. | 
					
						
							|  |  |  | func Test_NewConnectionManagerTest_DisconnectInvalid(t *testing.T) { | 
					
						
							|  |  |  | 	now := time.Now() | 
					
						
							| 
									
										
										
										
											2021-11-10 21:47:38 -06:00
										 |  |  | 	l := test.NewLogger() | 
					
						
							| 
									
										
										
										
											2024-10-10 18:00:22 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-31 10:18:56 -05:00
										 |  |  | 	vpncidr := netip.MustParsePrefix("172.1.1.1/24") | 
					
						
							|  |  |  | 	localrange := netip.MustParsePrefix("10.1.1.1/24") | 
					
						
							|  |  |  | 	vpnIp := netip.MustParseAddr("172.1.1.2") | 
					
						
							|  |  |  | 	preferredRanges := []netip.Prefix{localrange} | 
					
						
							| 
									
										
										
										
											2025-03-06 11:28:26 -06:00
										 |  |  | 	hostMap := newHostMap(l) | 
					
						
							| 
									
										
										
										
											2024-04-03 22:14:51 -05:00
										 |  |  | 	hostMap.preferredRanges.Store(&preferredRanges) | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Generate keys for CA and peer's cert. | 
					
						
							|  |  |  | 	pubCA, privCA, _ := ed25519.GenerateKey(rand.Reader) | 
					
						
							| 
									
										
										
										
											2024-10-10 18:00:22 -05:00
										 |  |  | 	tbs := &cert.TBSCertificate{ | 
					
						
							|  |  |  | 		Version:   1, | 
					
						
							|  |  |  | 		Name:      "ca", | 
					
						
							|  |  |  | 		IsCA:      true, | 
					
						
							|  |  |  | 		NotBefore: now, | 
					
						
							|  |  |  | 		NotAfter:  now.Add(1 * time.Hour), | 
					
						
							|  |  |  | 		PublicKey: pubCA, | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-08-21 14:11:06 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-10 18:00:22 -05:00
										 |  |  | 	caCert, err := tbs.Sign(nil, cert.Curve_CURVE25519, privCA) | 
					
						
							| 
									
										
										
										
											2025-03-10 17:38:14 -05:00
										 |  |  | 	require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2024-10-10 18:00:22 -05:00
										 |  |  | 	ncp := cert.NewCAPool() | 
					
						
							| 
									
										
										
										
											2025-03-10 17:38:14 -05:00
										 |  |  | 	require.NoError(t, ncp.AddCA(caCert)) | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	pubCrt, _, _ := ed25519.GenerateKey(rand.Reader) | 
					
						
							| 
									
										
										
										
											2024-10-10 18:00:22 -05:00
										 |  |  | 	tbs = &cert.TBSCertificate{ | 
					
						
							|  |  |  | 		Version:   1, | 
					
						
							|  |  |  | 		Name:      "host", | 
					
						
							|  |  |  | 		Networks:  []netip.Prefix{vpncidr}, | 
					
						
							|  |  |  | 		NotBefore: now, | 
					
						
							|  |  |  | 		NotAfter:  now.Add(60 * time.Second), | 
					
						
							|  |  |  | 		PublicKey: pubCrt, | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-10-10 18:00:22 -05:00
										 |  |  | 	peerCert, err := tbs.Sign(caCert, cert.Curve_CURVE25519, privCA) | 
					
						
							| 
									
										
										
										
											2025-03-10 17:38:14 -05:00
										 |  |  | 	require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2024-10-10 18:00:22 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	cachedPeerCert, err := ncp.VerifyCertificate(now.Add(time.Second), peerCert) | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	cs := &CertState{ | 
					
						
							| 
									
										
										
										
											2025-03-06 11:28:26 -06:00
										 |  |  | 		privateKey:       []byte{}, | 
					
						
							|  |  |  | 		v1Cert:           &dummyCert{}, | 
					
						
							|  |  |  | 		v1HandshakeBytes: []byte{}, | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-31 13:37:41 -04:00
										 |  |  | 	lh := newTestLighthouse() | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | 	ifce := &Interface{ | 
					
						
							| 
									
										
										
										
											2023-11-13 12:39:38 -06:00
										 |  |  | 		hostMap:          hostMap, | 
					
						
							|  |  |  | 		inside:           &test.NoopTun{}, | 
					
						
							|  |  |  | 		outside:          &udp.NoopConn{}, | 
					
						
							|  |  |  | 		firewall:         &Firewall{}, | 
					
						
							|  |  |  | 		lightHouse:       lh, | 
					
						
							|  |  |  | 		handshakeManager: NewHandshakeManager(l, hostMap, lh, &udp.NoopConn{}, defaultHandshakeConfig), | 
					
						
							|  |  |  | 		l:                l, | 
					
						
							|  |  |  | 		pki:              &PKI{}, | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-08-14 21:32:40 -05:00
										 |  |  | 	ifce.pki.cs.Store(cs) | 
					
						
							|  |  |  | 	ifce.pki.caPool.Store(ncp) | 
					
						
							| 
									
										
										
										
											2023-11-13 12:39:38 -06:00
										 |  |  | 	ifce.disconnectInvalid.Store(true) | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Create manager | 
					
						
							| 
									
										
										
										
											2021-11-02 14:14:26 -04:00
										 |  |  | 	ctx, cancel := context.WithCancel(context.Background()) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							| 
									
										
										
										
											2023-03-31 15:45:05 -05:00
										 |  |  | 	punchy := NewPunchyFromConfig(l, config.NewC(l)) | 
					
						
							|  |  |  | 	nc := newConnectionManager(ctx, l, ifce, 5, 10, punchy) | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | 	ifce.connectionManager = nc | 
					
						
							| 
									
										
										
										
											2023-07-24 12:37:52 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	hostinfo := &HostInfo{ | 
					
						
							| 
									
										
										
										
											2025-03-06 11:28:26 -06:00
										 |  |  | 		vpnAddrs: []netip.Addr{vpnIp}, | 
					
						
							| 
									
										
										
										
											2023-07-24 12:37:52 -05:00
										 |  |  | 		ConnectionState: &ConnectionState{ | 
					
						
							| 
									
										
										
										
											2024-10-10 18:00:22 -05:00
										 |  |  | 			myCert:   &dummyCert{}, | 
					
						
							|  |  |  | 			peerCert: cachedPeerCert, | 
					
						
							| 
									
										
										
										
											2023-08-21 14:11:06 -05:00
										 |  |  | 			H:        &noise.HandshakeState{}, | 
					
						
							| 
									
										
										
										
											2023-07-24 12:37:52 -05:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-07-24 12:37:52 -05:00
										 |  |  | 	nc.hostMap.unlockedAddHostInfo(hostinfo, ifce) | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Move ahead 45s. | 
					
						
							|  |  |  | 	// Check if to disconnect with invalid certificate. | 
					
						
							|  |  |  | 	// Should be alive. | 
					
						
							|  |  |  | 	nextTick := now.Add(45 * time.Second) | 
					
						
							| 
									
										
										
										
											2023-05-04 15:16:37 -05:00
										 |  |  | 	invalid := nc.isInvalidCertificate(nextTick, hostinfo) | 
					
						
							|  |  |  | 	assert.False(t, invalid) | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Move ahead 61s. | 
					
						
							|  |  |  | 	// Check if to disconnect with invalid certificate. | 
					
						
							|  |  |  | 	// Should be disconnected. | 
					
						
							|  |  |  | 	nextTick = now.Add(61 * time.Second) | 
					
						
							| 
									
										
										
										
											2023-05-04 15:16:37 -05:00
										 |  |  | 	invalid = nc.isInvalidCertificate(nextTick, hostinfo) | 
					
						
							|  |  |  | 	assert.True(t, invalid) | 
					
						
							| 
									
										
										
										
											2021-10-20 21:23:33 +03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2024-10-10 18:00:22 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | type dummyCert struct { | 
					
						
							|  |  |  | 	version        cert.Version | 
					
						
							|  |  |  | 	curve          cert.Curve | 
					
						
							|  |  |  | 	groups         []string | 
					
						
							|  |  |  | 	isCa           bool | 
					
						
							|  |  |  | 	issuer         string | 
					
						
							|  |  |  | 	name           string | 
					
						
							|  |  |  | 	networks       []netip.Prefix | 
					
						
							|  |  |  | 	notAfter       time.Time | 
					
						
							|  |  |  | 	notBefore      time.Time | 
					
						
							|  |  |  | 	publicKey      []byte | 
					
						
							|  |  |  | 	signature      []byte | 
					
						
							|  |  |  | 	unsafeNetworks []netip.Prefix | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) Version() cert.Version { | 
					
						
							|  |  |  | 	return d.version | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) Curve() cert.Curve { | 
					
						
							|  |  |  | 	return d.curve | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) Groups() []string { | 
					
						
							|  |  |  | 	return d.groups | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) IsCA() bool { | 
					
						
							|  |  |  | 	return d.isCa | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) Issuer() string { | 
					
						
							|  |  |  | 	return d.issuer | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) Name() string { | 
					
						
							|  |  |  | 	return d.name | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) Networks() []netip.Prefix { | 
					
						
							|  |  |  | 	return d.networks | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) NotAfter() time.Time { | 
					
						
							|  |  |  | 	return d.notAfter | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) NotBefore() time.Time { | 
					
						
							|  |  |  | 	return d.notBefore | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) PublicKey() []byte { | 
					
						
							|  |  |  | 	return d.publicKey | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) Signature() []byte { | 
					
						
							|  |  |  | 	return d.signature | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) UnsafeNetworks() []netip.Prefix { | 
					
						
							|  |  |  | 	return d.unsafeNetworks | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) MarshalForHandshakes() ([]byte, error) { | 
					
						
							|  |  |  | 	return nil, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) Sign(curve cert.Curve, key []byte) error { | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) CheckSignature(key []byte) bool { | 
					
						
							|  |  |  | 	return true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) Expired(t time.Time) bool { | 
					
						
							|  |  |  | 	return false | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) CheckRootConstraints(signer cert.Certificate) error { | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) VerifyPrivateKey(curve cert.Curve, key []byte) error { | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) String() string { | 
					
						
							|  |  |  | 	return "" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) Marshal() ([]byte, error) { | 
					
						
							|  |  |  | 	return nil, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) MarshalPEM() ([]byte, error) { | 
					
						
							|  |  |  | 	return nil, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) Fingerprint() (string, error) { | 
					
						
							|  |  |  | 	return "", nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) MarshalJSON() ([]byte, error) { | 
					
						
							|  |  |  | 	return nil, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *dummyCert) Copy() cert.Certificate { | 
					
						
							|  |  |  | 	return d | 
					
						
							|  |  |  | } |