handshake_ix.go 25 KB

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