acls.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. package logic
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "sort"
  7. "sync"
  8. "time"
  9. "github.com/gravitl/netmaker/database"
  10. "github.com/gravitl/netmaker/models"
  11. "github.com/gravitl/netmaker/servercfg"
  12. )
  13. var (
  14. aclCacheMutex = &sync.RWMutex{}
  15. aclCacheMap = make(map[string]models.Acl)
  16. )
  17. // CreateDefaultAclNetworkPolicies - create default acl network policies
  18. func CreateDefaultAclNetworkPolicies(netID models.NetworkID) {
  19. if netID.String() == "" {
  20. return
  21. }
  22. if !IsAclExists(fmt.Sprintf("%s.%s", netID, "all-nodes")) {
  23. defaultDeviceAcl := models.Acl{
  24. ID: fmt.Sprintf("%s.%s", netID, "all-nodes"),
  25. Name: "All Nodes",
  26. MetaData: "This Policy allows all nodes in the network to communicate with each other",
  27. Default: true,
  28. NetworkID: netID,
  29. RuleType: models.DevicePolicy,
  30. Src: []models.AclPolicyTag{
  31. {
  32. ID: models.DeviceAclID,
  33. Value: "*",
  34. }},
  35. Dst: []models.AclPolicyTag{
  36. {
  37. ID: models.DeviceAclID,
  38. Value: "*",
  39. }},
  40. AllowedDirection: models.TrafficDirectionBi,
  41. Enabled: true,
  42. CreatedBy: "auto",
  43. CreatedAt: time.Now().UTC(),
  44. }
  45. InsertAcl(defaultDeviceAcl)
  46. }
  47. if !IsAclExists(fmt.Sprintf("%s.%s", netID, "all-users")) {
  48. defaultUserAcl := models.Acl{
  49. ID: fmt.Sprintf("%s.%s", netID, "all-users"),
  50. Default: true,
  51. Name: "All Users",
  52. MetaData: "This policy gives access to everything in the network for an user",
  53. NetworkID: netID,
  54. RuleType: models.UserPolicy,
  55. Src: []models.AclPolicyTag{
  56. {
  57. ID: models.UserAclID,
  58. Value: "*",
  59. },
  60. },
  61. Dst: []models.AclPolicyTag{{
  62. ID: models.DeviceAclID,
  63. Value: "*",
  64. }},
  65. AllowedDirection: models.TrafficDirectionUni,
  66. Enabled: true,
  67. CreatedBy: "auto",
  68. CreatedAt: time.Now().UTC(),
  69. }
  70. InsertAcl(defaultUserAcl)
  71. }
  72. if !IsAclExists(fmt.Sprintf("%s.%s", netID, "all-remote-access-gws")) {
  73. defaultUserAcl := models.Acl{
  74. ID: fmt.Sprintf("%s.%s", netID, "all-remote-access-gws"),
  75. Default: true,
  76. Name: "All Remote Access Gateways",
  77. NetworkID: netID,
  78. RuleType: models.DevicePolicy,
  79. Src: []models.AclPolicyTag{
  80. {
  81. ID: models.DeviceAclID,
  82. Value: fmt.Sprintf("%s.%s", netID, models.RemoteAccessTagName),
  83. },
  84. },
  85. Dst: []models.AclPolicyTag{
  86. {
  87. ID: models.DeviceAclID,
  88. Value: "*",
  89. },
  90. },
  91. AllowedDirection: models.TrafficDirectionBi,
  92. Enabled: true,
  93. CreatedBy: "auto",
  94. CreatedAt: time.Now().UTC(),
  95. }
  96. InsertAcl(defaultUserAcl)
  97. }
  98. CreateDefaultUserPolicies(netID)
  99. }
  100. // DeleteDefaultNetworkPolicies - deletes all default network acl policies
  101. func DeleteDefaultNetworkPolicies(netId models.NetworkID) {
  102. acls, _ := ListAcls(netId)
  103. for _, acl := range acls {
  104. if acl.NetworkID == netId && acl.Default {
  105. DeleteAcl(acl)
  106. }
  107. }
  108. }
  109. // ValidateCreateAclReq - validates create req for acl
  110. func ValidateCreateAclReq(req models.Acl) error {
  111. // check if acl network exists
  112. _, err := GetNetwork(req.NetworkID.String())
  113. if err != nil {
  114. return errors.New("failed to get network details for " + req.NetworkID.String())
  115. }
  116. // err = CheckIDSyntax(req.Name)
  117. // if err != nil {
  118. // return err
  119. // }
  120. return nil
  121. }
  122. func listAclFromCache() (acls []models.Acl) {
  123. aclCacheMutex.RLock()
  124. defer aclCacheMutex.RUnlock()
  125. for _, acl := range aclCacheMap {
  126. acls = append(acls, acl)
  127. }
  128. return
  129. }
  130. func storeAclInCache(a models.Acl) {
  131. aclCacheMutex.Lock()
  132. defer aclCacheMutex.Unlock()
  133. aclCacheMap[a.ID] = a
  134. }
  135. func removeAclFromCache(a models.Acl) {
  136. aclCacheMutex.Lock()
  137. defer aclCacheMutex.Unlock()
  138. delete(aclCacheMap, a.ID)
  139. }
  140. func getAclFromCache(aID string) (a models.Acl, ok bool) {
  141. aclCacheMutex.RLock()
  142. defer aclCacheMutex.RUnlock()
  143. a, ok = aclCacheMap[aID]
  144. return
  145. }
  146. // InsertAcl - creates acl policy
  147. func InsertAcl(a models.Acl) error {
  148. d, err := json.Marshal(a)
  149. if err != nil {
  150. return err
  151. }
  152. err = database.Insert(a.ID, string(d), database.ACLS_TABLE_NAME)
  153. if err == nil && servercfg.CacheEnabled() {
  154. storeAclInCache(a)
  155. }
  156. return err
  157. }
  158. // GetAcl - gets acl info by id
  159. func GetAcl(aID string) (models.Acl, error) {
  160. a := models.Acl{}
  161. if servercfg.CacheEnabled() {
  162. if len(aclCacheMap) == 0 {
  163. _ = listAcls()
  164. }
  165. var ok bool
  166. a, ok = getAclFromCache(aID)
  167. if ok {
  168. return a, nil
  169. }
  170. }
  171. d, err := database.FetchRecord(database.ACLS_TABLE_NAME, aID)
  172. if err != nil {
  173. return a, err
  174. }
  175. err = json.Unmarshal([]byte(d), &a)
  176. if err != nil {
  177. return a, err
  178. }
  179. if servercfg.CacheEnabled() {
  180. storeAclInCache(a)
  181. }
  182. return a, nil
  183. }
  184. // IsAclExists - checks if acl exists
  185. func IsAclExists(aclID string) bool {
  186. _, err := GetAcl(aclID)
  187. return err == nil
  188. }
  189. // IsAclPolicyValid - validates if acl policy is valid
  190. func IsAclPolicyValid(acl models.Acl) bool {
  191. //check if src and dst are valid
  192. switch acl.RuleType {
  193. case models.UserPolicy:
  194. // src list should only contain users
  195. for _, srcI := range acl.Src {
  196. if srcI.ID == "" || srcI.Value == "" {
  197. return false
  198. }
  199. if srcI.Value == "*" {
  200. continue
  201. }
  202. if srcI.ID != models.UserAclID && srcI.ID != models.UserGroupAclID {
  203. return false
  204. }
  205. // check if user group is valid
  206. if srcI.ID == models.UserAclID {
  207. _, err := GetUser(srcI.Value)
  208. if err != nil {
  209. return false
  210. }
  211. } else if srcI.ID == models.UserGroupAclID {
  212. err := IsGroupValid(models.UserGroupID(srcI.Value))
  213. if err != nil {
  214. return false
  215. }
  216. // check if group belongs to this network
  217. netGrps := GetUserGroupsInNetwork(acl.NetworkID)
  218. if _, ok := netGrps[models.UserGroupID(srcI.Value)]; !ok {
  219. return false
  220. }
  221. }
  222. }
  223. for _, dstI := range acl.Dst {
  224. if dstI.ID == "" || dstI.Value == "" {
  225. return false
  226. }
  227. if dstI.ID != models.DeviceAclID {
  228. return false
  229. }
  230. if dstI.Value == "*" {
  231. continue
  232. }
  233. // check if tag is valid
  234. _, err := GetTag(models.TagID(dstI.Value))
  235. if err != nil {
  236. return false
  237. }
  238. }
  239. case models.DevicePolicy:
  240. for _, srcI := range acl.Src {
  241. if srcI.ID == "" || srcI.Value == "" {
  242. return false
  243. }
  244. if srcI.ID != models.DeviceAclID {
  245. return false
  246. }
  247. if srcI.Value == "*" {
  248. continue
  249. }
  250. // check if tag is valid
  251. _, err := GetTag(models.TagID(srcI.Value))
  252. if err != nil {
  253. return false
  254. }
  255. }
  256. for _, dstI := range acl.Dst {
  257. if dstI.ID == "" || dstI.Value == "" {
  258. return false
  259. }
  260. if dstI.ID != models.DeviceAclID {
  261. return false
  262. }
  263. if dstI.Value == "*" {
  264. continue
  265. }
  266. // check if tag is valid
  267. _, err := GetTag(models.TagID(dstI.Value))
  268. if err != nil {
  269. return false
  270. }
  271. }
  272. }
  273. return true
  274. }
  275. // UpdateAcl - updates allowed fields on acls and commits to DB
  276. func UpdateAcl(newAcl, acl models.Acl) error {
  277. if !acl.Default {
  278. acl.Name = newAcl.Name
  279. acl.Src = newAcl.Src
  280. acl.Dst = newAcl.Dst
  281. }
  282. acl.Enabled = newAcl.Enabled
  283. d, err := json.Marshal(acl)
  284. if err != nil {
  285. return err
  286. }
  287. err = database.Insert(acl.ID, string(d), database.ACLS_TABLE_NAME)
  288. if err == nil && servercfg.CacheEnabled() {
  289. storeAclInCache(acl)
  290. }
  291. return err
  292. }
  293. // UpsertAcl - upserts acl
  294. func UpsertAcl(acl models.Acl) error {
  295. d, err := json.Marshal(acl)
  296. if err != nil {
  297. return err
  298. }
  299. err = database.Insert(acl.ID, string(d), database.ACLS_TABLE_NAME)
  300. if err == nil && servercfg.CacheEnabled() {
  301. storeAclInCache(acl)
  302. }
  303. return err
  304. }
  305. // DeleteAcl - deletes acl policy
  306. func DeleteAcl(a models.Acl) error {
  307. err := database.DeleteRecord(database.ACLS_TABLE_NAME, a.ID)
  308. if err == nil && servercfg.CacheEnabled() {
  309. removeAclFromCache(a)
  310. }
  311. return err
  312. }
  313. // GetDefaultPolicy - fetches default policy in the network by ruleType
  314. func GetDefaultPolicy(netID models.NetworkID, ruleType models.AclPolicyType) (models.Acl, error) {
  315. aclID := "all-users"
  316. if ruleType == models.DevicePolicy {
  317. aclID = "all-nodes"
  318. }
  319. acl, err := GetAcl(fmt.Sprintf("%s.%s", netID, aclID))
  320. if err != nil {
  321. return models.Acl{}, errors.New("default rule not found")
  322. }
  323. if acl.Enabled {
  324. return acl, nil
  325. }
  326. // check if there are any custom all policies
  327. policies, _ := ListAcls(netID)
  328. for _, policy := range policies {
  329. if !policy.Enabled {
  330. continue
  331. }
  332. if policy.RuleType == ruleType {
  333. dstMap := convAclTagToValueMap(policy.Dst)
  334. srcMap := convAclTagToValueMap(policy.Src)
  335. if _, ok := srcMap["*"]; ok {
  336. if _, ok := dstMap["*"]; ok {
  337. return policy, nil
  338. }
  339. }
  340. }
  341. }
  342. return acl, nil
  343. }
  344. func listAcls() (acls []models.Acl) {
  345. if servercfg.CacheEnabled() && len(aclCacheMap) > 0 {
  346. return listAclFromCache()
  347. }
  348. data, err := database.FetchRecords(database.ACLS_TABLE_NAME)
  349. if err != nil && !database.IsEmptyRecord(err) {
  350. return []models.Acl{}
  351. }
  352. for _, dataI := range data {
  353. acl := models.Acl{}
  354. err := json.Unmarshal([]byte(dataI), &acl)
  355. if err != nil {
  356. continue
  357. }
  358. acls = append(acls, acl)
  359. if servercfg.CacheEnabled() {
  360. storeAclInCache(acl)
  361. }
  362. }
  363. return
  364. }
  365. // ListUserPolicies - lists all acl policies enforced on an user
  366. func ListUserPolicies(u models.User) []models.Acl {
  367. allAcls := listAcls()
  368. userAcls := []models.Acl{}
  369. for _, acl := range allAcls {
  370. if acl.RuleType == models.UserPolicy {
  371. srcMap := convAclTagToValueMap(acl.Src)
  372. if _, ok := srcMap[u.UserName]; ok {
  373. userAcls = append(userAcls, acl)
  374. } else {
  375. // check for user groups
  376. for gID := range u.UserGroups {
  377. if _, ok := srcMap[gID.String()]; ok {
  378. userAcls = append(userAcls, acl)
  379. break
  380. }
  381. }
  382. }
  383. }
  384. }
  385. return userAcls
  386. }
  387. // listPoliciesOfUser - lists all user acl policies applied to user in an network
  388. func listPoliciesOfUser(user models.User, netID models.NetworkID) []models.Acl {
  389. allAcls := listAcls()
  390. userAcls := []models.Acl{}
  391. for _, acl := range allAcls {
  392. if acl.NetworkID == netID && acl.RuleType == models.UserPolicy {
  393. srcMap := convAclTagToValueMap(acl.Src)
  394. if _, ok := srcMap[user.UserName]; ok {
  395. userAcls = append(userAcls, acl)
  396. continue
  397. }
  398. for netRole := range user.NetworkRoles {
  399. if _, ok := srcMap[netRole.String()]; ok {
  400. userAcls = append(userAcls, acl)
  401. continue
  402. }
  403. }
  404. for userG := range user.UserGroups {
  405. if _, ok := srcMap[userG.String()]; ok {
  406. userAcls = append(userAcls, acl)
  407. continue
  408. }
  409. }
  410. }
  411. }
  412. return userAcls
  413. }
  414. // listDevicePolicies - lists all device policies in a network
  415. func listDevicePolicies(netID models.NetworkID) []models.Acl {
  416. allAcls := listAcls()
  417. deviceAcls := []models.Acl{}
  418. for _, acl := range allAcls {
  419. if acl.NetworkID == netID && acl.RuleType == models.DevicePolicy {
  420. deviceAcls = append(deviceAcls, acl)
  421. }
  422. }
  423. return deviceAcls
  424. }
  425. // ListAcls - lists all acl policies
  426. func ListAcls(netID models.NetworkID) ([]models.Acl, error) {
  427. allAcls := listAcls()
  428. netAcls := []models.Acl{}
  429. for _, acl := range allAcls {
  430. if acl.NetworkID == netID {
  431. netAcls = append(netAcls, acl)
  432. }
  433. }
  434. return netAcls, nil
  435. }
  436. func convAclTagToValueMap(acltags []models.AclPolicyTag) map[string]struct{} {
  437. aclValueMap := make(map[string]struct{})
  438. for _, aclTagI := range acltags {
  439. aclValueMap[aclTagI.Value] = struct{}{}
  440. }
  441. return aclValueMap
  442. }
  443. // IsUserAllowedToCommunicate - check if user is allowed to communicate with peer
  444. func IsUserAllowedToCommunicate(userName string, peer models.Node) bool {
  445. if peer.IsStatic {
  446. peer = peer.StaticNode.ConvertToStaticNode()
  447. }
  448. acl, _ := GetDefaultPolicy(models.NetworkID(peer.Network), models.UserPolicy)
  449. if acl.Enabled {
  450. return true
  451. }
  452. user, err := GetUser(userName)
  453. if err != nil {
  454. return false
  455. }
  456. policies := listPoliciesOfUser(*user, models.NetworkID(peer.Network))
  457. for _, policy := range policies {
  458. if !policy.Enabled {
  459. continue
  460. }
  461. dstMap := convAclTagToValueMap(policy.Dst)
  462. if _, ok := dstMap["*"]; ok {
  463. return true
  464. }
  465. for tagID := range peer.Tags {
  466. if _, ok := dstMap[tagID.String()]; ok {
  467. return true
  468. }
  469. }
  470. }
  471. return false
  472. }
  473. // IsNodeAllowedToCommunicate - check node is allowed to communicate with the peer
  474. func IsNodeAllowedToCommunicate(node, peer models.Node) bool {
  475. if node.IsStatic {
  476. node = node.StaticNode.ConvertToStaticNode()
  477. }
  478. if peer.IsStatic {
  479. peer = peer.StaticNode.ConvertToStaticNode()
  480. }
  481. // check default policy if all allowed return true
  482. defaultPolicy, err := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
  483. if err == nil {
  484. if defaultPolicy.Enabled {
  485. return true
  486. }
  487. }
  488. // list device policies
  489. policies := listDevicePolicies(models.NetworkID(peer.Network))
  490. for _, policy := range policies {
  491. if !policy.Enabled {
  492. continue
  493. }
  494. srcMap := convAclTagToValueMap(policy.Src)
  495. dstMap := convAclTagToValueMap(policy.Dst)
  496. // fmt.Printf("\n======> SRCMAP: %+v\n", srcMap)
  497. // fmt.Printf("\n======> DSTMAP: %+v\n", dstMap)
  498. // fmt.Printf("\n======> node Tags: %+v\n", node.Tags)
  499. // fmt.Printf("\n======> peer Tags: %+v\n", peer.Tags)
  500. for tagID := range node.Tags {
  501. if _, ok := dstMap[tagID.String()]; ok {
  502. if _, ok := srcMap["*"]; ok {
  503. return true
  504. }
  505. for tagID := range peer.Tags {
  506. if _, ok := srcMap[tagID.String()]; ok {
  507. return true
  508. }
  509. }
  510. }
  511. if _, ok := srcMap[tagID.String()]; ok {
  512. if _, ok := dstMap["*"]; ok {
  513. return true
  514. }
  515. for tagID := range peer.Tags {
  516. if _, ok := dstMap[tagID.String()]; ok {
  517. return true
  518. }
  519. }
  520. }
  521. }
  522. for tagID := range peer.Tags {
  523. if _, ok := dstMap[tagID.String()]; ok {
  524. if _, ok := srcMap["*"]; ok {
  525. return true
  526. }
  527. for tagID := range node.Tags {
  528. if _, ok := srcMap[tagID.String()]; ok {
  529. return true
  530. }
  531. }
  532. }
  533. if _, ok := srcMap[tagID.String()]; ok {
  534. if _, ok := dstMap["*"]; ok {
  535. return true
  536. }
  537. for tagID := range node.Tags {
  538. if _, ok := dstMap[tagID.String()]; ok {
  539. return true
  540. }
  541. }
  542. }
  543. }
  544. }
  545. return false
  546. }
  547. // SortTagEntrys - Sorts slice of Tag entries by their id
  548. func SortAclEntrys(acls []models.Acl) {
  549. sort.Slice(acls, func(i, j int) bool {
  550. return acls[i].Name < acls[j].Name
  551. })
  552. }
  553. // UpdateDeviceTag - updates device tag on acl policies
  554. func UpdateDeviceTag(OldID, newID models.TagID, netID models.NetworkID) {
  555. acls := listDevicePolicies(netID)
  556. update := false
  557. for _, acl := range acls {
  558. for i, srcTagI := range acl.Src {
  559. if srcTagI.ID == models.DeviceAclID {
  560. if OldID.String() == srcTagI.Value {
  561. acl.Src[i].Value = newID.String()
  562. update = true
  563. }
  564. }
  565. }
  566. for i, dstTagI := range acl.Dst {
  567. if dstTagI.ID == models.DeviceAclID {
  568. if OldID.String() == dstTagI.Value {
  569. acl.Dst[i].Value = newID.String()
  570. update = true
  571. }
  572. }
  573. }
  574. if update {
  575. UpsertAcl(acl)
  576. }
  577. }
  578. }
  579. func CheckIfTagAsActivePolicy(tagID models.TagID, netID models.NetworkID) bool {
  580. acls := listDevicePolicies(netID)
  581. for _, acl := range acls {
  582. for _, srcTagI := range acl.Src {
  583. if srcTagI.ID == models.DeviceAclID {
  584. if tagID.String() == srcTagI.Value {
  585. return true
  586. }
  587. }
  588. }
  589. for _, dstTagI := range acl.Dst {
  590. if dstTagI.ID == models.DeviceAclID {
  591. return true
  592. }
  593. }
  594. }
  595. return false
  596. }
  597. // RemoveDeviceTagFromAclPolicies - remove device tag from acl policies
  598. func RemoveDeviceTagFromAclPolicies(tagID models.TagID, netID models.NetworkID) error {
  599. acls := listDevicePolicies(netID)
  600. update := false
  601. for _, acl := range acls {
  602. for i, srcTagI := range acl.Src {
  603. if srcTagI.ID == models.DeviceAclID {
  604. if tagID.String() == srcTagI.Value {
  605. acl.Src = append(acl.Src[:i], acl.Src[i+1:]...)
  606. update = true
  607. }
  608. }
  609. }
  610. for i, dstTagI := range acl.Dst {
  611. if dstTagI.ID == models.DeviceAclID {
  612. if tagID.String() == dstTagI.Value {
  613. acl.Dst = append(acl.Dst[:i], acl.Dst[i+1:]...)
  614. update = true
  615. }
  616. }
  617. }
  618. if update {
  619. UpsertAcl(acl)
  620. }
  621. }
  622. return nil
  623. }