connection_manager_test.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. package nebula
  2. import (
  3. "crypto/ed25519"
  4. "crypto/rand"
  5. "net"
  6. "testing"
  7. "time"
  8. "github.com/flynn/noise"
  9. "github.com/slackhq/nebula/cert"
  10. "github.com/stretchr/testify/assert"
  11. )
  12. var vpnIP uint32
  13. func Test_NewConnectionManagerTest(t *testing.T) {
  14. l := NewTestLogger()
  15. //_, tuncidr, _ := net.ParseCIDR("1.1.1.1/24")
  16. _, vpncidr, _ := net.ParseCIDR("172.1.1.1/24")
  17. _, localrange, _ := net.ParseCIDR("10.1.1.1/24")
  18. vpnIP = ip2int(net.ParseIP("172.1.1.2"))
  19. preferredRanges := []*net.IPNet{localrange}
  20. // Very incomplete mock objects
  21. hostMap := NewHostMap(l, "test", vpncidr, preferredRanges)
  22. cs := &CertState{
  23. rawCertificate: []byte{},
  24. privateKey: []byte{},
  25. certificate: &cert.NebulaCertificate{},
  26. rawCertificateNoKey: []byte{},
  27. }
  28. lh := NewLightHouse(l, false, &net.IPNet{IP: net.IP{0, 0, 0, 0}, Mask: net.IPMask{0, 0, 0, 0}}, []uint32{}, 1000, 0, &udpConn{}, false, 1, false)
  29. ifce := &Interface{
  30. hostMap: hostMap,
  31. inside: &Tun{},
  32. outside: &udpConn{},
  33. certState: cs,
  34. firewall: &Firewall{},
  35. lightHouse: lh,
  36. handshakeManager: NewHandshakeManager(l, vpncidr, preferredRanges, hostMap, lh, &udpConn{}, defaultHandshakeConfig),
  37. l: l,
  38. }
  39. now := time.Now()
  40. // Create manager
  41. nc := newConnectionManager(l, ifce, 5, 10)
  42. p := []byte("")
  43. nb := make([]byte, 12, 12)
  44. out := make([]byte, mtu)
  45. nc.HandleMonitorTick(now, p, nb, out)
  46. // Add an ip we have established a connection w/ to hostmap
  47. hostinfo := nc.hostMap.AddVpnIP(vpnIP)
  48. hostinfo.ConnectionState = &ConnectionState{
  49. certState: cs,
  50. H: &noise.HandshakeState{},
  51. }
  52. // We saw traffic out to vpnIP
  53. nc.Out(vpnIP)
  54. assert.NotContains(t, nc.pendingDeletion, vpnIP)
  55. assert.Contains(t, nc.hostMap.Hosts, vpnIP)
  56. // Move ahead 5s. Nothing should happen
  57. next_tick := now.Add(5 * time.Second)
  58. nc.HandleMonitorTick(next_tick, p, nb, out)
  59. nc.HandleDeletionTick(next_tick)
  60. // Move ahead 6s. We haven't heard back
  61. next_tick = now.Add(6 * time.Second)
  62. nc.HandleMonitorTick(next_tick, p, nb, out)
  63. nc.HandleDeletionTick(next_tick)
  64. // This host should now be up for deletion
  65. assert.Contains(t, nc.pendingDeletion, vpnIP)
  66. assert.Contains(t, nc.hostMap.Hosts, vpnIP)
  67. // Move ahead some more
  68. next_tick = now.Add(45 * time.Second)
  69. nc.HandleMonitorTick(next_tick, p, nb, out)
  70. nc.HandleDeletionTick(next_tick)
  71. // The host should be evicted
  72. assert.NotContains(t, nc.pendingDeletion, vpnIP)
  73. assert.NotContains(t, nc.hostMap.Hosts, vpnIP)
  74. }
  75. func Test_NewConnectionManagerTest2(t *testing.T) {
  76. l := NewTestLogger()
  77. //_, tuncidr, _ := net.ParseCIDR("1.1.1.1/24")
  78. _, vpncidr, _ := net.ParseCIDR("172.1.1.1/24")
  79. _, localrange, _ := net.ParseCIDR("10.1.1.1/24")
  80. preferredRanges := []*net.IPNet{localrange}
  81. // Very incomplete mock objects
  82. hostMap := NewHostMap(l, "test", vpncidr, preferredRanges)
  83. cs := &CertState{
  84. rawCertificate: []byte{},
  85. privateKey: []byte{},
  86. certificate: &cert.NebulaCertificate{},
  87. rawCertificateNoKey: []byte{},
  88. }
  89. lh := NewLightHouse(l, false, &net.IPNet{IP: net.IP{0, 0, 0, 0}, Mask: net.IPMask{0, 0, 0, 0}}, []uint32{}, 1000, 0, &udpConn{}, false, 1, false)
  90. ifce := &Interface{
  91. hostMap: hostMap,
  92. inside: &Tun{},
  93. outside: &udpConn{},
  94. certState: cs,
  95. firewall: &Firewall{},
  96. lightHouse: lh,
  97. handshakeManager: NewHandshakeManager(l, vpncidr, preferredRanges, hostMap, lh, &udpConn{}, defaultHandshakeConfig),
  98. l: l,
  99. }
  100. now := time.Now()
  101. // Create manager
  102. nc := newConnectionManager(l, ifce, 5, 10)
  103. p := []byte("")
  104. nb := make([]byte, 12, 12)
  105. out := make([]byte, mtu)
  106. nc.HandleMonitorTick(now, p, nb, out)
  107. // Add an ip we have established a connection w/ to hostmap
  108. hostinfo := nc.hostMap.AddVpnIP(vpnIP)
  109. hostinfo.ConnectionState = &ConnectionState{
  110. certState: cs,
  111. H: &noise.HandshakeState{},
  112. }
  113. // We saw traffic out to vpnIP
  114. nc.Out(vpnIP)
  115. assert.NotContains(t, nc.pendingDeletion, vpnIP)
  116. assert.Contains(t, nc.hostMap.Hosts, vpnIP)
  117. // Move ahead 5s. Nothing should happen
  118. next_tick := now.Add(5 * time.Second)
  119. nc.HandleMonitorTick(next_tick, p, nb, out)
  120. nc.HandleDeletionTick(next_tick)
  121. // Move ahead 6s. We haven't heard back
  122. next_tick = now.Add(6 * time.Second)
  123. nc.HandleMonitorTick(next_tick, p, nb, out)
  124. nc.HandleDeletionTick(next_tick)
  125. // This host should now be up for deletion
  126. assert.Contains(t, nc.pendingDeletion, vpnIP)
  127. assert.Contains(t, nc.hostMap.Hosts, vpnIP)
  128. // We heard back this time
  129. nc.In(vpnIP)
  130. // Move ahead some more
  131. next_tick = now.Add(45 * time.Second)
  132. nc.HandleMonitorTick(next_tick, p, nb, out)
  133. nc.HandleDeletionTick(next_tick)
  134. // The host should be evicted
  135. assert.NotContains(t, nc.pendingDeletion, vpnIP)
  136. assert.Contains(t, nc.hostMap.Hosts, vpnIP)
  137. }
  138. // Check if we can disconnect the peer.
  139. // Validate if the peer's certificate is invalid (expired, etc.)
  140. // Disconnect only if disconnectInvalid: true is set.
  141. func Test_NewConnectionManagerTest_DisconnectInvalid(t *testing.T) {
  142. now := time.Now()
  143. l := NewTestLogger()
  144. ipNet := net.IPNet{
  145. IP: net.IPv4(172, 1, 1, 2),
  146. Mask: net.IPMask{255, 255, 255, 0},
  147. }
  148. _, vpncidr, _ := net.ParseCIDR("172.1.1.1/24")
  149. _, localrange, _ := net.ParseCIDR("10.1.1.1/24")
  150. preferredRanges := []*net.IPNet{localrange}
  151. hostMap := NewHostMap(l, "test", vpncidr, preferredRanges)
  152. // Generate keys for CA and peer's cert.
  153. pubCA, privCA, _ := ed25519.GenerateKey(rand.Reader)
  154. caCert := cert.NebulaCertificate{
  155. Details: cert.NebulaCertificateDetails{
  156. Name: "ca",
  157. NotBefore: now,
  158. NotAfter: now.Add(1 * time.Hour),
  159. IsCA: true,
  160. PublicKey: pubCA,
  161. },
  162. }
  163. caCert.Sign(privCA)
  164. ncp := &cert.NebulaCAPool{
  165. CAs: cert.NewCAPool().CAs,
  166. }
  167. ncp.CAs["ca"] = &caCert
  168. pubCrt, _, _ := ed25519.GenerateKey(rand.Reader)
  169. peerCert := cert.NebulaCertificate{
  170. Details: cert.NebulaCertificateDetails{
  171. Name: "host",
  172. Ips: []*net.IPNet{&ipNet},
  173. Subnets: []*net.IPNet{},
  174. NotBefore: now,
  175. NotAfter: now.Add(60 * time.Second),
  176. PublicKey: pubCrt,
  177. IsCA: false,
  178. Issuer: "ca",
  179. },
  180. }
  181. peerCert.Sign(privCA)
  182. cs := &CertState{
  183. rawCertificate: []byte{},
  184. privateKey: []byte{},
  185. certificate: &cert.NebulaCertificate{},
  186. rawCertificateNoKey: []byte{},
  187. }
  188. lh := NewLightHouse(l, false, &net.IPNet{IP: net.IP{0, 0, 0, 0}, Mask: net.IPMask{0, 0, 0, 0}}, []uint32{}, 1000, 0, &udpConn{}, false, 1, false)
  189. ifce := &Interface{
  190. hostMap: hostMap,
  191. inside: &Tun{},
  192. outside: &udpConn{},
  193. certState: cs,
  194. firewall: &Firewall{},
  195. lightHouse: lh,
  196. handshakeManager: NewHandshakeManager(l, vpncidr, preferredRanges, hostMap, lh, &udpConn{}, defaultHandshakeConfig),
  197. l: l,
  198. disconnectInvalid: true,
  199. caPool: ncp,
  200. }
  201. // Create manager
  202. nc := newConnectionManager(l, ifce, 5, 10)
  203. ifce.connectionManager = nc
  204. hostinfo := nc.hostMap.AddVpnIP(vpnIP)
  205. hostinfo.ConnectionState = &ConnectionState{
  206. certState: cs,
  207. peerCert: &peerCert,
  208. H: &noise.HandshakeState{},
  209. }
  210. // Move ahead 45s.
  211. // Check if to disconnect with invalid certificate.
  212. // Should be alive.
  213. nextTick := now.Add(45 * time.Second)
  214. destroyed := nc.handleInvalidCertificate(nextTick, vpnIP, hostinfo)
  215. assert.False(t, destroyed)
  216. // Move ahead 61s.
  217. // Check if to disconnect with invalid certificate.
  218. // Should be disconnected.
  219. nextTick = now.Add(61 * time.Second)
  220. destroyed = nc.handleInvalidCertificate(nextTick, vpnIP, hostinfo)
  221. assert.True(t, destroyed)
  222. }