extpeers.go 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070
  1. package logic
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "net"
  8. "reflect"
  9. "sort"
  10. "strings"
  11. "sync"
  12. "time"
  13. "github.com/goombaio/namegenerator"
  14. "github.com/gravitl/netmaker/database"
  15. "github.com/gravitl/netmaker/db"
  16. "github.com/gravitl/netmaker/logger"
  17. "github.com/gravitl/netmaker/logic/acls"
  18. "github.com/gravitl/netmaker/models"
  19. "github.com/gravitl/netmaker/schema"
  20. "github.com/gravitl/netmaker/servercfg"
  21. "golang.org/x/exp/slog"
  22. "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
  23. )
  24. var (
  25. extClientCacheMutex = &sync.RWMutex{}
  26. extClientCacheMap = make(map[string]models.ExtClient)
  27. )
  28. func getAllExtClientsFromCache() (extClients []models.ExtClient) {
  29. extClientCacheMutex.RLock()
  30. for _, extclient := range extClientCacheMap {
  31. if extclient.Mutex == nil {
  32. extclient.Mutex = &sync.Mutex{}
  33. }
  34. extClients = append(extClients, extclient)
  35. }
  36. extClientCacheMutex.RUnlock()
  37. return
  38. }
  39. func deleteExtClientFromCache(key string) {
  40. extClientCacheMutex.Lock()
  41. delete(extClientCacheMap, key)
  42. extClientCacheMutex.Unlock()
  43. }
  44. func getExtClientFromCache(key string) (extclient models.ExtClient, ok bool) {
  45. extClientCacheMutex.RLock()
  46. extclient, ok = extClientCacheMap[key]
  47. if extclient.Mutex == nil {
  48. extclient.Mutex = &sync.Mutex{}
  49. }
  50. extClientCacheMutex.RUnlock()
  51. return
  52. }
  53. func storeExtClientInCache(key string, extclient models.ExtClient) {
  54. extClientCacheMutex.Lock()
  55. if extclient.Mutex == nil {
  56. extclient.Mutex = &sync.Mutex{}
  57. }
  58. extClientCacheMap[key] = extclient
  59. extClientCacheMutex.Unlock()
  60. }
  61. // ExtClient.GetEgressRangesOnNetwork - returns the egress ranges on network of ext client
  62. func GetEgressRangesOnNetwork(client *models.ExtClient) ([]string, error) {
  63. var result []string
  64. networkNodes, err := GetNetworkNodes(client.Network)
  65. if err != nil {
  66. return []string{}, err
  67. }
  68. // clientNode := client.ConvertToStaticNode()
  69. for _, currentNode := range networkNodes {
  70. if currentNode.Network != client.Network {
  71. continue
  72. }
  73. GetNodeEgressInfo(&currentNode)
  74. if currentNode.EgressDetails.IsInternetGateway && client.IngressGatewayID != currentNode.ID.String() {
  75. continue
  76. }
  77. if currentNode.EgressDetails.IsEgressGateway { // add the egress gateway range(s) to the result
  78. fmt.Println("EGRESSS EXTCLEINT: ", currentNode.EgressDetails)
  79. if len(currentNode.EgressDetails.EgressGatewayRanges) > 0 {
  80. result = append(result, currentNode.EgressDetails.EgressGatewayRanges...)
  81. }
  82. }
  83. }
  84. extclients, _ := GetNetworkExtClients(client.Network)
  85. for _, extclient := range extclients {
  86. if extclient.ClientID == client.ClientID {
  87. continue
  88. }
  89. result = append(result, extclient.ExtraAllowedIPs...)
  90. }
  91. return result, nil
  92. }
  93. // DeleteExtClient - deletes an existing ext client
  94. func DeleteExtClient(network string, clientid string) error {
  95. key, err := GetRecordKey(clientid, network)
  96. if err != nil {
  97. return err
  98. }
  99. extClient, err := GetExtClient(clientid, network)
  100. if err != nil {
  101. return err
  102. }
  103. err = database.DeleteRecord(database.EXT_CLIENT_TABLE_NAME, key)
  104. if err != nil {
  105. return err
  106. }
  107. if servercfg.CacheEnabled() {
  108. // recycle ip address
  109. if extClient.Address != "" {
  110. RemoveIpFromAllocatedIpMap(network, extClient.Address)
  111. }
  112. if extClient.Address6 != "" {
  113. RemoveIpFromAllocatedIpMap(network, extClient.Address6)
  114. }
  115. deleteExtClientFromCache(key)
  116. }
  117. go RemoveNodeFromAclPolicy(extClient.ConvertToStaticNode())
  118. return nil
  119. }
  120. // DeleteExtClientAndCleanup - deletes an existing ext client and update ACLs
  121. func DeleteExtClientAndCleanup(extClient models.ExtClient) error {
  122. //delete extClient record
  123. err := DeleteExtClient(extClient.Network, extClient.ClientID)
  124. if err != nil {
  125. slog.Error("DeleteExtClientAndCleanup-remove extClient record: ", "Error", err.Error())
  126. return err
  127. }
  128. //update ACLs
  129. var networkAcls acls.ACLContainer
  130. networkAcls, err = networkAcls.Get(acls.ContainerID(extClient.Network))
  131. if err != nil {
  132. slog.Error("DeleteExtClientAndCleanup-update network acls: ", "Error", err.Error())
  133. return err
  134. }
  135. for objId := range networkAcls {
  136. delete(networkAcls[objId], acls.AclID(extClient.ClientID))
  137. }
  138. delete(networkAcls, acls.AclID(extClient.ClientID))
  139. if _, err = networkAcls.Save(acls.ContainerID(extClient.Network)); err != nil {
  140. slog.Error("DeleteExtClientAndCleanup-update network acls:", "Error", err.Error())
  141. return err
  142. }
  143. return nil
  144. }
  145. //TODO - enforce extclient-to-extclient on ingress gw
  146. /* 1. fetch all non-user static nodes
  147. a. check against each user node, if allowed add rule
  148. */
  149. // GetNetworkExtClients - gets the ext clients of given network
  150. func GetNetworkExtClients(network string) ([]models.ExtClient, error) {
  151. var extclients []models.ExtClient
  152. if servercfg.CacheEnabled() {
  153. allextclients := getAllExtClientsFromCache()
  154. if len(allextclients) != 0 {
  155. for _, extclient := range allextclients {
  156. if extclient.Network == network {
  157. extclients = append(extclients, extclient)
  158. }
  159. }
  160. return extclients, nil
  161. }
  162. }
  163. records, err := database.FetchRecords(database.EXT_CLIENT_TABLE_NAME)
  164. if err != nil {
  165. if database.IsEmptyRecord(err) {
  166. return extclients, nil
  167. }
  168. return extclients, err
  169. }
  170. for _, value := range records {
  171. var extclient models.ExtClient
  172. err = json.Unmarshal([]byte(value), &extclient)
  173. if err != nil {
  174. continue
  175. }
  176. key, err := GetRecordKey(extclient.ClientID, extclient.Network)
  177. if err == nil {
  178. if servercfg.CacheEnabled() {
  179. storeExtClientInCache(key, extclient)
  180. }
  181. }
  182. if extclient.Network == network {
  183. extclients = append(extclients, extclient)
  184. }
  185. }
  186. return extclients, err
  187. }
  188. // GetExtClient - gets a single ext client on a network
  189. func GetExtClient(clientid string, network string) (models.ExtClient, error) {
  190. var extclient models.ExtClient
  191. key, err := GetRecordKey(clientid, network)
  192. if err != nil {
  193. return extclient, err
  194. }
  195. if servercfg.CacheEnabled() {
  196. if extclient, ok := getExtClientFromCache(key); ok {
  197. return extclient, nil
  198. }
  199. }
  200. data, err := database.FetchRecord(database.EXT_CLIENT_TABLE_NAME, key)
  201. if err != nil {
  202. return extclient, err
  203. }
  204. err = json.Unmarshal([]byte(data), &extclient)
  205. if servercfg.CacheEnabled() {
  206. storeExtClientInCache(key, extclient)
  207. }
  208. return extclient, err
  209. }
  210. // GetGwExtclients - return all ext clients attached to the passed gw id
  211. func GetGwExtclients(nodeID, network string) []models.ExtClient {
  212. gwClients := []models.ExtClient{}
  213. clients, err := GetNetworkExtClients(network)
  214. if err != nil {
  215. return gwClients
  216. }
  217. for _, client := range clients {
  218. if client.IngressGatewayID == nodeID {
  219. gwClients = append(gwClients, client)
  220. }
  221. }
  222. return gwClients
  223. }
  224. // GetExtClient - gets a single ext client on a network
  225. func GetExtClientByPubKey(publicKey string, network string) (*models.ExtClient, error) {
  226. netClients, err := GetNetworkExtClients(network)
  227. if err != nil {
  228. return nil, err
  229. }
  230. for i := range netClients {
  231. ec := netClients[i]
  232. if ec.PublicKey == publicKey {
  233. return &ec, nil
  234. }
  235. }
  236. return nil, fmt.Errorf("no client found")
  237. }
  238. // CreateExtClient - creates and saves an extclient
  239. func CreateExtClient(extclient *models.ExtClient) error {
  240. // lock because we may need unique IPs and having it concurrent makes parallel calls result in same "unique" IPs
  241. addressLock.Lock()
  242. defer addressLock.Unlock()
  243. if len(extclient.PublicKey) == 0 {
  244. privateKey, err := wgtypes.GeneratePrivateKey()
  245. if err != nil {
  246. return err
  247. }
  248. extclient.PrivateKey = privateKey.String()
  249. extclient.PublicKey = privateKey.PublicKey().String()
  250. } else if len(extclient.PrivateKey) == 0 && len(extclient.PublicKey) > 0 {
  251. extclient.PrivateKey = "[ENTER PRIVATE KEY]"
  252. }
  253. if extclient.ExtraAllowedIPs == nil {
  254. extclient.ExtraAllowedIPs = []string{}
  255. }
  256. parentNetwork, err := GetNetwork(extclient.Network)
  257. if err != nil {
  258. return err
  259. }
  260. if extclient.Address == "" {
  261. if parentNetwork.IsIPv4 == "yes" {
  262. newAddress, err := UniqueAddress(extclient.Network, true)
  263. if err != nil {
  264. return err
  265. }
  266. extclient.Address = newAddress.String()
  267. }
  268. }
  269. if extclient.Address6 == "" {
  270. if parentNetwork.IsIPv6 == "yes" {
  271. addr6, err := UniqueAddress6(extclient.Network, true)
  272. if err != nil {
  273. return err
  274. }
  275. extclient.Address6 = addr6.String()
  276. }
  277. }
  278. if extclient.ClientID == "" {
  279. extclient.ClientID, err = GenerateNodeName(extclient.Network)
  280. if err != nil {
  281. return err
  282. }
  283. }
  284. extclient.LastModified = time.Now().Unix()
  285. return SaveExtClient(extclient)
  286. }
  287. // GenerateNodeName - generates a random node name
  288. func GenerateNodeName(network string) (string, error) {
  289. seed := time.Now().UTC().UnixNano()
  290. nameGenerator := namegenerator.NewNameGenerator(seed)
  291. var name string
  292. cnt := 0
  293. for {
  294. if cnt > 10 {
  295. return "", errors.New("couldn't generate random name, try again")
  296. }
  297. cnt += 1
  298. name = nameGenerator.Generate()
  299. if len(name) > 15 {
  300. continue
  301. }
  302. _, err := GetExtClient(name, network)
  303. if err == nil {
  304. // config exists with same name
  305. continue
  306. }
  307. break
  308. }
  309. return name, nil
  310. }
  311. // SaveExtClient - saves an ext client to database
  312. func SaveExtClient(extclient *models.ExtClient) error {
  313. key, err := GetRecordKey(extclient.ClientID, extclient.Network)
  314. if err != nil {
  315. return err
  316. }
  317. data, err := json.Marshal(&extclient)
  318. if err != nil {
  319. return err
  320. }
  321. if err = database.Insert(key, string(data), database.EXT_CLIENT_TABLE_NAME); err != nil {
  322. return err
  323. }
  324. if servercfg.CacheEnabled() {
  325. storeExtClientInCache(key, *extclient)
  326. if _, ok := allocatedIpMap[extclient.Network]; ok {
  327. if extclient.Address != "" {
  328. AddIpToAllocatedIpMap(extclient.Network, net.ParseIP(extclient.Address))
  329. }
  330. if extclient.Address6 != "" {
  331. AddIpToAllocatedIpMap(extclient.Network, net.ParseIP(extclient.Address6))
  332. }
  333. }
  334. }
  335. return SetNetworkNodesLastModified(extclient.Network)
  336. }
  337. // UpdateExtClient - updates an ext client with new values
  338. func UpdateExtClient(old *models.ExtClient, update *models.CustomExtClient) models.ExtClient {
  339. new := *old
  340. new.ClientID = update.ClientID
  341. if update.PublicKey != "" && old.PublicKey != update.PublicKey {
  342. new.PublicKey = update.PublicKey
  343. }
  344. if update.DNS != old.DNS {
  345. new.DNS = update.DNS
  346. }
  347. if update.Enabled != old.Enabled {
  348. new.Enabled = update.Enabled
  349. }
  350. new.ExtraAllowedIPs = update.ExtraAllowedIPs
  351. if update.DeniedACLs != nil && !reflect.DeepEqual(old.DeniedACLs, update.DeniedACLs) {
  352. new.DeniedACLs = update.DeniedACLs
  353. }
  354. // replace any \r\n with \n in postup and postdown from HTTP request
  355. new.PostUp = strings.Replace(update.PostUp, "\r\n", "\n", -1)
  356. new.PostDown = strings.Replace(update.PostDown, "\r\n", "\n", -1)
  357. new.Tags = update.Tags
  358. return new
  359. }
  360. // GetExtClientsByID - gets the clients of attached gateway
  361. func GetExtClientsByID(nodeid, network string) ([]models.ExtClient, error) {
  362. var result []models.ExtClient
  363. currentClients, err := GetNetworkExtClients(network)
  364. if err != nil {
  365. return result, err
  366. }
  367. for i := range currentClients {
  368. if currentClients[i].IngressGatewayID == nodeid {
  369. result = append(result, currentClients[i])
  370. }
  371. }
  372. return result, nil
  373. }
  374. // GetAllExtClients - gets all ext clients from DB
  375. func GetAllExtClients() ([]models.ExtClient, error) {
  376. var clients = []models.ExtClient{}
  377. currentNetworks, err := GetNetworks()
  378. if err != nil && database.IsEmptyRecord(err) {
  379. return clients, nil
  380. } else if err != nil {
  381. return clients, err
  382. }
  383. for i := range currentNetworks {
  384. netName := currentNetworks[i].NetID
  385. netClients, err := GetNetworkExtClients(netName)
  386. if err != nil {
  387. continue
  388. }
  389. clients = append(clients, netClients...)
  390. }
  391. return clients, nil
  392. }
  393. // GetAllExtClientsWithStatus - returns all external clients with
  394. // given status.
  395. func GetAllExtClientsWithStatus(status models.NodeStatus) ([]models.ExtClient, error) {
  396. extClients, err := GetAllExtClients()
  397. if err != nil {
  398. return nil, err
  399. }
  400. var validExtClients []models.ExtClient
  401. for _, extClient := range extClients {
  402. node := extClient.ConvertToStaticNode()
  403. GetNodeCheckInStatus(&node, false)
  404. if node.Status == status {
  405. validExtClients = append(validExtClients, extClient)
  406. }
  407. }
  408. return validExtClients, nil
  409. }
  410. // ToggleExtClientConnectivity - enables or disables an ext client
  411. func ToggleExtClientConnectivity(client *models.ExtClient, enable bool) (models.ExtClient, error) {
  412. update := models.CustomExtClient{
  413. Enabled: enable,
  414. ClientID: client.ClientID,
  415. PublicKey: client.PublicKey,
  416. DNS: client.DNS,
  417. ExtraAllowedIPs: client.ExtraAllowedIPs,
  418. DeniedACLs: client.DeniedACLs,
  419. RemoteAccessClientID: client.RemoteAccessClientID,
  420. }
  421. // update in DB
  422. newClient := UpdateExtClient(client, &update)
  423. if err := DeleteExtClient(client.Network, client.ClientID); err != nil {
  424. slog.Error("failed to delete ext client during update", "id", client.ClientID, "network", client.Network, "error", err)
  425. return newClient, err
  426. }
  427. if err := SaveExtClient(&newClient); err != nil {
  428. slog.Error("failed to save updated ext client during update", "id", newClient.ClientID, "network", newClient.Network, "error", err)
  429. return newClient, err
  430. }
  431. return newClient, nil
  432. }
  433. // Sort a slice of net.IP addresses
  434. func sortIPs(ips []net.IP) {
  435. sort.Slice(ips, func(i, j int) bool {
  436. ip1, ip2 := ips[i].To16(), ips[j].To16()
  437. return string(ip1) < string(ip2) // Compare as byte slices
  438. })
  439. }
  440. func GetStaticNodeIps(node models.Node) (ips []net.IP) {
  441. defer func() {
  442. sortIPs(ips)
  443. }()
  444. defaultUserPolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
  445. defaultDevicePolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
  446. extclients := GetStaticNodesByNetwork(models.NetworkID(node.Network), false)
  447. for _, extclient := range extclients {
  448. if extclient.IsUserNode && defaultUserPolicy.Enabled {
  449. continue
  450. }
  451. if !extclient.IsUserNode && defaultDevicePolicy.Enabled {
  452. continue
  453. }
  454. if extclient.StaticNode.Address != "" {
  455. ips = append(ips, extclient.StaticNode.AddressIPNet4().IP)
  456. }
  457. if extclient.StaticNode.Address6 != "" {
  458. ips = append(ips, extclient.StaticNode.AddressIPNet6().IP)
  459. }
  460. }
  461. return
  462. }
  463. func getFwRulesForNodeAndPeerOnGw(node, peer models.Node, allowedPolicies []models.Acl) (rules []models.FwRule) {
  464. for _, policy := range allowedPolicies {
  465. // if static peer dst rule not for ingress node -> skip
  466. if node.Address.IP != nil {
  467. rules = append(rules, models.FwRule{
  468. SrcIP: net.IPNet{
  469. IP: node.Address.IP,
  470. Mask: net.CIDRMask(32, 32),
  471. },
  472. DstIP: net.IPNet{
  473. IP: peer.Address.IP,
  474. Mask: net.CIDRMask(32, 32),
  475. },
  476. AllowedProtocol: policy.Proto,
  477. AllowedPorts: policy.Port,
  478. Allow: true,
  479. })
  480. }
  481. if node.Address6.IP != nil {
  482. rules = append(rules, models.FwRule{
  483. SrcIP: net.IPNet{
  484. IP: node.Address6.IP,
  485. Mask: net.CIDRMask(128, 128),
  486. },
  487. DstIP: net.IPNet{
  488. IP: peer.Address6.IP,
  489. Mask: net.CIDRMask(128, 128),
  490. },
  491. AllowedProtocol: policy.Proto,
  492. AllowedPorts: policy.Port,
  493. Allow: true,
  494. })
  495. }
  496. if policy.AllowedDirection == models.TrafficDirectionBi {
  497. if node.Address.IP != nil {
  498. rules = append(rules, models.FwRule{
  499. SrcIP: net.IPNet{
  500. IP: peer.Address.IP,
  501. Mask: net.CIDRMask(32, 32),
  502. },
  503. DstIP: net.IPNet{
  504. IP: node.Address.IP,
  505. Mask: net.CIDRMask(32, 32),
  506. },
  507. AllowedProtocol: policy.Proto,
  508. AllowedPorts: policy.Port,
  509. Allow: true,
  510. })
  511. }
  512. if node.Address6.IP != nil {
  513. rules = append(rules, models.FwRule{
  514. SrcIP: net.IPNet{
  515. IP: peer.Address6.IP,
  516. Mask: net.CIDRMask(128, 128),
  517. },
  518. DstIP: net.IPNet{
  519. IP: node.Address6.IP,
  520. Mask: net.CIDRMask(128, 128),
  521. },
  522. AllowedProtocol: policy.Proto,
  523. AllowedPorts: policy.Port,
  524. Allow: true,
  525. })
  526. }
  527. }
  528. if len(node.StaticNode.ExtraAllowedIPs) > 0 {
  529. for _, additionalAllowedIPNet := range node.StaticNode.ExtraAllowedIPs {
  530. _, ipNet, err := net.ParseCIDR(additionalAllowedIPNet)
  531. if err != nil {
  532. continue
  533. }
  534. if ipNet.IP.To4() != nil && peer.Address.IP != nil {
  535. rules = append(rules, models.FwRule{
  536. SrcIP: net.IPNet{
  537. IP: peer.Address.IP,
  538. Mask: net.CIDRMask(32, 32),
  539. },
  540. DstIP: *ipNet,
  541. Allow: true,
  542. })
  543. } else if peer.Address6.IP != nil {
  544. rules = append(rules, models.FwRule{
  545. SrcIP: net.IPNet{
  546. IP: peer.Address6.IP,
  547. Mask: net.CIDRMask(128, 128),
  548. },
  549. DstIP: *ipNet,
  550. Allow: true,
  551. })
  552. }
  553. }
  554. }
  555. if len(peer.StaticNode.ExtraAllowedIPs) > 0 {
  556. for _, additionalAllowedIPNet := range peer.StaticNode.ExtraAllowedIPs {
  557. _, ipNet, err := net.ParseCIDR(additionalAllowedIPNet)
  558. if err != nil {
  559. continue
  560. }
  561. if ipNet.IP.To4() != nil && node.Address.IP != nil {
  562. rules = append(rules, models.FwRule{
  563. SrcIP: net.IPNet{
  564. IP: node.Address.IP,
  565. Mask: net.CIDRMask(32, 32),
  566. },
  567. DstIP: *ipNet,
  568. Allow: true,
  569. })
  570. } else if node.Address6.IP != nil {
  571. rules = append(rules, models.FwRule{
  572. SrcIP: net.IPNet{
  573. IP: node.Address6.IP,
  574. Mask: net.CIDRMask(128, 128),
  575. },
  576. DstIP: *ipNet,
  577. Allow: true,
  578. })
  579. }
  580. }
  581. }
  582. // add egress range rules
  583. for _, dstI := range policy.Dst {
  584. if dstI.ID == models.EgressID {
  585. e := schema.Egress{ID: dstI.Value}
  586. err := e.Get(db.WithContext(context.TODO()))
  587. if err != nil {
  588. continue
  589. }
  590. dstI.Value = e.Range
  591. ip, cidr, err := net.ParseCIDR(dstI.Value)
  592. if err == nil {
  593. if ip.To4() != nil {
  594. if node.Address.IP != nil {
  595. rules = append(rules, models.FwRule{
  596. SrcIP: net.IPNet{
  597. IP: node.Address.IP,
  598. Mask: net.CIDRMask(32, 32),
  599. },
  600. DstIP: *cidr,
  601. AllowedProtocol: policy.Proto,
  602. AllowedPorts: policy.Port,
  603. Allow: true,
  604. })
  605. }
  606. } else {
  607. if node.Address6.IP != nil {
  608. rules = append(rules, models.FwRule{
  609. SrcIP: net.IPNet{
  610. IP: node.Address6.IP,
  611. Mask: net.CIDRMask(128, 128),
  612. },
  613. DstIP: *cidr,
  614. AllowedProtocol: policy.Proto,
  615. AllowedPorts: policy.Port,
  616. Allow: true,
  617. })
  618. }
  619. }
  620. }
  621. }
  622. }
  623. }
  624. return
  625. }
  626. func getFwRulesForUserNodesOnGw(node models.Node, nodes []models.Node) (rules []models.FwRule) {
  627. defaultUserPolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
  628. userNodes := GetStaticUserNodesByNetwork(models.NetworkID(node.Network))
  629. for _, userNodeI := range userNodes {
  630. for _, peer := range nodes {
  631. if peer.IsUserNode {
  632. continue
  633. }
  634. if ok, allowedPolicies := IsUserAllowedToCommunicate(userNodeI.StaticNode.OwnerID, peer); ok {
  635. if peer.IsStatic {
  636. peer = peer.StaticNode.ConvertToStaticNode()
  637. }
  638. if !defaultUserPolicy.Enabled {
  639. for _, policy := range allowedPolicies {
  640. if userNodeI.StaticNode.Address != "" {
  641. rules = append(rules, models.FwRule{
  642. SrcIP: userNodeI.StaticNode.AddressIPNet4(),
  643. DstIP: net.IPNet{
  644. IP: peer.Address.IP,
  645. Mask: net.CIDRMask(32, 32),
  646. },
  647. AllowedProtocol: policy.Proto,
  648. AllowedPorts: policy.Port,
  649. Allow: true,
  650. })
  651. }
  652. if userNodeI.StaticNode.Address6 != "" {
  653. rules = append(rules, models.FwRule{
  654. SrcIP: userNodeI.StaticNode.AddressIPNet6(),
  655. DstIP: net.IPNet{
  656. IP: peer.Address6.IP,
  657. Mask: net.CIDRMask(128, 128),
  658. },
  659. AllowedProtocol: policy.Proto,
  660. AllowedPorts: policy.Port,
  661. Allow: true,
  662. })
  663. }
  664. // add egress ranges
  665. for _, dstI := range policy.Dst {
  666. if dstI.ID == models.EgressID {
  667. e := schema.Egress{ID: dstI.Value}
  668. err := e.Get(db.WithContext(context.TODO()))
  669. if err != nil {
  670. continue
  671. }
  672. dstI.Value = e.Range
  673. ip, cidr, err := net.ParseCIDR(dstI.Value)
  674. if err == nil {
  675. if ip.To4() != nil && userNodeI.StaticNode.Address != "" {
  676. rules = append(rules, models.FwRule{
  677. SrcIP: userNodeI.StaticNode.AddressIPNet4(),
  678. DstIP: *cidr,
  679. AllowedProtocol: policy.Proto,
  680. AllowedPorts: policy.Port,
  681. Allow: true,
  682. })
  683. } else if ip.To16() != nil && userNodeI.StaticNode.Address6 != "" {
  684. rules = append(rules, models.FwRule{
  685. SrcIP: userNodeI.StaticNode.AddressIPNet6(),
  686. DstIP: *cidr,
  687. AllowedProtocol: policy.Proto,
  688. AllowedPorts: policy.Port,
  689. Allow: true,
  690. })
  691. }
  692. }
  693. }
  694. }
  695. }
  696. }
  697. }
  698. }
  699. }
  700. return
  701. }
  702. func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
  703. // fetch user access to static clients via policies
  704. defer func() {
  705. sort.Slice(rules, func(i, j int) bool {
  706. if !rules[i].SrcIP.IP.Equal(rules[j].SrcIP.IP) {
  707. return string(rules[i].SrcIP.IP.To16()) < string(rules[j].SrcIP.IP.To16())
  708. }
  709. return string(rules[i].DstIP.IP.To16()) < string(rules[j].DstIP.IP.To16())
  710. })
  711. }()
  712. defaultDevicePolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
  713. nodes, _ := GetNetworkNodes(node.Network)
  714. nodes = append(nodes, GetStaticNodesByNetwork(models.NetworkID(node.Network), true)...)
  715. rules = getFwRulesForUserNodesOnGw(node, nodes)
  716. if defaultDevicePolicy.Enabled {
  717. return
  718. }
  719. for _, nodeI := range nodes {
  720. if !nodeI.IsStatic || nodeI.IsUserNode {
  721. continue
  722. }
  723. // if nodeI.StaticNode.IngressGatewayID != node.ID.String() {
  724. // continue
  725. // }
  726. for _, peer := range nodes {
  727. if peer.StaticNode.ClientID == nodeI.StaticNode.ClientID || peer.IsUserNode {
  728. continue
  729. }
  730. if nodeI.StaticNode.IngressGatewayID != node.ID.String() &&
  731. ((!peer.IsStatic && peer.ID.String() != node.ID.String()) ||
  732. (peer.IsStatic && peer.StaticNode.IngressGatewayID != node.ID.String())) {
  733. continue
  734. }
  735. if peer.IsStatic {
  736. peer = peer.StaticNode.ConvertToStaticNode()
  737. }
  738. var allowedPolicies1 []models.Acl
  739. var ok bool
  740. if ok, allowedPolicies1 = IsNodeAllowedToCommunicateV1(nodeI.StaticNode.ConvertToStaticNode(), peer, true); ok {
  741. rules = append(rules, getFwRulesForNodeAndPeerOnGw(nodeI.StaticNode.ConvertToStaticNode(), peer, allowedPolicies1)...)
  742. }
  743. if ok, allowedPolicies2 := IsNodeAllowedToCommunicateV1(peer, nodeI.StaticNode.ConvertToStaticNode(), true); ok {
  744. rules = append(rules,
  745. getFwRulesForNodeAndPeerOnGw(peer, nodeI.StaticNode.ConvertToStaticNode(),
  746. GetUniquePolicies(allowedPolicies1, allowedPolicies2))...)
  747. }
  748. }
  749. }
  750. return
  751. }
  752. func GetUniquePolicies(policies1, policies2 []models.Acl) []models.Acl {
  753. policies1Map := make(map[string]struct{})
  754. for _, policy1I := range policies1 {
  755. policies1Map[policy1I.ID] = struct{}{}
  756. }
  757. for i := len(policies2) - 1; i >= 0; i-- {
  758. if _, ok := policies1Map[policies2[i].ID]; ok {
  759. policies2 = append(policies2[:i], policies2[i+1:]...)
  760. }
  761. }
  762. return policies2
  763. }
  764. func GetExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, []models.EgressNetworkRoutes, error) {
  765. var peers []wgtypes.PeerConfig
  766. var idsAndAddr []models.IDandAddr
  767. var egressRoutes []models.EgressNetworkRoutes
  768. extPeers, err := GetNetworkExtClients(node.Network)
  769. if err != nil {
  770. return peers, idsAndAddr, egressRoutes, err
  771. }
  772. host, err := GetHost(node.HostID.String())
  773. if err != nil {
  774. return peers, idsAndAddr, egressRoutes, err
  775. }
  776. for _, extPeer := range extPeers {
  777. extPeer := extPeer
  778. if !IsClientNodeAllowed(&extPeer, peer.ID.String()) {
  779. continue
  780. }
  781. if extPeer.RemoteAccessClientID == "" {
  782. if ok := IsPeerAllowed(extPeer.ConvertToStaticNode(), *peer, true); !ok {
  783. continue
  784. }
  785. } else {
  786. if ok, _ := IsUserAllowedToCommunicate(extPeer.OwnerID, *peer); !ok {
  787. continue
  788. }
  789. }
  790. pubkey, err := wgtypes.ParseKey(extPeer.PublicKey)
  791. if err != nil {
  792. logger.Log(1, "error parsing ext pub key:", err.Error())
  793. continue
  794. }
  795. if host.PublicKey.String() == extPeer.PublicKey ||
  796. extPeer.IngressGatewayID != node.ID.String() || !extPeer.Enabled {
  797. continue
  798. }
  799. var allowedips []net.IPNet
  800. var peer wgtypes.PeerConfig
  801. if extPeer.Address != "" {
  802. var peeraddr = net.IPNet{
  803. IP: net.ParseIP(extPeer.Address),
  804. Mask: net.CIDRMask(32, 32),
  805. }
  806. if peeraddr.IP != nil && peeraddr.Mask != nil {
  807. allowedips = append(allowedips, peeraddr)
  808. }
  809. }
  810. if extPeer.Address6 != "" {
  811. var addr6 = net.IPNet{
  812. IP: net.ParseIP(extPeer.Address6),
  813. Mask: net.CIDRMask(128, 128),
  814. }
  815. if addr6.IP != nil && addr6.Mask != nil {
  816. allowedips = append(allowedips, addr6)
  817. }
  818. }
  819. for _, extraAllowedIP := range extPeer.ExtraAllowedIPs {
  820. _, cidr, err := net.ParseCIDR(extraAllowedIP)
  821. if err == nil {
  822. allowedips = append(allowedips, *cidr)
  823. }
  824. }
  825. egressRoutes = append(egressRoutes, getExtPeerEgressRoute(*node, extPeer)...)
  826. primaryAddr := extPeer.Address
  827. if primaryAddr == "" {
  828. primaryAddr = extPeer.Address6
  829. }
  830. peer = wgtypes.PeerConfig{
  831. PublicKey: pubkey,
  832. ReplaceAllowedIPs: true,
  833. AllowedIPs: allowedips,
  834. }
  835. peers = append(peers, peer)
  836. idsAndAddr = append(idsAndAddr, models.IDandAddr{
  837. ID: peer.PublicKey.String(),
  838. Name: extPeer.ClientID,
  839. Address: primaryAddr,
  840. IsExtClient: true,
  841. })
  842. }
  843. return peers, idsAndAddr, egressRoutes, nil
  844. }
  845. func getExtPeerEgressRoute(node models.Node, extPeer models.ExtClient) (egressRoutes []models.EgressNetworkRoutes) {
  846. r := models.EgressNetworkRoutes{
  847. PeerKey: extPeer.PublicKey,
  848. EgressGwAddr: extPeer.AddressIPNet4(),
  849. EgressGwAddr6: extPeer.AddressIPNet6(),
  850. NodeAddr: node.Address,
  851. NodeAddr6: node.Address6,
  852. EgressRanges: extPeer.ExtraAllowedIPs,
  853. }
  854. for _, extraAllowedIP := range extPeer.ExtraAllowedIPs {
  855. r.EgressRangesWithMetric = append(r.EgressRangesWithMetric, models.EgressRangeMetric{
  856. Network: extraAllowedIP,
  857. RouteMetric: 256,
  858. })
  859. }
  860. egressRoutes = append(egressRoutes, r)
  861. return
  862. }
  863. func getExtpeerEgressRanges(node models.Node) (ranges, ranges6 []net.IPNet) {
  864. extPeers, err := GetNetworkExtClients(node.Network)
  865. if err != nil {
  866. return
  867. }
  868. for _, extPeer := range extPeers {
  869. if len(extPeer.ExtraAllowedIPs) == 0 {
  870. continue
  871. }
  872. if ok, _ := IsNodeAllowedToCommunicateV1(extPeer.ConvertToStaticNode(), node, true); !ok {
  873. continue
  874. }
  875. for _, allowedRange := range extPeer.ExtraAllowedIPs {
  876. _, ipnet, err := net.ParseCIDR(allowedRange)
  877. if err == nil {
  878. if ipnet.IP.To4() != nil {
  879. ranges = append(ranges, *ipnet)
  880. } else {
  881. ranges6 = append(ranges6, *ipnet)
  882. }
  883. }
  884. }
  885. }
  886. return
  887. }
  888. func getExtpeersExtraRoutes(node models.Node) (egressRoutes []models.EgressNetworkRoutes) {
  889. extPeers, err := GetNetworkExtClients(node.Network)
  890. if err != nil {
  891. return
  892. }
  893. for _, extPeer := range extPeers {
  894. if len(extPeer.ExtraAllowedIPs) == 0 {
  895. continue
  896. }
  897. if ok, _ := IsNodeAllowedToCommunicateV1(extPeer.ConvertToStaticNode(), node, true); !ok {
  898. continue
  899. }
  900. egressRoutes = append(egressRoutes, getExtPeerEgressRoute(node, extPeer)...)
  901. }
  902. return
  903. }
  904. func GetExtclientAllowedIPs(client models.ExtClient) (allowedIPs []string) {
  905. gwnode, err := GetNodeByID(client.IngressGatewayID)
  906. if err != nil {
  907. logger.Log(0,
  908. fmt.Sprintf("failed to get ingress gateway node [%s] info: %v", client.IngressGatewayID, err))
  909. return
  910. }
  911. network, err := GetParentNetwork(client.Network)
  912. if err != nil {
  913. logger.Log(1, "Could not retrieve Ingress Gateway Network", client.Network)
  914. return
  915. }
  916. if IsInternetGw(gwnode) {
  917. egressrange := "0.0.0.0/0"
  918. if gwnode.Address6.IP != nil && client.Address6 != "" {
  919. egressrange += "," + "::/0"
  920. }
  921. allowedIPs = []string{egressrange}
  922. } else {
  923. allowedIPs = []string{network.AddressRange}
  924. if network.AddressRange6 != "" {
  925. allowedIPs = append(allowedIPs, network.AddressRange6)
  926. }
  927. if egressGatewayRanges, err := GetEgressRangesOnNetwork(&client); err == nil {
  928. allowedIPs = append(allowedIPs, egressGatewayRanges...)
  929. }
  930. }
  931. return
  932. }
  933. func GetStaticUserNodesByNetwork(network models.NetworkID) (staticNode []models.Node) {
  934. extClients, err := GetAllExtClients()
  935. if err != nil {
  936. return
  937. }
  938. for _, extI := range extClients {
  939. if extI.Network == network.String() {
  940. if extI.RemoteAccessClientID != "" {
  941. n := extI.ConvertToStaticNode()
  942. staticNode = append(staticNode, n)
  943. }
  944. }
  945. }
  946. return
  947. }
  948. func GetStaticNodesByNetwork(network models.NetworkID, onlyWg bool) (staticNode []models.Node) {
  949. extClients, err := GetAllExtClients()
  950. if err != nil {
  951. return
  952. }
  953. SortExtClient(extClients[:])
  954. for _, extI := range extClients {
  955. if extI.Network == network.String() {
  956. if onlyWg && extI.RemoteAccessClientID != "" {
  957. continue
  958. }
  959. n := models.Node{
  960. IsStatic: true,
  961. StaticNode: extI,
  962. IsUserNode: extI.RemoteAccessClientID != "",
  963. }
  964. staticNode = append(staticNode, n)
  965. }
  966. }
  967. return
  968. }
  969. func GetStaticNodesByGw(gwNode models.Node) (staticNode []models.Node) {
  970. extClients, err := GetAllExtClients()
  971. if err != nil {
  972. return
  973. }
  974. for _, extI := range extClients {
  975. if extI.IngressGatewayID == gwNode.ID.String() {
  976. n := models.Node{
  977. IsStatic: true,
  978. StaticNode: extI,
  979. IsUserNode: extI.RemoteAccessClientID != "",
  980. }
  981. staticNode = append(staticNode, n)
  982. }
  983. }
  984. return
  985. }