2021-10-21 16:24:11 -05:00
//go:build e2e_testing
2021-03-29 14:29:20 -05:00
// +build e2e_testing
package e2e
import (
2024-07-31 10:18:56 -05:00
"net/netip"
2024-10-10 18:00:22 -05:00
"slices"
2021-03-29 14:29:20 -05:00
"testing"
"time"
2021-03-31 10:26:35 -05:00
2025-03-06 11:28:26 -06:00
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
2023-03-30 12:09:20 -04:00
"github.com/sirupsen/logrus"
2021-03-31 13:36:10 -05:00
"github.com/slackhq/nebula"
2025-03-06 11:28:26 -06:00
"github.com/slackhq/nebula/cert"
"github.com/slackhq/nebula/cert_test"
2021-03-31 10:26:35 -05:00
"github.com/slackhq/nebula/e2e/router"
2021-11-03 20:54:04 -05:00
"github.com/slackhq/nebula/header"
"github.com/slackhq/nebula/udp"
2021-04-14 13:50:09 -05:00
"github.com/stretchr/testify/assert"
2025-03-10 17:38:14 -05:00
"github.com/stretchr/testify/require"
2025-03-31 16:08:34 -04:00
"gopkg.in/yaml.v3"
2021-03-29 14:29:20 -05:00
)
2022-09-01 09:44:58 -05:00
func BenchmarkHotPath ( b * testing . B ) {
2025-03-06 11:28:26 -06:00
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , _ , _ := newSimpleServer ( cert . Version1 , ca , caKey , "me" , "10.128.0.1/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "them" , "10.128.0.2/24" , nil )
2022-09-01 09:44:58 -05:00
// Put their info in our lighthouse
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
2022-09-01 09:44:58 -05:00
// Start the servers
myControl . Start ( )
theirControl . Start ( )
r := router . NewR ( b , myControl , theirControl )
r . CancelFlowLogs ( )
for n := 0 ; n < b . N ; n ++ {
2025-03-06 11:28:26 -06:00
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me" ) )
2022-09-01 09:44:58 -05:00
_ = r . RouteForAllUntilTxTun ( theirControl )
}
myControl . Stop ( )
theirControl . Stop ( )
}
2021-03-29 14:29:20 -05:00
func TestGoodHandshake ( t * testing . T ) {
2025-03-06 11:28:26 -06:00
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "me" , "10.128.0.1/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "them" , "10.128.0.2/24" , nil )
2021-03-29 14:29:20 -05:00
// Put their info in our lighthouse
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
2021-03-29 14:29:20 -05:00
// Start the servers
myControl . Start ( )
theirControl . Start ( )
2021-04-14 13:50:09 -05:00
t . Log ( "Send a udp packet through to begin standing up the tunnel, this should come out the other side" )
2025-03-06 11:28:26 -06:00
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me" ) )
2021-03-29 14:29:20 -05:00
2021-04-14 13:50:09 -05:00
t . Log ( "Have them consume my stage 0 packet. They have a tunnel now" )
2021-03-29 14:29:20 -05:00
theirControl . InjectUDPPacket ( myControl . GetFromUDP ( true ) )
2021-04-14 13:50:09 -05:00
t . Log ( "Get their stage 1 packet so that we can play with it" )
2021-03-31 13:36:10 -05:00
stage1Packet := theirControl . GetFromUDP ( true )
2021-04-14 13:50:09 -05:00
t . Log ( "I consume a garbage packet with a proper nebula header for our tunnel" )
2021-03-31 13:36:10 -05:00
// this should log a statement and get ignored, allowing the real handshake packet to complete the tunnel
badPacket := stage1Packet . Copy ( )
2021-11-03 20:54:04 -05:00
badPacket . Data = badPacket . Data [ : len ( badPacket . Data ) - header . Len ]
2021-03-31 13:36:10 -05:00
myControl . InjectUDPPacket ( badPacket )
2021-04-14 13:50:09 -05:00
t . Log ( "Have me consume their real stage 1 packet. I have a tunnel now" )
2021-03-31 13:36:10 -05:00
myControl . InjectUDPPacket ( stage1Packet )
2021-03-29 14:29:20 -05:00
2021-04-14 13:50:09 -05:00
t . Log ( "Wait until we see my cached packet come through" )
2021-03-29 14:29:20 -05:00
myControl . WaitForType ( 1 , 0 , theirControl )
2021-04-14 13:50:09 -05:00
t . Log ( "Make sure our host infos are correct" )
2025-03-06 11:28:26 -06:00
assertHostInfoPair ( t , myUdpAddr , theirUdpAddr , myVpnIpNet , theirVpnIpNet , myControl , theirControl )
2021-03-29 14:29:20 -05:00
2021-04-14 13:50:09 -05:00
t . Log ( "Get that cached packet and make sure it looks right" )
2021-03-29 14:29:20 -05:00
myCachedPacket := theirControl . GetFromTun ( true )
2025-03-06 11:28:26 -06:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , myCachedPacket , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , 80 )
2021-03-29 14:29:20 -05:00
2021-04-14 13:50:09 -05:00
t . Log ( "Do a bidirectional tunnel test" )
2022-06-27 12:33:29 -05:00
r := router . NewR ( t , myControl , theirControl )
defer r . RenderFlow ( )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2021-03-29 14:29:20 -05:00
2023-02-16 13:23:33 -06:00
r . RenderHostmaps ( "Final hostmaps" , myControl , theirControl )
2021-03-31 10:26:35 -05:00
myControl . Stop ( )
theirControl . Stop ( )
}
func TestWrongResponderHandshake ( t * testing . T ) {
2025-03-06 11:28:26 -06:00
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
2021-03-31 10:26:35 -05:00
2025-03-06 11:28:26 -06:00
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "me" , "10.128.0.100/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "them" , "10.128.0.99/24" , nil )
evilControl , evilVpnIp , evilUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "evil" , "10.128.0.2/24" , nil )
2021-03-31 10:26:35 -05:00
2024-10-23 14:28:02 -05:00
// Put the evil udp addr in for their vpn Ip, this is a case of being lied to by the lighthouse.
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , evilUdpAddr )
2024-10-23 14:28:02 -05:00
// Build a router so we don't have to reason who gets which packet
r := router . NewR ( t , myControl , theirControl , evilControl )
defer r . RenderFlow ( )
// Start the servers
myControl . Start ( )
theirControl . Start ( )
evilControl . Start ( )
t . Log ( "Start the handshake process, we will route until we see the evil tunnel closed" )
2025-03-06 11:28:26 -06:00
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me" ) )
2024-10-23 14:28:02 -05:00
h := & header . H { }
r . RouteForAllExitFunc ( func ( p * udp . Packet , c * nebula . Control ) router . ExitType {
err := h . Parse ( p . Data )
if err != nil {
panic ( err )
}
if h . Type == header . CloseTunnel && p . To == evilUdpAddr {
return router . RouteAndExit
}
return router . KeepRouting
} )
t . Log ( "Evil tunnel is closed, inject the correct udp addr for them" )
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
pendingHi := myControl . GetHostInfoByVpnAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , true )
2024-10-23 14:28:02 -05:00
assert . NotContains ( t , pendingHi . RemoteAddrs , evilUdpAddr )
2021-03-31 10:26:35 -05:00
2024-10-23 14:28:02 -05:00
t . Log ( "Route until we see the cached packet" )
r . RouteForAllExitFunc ( func ( p * udp . Packet , c * nebula . Control ) router . ExitType {
err := h . Parse ( p . Data )
if err != nil {
panic ( err )
}
if p . To == theirUdpAddr && h . Type == 1 {
return router . RouteAndExit
}
return router . KeepRouting
} )
t . Log ( "My cached packet should be received by them" )
myCachedPacket := theirControl . GetFromTun ( true )
2025-03-06 11:28:26 -06:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , myCachedPacket , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , 80 )
2024-10-23 14:28:02 -05:00
t . Log ( "Test the tunnel with them" )
2025-03-06 11:28:26 -06:00
assertHostInfoPair ( t , myUdpAddr , theirUdpAddr , myVpnIpNet , theirVpnIpNet , myControl , theirControl )
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2024-10-23 14:28:02 -05:00
t . Log ( "Flush all packets from all controllers" )
r . FlushAll ( )
t . Log ( "Ensure ensure I don't have any hostinfo artifacts from evil" )
2025-03-06 11:28:26 -06:00
assert . Nil ( t , myControl . GetHostInfoByVpnAddr ( evilVpnIp [ 0 ] . Addr ( ) , true ) , "My pending hostmap should not contain evil" )
assert . Nil ( t , myControl . GetHostInfoByVpnAddr ( evilVpnIp [ 0 ] . Addr ( ) , false ) , "My main hostmap should not contain evil" )
2024-10-23 14:28:02 -05:00
r . RenderHostmaps ( "Final hostmaps" , myControl , theirControl , evilControl )
t . Log ( "Success!" )
myControl . Stop ( )
theirControl . Stop ( )
}
func TestWrongResponderHandshakeStaticHostMap ( t * testing . T ) {
2025-03-06 11:28:26 -06:00
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
2024-10-23 14:28:02 -05:00
2025-03-06 11:28:26 -06:00
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "them" , "10.128.0.99/24" , nil )
evilControl , evilVpnIp , evilUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "evil" , "10.128.0.2/24" , nil )
2024-10-23 14:28:02 -05:00
o := m {
"static_host_map" : m {
2025-03-06 11:28:26 -06:00
theirVpnIpNet [ 0 ] . Addr ( ) . String ( ) : [ ] string { evilUdpAddr . String ( ) } ,
2024-10-23 14:28:02 -05:00
} ,
}
2025-03-06 11:28:26 -06:00
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "me" , "10.128.0.100/24" , o )
2024-10-23 14:28:02 -05:00
// Put the evil udp addr in for their vpn addr, this is a case of a remote at a static entry changing its vpn addr.
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , evilUdpAddr )
2021-03-31 17:32:02 -05:00
2021-03-31 10:26:35 -05:00
// Build a router so we don't have to reason who gets which packet
2022-06-27 12:33:29 -05:00
r := router . NewR ( t , myControl , theirControl , evilControl )
defer r . RenderFlow ( )
2021-03-31 10:26:35 -05:00
// Start the servers
myControl . Start ( )
theirControl . Start ( )
evilControl . Start ( )
2024-10-23 14:28:02 -05:00
t . Log ( "Start the handshake process, we will route until we see the evil tunnel closed" )
2025-03-06 11:28:26 -06:00
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me" ) )
2024-10-23 14:28:02 -05:00
h := & header . H { }
r . RouteForAllExitFunc ( func ( p * udp . Packet , c * nebula . Control ) router . ExitType {
err := h . Parse ( p . Data )
if err != nil {
panic ( err )
}
if h . Type == header . CloseTunnel && p . To == evilUdpAddr {
return router . RouteAndExit
}
return router . KeepRouting
} )
t . Log ( "Evil tunnel is closed, inject the correct udp addr for them" )
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
pendingHi := myControl . GetHostInfoByVpnAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , true )
2024-10-23 14:28:02 -05:00
assert . NotContains ( t , pendingHi . RemoteAddrs , evilUdpAddr )
t . Log ( "Route until we see the cached packet" )
2021-11-03 20:54:04 -05:00
r . RouteForAllExitFunc ( func ( p * udp . Packet , c * nebula . Control ) router . ExitType {
2021-04-14 13:50:09 -05:00
err := h . Parse ( p . Data )
if err != nil {
panic ( err )
}
2021-03-31 10:26:35 -05:00
2024-07-31 10:18:56 -05:00
if p . To == theirUdpAddr && h . Type == 1 {
2021-04-14 13:50:09 -05:00
return router . RouteAndExit
}
2021-03-31 10:26:35 -05:00
2021-04-14 13:50:09 -05:00
return router . KeepRouting
} )
2021-03-31 10:26:35 -05:00
2021-04-14 13:50:09 -05:00
t . Log ( "My cached packet should be received by them" )
2021-03-31 10:26:35 -05:00
myCachedPacket := theirControl . GetFromTun ( true )
2025-03-06 11:28:26 -06:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , myCachedPacket , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , 80 )
2021-03-31 10:26:35 -05:00
2021-04-14 13:50:09 -05:00
t . Log ( "Test the tunnel with them" )
2025-03-06 11:28:26 -06:00
assertHostInfoPair ( t , myUdpAddr , theirUdpAddr , myVpnIpNet , theirVpnIpNet , myControl , theirControl )
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2021-03-31 10:26:35 -05:00
2021-04-14 13:50:09 -05:00
t . Log ( "Flush all packets from all controllers" )
r . FlushAll ( )
t . Log ( "Ensure ensure I don't have any hostinfo artifacts from evil" )
2025-03-06 11:28:26 -06:00
assert . Nil ( t , myControl . GetHostInfoByVpnAddr ( evilVpnIp [ 0 ] . Addr ( ) , true ) , "My pending hostmap should not contain evil" )
assert . Nil ( t , myControl . GetHostInfoByVpnAddr ( evilVpnIp [ 0 ] . Addr ( ) , false ) , "My main hostmap should not contain evil" )
//NOTE: if evil lost the handshake race it may still have a tunnel since me would reject the handshake since the tunnel is complete
2021-03-31 10:26:35 -05:00
2023-02-16 13:23:33 -06:00
r . RenderHostmaps ( "Final hostmaps" , myControl , theirControl , evilControl )
2021-03-31 10:26:35 -05:00
t . Log ( "Success!" )
2021-04-14 13:50:09 -05:00
myControl . Stop ( )
theirControl . Stop ( )
}
2023-03-13 12:35:14 -05:00
func TestStage1Race ( t * testing . T ) {
// This tests ensures that two hosts handshaking with each other at the same time will allow traffic to flow
// But will eventually collapse down to a single tunnel
2025-03-06 11:28:26 -06:00
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "me " , "10.128.0.1/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "them" , "10.128.0.2/24" , nil )
2021-04-14 13:50:09 -05:00
// Put their info in our lighthouse and vice versa
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
theirControl . InjectLightHouseAddr ( myVpnIpNet [ 0 ] . Addr ( ) , myUdpAddr )
2021-04-14 13:50:09 -05:00
// Build a router so we don't have to reason who gets which packet
2022-06-27 12:33:29 -05:00
r := router . NewR ( t , myControl , theirControl )
defer r . RenderFlow ( )
2021-04-14 13:50:09 -05:00
// Start the servers
myControl . Start ( )
theirControl . Start ( )
t . Log ( "Trigger a handshake to start on both me and them" )
2025-03-06 11:28:26 -06:00
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me" ) )
theirControl . InjectTunUDPPacket ( myVpnIpNet [ 0 ] . Addr ( ) , 80 , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from them" ) )
2021-04-14 13:50:09 -05:00
t . Log ( "Get both stage 1 handshake packets" )
myHsForThem := myControl . GetFromUDP ( true )
theirHsForMe := theirControl . GetFromUDP ( true )
2022-06-27 12:33:29 -05:00
r . Log ( "Now inject both stage 1 handshake packets" )
r . InjectUDPPacket ( theirControl , myControl , theirHsForMe )
r . InjectUDPPacket ( myControl , theirControl , myHsForThem )
2021-04-14 13:50:09 -05:00
2023-03-13 12:35:14 -05:00
r . Log ( "Route until they receive a message packet" )
myCachedPacket := r . RouteForAllUntilTxTun ( theirControl )
2025-03-06 11:28:26 -06:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , myCachedPacket , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , 80 )
2021-04-14 13:50:09 -05:00
2023-03-13 12:35:14 -05:00
r . Log ( "Their cached packet should be received by me" )
theirCachedPacket := r . RouteForAllUntilTxTun ( myControl )
2025-03-06 11:28:26 -06:00
assertUdpPacket ( t , [ ] byte ( "Hi from them" ) , theirCachedPacket , theirVpnIpNet [ 0 ] . Addr ( ) , myVpnIpNet [ 0 ] . Addr ( ) , 80 , 80 )
2021-04-14 13:50:09 -05:00
2023-03-13 12:35:14 -05:00
r . Log ( "Do a bidirectional tunnel test" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2021-04-14 13:50:09 -05:00
2023-03-13 12:35:14 -05:00
myHostmapHosts := myControl . ListHostmapHosts ( false )
myHostmapIndexes := myControl . ListHostmapIndexes ( false )
theirHostmapHosts := theirControl . ListHostmapHosts ( false )
theirHostmapIndexes := theirControl . ListHostmapIndexes ( false )
2021-04-14 13:50:09 -05:00
2023-03-13 12:35:14 -05:00
// We should have two tunnels on both sides
assert . Len ( t , myHostmapHosts , 1 )
assert . Len ( t , theirHostmapHosts , 1 )
assert . Len ( t , myHostmapIndexes , 2 )
assert . Len ( t , theirHostmapIndexes , 2 )
2021-04-14 13:50:09 -05:00
2023-03-13 12:35:14 -05:00
r . RenderHostmaps ( "Starting hostmaps" , myControl , theirControl )
r . Log ( "Spin until connection manager tears down a tunnel" )
for len ( myControl . GetHostmap ( ) . Indexes ) + len ( theirControl . GetHostmap ( ) . Indexes ) > 2 {
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2023-03-13 12:35:14 -05:00
t . Log ( "Connection manager hasn't ticked yet" )
time . Sleep ( time . Second )
}
myFinalHostmapHosts := myControl . ListHostmapHosts ( false )
myFinalHostmapIndexes := myControl . ListHostmapIndexes ( false )
theirFinalHostmapHosts := theirControl . ListHostmapHosts ( false )
theirFinalHostmapIndexes := theirControl . ListHostmapIndexes ( false )
// We should only have a single tunnel now on both sides
assert . Len ( t , myFinalHostmapHosts , 1 )
assert . Len ( t , theirFinalHostmapHosts , 1 )
assert . Len ( t , myFinalHostmapIndexes , 1 )
assert . Len ( t , theirFinalHostmapIndexes , 1 )
2021-04-14 13:50:09 -05:00
2023-02-16 13:23:33 -06:00
r . RenderHostmaps ( "Final hostmaps" , myControl , theirControl )
2021-04-14 13:50:09 -05:00
myControl . Stop ( )
theirControl . Stop ( )
2023-03-13 12:35:14 -05:00
}
func TestUncleanShutdownRaceLoser ( t * testing . T ) {
2025-03-06 11:28:26 -06:00
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "me " , "10.128.0.1/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "them" , "10.128.0.2/24" , nil )
2023-03-13 12:35:14 -05:00
// Teach my how to get to the relay and that their can be reached via the relay
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
theirControl . InjectLightHouseAddr ( myVpnIpNet [ 0 ] . Addr ( ) , myUdpAddr )
2023-03-13 12:35:14 -05:00
// Build a router so we don't have to reason who gets which packet
r := router . NewR ( t , myControl , theirControl )
defer r . RenderFlow ( )
// Start the servers
myControl . Start ( )
theirControl . Start ( )
r . Log ( "Trigger a handshake from me to them" )
2025-03-06 11:28:26 -06:00
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me" ) )
2023-03-13 12:35:14 -05:00
p := r . RouteForAllUntilTxTun ( theirControl )
2025-03-06 11:28:26 -06:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , p , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , 80 )
2023-03-13 12:35:14 -05:00
r . Log ( "Nuke my hostmap" )
myHostmap := myControl . GetHostmap ( )
2024-07-31 10:18:56 -05:00
myHostmap . Hosts = map [ netip . Addr ] * nebula . HostInfo { }
2023-03-13 12:35:14 -05:00
myHostmap . Indexes = map [ uint32 ] * nebula . HostInfo { }
myHostmap . RemoteIndexes = map [ uint32 ] * nebula . HostInfo { }
2025-03-06 11:28:26 -06:00
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me again" ) )
2023-03-13 12:35:14 -05:00
p = r . RouteForAllUntilTxTun ( theirControl )
2025-03-06 11:28:26 -06:00
assertUdpPacket ( t , [ ] byte ( "Hi from me again" ) , p , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , 80 )
2023-03-13 12:35:14 -05:00
r . Log ( "Assert the tunnel works" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2023-03-13 12:35:14 -05:00
r . Log ( "Wait for the dead index to go away" )
start := len ( theirControl . GetHostmap ( ) . Indexes )
for {
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2023-03-13 12:35:14 -05:00
if len ( theirControl . GetHostmap ( ) . Indexes ) < start {
break
}
time . Sleep ( time . Second )
}
r . RenderHostmaps ( "Final hostmaps" , myControl , theirControl )
}
func TestUncleanShutdownRaceWinner ( t * testing . T ) {
2025-03-06 11:28:26 -06:00
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "me " , "10.128.0.1/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "them" , "10.128.0.2/24" , nil )
2023-03-13 12:35:14 -05:00
// Teach my how to get to the relay and that their can be reached via the relay
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
theirControl . InjectLightHouseAddr ( myVpnIpNet [ 0 ] . Addr ( ) , myUdpAddr )
2023-03-13 12:35:14 -05:00
// Build a router so we don't have to reason who gets which packet
r := router . NewR ( t , myControl , theirControl )
defer r . RenderFlow ( )
// Start the servers
myControl . Start ( )
theirControl . Start ( )
r . Log ( "Trigger a handshake from me to them" )
2025-03-06 11:28:26 -06:00
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me" ) )
2023-03-13 12:35:14 -05:00
p := r . RouteForAllUntilTxTun ( theirControl )
2025-03-06 11:28:26 -06:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , p , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , 80 )
2023-03-13 12:35:14 -05:00
r . RenderHostmaps ( "Final hostmaps" , myControl , theirControl )
r . Log ( "Nuke my hostmap" )
theirHostmap := theirControl . GetHostmap ( )
2024-07-31 10:18:56 -05:00
theirHostmap . Hosts = map [ netip . Addr ] * nebula . HostInfo { }
2023-03-13 12:35:14 -05:00
theirHostmap . Indexes = map [ uint32 ] * nebula . HostInfo { }
theirHostmap . RemoteIndexes = map [ uint32 ] * nebula . HostInfo { }
2025-03-06 11:28:26 -06:00
theirControl . InjectTunUDPPacket ( myVpnIpNet [ 0 ] . Addr ( ) , 80 , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from them again" ) )
2023-03-13 12:35:14 -05:00
p = r . RouteForAllUntilTxTun ( myControl )
2025-03-06 11:28:26 -06:00
assertUdpPacket ( t , [ ] byte ( "Hi from them again" ) , p , theirVpnIpNet [ 0 ] . Addr ( ) , myVpnIpNet [ 0 ] . Addr ( ) , 80 , 80 )
2023-03-13 12:35:14 -05:00
r . RenderHostmaps ( "Derp hostmaps" , myControl , theirControl )
r . Log ( "Assert the tunnel works" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2023-03-13 12:35:14 -05:00
r . Log ( "Wait for the dead index to go away" )
start := len ( myControl . GetHostmap ( ) . Indexes )
for {
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2023-03-13 12:35:14 -05:00
if len ( myControl . GetHostmap ( ) . Indexes ) < start {
break
}
time . Sleep ( time . Second )
}
r . RenderHostmaps ( "Final hostmaps" , myControl , theirControl )
2021-03-29 14:29:20 -05:00
}
2021-03-31 10:26:35 -05:00
2022-06-27 12:33:29 -05:00
func TestRelays ( t * testing . T ) {
2025-03-06 11:28:26 -06:00
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , _ , _ := newSimpleServer ( cert . Version1 , ca , caKey , "me " , "10.128.0.1/24" , m { "relay" : m { "use_relays" : true } } )
relayControl , relayVpnIpNet , relayUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "relay " , "10.128.0.128/24" , m { "relay" : m { "am_relay" : true } } )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "them " , "10.128.0.2/24" , m { "relay" : m { "use_relays" : true } } )
2022-06-27 12:33:29 -05:00
// Teach my how to get to the relay and that their can be reached via the relay
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( relayVpnIpNet [ 0 ] . Addr ( ) , relayUdpAddr )
myControl . InjectRelays ( theirVpnIpNet [ 0 ] . Addr ( ) , [ ] netip . Addr { relayVpnIpNet [ 0 ] . Addr ( ) } )
relayControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
2022-06-27 12:33:29 -05:00
// Build a router so we don't have to reason who gets which packet
r := router . NewR ( t , myControl , relayControl , theirControl )
defer r . RenderFlow ( )
// Start the servers
myControl . Start ( )
relayControl . Start ( )
theirControl . Start ( )
t . Log ( "Trigger a handshake from me to them via the relay" )
2025-03-06 11:28:26 -06:00
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me" ) )
2022-06-27 12:33:29 -05:00
p := r . RouteForAllUntilTxTun ( theirControl )
2023-03-13 12:35:14 -05:00
r . Log ( "Assert the tunnel works" )
2025-03-06 11:28:26 -06:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , p , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , 80 )
2023-02-16 13:23:33 -06:00
r . RenderHostmaps ( "Final hostmaps" , myControl , relayControl , theirControl )
2025-03-06 11:28:26 -06:00
}
func TestReestablishRelays ( t * testing . T ) {
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , _ , _ := newSimpleServer ( cert . Version1 , ca , caKey , "me " , "10.128.0.1/24" , m { "relay" : m { "use_relays" : true } } )
relayControl , relayVpnIpNet , relayUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "relay " , "10.128.0.128/24" , m { "relay" : m { "am_relay" : true } } )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "them " , "10.128.0.2/24" , m { "relay" : m { "use_relays" : true } } )
// Teach my how to get to the relay and that their can be reached via the relay
myControl . InjectLightHouseAddr ( relayVpnIpNet [ 0 ] . Addr ( ) , relayUdpAddr )
myControl . InjectRelays ( theirVpnIpNet [ 0 ] . Addr ( ) , [ ] netip . Addr { relayVpnIpNet [ 0 ] . Addr ( ) } )
relayControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
// Build a router so we don't have to reason who gets which packet
r := router . NewR ( t , myControl , relayControl , theirControl )
defer r . RenderFlow ( )
// Start the servers
myControl . Start ( )
relayControl . Start ( )
theirControl . Start ( )
t . Log ( "Trigger a handshake from me to them via the relay" )
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me" ) )
p := r . RouteForAllUntilTxTun ( theirControl )
r . Log ( "Assert the tunnel works" )
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , p , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , 80 )
t . Log ( "Ensure packet traversal from them to me via the relay" )
theirControl . InjectTunUDPPacket ( myVpnIpNet [ 0 ] . Addr ( ) , 80 , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from them" ) )
p = r . RouteForAllUntilTxTun ( myControl )
r . Log ( "Assert the tunnel works" )
assertUdpPacket ( t , [ ] byte ( "Hi from them" ) , p , theirVpnIpNet [ 0 ] . Addr ( ) , myVpnIpNet [ 0 ] . Addr ( ) , 80 , 80 )
// If we break the relay's connection to 'them', 'me' needs to detect and recover the connection
r . Log ( "Close the tunnel" )
relayControl . CloseTunnel ( theirVpnIpNet [ 0 ] . Addr ( ) , true )
start := len ( myControl . GetHostmap ( ) . Indexes )
curIndexes := len ( myControl . GetHostmap ( ) . Indexes )
for curIndexes >= start {
curIndexes = len ( myControl . GetHostmap ( ) . Indexes )
r . Logf ( "Wait for the dead index to go away:start=%v indexes, currnet=%v indexes" , start , curIndexes )
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me should fail" ) )
r . RouteForAllExitFunc ( func ( p * udp . Packet , c * nebula . Control ) router . ExitType {
return router . RouteAndExit
} )
time . Sleep ( 2 * time . Second )
}
r . Log ( "Dead index went away. Woot!" )
r . RenderHostmaps ( "Me removed hostinfo" , myControl , relayControl , theirControl )
// Next packet should re-establish a relayed connection and work just great.
t . Logf ( "Assert the tunnel..." )
for {
t . Log ( "RouteForAllUntilTxTun" )
myControl . InjectLightHouseAddr ( relayVpnIpNet [ 0 ] . Addr ( ) , relayUdpAddr )
myControl . InjectRelays ( theirVpnIpNet [ 0 ] . Addr ( ) , [ ] netip . Addr { relayVpnIpNet [ 0 ] . Addr ( ) } )
relayControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me" ) )
p = r . RouteForAllUntilTxTun ( theirControl )
r . Log ( "Assert the tunnel works" )
packet := gopacket . NewPacket ( p , layers . LayerTypeIPv4 , gopacket . Lazy )
v4 := packet . Layer ( layers . LayerTypeIPv4 ) . ( * layers . IPv4 )
if slices . Compare ( v4 . SrcIP , myVpnIpNet [ 0 ] . Addr ( ) . AsSlice ( ) ) != 0 {
t . Logf ( "SrcIP is unexpected...this is not the packet I'm looking for. Keep looking" )
continue
}
if slices . Compare ( v4 . DstIP , theirVpnIpNet [ 0 ] . Addr ( ) . AsSlice ( ) ) != 0 {
t . Logf ( "DstIP is unexpected...this is not the packet I'm looking for. Keep looking" )
continue
}
udp := packet . Layer ( layers . LayerTypeUDP ) . ( * layers . UDP )
if udp == nil {
t . Log ( "Not a UDP packet. This is not the packet I'm looking for. Keep looking" )
continue
}
data := packet . ApplicationLayer ( )
if data == nil {
t . Log ( "No data found in packet. This is not the packet I'm looking for. Keep looking." )
continue
}
if string ( data . Payload ( ) ) != "Hi from me" {
t . Logf ( "Unexpected payload: '%v', keep looking" , string ( data . Payload ( ) ) )
continue
}
t . Log ( "I found my lost packet. I am so happy." )
break
}
t . Log ( "Assert the tunnel works the other way, too" )
for {
t . Log ( "RouteForAllUntilTxTun" )
theirControl . InjectTunUDPPacket ( myVpnIpNet [ 0 ] . Addr ( ) , 80 , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from them" ) )
p = r . RouteForAllUntilTxTun ( myControl )
r . Log ( "Assert the tunnel works" )
packet := gopacket . NewPacket ( p , layers . LayerTypeIPv4 , gopacket . Lazy )
v4 := packet . Layer ( layers . LayerTypeIPv4 ) . ( * layers . IPv4 )
if slices . Compare ( v4 . DstIP , myVpnIpNet [ 0 ] . Addr ( ) . AsSlice ( ) ) != 0 {
t . Logf ( "Dst is unexpected...this is not the packet I'm looking for. Keep looking" )
continue
}
if slices . Compare ( v4 . SrcIP , theirVpnIpNet [ 0 ] . Addr ( ) . AsSlice ( ) ) != 0 {
t . Logf ( "SrcIP is unexpected...this is not the packet I'm looking for. Keep looking" )
continue
}
udp := packet . Layer ( layers . LayerTypeUDP ) . ( * layers . UDP )
if udp == nil {
t . Log ( "Not a UDP packet. This is not the packet I'm looking for. Keep looking" )
continue
}
data := packet . ApplicationLayer ( )
if data == nil {
t . Log ( "No data found in packet. This is not the packet I'm looking for. Keep looking." )
continue
}
if string ( data . Payload ( ) ) != "Hi from them" {
t . Logf ( "Unexpected payload: '%v', keep looking" , string ( data . Payload ( ) ) )
continue
}
t . Log ( "I found my lost packet. I am so happy." )
break
}
r . RenderHostmaps ( "Final hostmaps" , myControl , relayControl , theirControl )
2022-06-27 12:33:29 -05:00
}
2023-03-13 12:35:14 -05:00
func TestStage1RaceRelays ( t * testing . T ) {
//NOTE: this is a race between me and relay resulting in a full tunnel from me to them via relay
2025-03-06 11:28:26 -06:00
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "me " , "10.128.0.1/24" , m { "relay" : m { "use_relays" : true } } )
relayControl , relayVpnIpNet , relayUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "relay " , "10.128.0.128/24" , m { "relay" : m { "am_relay" : true } } )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "them " , "10.128.0.2/24" , m { "relay" : m { "use_relays" : true } } )
2023-03-13 12:35:14 -05:00
// Teach my how to get to the relay and that their can be reached via the relay
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( relayVpnIpNet [ 0 ] . Addr ( ) , relayUdpAddr )
theirControl . InjectLightHouseAddr ( relayVpnIpNet [ 0 ] . Addr ( ) , relayUdpAddr )
2023-03-13 12:35:14 -05:00
2025-03-06 11:28:26 -06:00
myControl . InjectRelays ( theirVpnIpNet [ 0 ] . Addr ( ) , [ ] netip . Addr { relayVpnIpNet [ 0 ] . Addr ( ) } )
theirControl . InjectRelays ( myVpnIpNet [ 0 ] . Addr ( ) , [ ] netip . Addr { relayVpnIpNet [ 0 ] . Addr ( ) } )
2023-03-13 12:35:14 -05:00
2025-03-06 11:28:26 -06:00
relayControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
relayControl . InjectLightHouseAddr ( myVpnIpNet [ 0 ] . Addr ( ) , myUdpAddr )
2023-03-13 12:35:14 -05:00
// Build a router so we don't have to reason who gets which packet
r := router . NewR ( t , myControl , relayControl , theirControl )
defer r . RenderFlow ( )
// Start the servers
myControl . Start ( )
relayControl . Start ( )
theirControl . Start ( )
2023-03-30 12:09:20 -04:00
r . Log ( "Get a tunnel between me and relay" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , relayVpnIpNet [ 0 ] . Addr ( ) , myControl , relayControl , r )
2023-03-13 12:35:14 -05:00
2023-03-30 12:09:20 -04:00
r . Log ( "Get a tunnel between them and relay" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , theirVpnIpNet [ 0 ] . Addr ( ) , relayVpnIpNet [ 0 ] . Addr ( ) , theirControl , relayControl , r )
2023-03-13 12:35:14 -05:00
2023-03-30 12:09:20 -04:00
r . Log ( "Trigger a handshake from both them and me via relay to them and me" )
2025-03-06 11:28:26 -06:00
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me" ) )
theirControl . InjectTunUDPPacket ( myVpnIpNet [ 0 ] . Addr ( ) , 80 , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from them" ) )
2023-03-13 12:35:14 -05:00
2023-03-30 12:09:20 -04:00
r . Log ( "Wait for a packet from them to me" )
p := r . RouteForAllUntilTxTun ( myControl )
_ = p
2023-03-13 12:35:14 -05:00
2023-07-26 12:52:14 -05:00
r . FlushAll ( )
2023-03-30 12:09:20 -04:00
myControl . Stop ( )
theirControl . Stop ( )
relayControl . Stop ( )
}
2023-03-13 12:35:14 -05:00
2023-03-30 12:09:20 -04:00
func TestStage1RaceRelays2 ( t * testing . T ) {
//NOTE: this is a race between me and relay resulting in a full tunnel from me to them via relay
2025-03-06 11:28:26 -06:00
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "me " , "10.128.0.1/24" , m { "relay" : m { "use_relays" : true } } )
relayControl , relayVpnIpNet , relayUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "relay " , "10.128.0.128/24" , m { "relay" : m { "am_relay" : true } } )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "them " , "10.128.0.2/24" , m { "relay" : m { "use_relays" : true } } )
2023-03-30 12:09:20 -04:00
l := NewTestLogger ( )
// Teach my how to get to the relay and that their can be reached via the relay
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( relayVpnIpNet [ 0 ] . Addr ( ) , relayUdpAddr )
theirControl . InjectLightHouseAddr ( relayVpnIpNet [ 0 ] . Addr ( ) , relayUdpAddr )
2023-03-30 12:09:20 -04:00
2025-03-06 11:28:26 -06:00
myControl . InjectRelays ( theirVpnIpNet [ 0 ] . Addr ( ) , [ ] netip . Addr { relayVpnIpNet [ 0 ] . Addr ( ) } )
theirControl . InjectRelays ( myVpnIpNet [ 0 ] . Addr ( ) , [ ] netip . Addr { relayVpnIpNet [ 0 ] . Addr ( ) } )
2023-03-13 12:35:14 -05:00
2025-03-06 11:28:26 -06:00
relayControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
relayControl . InjectLightHouseAddr ( myVpnIpNet [ 0 ] . Addr ( ) , myUdpAddr )
2023-03-30 12:09:20 -04:00
// Build a router so we don't have to reason who gets which packet
r := router . NewR ( t , myControl , relayControl , theirControl )
defer r . RenderFlow ( )
// Start the servers
myControl . Start ( )
relayControl . Start ( )
theirControl . Start ( )
r . Log ( "Get a tunnel between me and relay" )
l . Info ( "Get a tunnel between me and relay" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , relayVpnIpNet [ 0 ] . Addr ( ) , myControl , relayControl , r )
2023-03-13 12:35:14 -05:00
2023-03-30 12:09:20 -04:00
r . Log ( "Get a tunnel between them and relay" )
l . Info ( "Get a tunnel between them and relay" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , theirVpnIpNet [ 0 ] . Addr ( ) , relayVpnIpNet [ 0 ] . Addr ( ) , theirControl , relayControl , r )
2023-03-13 12:35:14 -05:00
2023-03-30 12:09:20 -04:00
r . Log ( "Trigger a handshake from both them and me via relay to them and me" )
l . Info ( "Trigger a handshake from both them and me via relay to them and me" )
2025-03-06 11:28:26 -06:00
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me" ) )
theirControl . InjectTunUDPPacket ( myVpnIpNet [ 0 ] . Addr ( ) , 80 , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from them" ) )
2023-03-30 12:09:20 -04:00
//r.RouteUntilAfterMsgType(myControl, header.Control, header.MessageNone)
//r.RouteUntilAfterMsgType(theirControl, header.Control, header.MessageNone)
2023-03-13 12:35:14 -05:00
2023-03-30 12:09:20 -04:00
r . Log ( "Wait for a packet from them to me" )
l . Info ( "Wait for a packet from them to me; myControl" )
r . RouteForAllUntilTxTun ( myControl )
l . Info ( "Wait for a packet from them to me; theirControl" )
r . RouteForAllUntilTxTun ( theirControl )
r . Log ( "Assert the tunnel works" )
l . Info ( "Assert the tunnel works" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , theirVpnIpNet [ 0 ] . Addr ( ) , myVpnIpNet [ 0 ] . Addr ( ) , theirControl , myControl , r )
2023-03-30 12:09:20 -04:00
t . Log ( "Wait until we remove extra tunnels" )
l . Info ( "Wait until we remove extra tunnels" )
l . WithFields (
logrus . Fields {
"myControl" : len ( myControl . GetHostmap ( ) . Indexes ) ,
"theirControl" : len ( theirControl . GetHostmap ( ) . Indexes ) ,
"relayControl" : len ( relayControl . GetHostmap ( ) . Indexes ) ,
} ) . Info ( "Waiting for hostinfos to be removed..." )
hostInfos := len ( myControl . GetHostmap ( ) . Indexes ) + len ( theirControl . GetHostmap ( ) . Indexes ) + len ( relayControl . GetHostmap ( ) . Indexes )
retries := 60
for hostInfos > 6 && retries > 0 {
hostInfos = len ( myControl . GetHostmap ( ) . Indexes ) + len ( theirControl . GetHostmap ( ) . Indexes ) + len ( relayControl . GetHostmap ( ) . Indexes )
l . WithFields (
logrus . Fields {
"myControl" : len ( myControl . GetHostmap ( ) . Indexes ) ,
"theirControl" : len ( theirControl . GetHostmap ( ) . Indexes ) ,
"relayControl" : len ( relayControl . GetHostmap ( ) . Indexes ) ,
} ) . Info ( "Waiting for hostinfos to be removed..." )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2023-03-30 12:09:20 -04:00
t . Log ( "Connection manager hasn't ticked yet" )
time . Sleep ( time . Second )
retries --
}
r . Log ( "Assert the tunnel works" )
l . Info ( "Assert the tunnel works" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , theirVpnIpNet [ 0 ] . Addr ( ) , myVpnIpNet [ 0 ] . Addr ( ) , theirControl , myControl , r )
2023-03-13 12:35:14 -05:00
myControl . Stop ( )
theirControl . Stop ( )
relayControl . Stop ( )
}
2024-07-31 10:18:56 -05:00
2023-05-04 15:16:37 -05:00
func TestRehandshakingRelays ( t * testing . T ) {
2025-03-06 11:28:26 -06:00
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , _ , _ := newSimpleServer ( cert . Version1 , ca , caKey , "me " , "10.128.0.1/24" , m { "relay" : m { "use_relays" : true } } )
relayControl , relayVpnIpNet , relayUdpAddr , relayConfig := newSimpleServer ( cert . Version1 , ca , caKey , "relay " , "10.128.0.128/24" , m { "relay" : m { "am_relay" : true } } )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "them " , "10.128.0.2/24" , m { "relay" : m { "use_relays" : true } } )
2023-05-04 15:16:37 -05:00
// Teach my how to get to the relay and that their can be reached via the relay
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( relayVpnIpNet [ 0 ] . Addr ( ) , relayUdpAddr )
myControl . InjectRelays ( theirVpnIpNet [ 0 ] . Addr ( ) , [ ] netip . Addr { relayVpnIpNet [ 0 ] . Addr ( ) } )
relayControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
2023-05-04 15:16:37 -05:00
// Build a router so we don't have to reason who gets which packet
r := router . NewR ( t , myControl , relayControl , theirControl )
defer r . RenderFlow ( )
// Start the servers
myControl . Start ( )
2023-09-05 09:29:27 -04:00
relayControl . Start ( )
theirControl . Start ( )
t . Log ( "Trigger a handshake from me to them via the relay" )
2025-03-06 11:28:26 -06:00
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me" ) )
2023-09-05 09:29:27 -04:00
p := r . RouteForAllUntilTxTun ( theirControl )
r . Log ( "Assert the tunnel works" )
2025-03-06 11:28:26 -06:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , p , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , 80 )
2023-09-05 09:29:27 -04:00
r . RenderHostmaps ( "working hostmaps" , myControl , relayControl , theirControl )
// When I update the certificate for the relay, both me and them will have 2 host infos for the relay,
// and the main host infos will not have any relay state to handle the me<->relay<->them tunnel.
r . Log ( "Renew relay certificate and spin until me and them sees it" )
2025-03-06 11:28:26 -06:00
_ , _ , myNextPrivKey , myNextPEM := cert_test . NewTestCert ( cert . Version1 , cert . Curve_CURVE25519 , ca , caKey , "relay" , time . Now ( ) , time . Now ( ) . Add ( 5 * time . Minute ) , relayVpnIpNet , nil , [ ] string { "new group" } )
2023-09-05 09:29:27 -04:00
2024-10-10 18:00:22 -05:00
caB , err := ca . MarshalPEM ( )
2023-09-05 09:29:27 -04:00
if err != nil {
panic ( err )
}
relayConfig . Settings [ "pki" ] = m {
"ca" : string ( caB ) ,
"cert" : string ( myNextPEM ) ,
"key" : string ( myNextPrivKey ) ,
}
rc , err := yaml . Marshal ( relayConfig . Settings )
2025-03-10 17:38:14 -05:00
require . NoError ( t , err )
2023-09-05 09:29:27 -04:00
relayConfig . ReloadConfigString ( string ( rc ) )
for {
r . Log ( "Assert the tunnel works between myVpnIpNet and relayVpnIpNet" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , relayVpnIpNet [ 0 ] . Addr ( ) , myControl , relayControl , r )
c := myControl . GetHostInfoByVpnAddr ( relayVpnIpNet [ 0 ] . Addr ( ) , false )
2024-10-10 18:00:22 -05:00
if len ( c . Cert . Groups ( ) ) != 0 {
2023-09-05 09:29:27 -04:00
// We have a new certificate now
r . Log ( "Certificate between my and relay is updated!" )
break
}
time . Sleep ( time . Second )
}
for {
r . Log ( "Assert the tunnel works between theirVpnIpNet and relayVpnIpNet" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , theirVpnIpNet [ 0 ] . Addr ( ) , relayVpnIpNet [ 0 ] . Addr ( ) , theirControl , relayControl , r )
c := theirControl . GetHostInfoByVpnAddr ( relayVpnIpNet [ 0 ] . Addr ( ) , false )
2024-10-10 18:00:22 -05:00
if len ( c . Cert . Groups ( ) ) != 0 {
2023-09-05 09:29:27 -04:00
// We have a new certificate now
r . Log ( "Certificate between their and relay is updated!" )
break
}
time . Sleep ( time . Second )
}
r . Log ( "Assert the relay tunnel still works" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , theirVpnIpNet [ 0 ] . Addr ( ) , myVpnIpNet [ 0 ] . Addr ( ) , theirControl , myControl , r )
2023-09-05 09:29:27 -04:00
r . RenderHostmaps ( "working hostmaps" , myControl , relayControl , theirControl )
// We should have two hostinfos on all sides
for len ( myControl . GetHostmap ( ) . Indexes ) != 2 {
t . Logf ( "Waiting for myControl hostinfos (%v != 2) to get cleaned up from lack of use..." , len ( myControl . GetHostmap ( ) . Indexes ) )
r . Log ( "Assert the relay tunnel still works" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , theirVpnIpNet [ 0 ] . Addr ( ) , myVpnIpNet [ 0 ] . Addr ( ) , theirControl , myControl , r )
2023-09-05 09:29:27 -04:00
r . Log ( "yupitdoes" )
time . Sleep ( time . Second )
}
t . Logf ( "myControl hostinfos got cleaned up!" )
for len ( theirControl . GetHostmap ( ) . Indexes ) != 2 {
t . Logf ( "Waiting for theirControl hostinfos (%v != 2) to get cleaned up from lack of use..." , len ( theirControl . GetHostmap ( ) . Indexes ) )
r . Log ( "Assert the relay tunnel still works" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , theirVpnIpNet [ 0 ] . Addr ( ) , myVpnIpNet [ 0 ] . Addr ( ) , theirControl , myControl , r )
2023-09-05 09:29:27 -04:00
r . Log ( "yupitdoes" )
time . Sleep ( time . Second )
}
t . Logf ( "theirControl hostinfos got cleaned up!" )
for len ( relayControl . GetHostmap ( ) . Indexes ) != 2 {
t . Logf ( "Waiting for relayControl hostinfos (%v != 2) to get cleaned up from lack of use..." , len ( relayControl . GetHostmap ( ) . Indexes ) )
r . Log ( "Assert the relay tunnel still works" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , theirVpnIpNet [ 0 ] . Addr ( ) , myVpnIpNet [ 0 ] . Addr ( ) , theirControl , myControl , r )
2023-09-05 09:29:27 -04:00
r . Log ( "yupitdoes" )
time . Sleep ( time . Second )
}
t . Logf ( "relayControl hostinfos got cleaned up!" )
}
func TestRehandshakingRelaysPrimary ( t * testing . T ) {
// This test is the same as TestRehandshakingRelays but one of the terminal types is a primary swap winner
2025-03-06 11:28:26 -06:00
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , _ , _ := newSimpleServer ( cert . Version1 , ca , caKey , "me " , "10.128.0.128/24" , m { "relay" : m { "use_relays" : true } } )
relayControl , relayVpnIpNet , relayUdpAddr , relayConfig := newSimpleServer ( cert . Version1 , ca , caKey , "relay " , "10.128.0.1/24" , m { "relay" : m { "am_relay" : true } } )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "them " , "10.128.0.2/24" , m { "relay" : m { "use_relays" : true } } )
2023-09-05 09:29:27 -04:00
// Teach my how to get to the relay and that their can be reached via the relay
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( relayVpnIpNet [ 0 ] . Addr ( ) , relayUdpAddr )
myControl . InjectRelays ( theirVpnIpNet [ 0 ] . Addr ( ) , [ ] netip . Addr { relayVpnIpNet [ 0 ] . Addr ( ) } )
relayControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
2023-09-05 09:29:27 -04:00
// Build a router so we don't have to reason who gets which packet
r := router . NewR ( t , myControl , relayControl , theirControl )
defer r . RenderFlow ( )
// Start the servers
myControl . Start ( )
2023-05-04 15:16:37 -05:00
relayControl . Start ( )
theirControl . Start ( )
t . Log ( "Trigger a handshake from me to them via the relay" )
2025-03-06 11:28:26 -06:00
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me" ) )
2023-05-04 15:16:37 -05:00
p := r . RouteForAllUntilTxTun ( theirControl )
r . Log ( "Assert the tunnel works" )
2025-03-06 11:28:26 -06:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , p , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , 80 )
2023-05-04 15:16:37 -05:00
r . RenderHostmaps ( "working hostmaps" , myControl , relayControl , theirControl )
// When I update the certificate for the relay, both me and them will have 2 host infos for the relay,
// and the main host infos will not have any relay state to handle the me<->relay<->them tunnel.
r . Log ( "Renew relay certificate and spin until me and them sees it" )
2025-03-06 11:28:26 -06:00
_ , _ , myNextPrivKey , myNextPEM := cert_test . NewTestCert ( cert . Version1 , cert . Curve_CURVE25519 , ca , caKey , "relay" , time . Now ( ) , time . Now ( ) . Add ( 5 * time . Minute ) , relayVpnIpNet , nil , [ ] string { "new group" } )
2023-05-04 15:16:37 -05:00
2024-10-10 18:00:22 -05:00
caB , err := ca . MarshalPEM ( )
2023-05-04 15:16:37 -05:00
if err != nil {
panic ( err )
}
relayConfig . Settings [ "pki" ] = m {
"ca" : string ( caB ) ,
"cert" : string ( myNextPEM ) ,
"key" : string ( myNextPrivKey ) ,
}
rc , err := yaml . Marshal ( relayConfig . Settings )
2025-03-10 17:38:14 -05:00
require . NoError ( t , err )
2023-05-04 15:16:37 -05:00
relayConfig . ReloadConfigString ( string ( rc ) )
for {
r . Log ( "Assert the tunnel works between myVpnIpNet and relayVpnIpNet" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , relayVpnIpNet [ 0 ] . Addr ( ) , myControl , relayControl , r )
c := myControl . GetHostInfoByVpnAddr ( relayVpnIpNet [ 0 ] . Addr ( ) , false )
2024-10-10 18:00:22 -05:00
if len ( c . Cert . Groups ( ) ) != 0 {
2023-05-04 15:16:37 -05:00
// We have a new certificate now
r . Log ( "Certificate between my and relay is updated!" )
break
}
time . Sleep ( time . Second )
}
for {
r . Log ( "Assert the tunnel works between theirVpnIpNet and relayVpnIpNet" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , theirVpnIpNet [ 0 ] . Addr ( ) , relayVpnIpNet [ 0 ] . Addr ( ) , theirControl , relayControl , r )
c := theirControl . GetHostInfoByVpnAddr ( relayVpnIpNet [ 0 ] . Addr ( ) , false )
2024-10-10 18:00:22 -05:00
if len ( c . Cert . Groups ( ) ) != 0 {
2023-05-04 15:16:37 -05:00
// We have a new certificate now
r . Log ( "Certificate between their and relay is updated!" )
break
}
time . Sleep ( time . Second )
}
r . Log ( "Assert the relay tunnel still works" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , theirVpnIpNet [ 0 ] . Addr ( ) , myVpnIpNet [ 0 ] . Addr ( ) , theirControl , myControl , r )
2023-05-04 15:16:37 -05:00
r . RenderHostmaps ( "working hostmaps" , myControl , relayControl , theirControl )
// We should have two hostinfos on all sides
for len ( myControl . GetHostmap ( ) . Indexes ) != 2 {
t . Logf ( "Waiting for myControl hostinfos (%v != 2) to get cleaned up from lack of use..." , len ( myControl . GetHostmap ( ) . Indexes ) )
r . Log ( "Assert the relay tunnel still works" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , theirVpnIpNet [ 0 ] . Addr ( ) , myVpnIpNet [ 0 ] . Addr ( ) , theirControl , myControl , r )
2023-05-04 15:16:37 -05:00
r . Log ( "yupitdoes" )
time . Sleep ( time . Second )
}
t . Logf ( "myControl hostinfos got cleaned up!" )
for len ( theirControl . GetHostmap ( ) . Indexes ) != 2 {
t . Logf ( "Waiting for theirControl hostinfos (%v != 2) to get cleaned up from lack of use..." , len ( theirControl . GetHostmap ( ) . Indexes ) )
r . Log ( "Assert the relay tunnel still works" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , theirVpnIpNet [ 0 ] . Addr ( ) , myVpnIpNet [ 0 ] . Addr ( ) , theirControl , myControl , r )
2023-05-04 15:16:37 -05:00
r . Log ( "yupitdoes" )
time . Sleep ( time . Second )
}
t . Logf ( "theirControl hostinfos got cleaned up!" )
for len ( relayControl . GetHostmap ( ) . Indexes ) != 2 {
t . Logf ( "Waiting for relayControl hostinfos (%v != 2) to get cleaned up from lack of use..." , len ( relayControl . GetHostmap ( ) . Indexes ) )
r . Log ( "Assert the relay tunnel still works" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , theirVpnIpNet [ 0 ] . Addr ( ) , myVpnIpNet [ 0 ] . Addr ( ) , theirControl , myControl , r )
2023-05-04 15:16:37 -05:00
r . Log ( "yupitdoes" )
time . Sleep ( time . Second )
}
t . Logf ( "relayControl hostinfos got cleaned up!" )
}
func TestRehandshaking ( t * testing . T ) {
2025-03-06 11:28:26 -06:00
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , myConfig := newSimpleServer ( cert . Version1 , ca , caKey , "me " , "10.128.0.2/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , theirConfig := newSimpleServer ( cert . Version1 , ca , caKey , "them" , "10.128.0.1/24" , nil )
2023-05-04 15:16:37 -05:00
// Put their info in our lighthouse and vice versa
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
theirControl . InjectLightHouseAddr ( myVpnIpNet [ 0 ] . Addr ( ) , myUdpAddr )
2023-05-04 15:16:37 -05:00
// Build a router so we don't have to reason who gets which packet
r := router . NewR ( t , myControl , theirControl )
defer r . RenderFlow ( )
// Start the servers
myControl . Start ( )
theirControl . Start ( )
t . Log ( "Stand up a tunnel between me and them" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2023-05-04 15:16:37 -05:00
r . RenderHostmaps ( "Starting hostmaps" , myControl , theirControl )
r . Log ( "Renew my certificate and spin until their sees it" )
2025-03-06 11:28:26 -06:00
_ , _ , myNextPrivKey , myNextPEM := cert_test . NewTestCert ( cert . Version1 , cert . Curve_CURVE25519 , ca , caKey , "me" , time . Now ( ) , time . Now ( ) . Add ( 5 * time . Minute ) , myVpnIpNet , nil , [ ] string { "new group" } )
2023-05-04 15:16:37 -05:00
2024-10-10 18:00:22 -05:00
caB , err := ca . MarshalPEM ( )
2023-05-04 15:16:37 -05:00
if err != nil {
panic ( err )
}
myConfig . Settings [ "pki" ] = m {
"ca" : string ( caB ) ,
"cert" : string ( myNextPEM ) ,
"key" : string ( myNextPrivKey ) ,
}
rc , err := yaml . Marshal ( myConfig . Settings )
2025-03-10 17:38:14 -05:00
require . NoError ( t , err )
2023-05-04 15:16:37 -05:00
myConfig . ReloadConfigString ( string ( rc ) )
for {
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
c := theirControl . GetHostInfoByVpnAddr ( myVpnIpNet [ 0 ] . Addr ( ) , false )
2024-10-10 18:00:22 -05:00
if len ( c . Cert . Groups ( ) ) != 0 {
2023-05-04 15:16:37 -05:00
// We have a new certificate now
break
}
time . Sleep ( time . Second )
}
2024-10-10 18:00:22 -05:00
r . Log ( "Got the new cert" )
2023-05-04 15:16:37 -05:00
// Flip their firewall to only allowing the new group to catch the tunnels reverting incorrectly
rc , err = yaml . Marshal ( theirConfig . Settings )
2025-03-10 17:38:14 -05:00
require . NoError ( t , err )
2023-05-04 15:16:37 -05:00
var theirNewConfig m
2025-03-10 17:38:14 -05:00
require . NoError ( t , yaml . Unmarshal ( rc , & theirNewConfig ) )
2025-03-31 16:08:34 -04:00
theirFirewall := theirNewConfig [ "firewall" ] . ( map [ string ] any )
2023-05-04 15:16:37 -05:00
theirFirewall [ "inbound" ] = [ ] m { {
"proto" : "any" ,
"port" : "any" ,
"group" : "new group" ,
} }
rc , err = yaml . Marshal ( theirNewConfig )
2025-03-10 17:38:14 -05:00
require . NoError ( t , err )
2023-05-04 15:16:37 -05:00
theirConfig . ReloadConfigString ( string ( rc ) )
r . Log ( "Spin until there is only 1 tunnel" )
for len ( myControl . GetHostmap ( ) . Indexes ) + len ( theirControl . GetHostmap ( ) . Indexes ) > 2 {
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2023-05-04 15:16:37 -05:00
t . Log ( "Connection manager hasn't ticked yet" )
time . Sleep ( time . Second )
}
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2023-05-04 15:16:37 -05:00
myFinalHostmapHosts := myControl . ListHostmapHosts ( false )
myFinalHostmapIndexes := myControl . ListHostmapIndexes ( false )
theirFinalHostmapHosts := theirControl . ListHostmapHosts ( false )
theirFinalHostmapIndexes := theirControl . ListHostmapIndexes ( false )
// Make sure the correct tunnel won
2025-03-06 11:28:26 -06:00
c := theirControl . GetHostInfoByVpnAddr ( myVpnIpNet [ 0 ] . Addr ( ) , false )
2024-10-10 18:00:22 -05:00
assert . Contains ( t , c . Cert . Groups ( ) , "new group" )
2023-05-04 15:16:37 -05:00
// We should only have a single tunnel now on both sides
assert . Len ( t , myFinalHostmapHosts , 1 )
assert . Len ( t , theirFinalHostmapHosts , 1 )
assert . Len ( t , myFinalHostmapIndexes , 1 )
assert . Len ( t , theirFinalHostmapIndexes , 1 )
r . RenderHostmaps ( "Final hostmaps" , myControl , theirControl )
myControl . Stop ( )
theirControl . Stop ( )
}
func TestRehandshakingLoser ( t * testing . T ) {
// The purpose of this test is that the race loser renews their certificate and rehandshakes. The final tunnel
// Should be the one with the new certificate
2025-03-06 11:28:26 -06:00
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , myConfig := newSimpleServer ( cert . Version1 , ca , caKey , "me " , "10.128.0.2/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , theirConfig := newSimpleServer ( cert . Version1 , ca , caKey , "them" , "10.128.0.1/24" , nil )
2023-05-04 15:16:37 -05:00
// Put their info in our lighthouse and vice versa
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
theirControl . InjectLightHouseAddr ( myVpnIpNet [ 0 ] . Addr ( ) , myUdpAddr )
2023-05-04 15:16:37 -05:00
// Build a router so we don't have to reason who gets which packet
r := router . NewR ( t , myControl , theirControl )
defer r . RenderFlow ( )
// Start the servers
myControl . Start ( )
theirControl . Start ( )
t . Log ( "Stand up a tunnel between me and them" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2023-05-04 15:16:37 -05:00
r . RenderHostmaps ( "Starting hostmaps" , myControl , theirControl )
r . Log ( "Renew their certificate and spin until mine sees it" )
2025-03-06 11:28:26 -06:00
_ , _ , theirNextPrivKey , theirNextPEM := cert_test . NewTestCert ( cert . Version1 , cert . Curve_CURVE25519 , ca , caKey , "them" , time . Now ( ) , time . Now ( ) . Add ( 5 * time . Minute ) , theirVpnIpNet , nil , [ ] string { "their new group" } )
2023-05-04 15:16:37 -05:00
2024-10-10 18:00:22 -05:00
caB , err := ca . MarshalPEM ( )
2023-05-04 15:16:37 -05:00
if err != nil {
panic ( err )
}
theirConfig . Settings [ "pki" ] = m {
"ca" : string ( caB ) ,
"cert" : string ( theirNextPEM ) ,
"key" : string ( theirNextPrivKey ) ,
}
rc , err := yaml . Marshal ( theirConfig . Settings )
2025-03-10 17:38:14 -05:00
require . NoError ( t , err )
2023-05-04 15:16:37 -05:00
theirConfig . ReloadConfigString ( string ( rc ) )
for {
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
theirCertInMe := myControl . GetHostInfoByVpnAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , false )
2023-05-04 15:16:37 -05:00
2024-10-10 18:00:22 -05:00
if slices . Contains ( theirCertInMe . Cert . Groups ( ) , "their new group" ) {
2023-05-04 15:16:37 -05:00
break
}
time . Sleep ( time . Second )
}
// Flip my firewall to only allowing the new group to catch the tunnels reverting incorrectly
rc , err = yaml . Marshal ( myConfig . Settings )
2025-03-10 17:38:14 -05:00
require . NoError ( t , err )
2023-05-04 15:16:37 -05:00
var myNewConfig m
2025-03-10 17:38:14 -05:00
require . NoError ( t , yaml . Unmarshal ( rc , & myNewConfig ) )
2025-03-31 16:08:34 -04:00
theirFirewall := myNewConfig [ "firewall" ] . ( map [ string ] any )
2023-05-04 15:16:37 -05:00
theirFirewall [ "inbound" ] = [ ] m { {
"proto" : "any" ,
"port" : "any" ,
"group" : "their new group" ,
} }
rc , err = yaml . Marshal ( myNewConfig )
2025-03-10 17:38:14 -05:00
require . NoError ( t , err )
2023-05-04 15:16:37 -05:00
myConfig . ReloadConfigString ( string ( rc ) )
r . Log ( "Spin until there is only 1 tunnel" )
for len ( myControl . GetHostmap ( ) . Indexes ) + len ( theirControl . GetHostmap ( ) . Indexes ) > 2 {
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2023-05-04 15:16:37 -05:00
t . Log ( "Connection manager hasn't ticked yet" )
time . Sleep ( time . Second )
}
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2023-05-04 15:16:37 -05:00
myFinalHostmapHosts := myControl . ListHostmapHosts ( false )
myFinalHostmapIndexes := myControl . ListHostmapIndexes ( false )
theirFinalHostmapHosts := theirControl . ListHostmapHosts ( false )
theirFinalHostmapIndexes := theirControl . ListHostmapIndexes ( false )
// Make sure the correct tunnel won
2025-03-06 11:28:26 -06:00
theirCertInMe := myControl . GetHostInfoByVpnAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , false )
2024-10-10 18:00:22 -05:00
assert . Contains ( t , theirCertInMe . Cert . Groups ( ) , "their new group" )
2023-05-04 15:16:37 -05:00
// We should only have a single tunnel now on both sides
assert . Len ( t , myFinalHostmapHosts , 1 )
assert . Len ( t , theirFinalHostmapHosts , 1 )
assert . Len ( t , myFinalHostmapIndexes , 1 )
assert . Len ( t , theirFinalHostmapIndexes , 1 )
r . RenderHostmaps ( "Final hostmaps" , myControl , theirControl )
myControl . Stop ( )
theirControl . Stop ( )
}
func TestRaceRegression ( t * testing . T ) {
// This test forces stage 1, stage 2, stage 1 to be received by me from them
// We had a bug where we were not finding the duplicate handshake and responding to the final stage 1 which
// caused a cross-linked hostinfo
2025-03-06 11:28:26 -06:00
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version1 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "me" , "10.128.0.1/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( cert . Version1 , ca , caKey , "them" , "10.128.0.2/24" , nil )
2023-05-04 15:16:37 -05:00
// Put their info in our lighthouse
2025-03-06 11:28:26 -06:00
myControl . InjectLightHouseAddr ( theirVpnIpNet [ 0 ] . Addr ( ) , theirUdpAddr )
theirControl . InjectLightHouseAddr ( myVpnIpNet [ 0 ] . Addr ( ) , myUdpAddr )
2023-05-04 15:16:37 -05:00
// Start the servers
myControl . Start ( )
theirControl . Start ( )
//them rx stage:1 initiatorIndex=642843150 responderIndex=0
//me rx stage:1 initiatorIndex=120607833 responderIndex=0
//them rx stage:1 initiatorIndex=642843150 responderIndex=0
//me rx stage:2 initiatorIndex=642843150 responderIndex=3701775874
//me rx stage:1 initiatorIndex=120607833 responderIndex=0
//them rx stage:2 initiatorIndex=120607833 responderIndex=4209862089
t . Log ( "Start both handshakes" )
2025-03-06 11:28:26 -06:00
myControl . InjectTunUDPPacket ( theirVpnIpNet [ 0 ] . Addr ( ) , 80 , myVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from me" ) )
theirControl . InjectTunUDPPacket ( myVpnIpNet [ 0 ] . Addr ( ) , 80 , theirVpnIpNet [ 0 ] . Addr ( ) , 80 , [ ] byte ( "Hi from them" ) )
2023-05-04 15:16:37 -05:00
t . Log ( "Get both stage 1" )
myStage1ForThem := myControl . GetFromUDP ( true )
theirStage1ForMe := theirControl . GetFromUDP ( true )
t . Log ( "Inject them in a special way" )
theirControl . InjectUDPPacket ( myStage1ForThem )
myControl . InjectUDPPacket ( theirStage1ForMe )
theirControl . InjectUDPPacket ( myStage1ForThem )
t . Log ( "Get both stage 2" )
myStage2ForThem := myControl . GetFromUDP ( true )
theirStage2ForMe := theirControl . GetFromUDP ( true )
t . Log ( "Inject them in a special way again" )
myControl . InjectUDPPacket ( theirStage2ForMe )
myControl . InjectUDPPacket ( theirStage1ForMe )
theirControl . InjectUDPPacket ( myStage2ForThem )
r := router . NewR ( t , myControl , theirControl )
defer r . RenderFlow ( )
t . Log ( "Flush the packets" )
r . RouteForAllUntilTxTun ( myControl )
r . RouteForAllUntilTxTun ( theirControl )
r . RenderHostmaps ( "Starting hostmaps" , myControl , theirControl )
t . Log ( "Make sure the tunnel still works" )
2025-03-06 11:28:26 -06:00
assertTunnel ( t , myVpnIpNet [ 0 ] . Addr ( ) , theirVpnIpNet [ 0 ] . Addr ( ) , myControl , theirControl , r )
2023-05-04 15:16:37 -05:00
myControl . Stop ( )
theirControl . Stop ( )
}
2023-03-13 12:35:14 -05:00
2025-03-06 11:28:26 -06:00
func TestV2NonPrimaryWithLighthouse ( t * testing . T ) {
ca , _ , caKey , _ := cert_test . NewTestCaCert ( cert . Version2 , cert . Curve_CURVE25519 , time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
lhControl , lhVpnIpNet , lhUdpAddr , _ := newSimpleServer ( cert . Version2 , ca , caKey , "lh " , "10.128.0.1/24, ff::1/64" , m { "lighthouse" : m { "am_lighthouse" : true } } )
o := m {
"static_host_map" : m {
lhVpnIpNet [ 1 ] . Addr ( ) . String ( ) : [ ] string { lhUdpAddr . String ( ) } ,
} ,
"lighthouse" : m {
"hosts" : [ ] string { lhVpnIpNet [ 1 ] . Addr ( ) . String ( ) } ,
"local_allow_list" : m {
// Try and block our lighthouse updates from using the actual addresses assigned to this computer
// If we start discovering addresses the test router doesn't know about then test traffic cant flow
"10.0.0.0/24" : true ,
"::/0" : false ,
} ,
} ,
}
myControl , myVpnIpNet , _ , _ := newSimpleServer ( cert . Version2 , ca , caKey , "me " , "10.128.0.2/24, ff::2/64" , o )
theirControl , theirVpnIpNet , _ , _ := newSimpleServer ( cert . Version2 , ca , caKey , "them" , "10.128.0.3/24, ff::3/64" , o )
// Build a router so we don't have to reason who gets which packet
r := router . NewR ( t , lhControl , myControl , theirControl )
defer r . RenderFlow ( )
// Start the servers
lhControl . Start ( )
myControl . Start ( )
theirControl . Start ( )
t . Log ( "Stand up an ipv6 tunnel between me and them" )
assert . True ( t , myVpnIpNet [ 1 ] . Addr ( ) . Is6 ( ) )
assert . True ( t , theirVpnIpNet [ 1 ] . Addr ( ) . Is6 ( ) )
assertTunnel ( t , myVpnIpNet [ 1 ] . Addr ( ) , theirVpnIpNet [ 1 ] . Addr ( ) , myControl , theirControl , r )
lhControl . Stop ( )
myControl . Stop ( )
theirControl . Stop ( )
}