handshake_ix.go 24 KB

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