acls.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  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, "remote-access-gws"),
  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.ID != models.UserAclID &&
  164. srcI.ID != models.UserGroupAclID && srcI.ID != models.UserRoleAclID {
  165. return false
  166. }
  167. // check if user group is valid
  168. if srcI.ID == models.UserAclID {
  169. _, err := GetUser(srcI.Value)
  170. if err != nil {
  171. return false
  172. }
  173. } else if srcI.ID == models.UserRoleAclID {
  174. if srcI.Value == "*" {
  175. continue
  176. }
  177. _, err := GetRole(models.UserRoleID(srcI.Value))
  178. if err != nil {
  179. return false
  180. }
  181. } else if srcI.ID == models.UserGroupAclID {
  182. if srcI.Value == "*" {
  183. continue
  184. }
  185. err := IsGroupValid(models.UserGroupID(srcI.Value))
  186. if err != nil {
  187. return false
  188. }
  189. }
  190. }
  191. for _, dstI := range acl.Dst {
  192. if dstI.ID == "" || dstI.Value == "" {
  193. return false
  194. }
  195. if dstI.ID == models.UserAclID ||
  196. dstI.ID == models.UserGroupAclID {
  197. return false
  198. }
  199. if dstI.ID != models.DeviceAclID {
  200. return false
  201. }
  202. if dstI.Value == "*" {
  203. continue
  204. }
  205. // check if tag is valid
  206. _, err := GetTag(models.TagID(dstI.Value))
  207. if err != nil {
  208. return false
  209. }
  210. }
  211. case models.DevicePolicy:
  212. for _, srcI := range acl.Src {
  213. if srcI.ID == "" || srcI.Value == "" {
  214. return false
  215. }
  216. if srcI.ID != models.DeviceAclID {
  217. return false
  218. }
  219. if srcI.Value == "*" {
  220. continue
  221. }
  222. // check if tag is valid
  223. _, err := GetTag(models.TagID(srcI.Value))
  224. if err != nil {
  225. return false
  226. }
  227. }
  228. for _, dstI := range acl.Dst {
  229. if dstI.ID == "" || dstI.Value == "" {
  230. return false
  231. }
  232. if dstI.ID != models.DeviceAclID {
  233. return false
  234. }
  235. if dstI.Value == "*" {
  236. continue
  237. }
  238. // check if tag is valid
  239. _, err := GetTag(models.TagID(dstI.Value))
  240. if err != nil {
  241. return false
  242. }
  243. }
  244. }
  245. return true
  246. }
  247. // UpdateAcl - updates allowed fields on acls and commits to DB
  248. func UpdateAcl(newAcl, acl models.Acl) error {
  249. if !acl.Default {
  250. acl.Name = newAcl.Name
  251. acl.Src = newAcl.Src
  252. acl.Dst = newAcl.Dst
  253. }
  254. acl.Enabled = newAcl.Enabled
  255. if acl.ID != newAcl.ID {
  256. database.DeleteRecord(database.ACLS_TABLE_NAME, acl.ID.String())
  257. acl.ID = newAcl.ID
  258. }
  259. d, err := json.Marshal(acl)
  260. if err != nil {
  261. return err
  262. }
  263. return database.Insert(acl.ID.String(), string(d), database.ACLS_TABLE_NAME)
  264. }
  265. // UpsertAcl - upserts acl
  266. func UpsertAcl(acl models.Acl) error {
  267. d, err := json.Marshal(acl)
  268. if err != nil {
  269. return err
  270. }
  271. return database.Insert(acl.ID.String(), string(d), database.ACLS_TABLE_NAME)
  272. }
  273. // DeleteAcl - deletes acl policy
  274. func DeleteAcl(a models.Acl) error {
  275. return database.DeleteRecord(database.ACLS_TABLE_NAME, a.ID.String())
  276. }
  277. // GetDefaultPolicy - fetches default policy in the network by ruleType
  278. func GetDefaultPolicy(netID models.NetworkID, ruleType models.AclPolicyType) (models.Acl, error) {
  279. aclID := "all-users"
  280. if ruleType == models.DevicePolicy {
  281. aclID = "all-nodes"
  282. }
  283. acl, err := GetAcl(models.AclID(fmt.Sprintf("%s.%s", netID, aclID)))
  284. if err != nil {
  285. return models.Acl{}, errors.New("default rule not found")
  286. }
  287. return acl, nil
  288. }
  289. // ListUserPolicies - lists all acl policies enforced on an user
  290. func ListUserPolicies(u models.User) []models.Acl {
  291. data, err := database.FetchRecords(database.ACLS_TABLE_NAME)
  292. if err != nil && !database.IsEmptyRecord(err) {
  293. return []models.Acl{}
  294. }
  295. acls := []models.Acl{}
  296. for _, dataI := range data {
  297. acl := models.Acl{}
  298. err := json.Unmarshal([]byte(dataI), &acl)
  299. if err != nil {
  300. continue
  301. }
  302. if acl.RuleType == models.UserPolicy {
  303. srcMap := convAclTagToValueMap(acl.Src)
  304. if _, ok := srcMap[u.UserName]; ok {
  305. acls = append(acls, acl)
  306. } else {
  307. // check for user groups
  308. for gID := range u.UserGroups {
  309. if _, ok := srcMap[gID.String()]; ok {
  310. acls = append(acls, acl)
  311. break
  312. }
  313. }
  314. }
  315. }
  316. }
  317. return acls
  318. }
  319. // listPoliciesOfUser - lists all user acl policies applied to user in an network
  320. func listPoliciesOfUser(user models.User, netID models.NetworkID) []models.Acl {
  321. data, err := database.FetchRecords(database.ACLS_TABLE_NAME)
  322. if err != nil && !database.IsEmptyRecord(err) {
  323. return []models.Acl{}
  324. }
  325. acls := []models.Acl{}
  326. for _, dataI := range data {
  327. acl := models.Acl{}
  328. err := json.Unmarshal([]byte(dataI), &acl)
  329. if err != nil {
  330. continue
  331. }
  332. if acl.NetworkID == netID && acl.RuleType == models.UserPolicy {
  333. srcMap := convAclTagToValueMap(acl.Src)
  334. if _, ok := srcMap[user.UserName]; ok {
  335. acls = append(acls, acl)
  336. continue
  337. }
  338. for userG := range user.UserGroups {
  339. if _, ok := srcMap[userG.String()]; ok {
  340. acls = append(acls, acl)
  341. continue
  342. }
  343. }
  344. }
  345. }
  346. return acls
  347. }
  348. // listUserPoliciesByNetwork - lists all acl user policies in a network
  349. func listUserPoliciesByNetwork(netID models.NetworkID) []models.Acl {
  350. data, err := database.FetchRecords(database.ACLS_TABLE_NAME)
  351. if err != nil && !database.IsEmptyRecord(err) {
  352. return []models.Acl{}
  353. }
  354. acls := []models.Acl{}
  355. for _, dataI := range data {
  356. acl := models.Acl{}
  357. err := json.Unmarshal([]byte(dataI), &acl)
  358. if err != nil {
  359. continue
  360. }
  361. if acl.NetworkID == netID && acl.RuleType == models.UserPolicy {
  362. acls = append(acls, acl)
  363. }
  364. }
  365. return acls
  366. }
  367. // listDevicePolicies - lists all device policies in a network
  368. func listDevicePolicies(netID models.NetworkID) []models.Acl {
  369. data, err := database.FetchRecords(database.ACLS_TABLE_NAME)
  370. if err != nil && !database.IsEmptyRecord(err) {
  371. return []models.Acl{}
  372. }
  373. acls := []models.Acl{}
  374. for _, dataI := range data {
  375. acl := models.Acl{}
  376. err := json.Unmarshal([]byte(dataI), &acl)
  377. if err != nil {
  378. continue
  379. }
  380. if acl.NetworkID == netID && acl.RuleType == models.DevicePolicy {
  381. acls = append(acls, acl)
  382. }
  383. }
  384. return acls
  385. }
  386. // ListAcls - lists all acl policies
  387. func ListAcls(netID models.NetworkID) ([]models.Acl, error) {
  388. data, err := database.FetchRecords(database.ACLS_TABLE_NAME)
  389. if err != nil && !database.IsEmptyRecord(err) {
  390. return []models.Acl{}, err
  391. }
  392. acls := []models.Acl{}
  393. for _, dataI := range data {
  394. acl := models.Acl{}
  395. err := json.Unmarshal([]byte(dataI), &acl)
  396. if err != nil {
  397. continue
  398. }
  399. if acl.NetworkID == netID {
  400. acls = append(acls, acl)
  401. }
  402. }
  403. return acls, nil
  404. }
  405. func convAclTagToValueMap(acltags []models.AclPolicyTag) map[string]struct{} {
  406. aclValueMap := make(map[string]struct{})
  407. for _, aclTagI := range acltags {
  408. aclValueMap[aclTagI.Value] = struct{}{}
  409. }
  410. return aclValueMap
  411. }
  412. // IsUserAllowedToCommunicate - check if user is allowed to communicate with peer
  413. func IsUserAllowedToCommunicate(userName string, peer models.Node) bool {
  414. user, err := GetUser(userName)
  415. if err != nil {
  416. return false
  417. }
  418. policies := listPoliciesOfUser(*user, models.NetworkID(peer.Network))
  419. for _, policy := range policies {
  420. if !policy.Enabled {
  421. continue
  422. }
  423. dstMap := convAclTagToValueMap(policy.Dst)
  424. for tagID := range peer.Tags {
  425. if _, ok := dstMap[tagID.String()]; ok {
  426. return true
  427. }
  428. }
  429. }
  430. return true
  431. }
  432. // IsNodeAllowedToCommunicate - check node is allowed to communicate with the peer
  433. func IsNodeAllowedToCommunicate(node, peer models.Node) bool {
  434. // check default policy if all allowed return true
  435. defaultPolicy, err := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
  436. if err == nil {
  437. if defaultPolicy.Enabled {
  438. return true
  439. }
  440. }
  441. // list device policies
  442. policies := listDevicePolicies(models.NetworkID(peer.Network))
  443. for _, policy := range policies {
  444. if !policy.Enabled {
  445. continue
  446. }
  447. srcMap := convAclTagToValueMap(policy.Src)
  448. dstMap := convAclTagToValueMap(policy.Dst)
  449. fmt.Printf("\n======> SRCMAP: %+v\n", srcMap)
  450. fmt.Printf("\n======> DSTMAP: %+v\n", dstMap)
  451. fmt.Printf("\n======> node Tags: %+v\n", node.Tags)
  452. fmt.Printf("\n======> peer Tags: %+v\n", peer.Tags)
  453. for tagID := range node.Tags {
  454. if _, ok := dstMap[tagID.String()]; ok {
  455. if _, ok := srcMap["*"]; ok {
  456. return true
  457. }
  458. for tagID := range peer.Tags {
  459. if _, ok := srcMap[tagID.String()]; ok {
  460. return true
  461. }
  462. }
  463. }
  464. if _, ok := srcMap[tagID.String()]; ok {
  465. if _, ok := dstMap["*"]; ok {
  466. return true
  467. }
  468. for tagID := range peer.Tags {
  469. if _, ok := dstMap[tagID.String()]; ok {
  470. return true
  471. }
  472. }
  473. }
  474. }
  475. for tagID := range peer.Tags {
  476. if _, ok := dstMap[tagID.String()]; ok {
  477. if _, ok := srcMap["*"]; ok {
  478. return true
  479. }
  480. for tagID := range node.Tags {
  481. if _, ok := srcMap[tagID.String()]; ok {
  482. return true
  483. }
  484. }
  485. }
  486. if _, ok := srcMap[tagID.String()]; ok {
  487. if _, ok := dstMap["*"]; ok {
  488. return true
  489. }
  490. for tagID := range node.Tags {
  491. if _, ok := dstMap[tagID.String()]; ok {
  492. return true
  493. }
  494. }
  495. }
  496. }
  497. }
  498. return false
  499. }
  500. // SortTagEntrys - Sorts slice of Tag entries by their id
  501. func SortAclEntrys(acls []models.Acl) {
  502. sort.Slice(acls, func(i, j int) bool {
  503. return acls[i].Name < acls[j].Name
  504. })
  505. }
  506. // UpdateDeviceTag - updates device tag on acl policies
  507. func UpdateDeviceTag(OldID, newID models.TagID, netID models.NetworkID) {
  508. acls := listDevicePolicies(netID)
  509. update := false
  510. for _, acl := range acls {
  511. for i, srcTagI := range acl.Src {
  512. if srcTagI.ID == models.DeviceAclID {
  513. if OldID.String() == srcTagI.Value {
  514. acl.Src[i].Value = newID.String()
  515. update = true
  516. }
  517. }
  518. }
  519. for i, dstTagI := range acl.Dst {
  520. if dstTagI.ID == models.DeviceAclID {
  521. if OldID.String() == dstTagI.Value {
  522. acl.Dst[i].Value = newID.String()
  523. update = true
  524. }
  525. }
  526. }
  527. if update {
  528. UpsertAcl(acl)
  529. }
  530. }
  531. }
  532. // RemoveDeviceTagFromAclPolicies - remove device tag from acl policies
  533. func RemoveDeviceTagFromAclPolicies(tagID models.TagID, netID models.NetworkID) error {
  534. acls := listDevicePolicies(netID)
  535. update := false
  536. for _, acl := range acls {
  537. for i, srcTagI := range acl.Src {
  538. if srcTagI.ID == models.DeviceAclID {
  539. if tagID.String() == srcTagI.Value {
  540. acl.Src = append(acl.Src[:i], acl.Src[i+1:]...)
  541. update = true
  542. }
  543. }
  544. }
  545. for i, dstTagI := range acl.Dst {
  546. if dstTagI.ID == models.DeviceAclID {
  547. if tagID.String() == dstTagI.Value {
  548. acl.Dst = append(acl.Dst[:i], acl.Dst[i+1:]...)
  549. update = true
  550. }
  551. }
  552. }
  553. if update {
  554. UpsertAcl(acl)
  555. }
  556. }
  557. return nil
  558. }