handshake_ix.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. package nebula
  2. import (
  3. "bytes"
  4. "sync/atomic"
  5. "time"
  6. "github.com/flynn/noise"
  7. "github.com/golang/protobuf/proto"
  8. )
  9. // NOISE IX Handshakes
  10. // This function constructs a handshake packet, but does not actually send it
  11. // Sending is done by the handshake manager
  12. func ixHandshakeStage0(f *Interface, vpnIp uint32, hostinfo *HostInfo) {
  13. // This queries the lighthouse if we don't know a remote for the host
  14. if hostinfo.remote == nil {
  15. ips, err := f.lightHouse.Query(vpnIp, f)
  16. if err != nil {
  17. //l.Debugln(err)
  18. }
  19. for _, ip := range ips {
  20. hostinfo.AddRemote(ip)
  21. }
  22. }
  23. err := f.handshakeManager.AddIndexHostInfo(hostinfo)
  24. if err != nil {
  25. l.WithError(err).WithField("vpnIp", IntIp(vpnIp)).
  26. WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).Error("Failed to generate index")
  27. return
  28. }
  29. ci := hostinfo.ConnectionState
  30. hsProto := &NebulaHandshakeDetails{
  31. InitiatorIndex: hostinfo.localIndexId,
  32. Time: uint64(time.Now().Unix()),
  33. Cert: ci.certState.rawCertificateNoKey,
  34. }
  35. hsBytes := []byte{}
  36. hs := &NebulaHandshake{
  37. Details: hsProto,
  38. }
  39. hsBytes, err = proto.Marshal(hs)
  40. if err != nil {
  41. l.WithError(err).WithField("vpnIp", IntIp(vpnIp)).
  42. WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).Error("Failed to marshal handshake message")
  43. return
  44. }
  45. header := HeaderEncode(make([]byte, HeaderLen), Version, uint8(handshake), handshakeIXPSK0, 0, 1)
  46. atomic.AddUint64(&ci.atomicMessageCounter, 1)
  47. msg, _, _, err := ci.H.WriteMessage(header, hsBytes)
  48. if err != nil {
  49. l.WithError(err).WithField("vpnIp", IntIp(vpnIp)).
  50. WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).Error("Failed to call noise.WriteMessage")
  51. return
  52. }
  53. // We are sending handshake packet 1, so we don't expect to receive
  54. // handshake packet 1 from the responder
  55. ci.window.Update(1)
  56. hostinfo.HandshakePacket[0] = msg
  57. hostinfo.HandshakeReady = true
  58. hostinfo.handshakeStart = time.Now()
  59. }
  60. func ixHandshakeStage1(f *Interface, addr *udpAddr, packet []byte, h *Header) {
  61. ci := f.newConnectionState(false, noise.HandshakeIX, []byte{}, 0)
  62. // Mark packet 1 as seen so it doesn't show up as missed
  63. ci.window.Update(1)
  64. msg, _, _, err := ci.H.ReadMessage(nil, packet[HeaderLen:])
  65. if err != nil {
  66. l.WithError(err).WithField("udpAddr", addr).
  67. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Failed to call noise.ReadMessage")
  68. return
  69. }
  70. hs := &NebulaHandshake{}
  71. err = proto.Unmarshal(msg, hs)
  72. /*
  73. l.Debugln("GOT INDEX: ", hs.Details.InitiatorIndex)
  74. */
  75. if err != nil || hs.Details == nil {
  76. l.WithError(err).WithField("udpAddr", addr).
  77. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Failed unmarshal handshake message")
  78. return
  79. }
  80. remoteCert, err := RecombineCertAndValidate(ci.H, hs.Details.Cert)
  81. if err != nil {
  82. l.WithError(err).WithField("udpAddr", addr).
  83. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).WithField("cert", remoteCert).
  84. Info("Invalid certificate from host")
  85. return
  86. }
  87. vpnIP := ip2int(remoteCert.Details.Ips[0].IP)
  88. certName := remoteCert.Details.Name
  89. fingerprint, _ := remoteCert.Sha256Sum()
  90. myIndex, err := generateIndex()
  91. if err != nil {
  92. l.WithError(err).WithField("vpnIp", IntIp(vpnIP)).WithField("udpAddr", addr).
  93. WithField("certName", certName).
  94. WithField("fingerprint", fingerprint).
  95. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Failed to generate index")
  96. return
  97. }
  98. hostinfo := &HostInfo{
  99. ConnectionState: ci,
  100. Remotes: []*HostInfoDest{},
  101. localIndexId: myIndex,
  102. remoteIndexId: hs.Details.InitiatorIndex,
  103. hostId: vpnIP,
  104. HandshakePacket: make(map[uint8][]byte, 0),
  105. }
  106. l.WithField("vpnIp", IntIp(vpnIP)).WithField("udpAddr", addr).
  107. WithField("certName", certName).
  108. WithField("fingerprint", fingerprint).
  109. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  110. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  111. Info("Handshake message received")
  112. hs.Details.ResponderIndex = myIndex
  113. hs.Details.Cert = ci.certState.rawCertificateNoKey
  114. hsBytes, err := proto.Marshal(hs)
  115. if err != nil {
  116. l.WithError(err).WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  117. WithField("certName", certName).
  118. WithField("fingerprint", fingerprint).
  119. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Failed to marshal handshake message")
  120. return
  121. }
  122. header := HeaderEncode(make([]byte, HeaderLen), Version, uint8(handshake), handshakeIXPSK0, hs.Details.InitiatorIndex, 2)
  123. msg, dKey, eKey, err := ci.H.WriteMessage(header, hsBytes)
  124. if err != nil {
  125. l.WithError(err).WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  126. WithField("certName", certName).
  127. WithField("fingerprint", fingerprint).
  128. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Failed to call noise.WriteMessage")
  129. return
  130. } else if dKey == nil || eKey == nil {
  131. l.WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  132. WithField("certName", certName).
  133. WithField("fingerprint", fingerprint).
  134. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Noise did not arrive at a key")
  135. return
  136. }
  137. hostinfo.HandshakePacket[0] = make([]byte, len(packet[HeaderLen:]))
  138. copy(hostinfo.HandshakePacket[0], packet[HeaderLen:])
  139. // Regardless of whether you are the sender or receiver, you should arrive here
  140. // and complete standing up the connection.
  141. hostinfo.HandshakePacket[2] = make([]byte, len(msg))
  142. copy(hostinfo.HandshakePacket[2], msg)
  143. // We are sending handshake packet 2, so we don't expect to receive
  144. // handshake packet 2 from the initiator.
  145. ci.window.Update(2)
  146. ci.peerCert = remoteCert
  147. ci.dKey = NewNebulaCipherState(dKey)
  148. ci.eKey = NewNebulaCipherState(eKey)
  149. //l.Debugln("got symmetric pairs")
  150. //hostinfo.ClearRemotes()
  151. hostinfo.AddRemote(*addr)
  152. hostinfo.ForcePromoteBest(f.hostMap.preferredRanges)
  153. hostinfo.CreateRemoteCIDR(remoteCert)
  154. hostinfo.Lock()
  155. defer hostinfo.Unlock()
  156. // Only overwrite existing record if we should win the handshake race
  157. overwrite := vpnIP > ip2int(f.certState.certificate.Details.Ips[0].IP)
  158. existing, err := f.handshakeManager.CheckAndComplete(hostinfo, 0, overwrite, f)
  159. if err != nil {
  160. switch err {
  161. case ErrAlreadySeen:
  162. msg = existing.HandshakePacket[2]
  163. f.messageMetrics.Tx(handshake, NebulaMessageSubType(msg[1]), 1)
  164. err := f.outside.WriteTo(msg, addr)
  165. if err != nil {
  166. l.WithField("vpnIp", IntIp(existing.hostId)).WithField("udpAddr", addr).
  167. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).WithField("cached", true).
  168. WithError(err).Error("Failed to send handshake message")
  169. } else {
  170. l.WithField("vpnIp", IntIp(existing.hostId)).WithField("udpAddr", addr).
  171. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).WithField("cached", true).
  172. Info("Handshake message sent")
  173. }
  174. return
  175. case ErrExistingHostInfo:
  176. // This means there was an existing tunnel and we didn't win
  177. // handshake avoidance
  178. l.WithField("vpnIp", IntIp(vpnIP)).WithField("udpAddr", addr).
  179. WithField("certName", certName).
  180. WithField("fingerprint", fingerprint).
  181. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  182. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  183. Info("Prevented a handshake race")
  184. // Send a test packet to trigger an authenticated tunnel test, this should suss out any lingering tunnel issues
  185. f.SendMessageToVpnIp(test, testRequest, vpnIP, []byte(""), make([]byte, 12, 12), make([]byte, mtu))
  186. return
  187. case ErrLocalIndexCollision:
  188. // This means we failed to insert because of collision on localIndexId. Just let the next handshake packet retry
  189. l.WithField("vpnIp", IntIp(vpnIP)).WithField("udpAddr", addr).
  190. WithField("certName", certName).
  191. WithField("fingerprint", fingerprint).
  192. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  193. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  194. WithField("localIndex", hostinfo.localIndexId).WithField("collision", IntIp(existing.hostId)).
  195. Error("Failed to add HostInfo due to localIndex collision")
  196. return
  197. default:
  198. // Shouldn't happen, but just in case someone adds a new error type to CheckAndComplete
  199. // And we forget to update it here
  200. l.WithError(err).WithField("vpnIp", IntIp(vpnIP)).WithField("udpAddr", addr).
  201. WithField("certName", certName).
  202. WithField("fingerprint", fingerprint).
  203. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  204. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  205. Error("Failed to add HostInfo to HostMap")
  206. return
  207. }
  208. }
  209. // Do the send
  210. f.messageMetrics.Tx(handshake, NebulaMessageSubType(msg[1]), 1)
  211. err = f.outside.WriteTo(msg, addr)
  212. if err != nil {
  213. l.WithField("vpnIp", IntIp(vpnIP)).WithField("udpAddr", addr).
  214. WithField("certName", certName).
  215. WithField("fingerprint", fingerprint).
  216. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  217. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  218. WithError(err).Error("Failed to send handshake")
  219. } else {
  220. l.WithField("vpnIp", IntIp(vpnIP)).WithField("udpAddr", addr).
  221. WithField("certName", certName).
  222. WithField("fingerprint", fingerprint).
  223. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  224. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  225. Info("Handshake message sent")
  226. }
  227. hostinfo.handshakeComplete()
  228. return
  229. }
  230. func ixHandshakeStage2(f *Interface, addr *udpAddr, hostinfo *HostInfo, packet []byte, h *Header) bool {
  231. if hostinfo == nil {
  232. return true
  233. }
  234. hostinfo.Lock()
  235. defer hostinfo.Unlock()
  236. if bytes.Equal(hostinfo.HandshakePacket[2], packet[HeaderLen:]) {
  237. l.WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  238. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).WithField("header", h).
  239. Info("Already seen this handshake packet")
  240. return false
  241. }
  242. ci := hostinfo.ConnectionState
  243. // Mark packet 2 as seen so it doesn't show up as missed
  244. ci.window.Update(2)
  245. hostinfo.HandshakePacket[2] = make([]byte, len(packet[HeaderLen:]))
  246. copy(hostinfo.HandshakePacket[2], packet[HeaderLen:])
  247. msg, eKey, dKey, err := ci.H.ReadMessage(nil, packet[HeaderLen:])
  248. if err != nil {
  249. l.WithError(err).WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  250. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).WithField("header", h).
  251. Error("Failed to call noise.ReadMessage")
  252. // We don't want to tear down the connection on a bad ReadMessage because it could be an attacker trying
  253. // to DOS us. Every other error condition after should to allow a possible good handshake to complete in the
  254. // near future
  255. return false
  256. } else if dKey == nil || eKey == nil {
  257. l.WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  258. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  259. Error("Noise did not arrive at a key")
  260. return true
  261. }
  262. hs := &NebulaHandshake{}
  263. err = proto.Unmarshal(msg, hs)
  264. if err != nil || hs.Details == nil {
  265. l.WithError(err).WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  266. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).Error("Failed unmarshal handshake message")
  267. return true
  268. }
  269. remoteCert, err := RecombineCertAndValidate(ci.H, hs.Details.Cert)
  270. if err != nil {
  271. l.WithError(err).WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  272. WithField("cert", remoteCert).WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  273. Error("Invalid certificate from host")
  274. return true
  275. }
  276. vpnIP := ip2int(remoteCert.Details.Ips[0].IP)
  277. certName := remoteCert.Details.Name
  278. fingerprint, _ := remoteCert.Sha256Sum()
  279. duration := time.Since(hostinfo.handshakeStart).Nanoseconds()
  280. l.WithField("vpnIp", IntIp(vpnIP)).WithField("udpAddr", addr).
  281. WithField("certName", certName).
  282. WithField("fingerprint", fingerprint).
  283. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  284. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  285. WithField("durationNs", duration).
  286. Info("Handshake message received")
  287. //ci.remoteIndex = hs.ResponderIndex
  288. hostinfo.remoteIndexId = hs.Details.ResponderIndex
  289. hs.Details.Cert = ci.certState.rawCertificateNoKey
  290. /*
  291. hsBytes, err := proto.Marshal(hs)
  292. if err != nil {
  293. l.Debugln("Failed to marshal handshake: ", err)
  294. return
  295. }
  296. */
  297. // Regardless of whether you are the sender or receiver, you should arrive here
  298. // and complete standing up the connection.
  299. ci.peerCert = remoteCert
  300. ci.dKey = NewNebulaCipherState(dKey)
  301. ci.eKey = NewNebulaCipherState(eKey)
  302. //l.Debugln("got symmetric pairs")
  303. //hostinfo.ClearRemotes()
  304. hostinfo.AddRemote(*addr)
  305. hostinfo.ForcePromoteBest(f.hostMap.preferredRanges)
  306. hostinfo.CreateRemoteCIDR(remoteCert)
  307. f.handshakeManager.Complete(hostinfo, f)
  308. hostinfo.handshakeComplete()
  309. f.metricHandshakes.Update(duration)
  310. return false
  311. }