acls.go 15 KB

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