handshake_ix.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  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)
  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).
  65. WithField("certVersion", v).
  66. WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).Error("Failed to marshal handshake message")
  67. return false
  68. }
  69. h := header.Encode(make([]byte, header.Len), header.Version, header.Handshake, header.HandshakeIXPSK0, 0, 1)
  70. msg, _, _, err := ci.H.WriteMessage(h, hsBytes)
  71. if err != nil {
  72. f.l.WithError(err).WithField("vpnAddrs", hh.hostinfo.vpnAddrs).
  73. WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).Error("Failed to call noise.WriteMessage")
  74. return false
  75. }
  76. // We are sending handshake packet 1, so we don't expect to receive
  77. // handshake packet 1 from the responder
  78. ci.window.Update(f.l, 1)
  79. hh.hostinfo.HandshakePacket[0] = msg
  80. hh.ready = true
  81. return true
  82. }
  83. func ixHandshakeStage1(f *Interface, addr netip.AddrPort, via *ViaSender, packet []byte, h *header.H) {
  84. cs := f.pki.getCertState()
  85. crt := cs.GetDefaultCertificate()
  86. if crt == nil {
  87. f.l.WithField("udpAddr", addr).
  88. WithField("handshake", m{"stage": 0, "style": "ix_psk0"}).
  89. WithField("certVersion", cs.defaultVersion).
  90. Error("Unable to handshake with host because no certificate is available")
  91. }
  92. ci, err := NewConnectionState(f.l, cs, crt, false, noise.HandshakeIX)
  93. if err != nil {
  94. f.l.WithError(err).WithField("udpAddr", addr).
  95. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  96. Error("Failed to create connection state")
  97. return
  98. }
  99. // Mark packet 1 as seen so it doesn't show up as missed
  100. ci.window.Update(f.l, 1)
  101. msg, _, _, err := ci.H.ReadMessage(nil, packet[header.Len:])
  102. if err != nil {
  103. f.l.WithError(err).WithField("udpAddr", addr).
  104. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  105. Error("Failed to call noise.ReadMessage")
  106. return
  107. }
  108. hs := &NebulaHandshake{}
  109. err = hs.Unmarshal(msg)
  110. if err != nil || hs.Details == nil {
  111. f.l.WithError(err).WithField("udpAddr", addr).
  112. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  113. Error("Failed unmarshal handshake message")
  114. return
  115. }
  116. rc, err := cert.Recombine(cert.Version(hs.Details.CertVersion), hs.Details.Cert, ci.H.PeerStatic(), ci.Curve())
  117. if err != nil {
  118. f.l.WithError(err).WithField("udpAddr", addr).
  119. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  120. Info("Handshake did not contain a certificate")
  121. return
  122. }
  123. remoteCert, err := f.pki.GetCAPool().VerifyCertificate(time.Now(), rc)
  124. if err != nil {
  125. fp, err := rc.Fingerprint()
  126. if err != nil {
  127. fp = "<error generating certificate fingerprint>"
  128. }
  129. e := f.l.WithError(err).WithField("udpAddr", addr).
  130. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  131. WithField("certVpnNetworks", rc.Networks()).
  132. WithField("certFingerprint", fp)
  133. if f.l.Level >= logrus.DebugLevel {
  134. e = e.WithField("cert", rc)
  135. }
  136. e.Info("Invalid certificate from host")
  137. return
  138. }
  139. if remoteCert.Certificate.Version() != ci.myCert.Version() {
  140. // We started off using the wrong certificate version, lets see if we can match the version that was sent to us
  141. rc := cs.getCertificate(remoteCert.Certificate.Version())
  142. if rc == nil {
  143. f.l.WithError(err).WithField("udpAddr", addr).
  144. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).WithField("cert", remoteCert).
  145. Info("Unable to handshake with host due to missing certificate version")
  146. return
  147. }
  148. // Record the certificate we are actually using
  149. ci.myCert = rc
  150. }
  151. if len(remoteCert.Certificate.Networks()) == 0 {
  152. f.l.WithError(err).WithField("udpAddr", addr).
  153. WithField("cert", remoteCert).
  154. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  155. Info("No networks in certificate")
  156. return
  157. }
  158. var vpnAddrs []netip.Addr
  159. var filteredNetworks []netip.Prefix
  160. certName := remoteCert.Certificate.Name()
  161. certVersion := remoteCert.Certificate.Version()
  162. fingerprint := remoteCert.Fingerprint
  163. issuer := remoteCert.Certificate.Issuer()
  164. for _, network := range remoteCert.Certificate.Networks() {
  165. vpnAddr := network.Addr()
  166. _, found := f.myVpnAddrsTable.Lookup(vpnAddr)
  167. if found {
  168. f.l.WithField("vpnAddr", vpnAddr).WithField("udpAddr", addr).
  169. WithField("certName", certName).
  170. WithField("certVersion", certVersion).
  171. WithField("fingerprint", fingerprint).
  172. WithField("issuer", issuer).
  173. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Refusing to handshake with myself")
  174. return
  175. }
  176. // vpnAddrs outside our vpn networks are of no use to us, filter them out
  177. if _, ok := f.myVpnNetworksTable.Lookup(vpnAddr); !ok {
  178. continue
  179. }
  180. filteredNetworks = append(filteredNetworks, network)
  181. vpnAddrs = append(vpnAddrs, vpnAddr)
  182. }
  183. if len(vpnAddrs) == 0 {
  184. f.l.WithError(err).WithField("udpAddr", addr).
  185. WithField("certName", certName).
  186. WithField("certVersion", certVersion).
  187. WithField("fingerprint", fingerprint).
  188. WithField("issuer", issuer).
  189. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("No usable vpn addresses from host, refusing handshake")
  190. return
  191. }
  192. if addr.IsValid() {
  193. // addr can be invalid when the tunnel is being relayed.
  194. // We only want to apply the remote allow list for direct tunnels here
  195. if !f.lightHouse.GetRemoteAllowList().AllowAll(vpnAddrs, addr.Addr()) {
  196. f.l.WithField("vpnAddrs", vpnAddrs).WithField("udpAddr", addr).Debug("lighthouse.remote_allow_list denied incoming handshake")
  197. return
  198. }
  199. }
  200. myIndex, err := generateIndex(f.l)
  201. if err != nil {
  202. f.l.WithError(err).WithField("vpnAddrs", vpnAddrs).WithField("udpAddr", addr).
  203. WithField("certName", certName).
  204. WithField("certVersion", certVersion).
  205. WithField("fingerprint", fingerprint).
  206. WithField("issuer", issuer).
  207. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Failed to generate index")
  208. return
  209. }
  210. hostinfo := &HostInfo{
  211. syncRWMutex: newSyncRWMutex("hostinfo"),
  212. ConnectionState: ci,
  213. localIndexId: myIndex,
  214. remoteIndexId: hs.Details.InitiatorIndex,
  215. vpnAddrs: vpnAddrs,
  216. HandshakePacket: make(map[uint8][]byte, 0),
  217. lastHandshakeTime: hs.Details.Time,
  218. relayState: RelayState{
  219. syncRWMutex: newSyncRWMutex("relay-state"),
  220. relays: map[netip.Addr]struct{}{},
  221. relayForByAddr: map[netip.Addr]*Relay{},
  222. relayForByIdx: map[uint32]*Relay{},
  223. },
  224. }
  225. f.l.WithField("vpnAddrs", vpnAddrs).WithField("udpAddr", addr).
  226. WithField("certName", certName).
  227. WithField("certVersion", certVersion).
  228. WithField("fingerprint", fingerprint).
  229. WithField("issuer", issuer).
  230. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  231. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  232. Info("Handshake message received")
  233. hs.Details.ResponderIndex = myIndex
  234. hs.Details.Cert = cs.getHandshakeBytes(ci.myCert.Version())
  235. if hs.Details.Cert == nil {
  236. f.l.WithField("vpnAddrs", vpnAddrs).WithField("udpAddr", addr).
  237. WithField("certName", certName).
  238. WithField("certVersion", certVersion).
  239. WithField("fingerprint", fingerprint).
  240. WithField("issuer", issuer).
  241. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  242. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).
  243. WithField("certVersion", ci.myCert.Version()).
  244. Error("Unable to handshake with host because no certificate handshake bytes is available")
  245. return
  246. }
  247. hs.Details.CertVersion = uint32(ci.myCert.Version())
  248. // Update the time in case their clock is way off from ours
  249. hs.Details.Time = uint64(time.Now().UnixNano())
  250. hsBytes, err := hs.Marshal()
  251. if err != nil {
  252. f.l.WithError(err).WithField("vpnAddrs", hostinfo.vpnAddrs).WithField("udpAddr", addr).
  253. WithField("certName", certName).
  254. WithField("certVersion", certVersion).
  255. WithField("fingerprint", fingerprint).
  256. WithField("issuer", issuer).
  257. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Failed to marshal handshake message")
  258. return
  259. }
  260. nh := header.Encode(make([]byte, header.Len), header.Version, header.Handshake, header.HandshakeIXPSK0, hs.Details.InitiatorIndex, 2)
  261. msg, dKey, eKey, err := ci.H.WriteMessage(nh, hsBytes)
  262. if err != nil {
  263. f.l.WithError(err).WithField("vpnAddrs", hostinfo.vpnAddrs).WithField("udpAddr", addr).
  264. WithField("certName", certName).
  265. WithField("certVersion", certVersion).
  266. WithField("fingerprint", fingerprint).
  267. WithField("issuer", issuer).
  268. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Failed to call noise.WriteMessage")
  269. return
  270. } else if dKey == nil || eKey == nil {
  271. f.l.WithField("vpnAddrs", hostinfo.vpnAddrs).WithField("udpAddr", addr).
  272. WithField("certName", certName).
  273. WithField("certVersion", certVersion).
  274. WithField("fingerprint", fingerprint).
  275. WithField("issuer", issuer).
  276. WithField("handshake", m{"stage": 1, "style": "ix_psk0"}).Error("Noise did not arrive at a key")
  277. return
  278. }
  279. hostinfo.HandshakePacket[0] = make([]byte, len(packet[header.Len:]))
  280. copy(hostinfo.HandshakePacket[0], packet[header.Len:])
  281. // Regardless of whether you are the sender or receiver, you should arrive here
  282. // and complete standing up the connection.
  283. hostinfo.HandshakePacket[2] = make([]byte, len(msg))
  284. copy(hostinfo.HandshakePacket[2], msg)
  285. // We are sending handshake packet 2, so we don't expect to receive
  286. // handshake packet 2 from the initiator.
  287. ci.window.Update(f.l, 2)
  288. ci.peerCert = remoteCert
  289. ci.dKey = NewNebulaCipherState(dKey)
  290. ci.eKey = NewNebulaCipherState(eKey)
  291. hostinfo.remotes = f.lightHouse.QueryCache(vpnAddrs)
  292. hostinfo.SetRemote(addr)
  293. hostinfo.buildNetworks(filteredNetworks, remoteCert.Certificate.UnsafeNetworks())
  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, addr) {
  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 addr.IsValid() {
  307. err := f.outside.WriteTo(msg, addr)
  308. if err != nil {
  309. f.l.WithField("vpnAddrs", existing.vpnAddrs).WithField("udpAddr", addr).
  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("udpAddr", addr).
  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 == nil {
  320. f.l.Error("Handshake send failed: both addr and via 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("udpAddr", addr).
  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("udpAddr", addr).
  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("udpAddr", addr).
  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 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("certVersion", certVersion).
  379. WithField("fingerprint", fingerprint).
  380. WithField("issuer", issuer).
  381. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  382. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  383. WithError(err).Error("Failed to send handshake")
  384. } else {
  385. f.l.WithField("vpnAddrs", vpnAddrs).WithField("udpAddr", addr).
  386. WithField("certName", certName).
  387. WithField("certVersion", certVersion).
  388. WithField("fingerprint", fingerprint).
  389. WithField("issuer", issuer).
  390. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  391. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  392. Info("Handshake message sent")
  393. }
  394. } else {
  395. if via == nil {
  396. f.l.Error("Handshake send failed: both addr and via are nil.")
  397. return
  398. }
  399. hostinfo.relayState.InsertRelayTo(via.relayHI.vpnAddrs[0])
  400. // I successfully received a handshake. Just in case I marked this tunnel as 'Disestablished', ensure
  401. // it's correctly marked as working.
  402. via.relayHI.relayState.UpdateRelayForByIdxState(via.remoteIdx, Established)
  403. f.SendVia(via.relayHI, via.relay, msg, make([]byte, 12), make([]byte, mtu), false)
  404. f.l.WithField("vpnAddrs", vpnAddrs).WithField("relay", via.relayHI.vpnAddrs[0]).
  405. WithField("certName", certName).
  406. WithField("certVersion", certVersion).
  407. WithField("fingerprint", fingerprint).
  408. WithField("issuer", issuer).
  409. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  410. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  411. Info("Handshake message sent")
  412. }
  413. f.connectionManager.AddTrafficWatch(hostinfo.localIndexId)
  414. hostinfo.remotes.ResetBlockedRemotes()
  415. return
  416. }
  417. func ixHandshakeStage2(f *Interface, addr netip.AddrPort, via *ViaSender, hh *HandshakeHostInfo, packet []byte, h *header.H) bool {
  418. if hh == nil {
  419. // Nothing here to tear down, got a bogus stage 2 packet
  420. return true
  421. }
  422. hh.Lock()
  423. defer hh.Unlock()
  424. hostinfo := hh.hostinfo
  425. if addr.IsValid() {
  426. // The vpnAddr we know about is the one we tried to handshake with, use it to apply the remote allow list.
  427. if !f.lightHouse.GetRemoteAllowList().AllowAll(hostinfo.vpnAddrs, addr.Addr()) {
  428. f.l.WithField("vpnAddrs", hostinfo.vpnAddrs).WithField("udpAddr", addr).Debug("lighthouse.remote_allow_list denied incoming handshake")
  429. return false
  430. }
  431. }
  432. ci := hostinfo.ConnectionState
  433. msg, eKey, dKey, err := ci.H.ReadMessage(nil, packet[header.Len:])
  434. if err != nil {
  435. f.l.WithError(err).WithField("vpnAddrs", hostinfo.vpnAddrs).WithField("udpAddr", addr).
  436. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).WithField("header", h).
  437. Error("Failed to call noise.ReadMessage")
  438. // We don't want to tear down the connection on a bad ReadMessage because it could be an attacker trying
  439. // to DOS us. Every other error condition after should to allow a possible good handshake to complete in the
  440. // near future
  441. return false
  442. } else if dKey == nil || eKey == nil {
  443. f.l.WithField("vpnAddrs", hostinfo.vpnAddrs).WithField("udpAddr", addr).
  444. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  445. Error("Noise did not arrive at a key")
  446. // This should be impossible in IX but just in case, if we get here then there is no chance to recover
  447. // the handshake state machine. Tear it down
  448. return true
  449. }
  450. hs := &NebulaHandshake{}
  451. err = hs.Unmarshal(msg)
  452. if err != nil || hs.Details == nil {
  453. f.l.WithError(err).WithField("vpnAddrs", hostinfo.vpnAddrs).WithField("udpAddr", addr).
  454. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).Error("Failed unmarshal handshake message")
  455. // The handshake state machine is complete, if things break now there is no chance to recover. Tear down and start again
  456. return true
  457. }
  458. rc, err := cert.Recombine(cert.Version(hs.Details.CertVersion), hs.Details.Cert, ci.H.PeerStatic(), ci.Curve())
  459. if err != nil {
  460. f.l.WithError(err).WithField("udpAddr", addr).
  461. WithField("vpnAddrs", hostinfo.vpnAddrs).
  462. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  463. Info("Handshake did not contain a certificate")
  464. return true
  465. }
  466. remoteCert, err := f.pki.GetCAPool().VerifyCertificate(time.Now(), rc)
  467. if err != nil {
  468. fp, err := rc.Fingerprint()
  469. if err != nil {
  470. fp = "<error generating certificate fingerprint>"
  471. }
  472. e := f.l.WithError(err).WithField("udpAddr", addr).
  473. WithField("vpnAddrs", hostinfo.vpnAddrs).
  474. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  475. WithField("certFingerprint", fp).
  476. WithField("certVpnNetworks", rc.Networks())
  477. if f.l.Level >= logrus.DebugLevel {
  478. e = e.WithField("cert", rc)
  479. }
  480. e.Info("Invalid certificate from host")
  481. return true
  482. }
  483. if len(remoteCert.Certificate.Networks()) == 0 {
  484. f.l.WithError(err).WithField("udpAddr", addr).
  485. WithField("vpnAddrs", hostinfo.vpnAddrs).
  486. WithField("cert", remoteCert).
  487. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  488. Info("No networks in certificate")
  489. return true
  490. }
  491. vpnNetworks := remoteCert.Certificate.Networks()
  492. certName := remoteCert.Certificate.Name()
  493. certVersion := remoteCert.Certificate.Version()
  494. fingerprint := remoteCert.Fingerprint
  495. issuer := remoteCert.Certificate.Issuer()
  496. hostinfo.remoteIndexId = hs.Details.ResponderIndex
  497. hostinfo.lastHandshakeTime = hs.Details.Time
  498. // Store their cert and our symmetric keys
  499. ci.peerCert = remoteCert
  500. ci.dKey = NewNebulaCipherState(dKey)
  501. ci.eKey = NewNebulaCipherState(eKey)
  502. // Make sure the current udpAddr being used is set for responding
  503. if addr.IsValid() {
  504. hostinfo.SetRemote(addr)
  505. } else {
  506. hostinfo.relayState.InsertRelayTo(via.relayHI.vpnAddrs[0])
  507. }
  508. var vpnAddrs []netip.Addr
  509. var filteredNetworks []netip.Prefix
  510. for _, network := range vpnNetworks {
  511. // vpnAddrs outside our vpn networks are of no use to us, filter them out
  512. vpnAddr := network.Addr()
  513. if _, ok := f.myVpnNetworksTable.Lookup(vpnAddr); !ok {
  514. continue
  515. }
  516. filteredNetworks = append(filteredNetworks, network)
  517. vpnAddrs = append(vpnAddrs, vpnAddr)
  518. }
  519. if len(vpnAddrs) == 0 {
  520. f.l.WithError(err).WithField("udpAddr", addr).
  521. WithField("certName", certName).
  522. WithField("certVersion", certVersion).
  523. WithField("fingerprint", fingerprint).
  524. WithField("issuer", issuer).
  525. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).Error("No usable vpn addresses from host, refusing handshake")
  526. return true
  527. }
  528. // Ensure the right host responded
  529. if !slices.Contains(vpnAddrs, hostinfo.vpnAddrs[0]) {
  530. f.l.WithField("intendedVpnAddrs", hostinfo.vpnAddrs).WithField("haveVpnNetworks", vpnNetworks).
  531. WithField("udpAddr", addr).
  532. WithField("certName", certName).
  533. WithField("certVersion", certVersion).
  534. WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  535. Info("Incorrect host responded to handshake")
  536. // Release our old handshake from pending, it should not continue
  537. f.handshakeManager.DeleteHostInfo(hostinfo)
  538. // Create a new hostinfo/handshake for the intended vpn ip
  539. f.handshakeManager.StartHandshake(hostinfo.vpnAddrs[0], func(newHH *HandshakeHostInfo) {
  540. // Block the current used address
  541. newHH.hostinfo.remotes = hostinfo.remotes
  542. newHH.hostinfo.remotes.BlockRemote(addr)
  543. f.l.WithField("blockedUdpAddrs", newHH.hostinfo.remotes.CopyBlockedRemotes()).
  544. WithField("vpnNetworks", vpnNetworks).
  545. WithField("remotes", newHH.hostinfo.remotes.CopyAddrs(f.hostMap.GetPreferredRanges())).
  546. Info("Blocked addresses for handshakes")
  547. // Swap the packet store to benefit the original intended recipient
  548. newHH.packetStore = hh.packetStore
  549. hh.packetStore = []*cachedPacket{}
  550. // Finally, put the correct vpn addrs in the host info, tell them to close the tunnel, and return true to tear down
  551. hostinfo.vpnAddrs = vpnAddrs
  552. f.sendCloseTunnel(hostinfo)
  553. })
  554. return true
  555. }
  556. // Mark packet 2 as seen so it doesn't show up as missed
  557. ci.window.Update(f.l, 2)
  558. duration := time.Since(hh.startTime).Nanoseconds()
  559. f.l.WithField("vpnAddrs", vpnAddrs).WithField("udpAddr", addr).
  560. WithField("certName", certName).
  561. WithField("certVersion", certVersion).
  562. WithField("fingerprint", fingerprint).
  563. WithField("issuer", issuer).
  564. WithField("initiatorIndex", hs.Details.InitiatorIndex).WithField("responderIndex", hs.Details.ResponderIndex).
  565. WithField("remoteIndex", h.RemoteIndex).WithField("handshake", m{"stage": 2, "style": "ix_psk0"}).
  566. WithField("durationNs", duration).
  567. WithField("sentCachedPackets", len(hh.packetStore)).
  568. Info("Handshake message received")
  569. // Build up the radix for the firewall if we have subnets in the cert
  570. hostinfo.vpnAddrs = vpnAddrs
  571. hostinfo.buildNetworks(filteredNetworks, remoteCert.Certificate.UnsafeNetworks())
  572. // Complete our handshake and update metrics, this will replace any existing tunnels for the vpnAddrs here
  573. f.handshakeManager.Complete(hostinfo, f)
  574. f.connectionManager.AddTrafficWatch(hostinfo.localIndexId)
  575. if f.l.Level >= logrus.DebugLevel {
  576. hostinfo.logger(f.l).Debugf("Sending %d stored packets", len(hh.packetStore))
  577. }
  578. if len(hh.packetStore) > 0 {
  579. nb := make([]byte, 12, 12)
  580. out := make([]byte, mtu)
  581. for _, cp := range hh.packetStore {
  582. cp.callback(cp.messageType, cp.messageSubType, hostinfo, cp.packet, nb, out)
  583. }
  584. f.cachedPacketMetrics.sent.Inc(int64(len(hh.packetStore)))
  585. }
  586. hostinfo.remotes.ResetBlockedRemotes()
  587. f.metricHandshakes.Update(duration)
  588. return false
  589. }