handshake_ix.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. package nebula
  2. import (
  3. "net/netip"
  4. "time"
  5. "github.com/flynn/noise"
  6. "github.com/sirupsen/logrus"
  7. "github.com/slackhq/nebula/cert"
  8. "github.com/slackhq/nebula/header"
  9. )
  10. // NOISE IX Handshakes
  11. // This function constructs a handshake packet, but does not actually send it
  12. // Sending is done by the handshake manager
  13. func ixHandshakeStage0(f *Interface, hh *HandshakeHostInfo) bool {
  14. err := f.handshakeManager.allocateIndex(hh)
  15. if err != nil {
  16. f.l.WithError(err).WithField("vpnAddrs", hh.hostinfo.vpnAddrs).
  17. WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).Error("Failed to generate index")
  18. return false
  19. }
  20. cs := f.pki.getCertState()
  21. v := cs.initiatingVersion
  22. if hh.initiatingVersionOverride != cert.VersionPre1 {
  23. v = hh.initiatingVersionOverride
  24. } else if v < cert.Version2 {
  25. // If we're connecting to a v6 address we should encourage use of a V2 cert
  26. for _, a := range hh.hostinfo.vpnAddrs {
  27. if a.Is6() {
  28. v = cert.Version2
  29. break
  30. }
  31. }
  32. }
  33. crt := cs.getCertificate(v)
  34. if crt == nil {
  35. f.l.WithField("vpnAddrs", hh.hostinfo.vpnAddrs).
  36. WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).
  37. WithField("certVersion", v).
  38. Error("Unable to handshake with host because no certificate is available")
  39. return false
  40. }
  41. crtHs := cs.getHandshakeBytes(v)
  42. if crtHs == nil {
  43. f.l.WithField("vpnAddrs", hh.hostinfo.vpnAddrs).
  44. WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).
  45. WithField("certVersion", v).
  46. Error("Unable to handshake with host because no certificate handshake bytes is available")
  47. return false
  48. }
  49. ci, err := NewConnectionState(f.l, cs, crt, true, noise.HandshakeIX)
  50. if err != nil {
  51. f.l.WithError(err).WithField("vpnAddrs", hh.hostinfo.vpnAddrs).
  52. WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).
  53. WithField("certVersion", v).
  54. Error("Failed to create connection state")
  55. return false
  56. }
  57. hh.hostinfo.ConnectionState = ci
  58. hs := &NebulaHandshake{
  59. Details: &NebulaHandshakeDetails{
  60. InitiatorIndex: hh.hostinfo.localIndexId,
  61. Time: uint64(time.Now().UnixNano()),
  62. Cert: crtHs,
  63. CertVersion: uint32(v),
  64. },
  65. }
  66. hsBytes, err := hs.Marshal()
  67. if err != nil {
  68. f.l.WithError(err).WithField("vpnAddrs", hh.hostinfo.vpnAddrs).
  69. WithField("certVersion", v).
  70. WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).Error("Failed to marshal handshake message")
  71. return false
  72. }
  73. h := header.Encode(make([]byte, header.Len), header.Version, header.Handshake, header.HandshakeIXPSK0, 0, 1)
  74. msg, _, _, err := ci.H.WriteMessage(h, hsBytes)
  75. if err != nil {
  76. f.l.WithError(err).WithField("vpnAddrs", hh.hostinfo.vpnAddrs).
  77. WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).Error("Failed to call noise.WriteMessage")
  78. return false
  79. }
  80. // We are sending handshake packet 1, so we don't expect to receive
  81. // handshake packet 1 from the responder
  82. ci.window.Update(f.l, 1)
  83. hh.hostinfo.HandshakePacket[0] = msg
  84. hh.ready = true
  85. return true
  86. }
  87. func ixHandshakeStage1(f *Interface, via ViaSender, packet []byte, h *header.H) {
  88. cs := f.pki.getCertState()
  89. crt := cs.GetDefaultCertificate()
  90. if crt == nil {
  91. f.l.WithField("from", via).
  92. WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).
  93. WithField("certVersion", cs.initiatingVersion).
  94. Error("Unable to handshake with host because no certificate is available")
  95. return
  96. }
  97. ci, err := NewConnectionState(f.l, cs, crt, false, noise.HandshakeIX)
  98. if err != nil {
  99. f.l.WithError(err).WithField("from", via).
  100. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  101. Error("Failed to create connection state")
  102. return
  103. }
  104. // Mark packet 1 as seen so it doesn't show up as missed
  105. ci.window.Update(f.l, 1)
  106. msg, _, _, err := ci.H.ReadMessage(nil, packet[header.Len:])
  107. if err != nil {
  108. f.l.WithError(err).WithField("from", via).
  109. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  110. Error("Failed to call noise.ReadMessage")
  111. return
  112. }
  113. hs := &NebulaHandshake{}
  114. err = hs.Unmarshal(msg)
  115. if err != nil || hs.Details == nil {
  116. f.l.WithError(err).WithField("from", via).
  117. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  118. Error("Failed unmarshal handshake message")
  119. return
  120. }
  121. rc, err := cert.Recombine(cert.Version(hs.Details.CertVersion), hs.Details.Cert, ci.H.PeerStatic(), ci.Curve())
  122. if err != nil {
  123. f.l.WithError(err).WithField("from", via).
  124. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  125. Info("Handshake did not contain a certificate")
  126. return
  127. }
  128. remoteCert, err := f.pki.GetCAPool().VerifyCertificate(time.Now(), rc)
  129. if err != nil {
  130. fp, fperr := rc.Fingerprint()
  131. if fperr != nil {
  132. fp = "<error generating certificate fingerprint>"
  133. }
  134. e := f.l.WithError(err).WithField("from", via).
  135. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  136. WithField("certVpnNetworks", rc.Networks()).
  137. WithField("certFingerprint", fp)
  138. if f.l.Level >= logrus.DebugLevel {
  139. e = e.WithField("cert", rc)
  140. }
  141. e.Info("Invalid certificate from host")
  142. return
  143. }
  144. if remoteCert.Certificate.Version() != ci.myCert.Version() {
  145. // We started off using the wrong certificate version, lets see if we can match the version that was sent to us
  146. myCertOtherVersion := cs.getCertificate(remoteCert.Certificate.Version())
  147. if myCertOtherVersion == nil {
  148. if f.l.Level >= logrus.DebugLevel {
  149. f.l.WithError(err).WithFields(m{
  150. "from": via,
  151. "handshake": m{"stage": 1, "style": "ix_psk0"},
  152. "cert": remoteCert,
  153. }).Debug("Might be unable to handshake with host due to missing certificate version")
  154. }
  155. } else {
  156. // Record the certificate we are actually using
  157. ci.myCert = myCertOtherVersion
  158. }
  159. }
  160. if len(remoteCert.Certificate.Networks()) == 0 {
  161. f.l.WithError(err).WithField("from", via).
  162. WithField("cert", remoteCert).
  163. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  164. Info("No networks in certificate")
  165. return
  166. }
  167. certName := remoteCert.Certificate.Name()
  168. certVersion := remoteCert.Certificate.Version()
  169. fingerprint := remoteCert.Fingerprint
  170. issuer := remoteCert.Certificate.Issuer()
  171. vpnNetworks := remoteCert.Certificate.Networks()
  172. anyVpnAddrsInCommon := false
  173. vpnAddrs := make([]netip.Addr, len(vpnNetworks))
  174. for i, network := range vpnNetworks {
  175. if f.myVpnAddrsTable.Contains(network.Addr()) {
  176. f.l.WithField("vpnNetworks", vpnNetworks).WithField("from", via).
  177. WithField("certName", certName).
  178. WithField("certVersion", certVersion).
  179. WithField("fingerprint", fingerprint).
  180. WithField("issuer", issuer).
  181. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Refusing to handshake with myself")
  182. return
  183. }
  184. vpnAddrs[i] = network.Addr()
  185. if f.myVpnNetworksTable.Contains(network.Addr()) {
  186. anyVpnAddrsInCommon = true
  187. }
  188. }
  189. if !via.IsRelayed {
  190. // We only want to apply the remote allow list for direct tunnels here
  191. if !f.lightHouse.GetRemoteAllowList().AllowAll(vpnAddrs, via.UdpAddr.Addr()) {
  192. f.l.WithField("vpnAddrs", vpnAddrs).WithField("from", via).
  193. Debug("lighthouse.remote_allow_list denied incoming handshake")
  194. return
  195. }
  196. }
  197. myIndex, err := generateIndex(f.l)
  198. if err != nil {
  199. f.l.WithError(err).WithField("vpnAddrs", vpnAddrs).WithField("from", via).
  200. WithField("certName", certName).
  201. WithField("certVersion", certVersion).
  202. WithField("fingerprint", fingerprint).
  203. WithField("issuer", issuer).
  204. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Failed to generate index")
  205. return
  206. }
  207. hostinfo := &HostInfo{
  208. ConnectionState: ci,
  209. localIndexId: myIndex,
  210. remoteIndexId: hs.Details.InitiatorIndex,
  211. vpnAddrs: vpnAddrs,
  212. HandshakePacket: make(map[uint8][]byte, 0),
  213. lastHandshakeTime: hs.Details.Time,
  214. relayState: RelayState{
  215. relays: nil,
  216. relayForByAddr: map[netip.Addr]*Relay{},
  217. relayForByIdx: map[uint32]*Relay{},
  218. },
  219. }
  220. msgRxL := f.l.WithFields(m{
  221. "vpnAddrs": vpnAddrs,
  222. "from": via,
  223. "certName": certName,
  224. "certVersion": certVersion,
  225. "fingerprint": fingerprint,
  226. "issuer": issuer,
  227. "initiatorIndex": hs.Details.InitiatorIndex,
  228. "responderIndex": hs.Details.ResponderIndex,
  229. "remoteIndex": h.RemoteIndex,
  230. "handshake": m{"stage": 1, "style": "ix_psk0"},
  231. })
  232. if anyVpnAddrsInCommon {
  233. msgRxL.Info("Handshake message received")
  234. } else {
  235. //todo warn if not lighthouse or relay?
  236. msgRxL.Info("Handshake message received, but no vpnNetworks in common.")
  237. }
  238. hs.Details.ResponderIndex = myIndex
  239. hs.Details.Cert = cs.getHandshakeBytes(ci.myCert.Version())
  240. if hs.Details.Cert == nil {
  241. msgRxL.WithField("myCertVersion", ci.myCert.Version()).
  242. Error("Unable to handshake with host because no certificate handshake bytes is available")
  243. return
  244. }
  245. hs.Details.CertVersion = uint32(ci.myCert.Version())
  246. // Update the time in case their clock is way off from ours
  247. hs.Details.Time = uint64(time.Now().UnixNano())
  248. hsBytes, err := hs.Marshal()
  249. if err != nil {
  250. f.l.WithError(err).WithField("vpnAddrs", hostinfo.vpnAddrs).WithField("from", via).
  251. WithField("certName", certName).
  252. WithField("certVersion", certVersion).
  253. WithField("fingerprint", fingerprint).
  254. WithField("issuer", issuer).
  255. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Failed to marshal handshake message")
  256. return
  257. }
  258. nh := header.Encode(make([]byte, header.Len), header.Version, header.Handshake, header.HandshakeIXPSK0, hs.Details.InitiatorIndex, 2)
  259. msg, dKey, eKey, err := ci.H.WriteMessage(nh, hsBytes)
  260. if err != nil {
  261. f.l.WithError(err).WithField("vpnAddrs", hostinfo.vpnAddrs).WithField("from", via).
  262. WithField("certName", certName).
  263. WithField("certVersion", certVersion).
  264. WithField("fingerprint", fingerprint).
  265. WithField("issuer", issuer).
  266. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Failed to call noise.WriteMessage")
  267. return
  268. } else if dKey == nil || eKey == nil {
  269. f.l.WithField("vpnAddrs", hostinfo.vpnAddrs).WithField("from", via).
  270. WithField("certName", certName).
  271. WithField("certVersion", certVersion).
  272. WithField("fingerprint", fingerprint).
  273. WithField("issuer", issuer).
  274. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Noise did not arrive at a key")
  275. return
  276. }
  277. hostinfo.HandshakePacket[0] = make([]byte, len(packet[header.Len:]))
  278. copy(hostinfo.HandshakePacket[0], packet[header.Len:])
  279. // Regardless of whether you are the sender or receiver, you should arrive here
  280. // and complete standing up the connection.
  281. hostinfo.HandshakePacket[2] = make([]byte, len(msg))
  282. copy(hostinfo.HandshakePacket[2], msg)
  283. // We are sending handshake packet 2, so we don't expect to receive
  284. // handshake packet 2 from the initiator.
  285. ci.window.Update(f.l, 2)
  286. ci.peerCert = remoteCert
  287. ci.dKey = NewNebulaCipherState(dKey)
  288. ci.eKey = NewNebulaCipherState(eKey)
  289. hostinfo.remotes = f.lightHouse.QueryCache(vpnAddrs)
  290. if !via.IsRelayed {
  291. hostinfo.SetRemote(via.UdpAddr)
  292. }
  293. hostinfo.buildNetworks(f.myVpnNetworksTable, remoteCert.Certificate)
  294. existing, err := f.handshakeManager.CheckAndComplete(hostinfo, 0, f)
  295. if err != nil {
  296. switch err {
  297. case ErrAlreadySeen:
  298. // Update remote if preferred
  299. if existing.SetRemoteIfPreferred(f.hostMap, via) {
  300. // Send a test packet to ensure the other side has also switched to
  301. // the preferred remote
  302. f.SendMessageToVpnAddr(header.Test, header.TestRequest, vpnAddrs[0], []byte(""), make([]byte, 12, 12), make([]byte, mtu))
  303. }
  304. msg = existing.HandshakePacket[2]
  305. f.messageMetrics.Tx(header.Handshake, header.MessageSubType(msg[1]), 1)
  306. if !via.IsRelayed {
  307. err := f.outside.WriteTo(msg, via.UdpAddr)
  308. if err != nil {
  309. f.l.WithField("vpnAddrs", existing.vpnAddrs).WithField("from", via).
  310. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).WithField("cached", true).
  311. WithError(err).Error("Failed to send handshake message")
  312. } else {
  313. f.l.WithField("vpnAddrs", existing.vpnAddrs).WithField("from", via).
  314. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).WithField("cached", true).
  315. Info("Handshake message sent")
  316. }
  317. return
  318. } else {
  319. if via.relay == nil {
  320. f.l.Error("Handshake send failed: both addr and via.relay are nil.")
  321. return
  322. }
  323. hostinfo.relayState.InsertRelayTo(via.relayHI.vpnAddrs[0])
  324. f.SendVia(via.relayHI, via.relay, msg, make([]byte, 12), make([]byte, mtu), false)
  325. f.l.WithField("vpnAddrs", existing.vpnAddrs).WithField("relay", via.relayHI.vpnAddrs[0]).
  326. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).WithField("cached", true).
  327. Info("Handshake message sent")
  328. return
  329. }
  330. case ErrExistingHostInfo:
  331. // This means there was an existing tunnel and this handshake was older than the one we are currently based on
  332. f.l.WithField("vpnAddrs", vpnAddrs).WithField("from", via).
  333. WithField("certName", certName).
  334. WithField("certVersion", certVersion).
  335. WithField("oldHandshakeTime", existing.lastHandshakeTime).
  336. WithField("newHandshakeTime", hostinfo.lastHandshakeTime).
  337. WithField("fingerprint", fingerprint).
  338. WithField("issuer", issuer).
  339. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  340. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  341. Info("Handshake too old")
  342. // Send a test packet to trigger an authenticated tunnel test, this should suss out any lingering tunnel issues
  343. f.SendMessageToVpnAddr(header.Test, header.TestRequest, vpnAddrs[0], []byte(""), make([]byte, 12, 12), make([]byte, mtu))
  344. return
  345. case ErrLocalIndexCollision:
  346. // This means we failed to insert because of collision on localIndexId. Just let the next handshake packet retry
  347. f.l.WithField("vpnAddrs", vpnAddrs).WithField("from", via).
  348. WithField("certName", certName).
  349. WithField("certVersion", certVersion).
  350. WithField("fingerprint", fingerprint).
  351. WithField("issuer", issuer).
  352. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  353. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  354. WithField("localIndex", hostinfo.localIndexId).WithField("collision", existing.vpnAddrs).
  355. Error("Failed to add HostInfo due to localIndex collision")
  356. return
  357. default:
  358. // Shouldn't happen, but just in case someone adds a new error type to CheckAndComplete
  359. // And we forget to update it here
  360. f.l.WithError(err).WithField("vpnAddrs", vpnAddrs).WithField("from", via).
  361. WithField("certName", certName).
  362. WithField("certVersion", certVersion).
  363. WithField("fingerprint", fingerprint).
  364. WithField("issuer", issuer).
  365. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  366. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  367. Error("Failed to add HostInfo to HostMap")
  368. return
  369. }
  370. }
  371. // Do the send
  372. f.messageMetrics.Tx(header.Handshake, header.MessageSubType(msg[1]), 1)
  373. if !via.IsRelayed {
  374. err = f.outside.WriteTo(msg, via.UdpAddr)
  375. log := f.l.WithField("vpnAddrs", vpnAddrs).WithField("from", via).
  376. WithField("certName", certName).
  377. WithField("certVersion", certVersion).
  378. WithField("fingerprint", fingerprint).
  379. WithField("issuer", issuer).
  380. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  381. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 2, "style": "ix_psk0"})
  382. if err != nil {
  383. log.WithError(err).Error("Failed to send handshake")
  384. } else {
  385. log.Info("Handshake message sent")
  386. }
  387. } else {
  388. if via.relay == nil {
  389. f.l.Error("Handshake send failed: both addr and via.relay are nil.")
  390. return
  391. }
  392. hostinfo.relayState.InsertRelayTo(via.relayHI.vpnAddrs[0])
  393. // I successfully received a handshake. Just in case I marked this tunnel as 'Disestablished', ensure
  394. // it's correctly marked as working.
  395. via.relayHI.relayState.UpdateRelayForByIdxState(via.remoteIdx, Established)
  396. f.SendVia(via.relayHI, via.relay, msg, make([]byte, 12), make([]byte, mtu), false)
  397. f.l.WithField("vpnAddrs", vpnAddrs).WithField("relay", via.relayHI.vpnAddrs[0]).
  398. WithField("certName", certName).
  399. WithField("certVersion", certVersion).
  400. WithField("fingerprint", fingerprint).
  401. WithField("issuer", issuer).
  402. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  403. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  404. Info("Handshake message sent")
  405. }
  406. f.connectionManager.AddTrafficWatch(hostinfo)
  407. hostinfo.remotes.RefreshFromHandshake(vpnAddrs)
  408. return
  409. }
  410. func ixHandshakeStage2(f *Interface, via ViaSender, hh *HandshakeHostInfo, packet []byte, h *header.H) bool {
  411. if hh == nil {
  412. // Nothing here to tear down, got a bogus stage 2 packet
  413. return true
  414. }
  415. hh.Lock()
  416. defer hh.Unlock()
  417. hostinfo := hh.hostinfo
  418. if !via.IsRelayed {
  419. // The vpnAddr we know about is the one we tried to handshake with, use it to apply the remote allow list.
  420. if !f.lightHouse.GetRemoteAllowList().AllowAll(hostinfo.vpnAddrs, via.UdpAddr.Addr()) {
  421. f.l.WithField("vpnAddrs", hostinfo.vpnAddrs).WithField("from", via).Debug("lighthouse.remote_allow_list denied incoming handshake")
  422. return false
  423. }
  424. }
  425. ci := hostinfo.ConnectionState
  426. msg, eKey, dKey, err := ci.H.ReadMessage(nil, packet[header.Len:])
  427. if err != nil {
  428. f.l.WithError(err).WithField("vpnAddrs", hostinfo.vpnAddrs).WithField("from", via).
  429. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).WithField("header", h).
  430. Error("Failed to call noise.ReadMessage")
  431. // We don't want to tear down the connection on a bad ReadMessage because it could be an attacker trying
  432. // to DOS us. Every other error condition after should to allow a possible good handshake to complete in the
  433. // near future
  434. return false
  435. } else if dKey == nil || eKey == nil {
  436. f.l.WithField("vpnAddrs", hostinfo.vpnAddrs).WithField("from", via).
  437. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  438. Error("Noise did not arrive at a key")
  439. // This should be impossible in IX but just in case, if we get here then there is no chance to recover
  440. // the handshake state machine. Tear it down
  441. return true
  442. }
  443. hs := &NebulaHandshake{}
  444. err = hs.Unmarshal(msg)
  445. if err != nil || hs.Details == nil {
  446. f.l.WithError(err).WithField("vpnAddrs", hostinfo.vpnAddrs).WithField("from", via).
  447. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).Error("Failed unmarshal handshake message")
  448. // The handshake state machine is complete, if things break now there is no chance to recover. Tear down and start again
  449. return true
  450. }
  451. rc, err := cert.Recombine(cert.Version(hs.Details.CertVersion), hs.Details.Cert, ci.H.PeerStatic(), ci.Curve())
  452. if err != nil {
  453. f.l.WithError(err).WithField("from", via).
  454. WithField("vpnAddrs", hostinfo.vpnAddrs).
  455. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  456. Info("Handshake did not contain a certificate")
  457. return true
  458. }
  459. remoteCert, err := f.pki.GetCAPool().VerifyCertificate(time.Now(), rc)
  460. if err != nil {
  461. fp, err := rc.Fingerprint()
  462. if err != nil {
  463. fp = "<error generating certificate fingerprint>"
  464. }
  465. e := f.l.WithError(err).WithField("from", via).
  466. WithField("vpnAddrs", hostinfo.vpnAddrs).
  467. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  468. WithField("certFingerprint", fp).
  469. WithField("certVpnNetworks", rc.Networks())
  470. if f.l.Level >= logrus.DebugLevel {
  471. e = e.WithField("cert", rc)
  472. }
  473. e.Info("Invalid certificate from host")
  474. return true
  475. }
  476. if len(remoteCert.Certificate.Networks()) == 0 {
  477. f.l.WithError(err).WithField("from", via).
  478. WithField("vpnAddrs", hostinfo.vpnAddrs).
  479. WithField("cert", remoteCert).
  480. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  481. Info("No networks in certificate")
  482. return true
  483. }
  484. vpnNetworks := remoteCert.Certificate.Networks()
  485. certName := remoteCert.Certificate.Name()
  486. certVersion := remoteCert.Certificate.Version()
  487. fingerprint := remoteCert.Fingerprint
  488. issuer := remoteCert.Certificate.Issuer()
  489. hostinfo.remoteIndexId = hs.Details.ResponderIndex
  490. hostinfo.lastHandshakeTime = hs.Details.Time
  491. // Store their cert and our symmetric keys
  492. ci.peerCert = remoteCert
  493. ci.dKey = NewNebulaCipherState(dKey)
  494. ci.eKey = NewNebulaCipherState(eKey)
  495. // Make sure the current udpAddr being used is set for responding
  496. if !via.IsRelayed {
  497. hostinfo.SetRemote(via.UdpAddr)
  498. } else {
  499. hostinfo.relayState.InsertRelayTo(via.relayHI.vpnAddrs[0])
  500. }
  501. correctHostResponded := false
  502. anyVpnAddrsInCommon := false
  503. vpnAddrs := make([]netip.Addr, len(vpnNetworks))
  504. for i, network := range vpnNetworks {
  505. vpnAddrs[i] = network.Addr()
  506. if f.myVpnNetworksTable.Contains(network.Addr()) {
  507. anyVpnAddrsInCommon = true
  508. }
  509. if hostinfo.vpnAddrs[0] == network.Addr() {
  510. // todo is it more correct to see if any of hostinfo.vpnAddrs are in the cert? it should have len==1, but one day it might not?
  511. correctHostResponded = true
  512. }
  513. }
  514. // Ensure the right host responded
  515. if !correctHostResponded {
  516. f.l.WithField("intendedVpnAddrs", hostinfo.vpnAddrs).WithField("haveVpnNetworks", vpnNetworks).
  517. WithField("from", via).
  518. WithField("certName", certName).
  519. WithField("certVersion", certVersion).
  520. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  521. Info("Incorrect host responded to handshake")
  522. // Release our old handshake from pending, it should not continue
  523. f.handshakeManager.DeleteHostInfo(hostinfo)
  524. // Create a new hostinfo/handshake for the intended vpn ip
  525. //TODO is hostinfo.vpnAddrs[0] always the address to use?
  526. f.handshakeManager.StartHandshake(hostinfo.vpnAddrs[0], func(newHH *HandshakeHostInfo) {
  527. // Block the current used address
  528. newHH.hostinfo.remotes = hostinfo.remotes
  529. newHH.hostinfo.remotes.BlockRemote(via)
  530. f.l.WithField("blockedUdpAddrs", newHH.hostinfo.remotes.CopyBlockedRemotes()).
  531. WithField("vpnNetworks", vpnNetworks).
  532. WithField("remotes", newHH.hostinfo.remotes.CopyAddrs(f.hostMap.GetPreferredRanges())).
  533. Info("Blocked addresses for handshakes")
  534. // Swap the packet store to benefit the original intended recipient
  535. newHH.packetStore = hh.packetStore
  536. hh.packetStore = []*cachedPacket{}
  537. // Finally, put the correct vpn addrs in the host info, tell them to close the tunnel, and return true to tear down
  538. hostinfo.vpnAddrs = vpnAddrs
  539. f.sendCloseTunnel(hostinfo)
  540. })
  541. return true
  542. }
  543. // Mark packet 2 as seen so it doesn't show up as missed
  544. ci.window.Update(f.l, 2)
  545. duration := time.Since(hh.startTime).Nanoseconds()
  546. msgRxL := f.l.WithField("vpnAddrs", vpnAddrs).WithField("from", via).
  547. WithField("certName", certName).
  548. WithField("certVersion", certVersion).
  549. WithField("fingerprint", fingerprint).
  550. WithField("issuer", issuer).
  551. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  552. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  553. WithField("durationNs", duration).
  554. WithField("sentCachedPackets", len(hh.packetStore))
  555. if anyVpnAddrsInCommon {
  556. msgRxL.Info("Handshake message received")
  557. } else {
  558. //todo warn if not lighthouse or relay?
  559. msgRxL.Info("Handshake message received, but no vpnNetworks in common.")
  560. }
  561. // Build up the radix for the firewall if we have subnets in the cert
  562. hostinfo.vpnAddrs = vpnAddrs
  563. hostinfo.buildNetworks(f.myVpnNetworksTable, remoteCert.Certificate)
  564. // Complete our handshake and update metrics, this will replace any existing tunnels for the vpnAddrs here
  565. f.handshakeManager.Complete(hostinfo, f)
  566. f.connectionManager.AddTrafficWatch(hostinfo)
  567. if f.l.Level >= logrus.DebugLevel {
  568. hostinfo.logger(f.l).Debugf("Sending %d stored packets", len(hh.packetStore))
  569. }
  570. if len(hh.packetStore) > 0 {
  571. nb := make([]byte, 12, 12)
  572. out := make([]byte, mtu)
  573. for _, cp := range hh.packetStore {
  574. cp.callback(cp.messageType, cp.messageSubType, hostinfo, cp.packet, nb, out)
  575. }
  576. f.cachedPacketMetrics.sent.Inc(int64(len(hh.packetStore)))
  577. }
  578. hostinfo.remotes.RefreshFromHandshake(vpnAddrs)
  579. f.metricHandshakes.Update(duration)
  580. return false
  581. }