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 (
2023-05-04 15:16:37 -05:00
"fmt"
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
2023-03-30 12:09:20 -04:00
"github.com/sirupsen/logrus"
2021-03-31 13:36:10 -05:00
"github.com/slackhq/nebula"
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"
2023-05-04 15:16:37 -05:00
"gopkg.in/yaml.v2"
2021-03-29 14:29:20 -05:00
)
2022-09-01 09:44:58 -05:00
func BenchmarkHotPath ( b * testing . B ) {
2024-07-31 10:18:56 -05:00
ca , _ , caKey , _ := NewTestCaCert ( time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , _ , _ , _ := newSimpleServer ( ca , caKey , "me" , "10.128.0.1/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( ca , caKey , "them" , "10.128.0.2/24" , nil )
2022-09-01 09:44:58 -05:00
// Put their info in our lighthouse
2024-07-31 10:18:56 -05:00
myControl . InjectLightHouseAddr ( theirVpnIpNet . 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 ++ {
2024-07-31 10:18:56 -05:00
myControl . InjectTunUDPPacket ( theirVpnIpNet . Addr ( ) , 80 , 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 ) {
2024-07-31 10:18:56 -05:00
ca , _ , caKey , _ := NewTestCaCert ( time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( ca , caKey , "me" , "10.128.0.1/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( ca , caKey , "them" , "10.128.0.2/24" , nil )
2021-03-29 14:29:20 -05:00
// Put their info in our lighthouse
2024-07-31 10:18:56 -05:00
myControl . InjectLightHouseAddr ( theirVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
myControl . InjectTunUDPPacket ( theirVpnIpNet . Addr ( ) , 80 , 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" )
2024-07-31 10:18:56 -05:00
assertHostInfoPair ( t , myUdpAddr , theirUdpAddr , myVpnIpNet . Addr ( ) , theirVpnIpNet . Addr ( ) , 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 )
2024-07-31 10:18:56 -05:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , myCachedPacket , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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 ( )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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 ( )
//TODO: assert hostmaps
}
func TestWrongResponderHandshake ( t * testing . T ) {
2024-07-31 10:18:56 -05:00
ca , _ , caKey , _ := NewTestCaCert ( time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
2021-03-31 10:26:35 -05:00
2021-04-14 13:50:09 -05:00
// The IPs here are chosen on purpose:
// The current remote handling will sort by preference, public, and then lexically.
// So we need them to have a higher address than evil (we could apply a preference though)
2024-07-31 10:18:56 -05:00
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( ca , caKey , "me" , "10.128.0.100/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( ca , caKey , "them" , "10.128.0.99/24" , nil )
evilControl , evilVpnIp , evilUdpAddr , _ := newSimpleServer ( ca , caKey , "evil" , "10.128.0.2/24" , nil )
2021-03-31 10:26:35 -05:00
2021-04-14 13:50:09 -05:00
// Add their real udp addr, which should be tried after evil.
2024-07-31 10:18:56 -05:00
myControl . InjectLightHouseAddr ( theirVpnIpNet . Addr ( ) , theirUdpAddr )
2021-03-31 10:26:35 -05:00
2021-04-14 13:50:09 -05:00
// Put the evil udp addr in for their vpn Ip, this is a case of being lied to by the lighthouse.
2024-07-31 10:18:56 -05:00
myControl . InjectLightHouseAddr ( theirVpnIpNet . 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 ( )
2021-04-14 13:50:09 -05:00
t . Log ( "Start the handshake process, we will route until we see our cached packet get sent to them" )
2024-07-31 10:18:56 -05:00
myControl . InjectTunUDPPacket ( theirVpnIpNet . Addr ( ) , 80 , 80 , [ ] byte ( "Hi from me" ) )
2021-11-03 20:54:04 -05:00
r . RouteForAllExitFunc ( func ( p * udp . Packet , c * nebula . Control ) router . ExitType {
h := & header . H { }
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
//TODO: Assert pending hostmap - I should have a correct hostinfo for them now
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 )
2024-07-31 10:18:56 -05:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , myCachedPacket , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertHostInfoPair ( t , myUdpAddr , theirUdpAddr , myVpnIpNet . Addr ( ) , theirVpnIpNet . Addr ( ) , myControl , theirControl )
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assert . Nil ( t , myControl . GetHostInfoByVpnIp ( evilVpnIp . Addr ( ) , true ) , "My pending hostmap should not contain evil" )
assert . Nil ( t , myControl . GetHostInfoByVpnIp ( evilVpnIp . Addr ( ) , false ) , "My main hostmap should not contain evil" )
2021-04-14 13:50:09 -05:00
//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
//TODO: assert hostmaps for everyone
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
2024-07-31 10:18:56 -05:00
ca , _ , caKey , _ := NewTestCaCert ( time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( ca , caKey , "me " , "10.128.0.1/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( 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
2024-07-31 10:18:56 -05:00
myControl . InjectLightHouseAddr ( theirVpnIpNet . Addr ( ) , theirUdpAddr )
theirControl . InjectLightHouseAddr ( myVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
myControl . InjectTunUDPPacket ( theirVpnIpNet . Addr ( ) , 80 , 80 , [ ] byte ( "Hi from me" ) )
theirControl . InjectTunUDPPacket ( myVpnIpNet . Addr ( ) , 80 , 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 )
2024-07-31 10:18:56 -05:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , myCachedPacket , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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 )
2024-07-31 10:18:56 -05:00
assertUdpPacket ( t , [ ] byte ( "Hi from them" ) , theirCachedPacket , theirVpnIpNet . Addr ( ) , myVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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 {
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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 ) {
2024-07-31 10:18:56 -05:00
ca , _ , caKey , _ := NewTestCaCert ( time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( ca , caKey , "me " , "10.128.0.1/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( 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
2024-07-31 10:18:56 -05:00
myControl . InjectLightHouseAddr ( theirVpnIpNet . Addr ( ) , theirUdpAddr )
theirControl . InjectLightHouseAddr ( myVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
myControl . InjectTunUDPPacket ( theirVpnIpNet . Addr ( ) , 80 , 80 , [ ] byte ( "Hi from me" ) )
2023-03-13 12:35:14 -05:00
p := r . RouteForAllUntilTxTun ( theirControl )
2024-07-31 10:18:56 -05:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , p , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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 { }
2024-07-31 10:18:56 -05:00
myControl . InjectTunUDPPacket ( theirVpnIpNet . Addr ( ) , 80 , 80 , [ ] byte ( "Hi from me again" ) )
2023-03-13 12:35:14 -05:00
p = r . RouteForAllUntilTxTun ( theirControl )
2024-07-31 10:18:56 -05:00
assertUdpPacket ( t , [ ] byte ( "Hi from me again" ) , p , myVpnIpNet . Addr ( ) , theirVpnIpNet . Addr ( ) , 80 , 80 )
2023-03-13 12:35:14 -05:00
r . Log ( "Assert the tunnel works" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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 {
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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 ) {
2024-07-31 10:18:56 -05:00
ca , _ , caKey , _ := NewTestCaCert ( time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( ca , caKey , "me " , "10.128.0.1/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( 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
2024-07-31 10:18:56 -05:00
myControl . InjectLightHouseAddr ( theirVpnIpNet . Addr ( ) , theirUdpAddr )
theirControl . InjectLightHouseAddr ( myVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
myControl . InjectTunUDPPacket ( theirVpnIpNet . Addr ( ) , 80 , 80 , [ ] byte ( "Hi from me" ) )
2023-03-13 12:35:14 -05:00
p := r . RouteForAllUntilTxTun ( theirControl )
2024-07-31 10:18:56 -05:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , p , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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 { }
2024-07-31 10:18:56 -05:00
theirControl . InjectTunUDPPacket ( myVpnIpNet . Addr ( ) , 80 , 80 , [ ] byte ( "Hi from them again" ) )
2023-03-13 12:35:14 -05:00
p = r . RouteForAllUntilTxTun ( myControl )
2024-07-31 10:18:56 -05:00
assertUdpPacket ( t , [ ] byte ( "Hi from them again" ) , p , theirVpnIpNet . Addr ( ) , myVpnIpNet . Addr ( ) , 80 , 80 )
2023-03-13 12:35:14 -05:00
r . RenderHostmaps ( "Derp hostmaps" , myControl , theirControl )
r . Log ( "Assert the tunnel works" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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 {
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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 ) {
2024-07-31 10:18:56 -05:00
ca , _ , caKey , _ := NewTestCaCert ( time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , _ , _ := newSimpleServer ( ca , caKey , "me " , "10.128.0.1/24" , m { "relay" : m { "use_relays" : true } } )
relayControl , relayVpnIpNet , relayUdpAddr , _ := newSimpleServer ( ca , caKey , "relay " , "10.128.0.128/24" , m { "relay" : m { "am_relay" : true } } )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( 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
2024-07-31 10:18:56 -05:00
myControl . InjectLightHouseAddr ( relayVpnIpNet . Addr ( ) , relayUdpAddr )
myControl . InjectRelays ( theirVpnIpNet . Addr ( ) , [ ] netip . Addr { relayVpnIpNet . Addr ( ) } )
relayControl . InjectLightHouseAddr ( theirVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
myControl . InjectTunUDPPacket ( theirVpnIpNet . Addr ( ) , 80 , 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" )
2024-07-31 10:18:56 -05:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , p , myVpnIpNet . Addr ( ) , theirVpnIpNet . Addr ( ) , 80 , 80 )
2023-02-16 13:23:33 -06:00
r . RenderHostmaps ( "Final hostmaps" , myControl , relayControl , theirControl )
2022-06-27 12:33:29 -05:00
//TODO: assert we actually used the relay even though it should be impossible for a tunnel to have occurred without it
}
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
2024-07-31 10:18:56 -05:00
ca , _ , caKey , _ := NewTestCaCert ( time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( ca , caKey , "me " , "10.128.0.1/24" , m { "relay" : m { "use_relays" : true } } )
relayControl , relayVpnIpNet , relayUdpAddr , _ := newSimpleServer ( ca , caKey , "relay " , "10.128.0.128/24" , m { "relay" : m { "am_relay" : true } } )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( 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
2024-07-31 10:18:56 -05:00
myControl . InjectLightHouseAddr ( relayVpnIpNet . Addr ( ) , relayUdpAddr )
theirControl . InjectLightHouseAddr ( relayVpnIpNet . Addr ( ) , relayUdpAddr )
2023-03-13 12:35:14 -05:00
2024-07-31 10:18:56 -05:00
myControl . InjectRelays ( theirVpnIpNet . Addr ( ) , [ ] netip . Addr { relayVpnIpNet . Addr ( ) } )
theirControl . InjectRelays ( myVpnIpNet . Addr ( ) , [ ] netip . Addr { relayVpnIpNet . Addr ( ) } )
2023-03-13 12:35:14 -05:00
2024-07-31 10:18:56 -05:00
relayControl . InjectLightHouseAddr ( theirVpnIpNet . Addr ( ) , theirUdpAddr )
relayControl . InjectLightHouseAddr ( myVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , relayVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , theirVpnIpNet . Addr ( ) , relayVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
myControl . InjectTunUDPPacket ( theirVpnIpNet . Addr ( ) , 80 , 80 , [ ] byte ( "Hi from me" ) )
theirControl . InjectTunUDPPacket ( myVpnIpNet . Addr ( ) , 80 , 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 ( )
//
////TODO: assert hostmaps
}
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
2024-07-31 10:18:56 -05:00
ca , _ , caKey , _ := NewTestCaCert ( time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( ca , caKey , "me " , "10.128.0.1/24" , m { "relay" : m { "use_relays" : true } } )
relayControl , relayVpnIpNet , relayUdpAddr , _ := newSimpleServer ( ca , caKey , "relay " , "10.128.0.128/24" , m { "relay" : m { "am_relay" : true } } )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( 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
2024-07-31 10:18:56 -05:00
myControl . InjectLightHouseAddr ( relayVpnIpNet . Addr ( ) , relayUdpAddr )
theirControl . InjectLightHouseAddr ( relayVpnIpNet . Addr ( ) , relayUdpAddr )
2023-03-30 12:09:20 -04:00
2024-07-31 10:18:56 -05:00
myControl . InjectRelays ( theirVpnIpNet . Addr ( ) , [ ] netip . Addr { relayVpnIpNet . Addr ( ) } )
theirControl . InjectRelays ( myVpnIpNet . Addr ( ) , [ ] netip . Addr { relayVpnIpNet . Addr ( ) } )
2023-03-13 12:35:14 -05:00
2024-07-31 10:18:56 -05:00
relayControl . InjectLightHouseAddr ( theirVpnIpNet . Addr ( ) , theirUdpAddr )
relayControl . InjectLightHouseAddr ( myVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , relayVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , theirVpnIpNet . Addr ( ) , relayVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
myControl . InjectTunUDPPacket ( theirVpnIpNet . Addr ( ) , 80 , 80 , [ ] byte ( "Hi from me" ) )
theirControl . InjectTunUDPPacket ( myVpnIpNet . Addr ( ) , 80 , 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , theirVpnIpNet . Addr ( ) , myVpnIpNet . 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..." )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , theirVpnIpNet . Addr ( ) , myVpnIpNet . Addr ( ) , theirControl , myControl , r )
2023-03-13 12:35:14 -05:00
myControl . Stop ( )
theirControl . Stop ( )
relayControl . Stop ( )
2023-03-30 12:09:20 -04:00
2023-03-13 12:35:14 -05:00
//
////TODO: assert hostmaps
}
2024-07-31 10:18:56 -05:00
2023-05-04 15:16:37 -05:00
func TestRehandshakingRelays ( t * testing . T ) {
2024-07-31 10:18:56 -05:00
ca , _ , caKey , _ := NewTestCaCert ( time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , _ , _ := newSimpleServer ( ca , caKey , "me " , "10.128.0.1/24" , m { "relay" : m { "use_relays" : true } } )
relayControl , relayVpnIpNet , relayUdpAddr , relayConfig := newSimpleServer ( ca , caKey , "relay " , "10.128.0.128/24" , m { "relay" : m { "am_relay" : true } } )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( 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
2024-07-31 10:18:56 -05:00
myControl . InjectLightHouseAddr ( relayVpnIpNet . Addr ( ) , relayUdpAddr )
myControl . InjectRelays ( theirVpnIpNet . Addr ( ) , [ ] netip . Addr { relayVpnIpNet . Addr ( ) } )
relayControl . InjectLightHouseAddr ( theirVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
myControl . InjectTunUDPPacket ( theirVpnIpNet . Addr ( ) , 80 , 80 , [ ] byte ( "Hi from me" ) )
2023-09-05 09:29:27 -04:00
p := r . RouteForAllUntilTxTun ( theirControl )
r . Log ( "Assert the tunnel works" )
2024-07-31 10:18:56 -05:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , p , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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" )
2024-10-10 18:00:22 -05:00
_ , _ , myNextPrivKey , myNextPEM := NewTestCert ( ca , caKey , "relay" , time . Now ( ) , time . Now ( ) . Add ( 5 * time . Minute ) , [ ] netip . Prefix { 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 )
assert . NoError ( t , err )
relayConfig . ReloadConfigString ( string ( rc ) )
for {
r . Log ( "Assert the tunnel works between myVpnIpNet and relayVpnIpNet" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , relayVpnIpNet . Addr ( ) , myControl , relayControl , r )
c := myControl . GetHostInfoByVpnIp ( relayVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , theirVpnIpNet . Addr ( ) , relayVpnIpNet . Addr ( ) , theirControl , relayControl , r )
c := theirControl . GetHostInfoByVpnIp ( relayVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , theirVpnIpNet . Addr ( ) , myVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , theirVpnIpNet . Addr ( ) , myVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , theirVpnIpNet . Addr ( ) , myVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , theirVpnIpNet . Addr ( ) , myVpnIpNet . 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
2024-07-31 10:18:56 -05:00
ca , _ , caKey , _ := NewTestCaCert ( time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , _ , _ := newSimpleServer ( ca , caKey , "me " , "10.128.0.128/24" , m { "relay" : m { "use_relays" : true } } )
relayControl , relayVpnIpNet , relayUdpAddr , relayConfig := newSimpleServer ( ca , caKey , "relay " , "10.128.0.1/24" , m { "relay" : m { "am_relay" : true } } )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( 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
2024-07-31 10:18:56 -05:00
myControl . InjectLightHouseAddr ( relayVpnIpNet . Addr ( ) , relayUdpAddr )
myControl . InjectRelays ( theirVpnIpNet . Addr ( ) , [ ] netip . Addr { relayVpnIpNet . Addr ( ) } )
relayControl . InjectLightHouseAddr ( theirVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
myControl . InjectTunUDPPacket ( theirVpnIpNet . Addr ( ) , 80 , 80 , [ ] byte ( "Hi from me" ) )
2023-05-04 15:16:37 -05:00
p := r . RouteForAllUntilTxTun ( theirControl )
r . Log ( "Assert the tunnel works" )
2024-07-31 10:18:56 -05:00
assertUdpPacket ( t , [ ] byte ( "Hi from me" ) , p , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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" )
2024-10-10 18:00:22 -05:00
_ , _ , myNextPrivKey , myNextPEM := NewTestCert ( ca , caKey , "relay" , time . Now ( ) , time . Now ( ) . Add ( 5 * time . Minute ) , [ ] netip . Prefix { 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 )
assert . NoError ( t , err )
relayConfig . ReloadConfigString ( string ( rc ) )
for {
r . Log ( "Assert the tunnel works between myVpnIpNet and relayVpnIpNet" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , relayVpnIpNet . Addr ( ) , myControl , relayControl , r )
c := myControl . GetHostInfoByVpnIp ( relayVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , theirVpnIpNet . Addr ( ) , relayVpnIpNet . Addr ( ) , theirControl , relayControl , r )
c := theirControl . GetHostInfoByVpnIp ( relayVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , theirVpnIpNet . Addr ( ) , myVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , theirVpnIpNet . Addr ( ) , myVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , theirVpnIpNet . Addr ( ) , myVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , theirVpnIpNet . Addr ( ) , myVpnIpNet . 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 ) {
2024-07-31 10:18:56 -05:00
ca , _ , caKey , _ := NewTestCaCert ( time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , myConfig := newSimpleServer ( ca , caKey , "me " , "10.128.0.2/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , theirConfig := newSimpleServer ( 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
2024-07-31 10:18:56 -05:00
myControl . InjectLightHouseAddr ( theirVpnIpNet . Addr ( ) , theirUdpAddr )
theirControl . InjectLightHouseAddr ( myVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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" )
2024-10-10 18:00:22 -05:00
_ , _ , myNextPrivKey , myNextPEM := NewTestCert ( ca , caKey , "me" , time . Now ( ) , time . Now ( ) . Add ( 5 * time . Minute ) , [ ] netip . Prefix { 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 )
assert . NoError ( t , err )
myConfig . ReloadConfigString ( string ( rc ) )
for {
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . Addr ( ) , myControl , theirControl , r )
c := theirControl . GetHostInfoByVpnIp ( myVpnIpNet . 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 )
assert . NoError ( t , err )
var theirNewConfig m
assert . NoError ( t , yaml . Unmarshal ( rc , & theirNewConfig ) )
theirFirewall := theirNewConfig [ "firewall" ] . ( map [ interface { } ] interface { } )
theirFirewall [ "inbound" ] = [ ] m { {
"proto" : "any" ,
"port" : "any" ,
"group" : "new group" ,
} }
rc , err = yaml . Marshal ( theirNewConfig )
assert . NoError ( t , err )
theirConfig . ReloadConfigString ( string ( rc ) )
r . Log ( "Spin until there is only 1 tunnel" )
for len ( myControl . GetHostmap ( ) . Indexes ) + len ( theirControl . GetHostmap ( ) . Indexes ) > 2 {
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . Addr ( ) , myControl , theirControl , r )
2023-05-04 15:16:37 -05:00
t . Log ( "Connection manager hasn't ticked yet" )
time . Sleep ( time . Second )
}
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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
2024-07-31 10:18:56 -05:00
c := theirControl . GetHostInfoByVpnIp ( myVpnIpNet . 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
2024-07-31 10:18:56 -05:00
ca , _ , caKey , _ := NewTestCaCert ( time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , myConfig := newSimpleServer ( ca , caKey , "me " , "10.128.0.2/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , theirConfig := newSimpleServer ( 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
2024-07-31 10:18:56 -05:00
myControl . InjectLightHouseAddr ( theirVpnIpNet . Addr ( ) , theirUdpAddr )
theirControl . InjectLightHouseAddr ( myVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . Addr ( ) , myControl , theirControl , r )
2023-05-04 15:16:37 -05:00
2024-07-31 10:18:56 -05:00
tt1 := myControl . GetHostInfoByVpnIp ( theirVpnIpNet . Addr ( ) , false )
tt2 := theirControl . GetHostInfoByVpnIp ( myVpnIpNet . Addr ( ) , false )
2023-05-04 15:16:37 -05:00
fmt . Println ( tt1 . LocalIndex , tt2 . LocalIndex )
r . RenderHostmaps ( "Starting hostmaps" , myControl , theirControl )
r . Log ( "Renew their certificate and spin until mine sees it" )
2024-10-10 18:00:22 -05:00
_ , _ , theirNextPrivKey , theirNextPEM := NewTestCert ( ca , caKey , "them" , time . Now ( ) , time . Now ( ) . Add ( 5 * time . Minute ) , [ ] netip . Prefix { 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 )
assert . NoError ( t , err )
theirConfig . ReloadConfigString ( string ( rc ) )
for {
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . Addr ( ) , myControl , theirControl , r )
theirCertInMe := myControl . GetHostInfoByVpnIp ( theirVpnIpNet . 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 )
assert . NoError ( t , err )
var myNewConfig m
assert . NoError ( t , yaml . Unmarshal ( rc , & myNewConfig ) )
theirFirewall := myNewConfig [ "firewall" ] . ( map [ interface { } ] interface { } )
theirFirewall [ "inbound" ] = [ ] m { {
"proto" : "any" ,
"port" : "any" ,
"group" : "their new group" ,
} }
rc , err = yaml . Marshal ( myNewConfig )
assert . NoError ( t , err )
myConfig . ReloadConfigString ( string ( rc ) )
r . Log ( "Spin until there is only 1 tunnel" )
for len ( myControl . GetHostmap ( ) . Indexes ) + len ( theirControl . GetHostmap ( ) . Indexes ) > 2 {
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . Addr ( ) , myControl , theirControl , r )
2023-05-04 15:16:37 -05:00
t . Log ( "Connection manager hasn't ticked yet" )
time . Sleep ( time . Second )
}
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . 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
2024-07-31 10:18:56 -05:00
theirCertInMe := myControl . GetHostInfoByVpnIp ( theirVpnIpNet . 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
2024-07-31 10:18:56 -05:00
ca , _ , caKey , _ := NewTestCaCert ( time . Now ( ) , time . Now ( ) . Add ( 10 * time . Minute ) , nil , nil , [ ] string { } )
myControl , myVpnIpNet , myUdpAddr , _ := newSimpleServer ( ca , caKey , "me" , "10.128.0.1/24" , nil )
theirControl , theirVpnIpNet , theirUdpAddr , _ := newSimpleServer ( ca , caKey , "them" , "10.128.0.2/24" , nil )
2023-05-04 15:16:37 -05:00
// Put their info in our lighthouse
2024-07-31 10:18:56 -05:00
myControl . InjectLightHouseAddr ( theirVpnIpNet . Addr ( ) , theirUdpAddr )
theirControl . InjectLightHouseAddr ( myVpnIpNet . 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" )
2024-07-31 10:18:56 -05:00
myControl . InjectTunUDPPacket ( theirVpnIpNet . Addr ( ) , 80 , 80 , [ ] byte ( "Hi from me" ) )
theirControl . InjectTunUDPPacket ( myVpnIpNet . Addr ( ) , 80 , 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 )
//TODO: ensure stage 2
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" )
2024-07-31 10:18:56 -05:00
assertTunnel ( t , myVpnIpNet . Addr ( ) , theirVpnIpNet . Addr ( ) , myControl , theirControl , r )
2023-05-04 15:16:37 -05:00
myControl . Stop ( )
theirControl . Stop ( )
}
2023-03-13 12:35:14 -05:00
2023-05-04 15:16:37 -05:00
//TODO: test
// Race winner renews and handshakes
// Race loser renews and handshakes
// Does race winner repin the cert to old?
2021-04-14 13:50:09 -05:00
//TODO: add a test with many lies