1
0

handshake_manager_test.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. //go:build e2e_testing
  2. package e2e
  3. import (
  4. "net/netip"
  5. "testing"
  6. "time"
  7. "github.com/slackhq/nebula"
  8. "github.com/slackhq/nebula/cert"
  9. "github.com/slackhq/nebula/cert_test"
  10. "github.com/slackhq/nebula/e2e/router"
  11. "github.com/slackhq/nebula/header"
  12. "github.com/slackhq/nebula/udp"
  13. "github.com/stretchr/testify/assert"
  14. )
  15. // makeHandshakePacket creates a handshake packet with the given parameters.
  16. func makeHandshakePacket(from, to netip.AddrPort, subtype header.MessageSubType, remoteIndex uint32, counter uint64) *udp.Packet {
  17. data := make([]byte, 200)
  18. header.Encode(data, header.Version, header.Handshake, subtype, remoteIndex, counter)
  19. for i := header.Len; i < len(data); i++ {
  20. data[i] = byte(i)
  21. }
  22. return &udp.Packet{To: to, From: from, Data: data}
  23. }
  24. func TestHandshakeRetransmitDuplicate(t *testing.T) {
  25. t.Parallel()
  26. // Verify the responder correctly handles receiving the same msg1 multiple times
  27. // (retransmission). The duplicate goes through CheckAndComplete -> ErrAlreadySeen
  28. // and the cached response is resent.
  29. ca, _, caKey, _ := cert_test.NewTestCaCert(cert.Version1, cert.Curve_CURVE25519, time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
  30. myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.1/24", nil)
  31. theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", nil)
  32. myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
  33. theirControl.InjectLightHouseAddr(myVpnIpNet[0].Addr(), myUdpAddr)
  34. myControl.Start()
  35. theirControl.Start()
  36. r := router.NewR(t, myControl, theirControl)
  37. defer r.RenderFlow()
  38. t.Log("Trigger handshake from me to them")
  39. myControl.InjectTunPacket(BuildTunUDPPacket(theirVpnIpNet[0].Addr(), 80, myVpnIpNet[0].Addr(), 80, []byte("Hi")))
  40. t.Log("Grab my msg1")
  41. msg1 := myControl.GetFromUDP(true)
  42. t.Log("Inject msg1 into them, first time")
  43. theirControl.InjectUDPPacket(msg1)
  44. _ = theirControl.GetFromUDP(true)
  45. t.Log("Inject the SAME msg1 again, tests ErrAlreadySeen path")
  46. theirControl.InjectUDPPacket(msg1)
  47. resp2 := theirControl.GetFromUDP(true)
  48. assert.NotNil(t, resp2, "should get cached response on duplicate msg1")
  49. t.Log("Complete handshake with cached response")
  50. myControl.InjectUDPPacket(resp2)
  51. myControl.WaitForType(1, 0, theirControl)
  52. t.Log("Drain cached packet and verify tunnel works")
  53. cachedPacket := theirControl.GetFromTun(true)
  54. assertUdpPacket(t, []byte("Hi"), cachedPacket, myVpnIpNet[0].Addr(), theirVpnIpNet[0].Addr(), 80, 80)
  55. assertTunnel(t, myVpnIpNet[0].Addr(), theirVpnIpNet[0].Addr(), myControl, theirControl, r)
  56. t.Log("Verify only one tunnel exists on each side")
  57. assert.Len(t, myControl.ListHostmapHosts(false), 1)
  58. assert.Len(t, theirControl.ListHostmapHosts(false), 1)
  59. myControl.Stop()
  60. theirControl.Stop()
  61. }
  62. func TestHandshakeTruncatedPacketRecovery(t *testing.T) {
  63. t.Parallel()
  64. // Verify that a truncated handshake packet is ignored and the real
  65. // packet can still complete the handshake.
  66. ca, _, caKey, _ := cert_test.NewTestCaCert(cert.Version1, cert.Curve_CURVE25519, time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
  67. myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.1/24", nil)
  68. theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", nil)
  69. myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
  70. theirControl.InjectLightHouseAddr(myVpnIpNet[0].Addr(), myUdpAddr)
  71. myControl.Start()
  72. theirControl.Start()
  73. r := router.NewR(t, myControl, theirControl)
  74. defer r.RenderFlow()
  75. t.Log("Trigger handshake")
  76. myControl.InjectTunPacket(BuildTunUDPPacket(theirVpnIpNet[0].Addr(), 80, myVpnIpNet[0].Addr(), 80, []byte("Hi")))
  77. t.Log("Get msg1 and deliver to responder")
  78. msg1 := myControl.GetFromUDP(true)
  79. theirControl.InjectUDPPacket(msg1)
  80. t.Log("Get the real response")
  81. realResp := theirControl.GetFromUDP(true)
  82. t.Log("Truncate the response and inject, should be ignored")
  83. truncResp := realResp.Copy()
  84. truncResp.Data = truncResp.Data[:header.Len]
  85. myControl.InjectUDPPacket(truncResp)
  86. t.Log("Verify pending handshake survived the truncated packet")
  87. assert.NotEmpty(t, myControl.ListHostmapHosts(true), "pending handshake should still exist")
  88. t.Log("Inject real response, should complete handshake")
  89. myControl.InjectUDPPacket(realResp)
  90. myControl.WaitForType(1, 0, theirControl)
  91. t.Log("Drain and verify tunnel")
  92. cachedPacket := theirControl.GetFromTun(true)
  93. assertUdpPacket(t, []byte("Hi"), cachedPacket, myVpnIpNet[0].Addr(), theirVpnIpNet[0].Addr(), 80, 80)
  94. assertTunnel(t, myVpnIpNet[0].Addr(), theirVpnIpNet[0].Addr(), myControl, theirControl, r)
  95. myControl.Stop()
  96. theirControl.Stop()
  97. }
  98. func TestHandshakeOrphanedMsg2Dropped(t *testing.T) {
  99. t.Parallel()
  100. // A msg2 arriving with no matching pending index should be silently dropped
  101. // with no response sent and no state changes.
  102. ca, _, caKey, _ := cert_test.NewTestCaCert(cert.Version1, cert.Curve_CURVE25519, time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
  103. myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.1/24", nil)
  104. theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", nil)
  105. myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
  106. theirControl.InjectLightHouseAddr(myVpnIpNet[0].Addr(), myUdpAddr)
  107. myControl.Start()
  108. theirControl.Start()
  109. r := router.NewR(t, myControl, theirControl)
  110. defer r.RenderFlow()
  111. t.Log("Complete a normal handshake")
  112. myControl.InjectTunPacket(BuildTunUDPPacket(theirVpnIpNet[0].Addr(), 80, myVpnIpNet[0].Addr(), 80, []byte("Hi")))
  113. r.RouteForAllUntilTxTun(theirControl)
  114. assertTunnel(t, myVpnIpNet[0].Addr(), theirVpnIpNet[0].Addr(), myControl, theirControl, r)
  115. t.Log("Record hostmap state")
  116. myIndexes := len(myControl.ListHostmapIndexes(false))
  117. t.Log("Inject a fake msg2 with unknown RemoteIndex")
  118. myControl.InjectUDPPacket(makeHandshakePacket(theirUdpAddr, myUdpAddr, header.HandshakeIXPSK0, 0xDEADBEEF, 2))
  119. t.Log("Verify no new indexes created")
  120. assert.Equal(t, myIndexes, len(myControl.ListHostmapIndexes(false)))
  121. t.Log("Verify no UDP response was sent")
  122. time.Sleep(100 * time.Millisecond)
  123. assert.Nil(t, myControl.GetFromUDP(false), "should not send a response to orphaned msg2")
  124. t.Log("Verify existing tunnel still works")
  125. assertTunnel(t, myVpnIpNet[0].Addr(), theirVpnIpNet[0].Addr(), myControl, theirControl, r)
  126. myControl.Stop()
  127. theirControl.Stop()
  128. }
  129. func TestHandshakeUnknownMessageCounter(t *testing.T) {
  130. t.Parallel()
  131. // A handshake packet with an unexpected message counter should be silently
  132. // dropped with no side effects and no UDP response.
  133. ca, _, caKey, _ := cert_test.NewTestCaCert(cert.Version1, cert.Curve_CURVE25519, time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
  134. myControl, _, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.1/24", nil)
  135. theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", nil)
  136. myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
  137. myControl.Start()
  138. theirControl.Start()
  139. t.Log("Inject handshake with MessageCounter=3")
  140. myControl.InjectUDPPacket(makeHandshakePacket(theirUdpAddr, myUdpAddr, header.HandshakeIXPSK0, 0, 3))
  141. t.Log("Inject handshake with MessageCounter=99")
  142. myControl.InjectUDPPacket(makeHandshakePacket(theirUdpAddr, myUdpAddr, header.HandshakeIXPSK0, 0, 99))
  143. t.Log("Verify no tunnels or pending handshakes")
  144. assert.Empty(t, myControl.ListHostmapHosts(false))
  145. assert.Empty(t, myControl.ListHostmapHosts(true))
  146. t.Log("Verify no UDP response was sent")
  147. time.Sleep(100 * time.Millisecond)
  148. assert.Nil(t, myControl.GetFromUDP(false))
  149. myControl.Stop()
  150. theirControl.Stop()
  151. }
  152. func TestHandshakeUnknownSubtype(t *testing.T) {
  153. t.Parallel()
  154. // A handshake packet with an unknown subtype should be silently dropped.
  155. ca, _, caKey, _ := cert_test.NewTestCaCert(cert.Version1, cert.Curve_CURVE25519, time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
  156. myControl, _, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.1/24", nil)
  157. theirControl, _, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", nil)
  158. myControl.Start()
  159. theirControl.Start()
  160. t.Log("Inject handshake with unknown subtype 99")
  161. myControl.InjectUDPPacket(makeHandshakePacket(theirUdpAddr, myUdpAddr, header.MessageSubType(99), 0, 1))
  162. t.Log("Verify no tunnels or pending handshakes")
  163. assert.Empty(t, myControl.ListHostmapHosts(false))
  164. assert.Empty(t, myControl.ListHostmapHosts(true))
  165. t.Log("Verify no UDP response was sent")
  166. time.Sleep(100 * time.Millisecond)
  167. assert.Nil(t, myControl.GetFromUDP(false))
  168. myControl.Stop()
  169. theirControl.Stop()
  170. }
  171. func TestHandshakeLateResponse(t *testing.T) {
  172. t.Parallel()
  173. // After a handshake times out, a late response should be silently ignored
  174. // with no new tunnels created.
  175. ca, _, caKey, _ := cert_test.NewTestCaCert(cert.Version1, cert.Curve_CURVE25519, time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
  176. myControl, myVpnIpNet, _, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.1/24", m{
  177. "handshakes": m{
  178. "try_interval": "200ms",
  179. "retries": 2,
  180. },
  181. })
  182. theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", nil)
  183. myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
  184. myControl.Start()
  185. theirControl.Start()
  186. t.Log("Trigger handshake from me")
  187. myControl.InjectTunPacket(BuildTunUDPPacket(theirVpnIpNet[0].Addr(), 80, myVpnIpNet[0].Addr(), 80, []byte("Hi")))
  188. t.Log("Grab msg1 but don't deliver")
  189. msg1 := myControl.GetFromUDP(true)
  190. t.Log("Wait for handshake to time out")
  191. for i := 0; i < 5; i++ {
  192. time.Sleep(300 * time.Millisecond)
  193. myControl.GetFromUDP(false)
  194. }
  195. t.Log("Confirm no pending handshakes remain")
  196. assert.Empty(t, myControl.ListHostmapHosts(true))
  197. t.Log("Deliver old msg1 to them, they create a tunnel")
  198. theirControl.InjectUDPPacket(msg1)
  199. resp := theirControl.GetFromUDP(true)
  200. assert.NotNil(t, resp)
  201. t.Log("Inject late response into me, should be ignored")
  202. myControl.InjectUDPPacket(resp)
  203. t.Log("No tunnel should exist on my side")
  204. assert.Empty(t, myControl.ListHostmapHosts(false))
  205. assert.Empty(t, myControl.ListHostmapHosts(true))
  206. myControl.Stop()
  207. theirControl.Stop()
  208. }
  209. func TestHandshakeSelfConnectionRejected(t *testing.T) {
  210. t.Parallel()
  211. // Verify that a node rejects a handshake containing its own VPN IP in the
  212. // peer cert. We do this by sending the initiator's own msg1 back to itself.
  213. ca, _, caKey, _ := cert_test.NewTestCaCert(cert.Version1, cert.Curve_CURVE25519, time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
  214. myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.1/24", nil)
  215. // Need a lighthouse entry to trigger a handshake
  216. myControl.InjectLightHouseAddr(netip.MustParseAddr("10.128.0.2"), netip.MustParseAddrPort("10.0.0.2:4242"))
  217. myControl.Start()
  218. t.Log("Trigger handshake from me")
  219. myControl.InjectTunPacket(BuildTunUDPPacket(netip.MustParseAddr("10.128.0.2"), 80, myVpnIpNet[0].Addr(), 80, []byte("Hi")))
  220. msg1 := myControl.GetFromUDP(true)
  221. t.Log("Drain any handshake retransmits before injecting")
  222. time.Sleep(100 * time.Millisecond)
  223. for myControl.GetFromUDP(false) != nil {
  224. }
  225. t.Log("Feed my own msg1 back to me as if it came from someone else")
  226. selfMsg := msg1.Copy()
  227. selfMsg.From = netip.MustParseAddrPort("10.0.0.99:4242")
  228. selfMsg.To = myUdpAddr
  229. myControl.InjectUDPPacket(selfMsg)
  230. t.Log("Verify no response was sent (self-connection rejected)")
  231. time.Sleep(100 * time.Millisecond)
  232. // Drain any further retransmits from the original handshake, then check
  233. // that none of them are a handshake response (MessageCounter=2)
  234. h := &header.H{}
  235. for {
  236. p := myControl.GetFromUDP(false)
  237. if p == nil {
  238. break
  239. }
  240. _ = h.Parse(p.Data)
  241. assert.NotEqual(t, uint64(2), h.MessageCounter,
  242. "should not send a stage 2 response to self-connection")
  243. }
  244. t.Log("Verify no tunnel to myself was created")
  245. assert.Nil(t, myControl.GetHostInfoByVpnAddr(myVpnIpNet[0].Addr(), false))
  246. myControl.Stop()
  247. }
  248. func TestHandshakeMessageCounter0Dropped(t *testing.T) {
  249. t.Parallel()
  250. // MessageCounter=0 is not a valid handshake message and should be dropped.
  251. ca, _, caKey, _ := cert_test.NewTestCaCert(cert.Version1, cert.Curve_CURVE25519, time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
  252. myControl, _, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.1/24", nil)
  253. _, _, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", nil)
  254. myControl.Start()
  255. t.Log("Inject handshake with MessageCounter=0")
  256. myControl.InjectUDPPacket(makeHandshakePacket(theirUdpAddr, myUdpAddr, header.HandshakeIXPSK0, 0, 0))
  257. time.Sleep(100 * time.Millisecond)
  258. assert.Empty(t, myControl.ListHostmapHosts(false))
  259. assert.Empty(t, myControl.ListHostmapHosts(true))
  260. assert.Nil(t, myControl.GetFromUDP(false))
  261. myControl.Stop()
  262. }
  263. func TestHandshakeRemoteAllowList(t *testing.T) {
  264. t.Parallel()
  265. // Verify that a handshake from a blocked underlay IP is dropped with no
  266. // response and no state changes. Then verify the same packet from an
  267. // allowed IP succeeds.
  268. ca, _, caKey, _ := cert_test.NewTestCaCert(cert.Version1, cert.Curve_CURVE25519, time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
  269. myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.1/24", m{
  270. "lighthouse": m{
  271. "remote_allow_list": m{
  272. "10.0.0.0/8": true,
  273. "0.0.0.0/0": false,
  274. },
  275. },
  276. })
  277. theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", nil)
  278. myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
  279. theirControl.InjectLightHouseAddr(myVpnIpNet[0].Addr(), myUdpAddr)
  280. myControl.Start()
  281. theirControl.Start()
  282. r := router.NewR(t, myControl, theirControl)
  283. defer r.RenderFlow()
  284. t.Log("Trigger handshake from them")
  285. theirControl.InjectTunPacket(BuildTunUDPPacket(myVpnIpNet[0].Addr(), 80, theirVpnIpNet[0].Addr(), 80, []byte("Hi")))
  286. msg1 := theirControl.GetFromUDP(true)
  287. t.Log("Rewrite the source to a blocked IP and inject")
  288. blockedMsg := msg1.Copy()
  289. blockedMsg.From = netip.MustParseAddrPort("192.168.1.1:4242")
  290. myControl.InjectUDPPacket(blockedMsg)
  291. t.Log("Verify no tunnel, no pending, no response from blocked source")
  292. time.Sleep(100 * time.Millisecond)
  293. assert.Empty(t, myControl.ListHostmapHosts(false))
  294. assert.Empty(t, myControl.ListHostmapHosts(true))
  295. assert.Nil(t, myControl.GetFromUDP(false), "should not respond to blocked source")
  296. t.Log("Now inject the real packet from the allowed source")
  297. myControl.InjectUDPPacket(msg1)
  298. t.Log("Verify handshake completes from allowed source")
  299. resp := myControl.GetFromUDP(true)
  300. assert.NotNil(t, resp)
  301. theirControl.InjectUDPPacket(resp)
  302. theirControl.WaitForType(1, 0, myControl)
  303. t.Log("Drain cached packet and verify tunnel works")
  304. cachedPacket := myControl.GetFromTun(true)
  305. assertUdpPacket(t, []byte("Hi"), cachedPacket, theirVpnIpNet[0].Addr(), myVpnIpNet[0].Addr(), 80, 80)
  306. assertTunnel(t, myVpnIpNet[0].Addr(), theirVpnIpNet[0].Addr(), myControl, theirControl, r)
  307. myControl.Stop()
  308. theirControl.Stop()
  309. }
  310. func TestHandshakeAlreadySeenPreferredRemote(t *testing.T) {
  311. t.Parallel()
  312. // When a duplicate msg1 arrives via ErrAlreadySeen, verify the tunnel
  313. // remains functional and hostmap index count is stable.
  314. ca, _, caKey, _ := cert_test.NewTestCaCert(cert.Version1, cert.Curve_CURVE25519, time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
  315. myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.1/24", nil)
  316. theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", nil)
  317. myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
  318. theirControl.InjectLightHouseAddr(myVpnIpNet[0].Addr(), myUdpAddr)
  319. myControl.Start()
  320. theirControl.Start()
  321. r := router.NewR(t, myControl, theirControl)
  322. defer r.RenderFlow()
  323. t.Log("Complete a normal handshake via the router")
  324. myControl.InjectTunPacket(BuildTunUDPPacket(theirVpnIpNet[0].Addr(), 80, myVpnIpNet[0].Addr(), 80, []byte("Hi")))
  325. r.RouteForAllUntilTxTun(theirControl)
  326. assertTunnel(t, myVpnIpNet[0].Addr(), theirVpnIpNet[0].Addr(), myControl, theirControl, r)
  327. t.Log("Record hostmap state")
  328. theirIndexes := len(theirControl.ListHostmapIndexes(false))
  329. hi := theirControl.GetHostInfoByVpnAddr(myVpnIpNet[0].Addr(), false)
  330. assert.NotNil(t, hi)
  331. originalRemote := hi.CurrentRemote
  332. t.Log("Re-trigger traffic to cause a new handshake attempt (ErrAlreadySeen)")
  333. myControl.InjectTunPacket(BuildTunUDPPacket(theirVpnIpNet[0].Addr(), 80, myVpnIpNet[0].Addr(), 80, []byte("roam")))
  334. r.RouteForAllUntilTxTun(theirControl)
  335. t.Log("Verify tunnel still works")
  336. assertTunnel(t, myVpnIpNet[0].Addr(), theirVpnIpNet[0].Addr(), myControl, theirControl, r)
  337. t.Log("Verify remote is still valid and index count is stable")
  338. hi2 := theirControl.GetHostInfoByVpnAddr(myVpnIpNet[0].Addr(), false)
  339. assert.NotNil(t, hi2)
  340. assert.Equal(t, originalRemote, hi2.CurrentRemote)
  341. assert.Equal(t, theirIndexes, len(theirControl.ListHostmapIndexes(false)),
  342. "no extra indexes should be created from ErrAlreadySeen")
  343. myControl.Stop()
  344. theirControl.Stop()
  345. }
  346. func TestHandshakeWrongResponderPacketStore(t *testing.T) {
  347. t.Parallel()
  348. // Verify that when the wrong host responds, the cached packets are
  349. // transferred to the new handshake, the evil tunnel is closed, evil's
  350. // address is blocked, and the correct tunnel is eventually established.
  351. ca, _, caKey, _ := cert_test.NewTestCaCert(cert.Version1, cert.Curve_CURVE25519, time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
  352. myControl, myVpnIpNet, myUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.100/24", nil)
  353. theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.99/24", nil)
  354. evilControl, evilVpnIpNet, evilUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "evil", "10.128.0.2/24", nil)
  355. myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), evilUdpAddr)
  356. r := router.NewR(t, myControl, theirControl, evilControl)
  357. defer r.RenderFlow()
  358. myControl.Start()
  359. theirControl.Start()
  360. evilControl.Start()
  361. t.Log("Send multiple packets to them (cached during handshake)")
  362. myControl.InjectTunPacket(BuildTunUDPPacket(theirVpnIpNet[0].Addr(), 80, myVpnIpNet[0].Addr(), 80, []byte("packet1")))
  363. myControl.InjectTunPacket(BuildTunUDPPacket(theirVpnIpNet[0].Addr(), 80, myVpnIpNet[0].Addr(), 80, []byte("packet2")))
  364. t.Log("Route until evil tunnel is closed")
  365. h := &header.H{}
  366. r.RouteForAllExitFunc(func(p *udp.Packet, c *nebula.Control) router.ExitType {
  367. if err := h.Parse(p.Data); err != nil {
  368. panic(err)
  369. }
  370. if h.Type == header.CloseTunnel && p.To == evilUdpAddr {
  371. return router.RouteAndExit
  372. }
  373. return router.KeepRouting
  374. })
  375. t.Log("Verify evil's address is blocked in the new pending handshake")
  376. pendingHI := myControl.GetHostInfoByVpnAddr(theirVpnIpNet[0].Addr(), true)
  377. if pendingHI != nil {
  378. assert.NotContains(t, pendingHI.RemoteAddrs, evilUdpAddr,
  379. "evil's address should be blocked")
  380. }
  381. t.Log("Inject correct lighthouse addr for them")
  382. myControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
  383. t.Log("Route until cached packets arrive at the real them")
  384. p := r.RouteForAllUntilTxTun(theirControl)
  385. assert.NotNil(t, p, "a cached packet should be delivered to the correct host")
  386. t.Log("Verify the correct host has a tunnel")
  387. assertHostInfoPair(t, myUdpAddr, theirUdpAddr, myVpnIpNet, theirVpnIpNet, myControl, theirControl)
  388. t.Log("Verify no hostinfo artifacts from evil remain")
  389. assert.Nil(t, myControl.GetHostInfoByVpnAddr(evilVpnIpNet[0].Addr(), true),
  390. "no pending hostinfo for evil")
  391. assert.Nil(t, myControl.GetHostInfoByVpnAddr(evilVpnIpNet[0].Addr(), false),
  392. "no main hostinfo for evil")
  393. myControl.Stop()
  394. theirControl.Stop()
  395. evilControl.Stop()
  396. }
  397. func TestHandshakeRelayComplete(t *testing.T) {
  398. t.Parallel()
  399. // Verify that a relay handshake completes correctly and relay state is
  400. // properly maintained on all three nodes.
  401. ca, _, caKey, _ := cert_test.NewTestCaCert(cert.Version1, cert.Curve_CURVE25519, time.Now(), time.Now().Add(10*time.Minute), nil, nil, []string{})
  402. myControl, myVpnIpNet, _, _ := newSimpleServer(cert.Version1, ca, caKey, "me", "10.128.0.1/24", m{"relay": m{"use_relays": true}})
  403. relayControl, relayVpnIpNet, relayUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "relay", "10.128.0.128/24", m{"relay": m{"am_relay": true}})
  404. theirControl, theirVpnIpNet, theirUdpAddr, _ := newSimpleServer(cert.Version1, ca, caKey, "them", "10.128.0.2/24", m{"relay": m{"use_relays": true}})
  405. myControl.InjectLightHouseAddr(relayVpnIpNet[0].Addr(), relayUdpAddr)
  406. myControl.InjectRelays(theirVpnIpNet[0].Addr(), []netip.Addr{relayVpnIpNet[0].Addr()})
  407. relayControl.InjectLightHouseAddr(theirVpnIpNet[0].Addr(), theirUdpAddr)
  408. r := router.NewR(t, myControl, relayControl, theirControl)
  409. defer r.RenderFlow()
  410. myControl.Start()
  411. relayControl.Start()
  412. theirControl.Start()
  413. t.Log("Trigger handshake via relay")
  414. myControl.InjectTunPacket(BuildTunUDPPacket(theirVpnIpNet[0].Addr(), 80, myVpnIpNet[0].Addr(), 80, []byte("Hi via relay")))
  415. p := r.RouteForAllUntilTxTun(theirControl)
  416. assertUdpPacket(t, []byte("Hi via relay"), p, myVpnIpNet[0].Addr(), theirVpnIpNet[0].Addr(), 80, 80)
  417. t.Log("Verify bidirectional tunnel via relay")
  418. assertTunnel(t, myVpnIpNet[0].Addr(), theirVpnIpNet[0].Addr(), myControl, theirControl, r)
  419. t.Log("Verify relay state on my side shows relay-to-me")
  420. myHI := myControl.GetHostInfoByVpnAddr(theirVpnIpNet[0].Addr(), false)
  421. assert.NotNil(t, myHI)
  422. assert.NotEmpty(t, myHI.CurrentRelaysToMe, "should have relay-to-me for them")
  423. t.Log("Verify relay state on their side shows relay-to-me")
  424. theirHI := theirControl.GetHostInfoByVpnAddr(myVpnIpNet[0].Addr(), false)
  425. assert.NotNil(t, theirHI)
  426. assert.NotEmpty(t, theirHI.CurrentRelaysToMe, "should have relay-to-me for me")
  427. t.Log("Verify relay node shows through-me relays")
  428. relayHI := relayControl.GetHostInfoByVpnAddr(myVpnIpNet[0].Addr(), false)
  429. assert.NotNil(t, relayHI)
  430. myControl.Stop()
  431. relayControl.Stop()
  432. theirControl.Stop()
  433. }
  434. // NOTE: Relay V1 cert + IPv6 rejection is not tested here because
  435. // BuildTunUDPPacket from a V4 node to a V6 address panics in the test
  436. // framework. The check is in handshake_manager.go handleOutbound relay
  437. // logic (lines ~304-313): if the relay host has a V1 cert and either
  438. // address is IPv6, the relay is skipped.
  439. // NOTE: Relay reestablishment (Disestablished state transition) is covered
  440. // by the existing TestReestablishRelays in handshakes_test.go.