handshake_ix.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. package nebula
  2. import (
  3. "sync/atomic"
  4. "time"
  5. "bytes"
  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. myIndex, err := generateIndex()
  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. f.handshakeManager.AddIndexHostInfo(myIndex, hostinfo)
  31. hsProto := &NebulaHandshakeDetails{
  32. InitiatorIndex: myIndex,
  33. Time: uint64(time.Now().Unix()),
  34. Cert: ci.certState.rawCertificateNoKey,
  35. }
  36. hsBytes := []byte{}
  37. hs := &NebulaHandshake{
  38. Details: hsProto,
  39. }
  40. hsBytes, err = proto.Marshal(hs)
  41. if err != nil {
  42. l.WithError(err).WithField("vpnIp", IntIp(vpnIp)).
  43. WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).Error("Failed to marshal handshake message")
  44. return
  45. }
  46. header := HeaderEncode(make([]byte, HeaderLen), Version, uint8(handshake), handshakeIXPSK0, 0, 1)
  47. atomic.AddUint64(ci.messageCounter, 1)
  48. msg, _, _, err := ci.H.WriteMessage(header, hsBytes)
  49. if err != nil {
  50. l.WithError(err).WithField("vpnIp", IntIp(vpnIp)).
  51. WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).Error("Failed to call noise.WriteMessage")
  52. return
  53. }
  54. hostinfo.HandshakePacket[0] = msg
  55. hostinfo.HandshakeReady = true
  56. hostinfo.handshakeStart = time.Now()
  57. }
  58. func ixHandshakeStage1(f *Interface, addr *udpAddr, hostinfo *HostInfo, packet []byte, h *Header) bool {
  59. var ip uint32
  60. if h.RemoteIndex == 0 {
  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 true
  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 true
  79. }
  80. hostinfo, _ := f.handshakeManager.pendingHostMap.QueryReverseIndex(hs.Details.InitiatorIndex)
  81. if hostinfo != nil && bytes.Equal(hostinfo.HandshakePacket[0], packet[HeaderLen:]) {
  82. if msg, ok := hostinfo.HandshakePacket[2]; ok {
  83. f.messageMetrics.Tx(handshake, NebulaMessageSubType(msg[1]), 1)
  84. err := f.outside.WriteTo(msg, addr)
  85. if err != nil {
  86. l.WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  87. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).WithField("cached", true).
  88. WithError(err).Error("Failed to send handshake message")
  89. } else {
  90. l.WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  91. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).WithField("cached", true).
  92. Info("Handshake message sent")
  93. }
  94. return false
  95. }
  96. l.WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  97. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).WithField("cached", true).
  98. WithField("packets", hostinfo.HandshakePacket).
  99. Error("Seen this handshake packet already but don't have a cached packet to return")
  100. }
  101. remoteCert, err := RecombineCertAndValidate(ci.H, hs.Details.Cert)
  102. if err != nil {
  103. l.WithError(err).WithField("udpAddr", addr).
  104. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).WithField("cert", remoteCert).
  105. Info("Invalid certificate from host")
  106. return true
  107. }
  108. vpnIP := ip2int(remoteCert.Details.Ips[0].IP)
  109. certName := remoteCert.Details.Name
  110. myIndex, err := generateIndex()
  111. if err != nil {
  112. l.WithError(err).WithField("vpnIp", IntIp(vpnIP)).WithField("udpAddr", addr).
  113. WithField("certName", certName).
  114. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Failed to generate index")
  115. return true
  116. }
  117. hostinfo, err = f.handshakeManager.AddIndex(myIndex, ci)
  118. if err != nil {
  119. l.WithError(err).WithField("vpnIp", IntIp(vpnIP)).WithField("udpAddr", addr).
  120. WithField("certName", certName).
  121. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Error adding index to connection manager")
  122. return true
  123. }
  124. l.WithField("vpnIp", IntIp(vpnIP)).WithField("udpAddr", addr).
  125. WithField("certName", certName).
  126. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  127. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  128. Info("Handshake message received")
  129. hostinfo.remoteIndexId = hs.Details.InitiatorIndex
  130. hs.Details.ResponderIndex = myIndex
  131. hs.Details.Cert = ci.certState.rawCertificateNoKey
  132. hsBytes, err := proto.Marshal(hs)
  133. if err != nil {
  134. l.WithError(err).WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  135. WithField("certName", certName).
  136. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Failed to marshal handshake message")
  137. return true
  138. }
  139. header := HeaderEncode(make([]byte, HeaderLen), Version, uint8(handshake), handshakeIXPSK0, hs.Details.InitiatorIndex, 2)
  140. msg, dKey, eKey, err := ci.H.WriteMessage(header, hsBytes)
  141. if err != nil {
  142. l.WithError(err).WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  143. WithField("certName", certName).
  144. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Failed to call noise.WriteMessage")
  145. return true
  146. }
  147. if f.hostMap.CheckHandshakeCompleteIP(vpnIP) && vpnIP < ip2int(f.certState.certificate.Details.Ips[0].IP) {
  148. l.WithField("vpnIp", IntIp(vpnIP)).WithField("udpAddr", addr).
  149. WithField("certName", certName).
  150. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  151. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  152. Info("Prevented a handshake race")
  153. // Send a test packet to trigger an authenticated tunnel test, this should suss out any lingering tunnel issues
  154. f.SendMessageToVpnIp(test, testRequest, vpnIP, []byte(""), make([]byte, 12, 12), make([]byte, mtu))
  155. return true
  156. }
  157. hostinfo.HandshakePacket[0] = make([]byte, len(packet[HeaderLen:]))
  158. copy(hostinfo.HandshakePacket[0], packet[HeaderLen:])
  159. // Regardless of whether you are the sender or receiver, you should arrive here
  160. // and complete standing up the connection.
  161. if dKey != nil && eKey != nil {
  162. hostinfo.HandshakePacket[2] = make([]byte, len(msg))
  163. copy(hostinfo.HandshakePacket[2], msg)
  164. f.messageMetrics.Tx(handshake, NebulaMessageSubType(msg[1]), 1)
  165. err := f.outside.WriteTo(msg, addr)
  166. if err != nil {
  167. l.WithField("vpnIp", IntIp(vpnIP)).WithField("udpAddr", addr).
  168. WithField("certName", certName).
  169. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  170. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  171. WithError(err).Error("Failed to send handshake")
  172. } else {
  173. l.WithField("vpnIp", IntIp(vpnIP)).WithField("udpAddr", addr).
  174. WithField("certName", certName).
  175. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  176. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  177. Info("Handshake message sent")
  178. }
  179. ip = ip2int(remoteCert.Details.Ips[0].IP)
  180. ci.peerCert = remoteCert
  181. ci.dKey = NewNebulaCipherState(dKey)
  182. ci.eKey = NewNebulaCipherState(eKey)
  183. //l.Debugln("got symmetric pairs")
  184. //hostinfo.ClearRemotes()
  185. hostinfo.AddRemote(*addr)
  186. hostinfo.CreateRemoteCIDR(remoteCert)
  187. f.lightHouse.AddRemoteAndReset(ip, addr)
  188. if f.serveDns {
  189. dnsR.Add(remoteCert.Details.Name+".", remoteCert.Details.Ips[0].IP.String())
  190. }
  191. ho, err := f.hostMap.QueryVpnIP(vpnIP)
  192. if err == nil && ho.localIndexId != 0 {
  193. l.WithField("vpnIp", vpnIP).
  194. WithField("certName", certName).
  195. WithField("action", "removing stale index").
  196. WithField("index", ho.localIndexId).
  197. Debug("Handshake processing")
  198. f.hostMap.DeleteIndex(ho.localIndexId)
  199. }
  200. f.hostMap.AddIndexHostInfo(hostinfo.localIndexId, hostinfo)
  201. f.hostMap.AddVpnIPHostInfo(vpnIP, hostinfo)
  202. hostinfo.handshakeComplete()
  203. } else {
  204. l.WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  205. WithField("certName", certName).
  206. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  207. Error("Noise did not arrive at a key")
  208. return true
  209. }
  210. }
  211. f.hostMap.AddRemote(ip, addr)
  212. return false
  213. }
  214. func ixHandshakeStage2(f *Interface, addr *udpAddr, hostinfo *HostInfo, packet []byte, h *Header) bool {
  215. if hostinfo == nil {
  216. return true
  217. }
  218. if bytes.Equal(hostinfo.HandshakePacket[2], packet[HeaderLen:]) {
  219. l.WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  220. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).WithField("header", h).
  221. Error("Already seen this handshake packet")
  222. return false
  223. }
  224. ci := hostinfo.ConnectionState
  225. // Mark packet 2 as seen so it doesn't show up as missed
  226. ci.window.Update(2)
  227. hostinfo.HandshakePacket[2] = make([]byte, len(packet[HeaderLen:]))
  228. copy(hostinfo.HandshakePacket[2], packet[HeaderLen:])
  229. msg, eKey, dKey, err := ci.H.ReadMessage(nil, packet[HeaderLen:])
  230. if err != nil {
  231. l.WithError(err).WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  232. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).WithField("header", h).
  233. Error("Failed to call noise.ReadMessage")
  234. // We don't want to tear down the connection on a bad ReadMessage because it could be an attacker trying
  235. // to DOS us. Every other error condition after should to allow a possible good handshake to complete in the
  236. // near future
  237. return false
  238. }
  239. hs := &NebulaHandshake{}
  240. err = proto.Unmarshal(msg, hs)
  241. if err != nil || hs.Details == nil {
  242. l.WithError(err).WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  243. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).Error("Failed unmarshal handshake message")
  244. return true
  245. }
  246. remoteCert, err := RecombineCertAndValidate(ci.H, hs.Details.Cert)
  247. if err != nil {
  248. l.WithError(err).WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  249. WithField("cert", remoteCert).WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  250. Error("Invalid certificate from host")
  251. return true
  252. }
  253. vpnIP := ip2int(remoteCert.Details.Ips[0].IP)
  254. certName := remoteCert.Details.Name
  255. duration := time.Since(hostinfo.handshakeStart).Nanoseconds()
  256. l.WithField("vpnIp", IntIp(vpnIP)).WithField("udpAddr", addr).
  257. WithField("certName", certName).
  258. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  259. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  260. WithField("durationNs", duration).
  261. Info("Handshake message received")
  262. //ci.remoteIndex = hs.ResponderIndex
  263. hostinfo.remoteIndexId = hs.Details.ResponderIndex
  264. hs.Details.Cert = ci.certState.rawCertificateNoKey
  265. /*
  266. hsBytes, err := proto.Marshal(hs)
  267. if err != nil {
  268. l.Debugln("Failed to marshal handshake: ", err)
  269. return
  270. }
  271. */
  272. // Regardless of whether you are the sender or receiver, you should arrive here
  273. // and complete standing up the connection.
  274. if dKey != nil && eKey != nil {
  275. ip := ip2int(remoteCert.Details.Ips[0].IP)
  276. ci.peerCert = remoteCert
  277. ci.dKey = NewNebulaCipherState(dKey)
  278. ci.eKey = NewNebulaCipherState(eKey)
  279. //l.Debugln("got symmetric pairs")
  280. //hostinfo.ClearRemotes()
  281. f.hostMap.AddRemote(ip, addr)
  282. hostinfo.CreateRemoteCIDR(remoteCert)
  283. f.lightHouse.AddRemoteAndReset(ip, addr)
  284. if f.serveDns {
  285. dnsR.Add(remoteCert.Details.Name+".", remoteCert.Details.Ips[0].IP.String())
  286. }
  287. ho, err := f.hostMap.QueryVpnIP(vpnIP)
  288. if err == nil && ho.localIndexId != 0 {
  289. l.WithField("vpnIp", vpnIP).
  290. WithField("certName", certName).
  291. WithField("action", "removing stale index").
  292. WithField("index", ho.localIndexId).
  293. Debug("Handshake processing")
  294. f.hostMap.DeleteIndex(ho.localIndexId)
  295. }
  296. f.hostMap.AddVpnIPHostInfo(vpnIP, hostinfo)
  297. f.hostMap.AddIndexHostInfo(hostinfo.localIndexId, hostinfo)
  298. hostinfo.handshakeComplete()
  299. f.metricHandshakes.Update(duration)
  300. } else {
  301. l.WithField("vpnIp", IntIp(hostinfo.hostId)).WithField("udpAddr", addr).
  302. WithField("certName", certName).
  303. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  304. Error("Noise did not arrive at a key")
  305. return true
  306. }
  307. return false
  308. }