dynsec_helper.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. package mq
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "time"
  7. mqtt "github.com/eclipse/paho.mqtt.golang"
  8. "github.com/gravitl/netmaker/servercfg"
  9. )
  10. const (
  11. // constant for admin role
  12. adminRole = "admin"
  13. // constant for server role
  14. serverRole = "server"
  15. // constant for exporter role
  16. exporterRole = "exporter"
  17. // constant for node role
  18. NodeRole = "node"
  19. // const for dynamic security file
  20. dynamicSecurityFile = "dynamic-security.json"
  21. )
  22. var (
  23. // default configuration of dynamic security
  24. dynConfigInI = dynJSON{
  25. Clients: []client{
  26. {
  27. Username: mqAdminUserName,
  28. TextName: "netmaker admin user",
  29. Password: "",
  30. Salt: "",
  31. Iterations: 0,
  32. Roles: []clientRole{
  33. {
  34. Rolename: adminRole,
  35. },
  36. },
  37. },
  38. {
  39. Username: mqNetmakerServerUserName,
  40. TextName: "netmaker server user",
  41. Password: "",
  42. Salt: "",
  43. Iterations: 0,
  44. Roles: []clientRole{
  45. {
  46. Rolename: serverRole,
  47. },
  48. },
  49. },
  50. exporterMQClient,
  51. },
  52. Roles: []role{
  53. {
  54. Rolename: adminRole,
  55. Acls: fetchAdminAcls(),
  56. },
  57. {
  58. Rolename: serverRole,
  59. Acls: fetchServerAcls(),
  60. },
  61. {
  62. Rolename: NodeRole,
  63. Acls: fetchNodeAcls(),
  64. },
  65. exporterMQRole,
  66. },
  67. DefaultAcl: defaultAccessAcl{
  68. PublishClientSend: false,
  69. PublishClientReceive: true,
  70. Subscribe: false,
  71. Unsubscribe: true,
  72. },
  73. }
  74. exporterMQClient = client{
  75. Username: mqExporterUserName,
  76. TextName: "netmaker metrics exporter",
  77. Password: "",
  78. Salt: "",
  79. Iterations: 101,
  80. Roles: []clientRole{
  81. {
  82. Rolename: exporterRole,
  83. },
  84. },
  85. }
  86. exporterMQRole = role{
  87. Rolename: exporterRole,
  88. Acls: fetchExporterAcls(),
  89. }
  90. )
  91. // DynListCLientsCmdResp - struct for list clients response from MQ
  92. type DynListCLientsCmdResp struct {
  93. Responses []struct {
  94. Command string `json:"command"`
  95. Error string `json:"error"`
  96. Data ListClientsData `json:"data"`
  97. } `json:"responses"`
  98. }
  99. // ListClientsData - struct for list clients data
  100. type ListClientsData struct {
  101. Clients []string `json:"clients"`
  102. TotalCount int `json:"totalCount"`
  103. }
  104. // GetAdminClient - fetches admin client of the MQ
  105. func GetAdminClient() (mqtt.Client, error) {
  106. opts := mqtt.NewClientOptions()
  107. setMqOptions(mqAdminUserName, servercfg.GetMqAdminPassword(), opts)
  108. mqclient := mqtt.NewClient(opts)
  109. var connecterr error
  110. if token := mqclient.Connect(); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
  111. if token.Error() == nil {
  112. connecterr = errors.New("connect timeout")
  113. } else {
  114. connecterr = token.Error()
  115. }
  116. }
  117. return mqclient, connecterr
  118. }
  119. // ListClients - to list all clients in the MQ
  120. func ListClients(client mqtt.Client) (ListClientsData, error) {
  121. respChan := make(chan mqtt.Message, 10)
  122. defer close(respChan)
  123. command := "listClients"
  124. resp := ListClientsData{}
  125. msg := MqDynsecPayload{
  126. Commands: []MqDynSecCmd{
  127. {
  128. Command: command,
  129. },
  130. },
  131. }
  132. client.Subscribe("$CONTROL/dynamic-security/v1/response", 2, mqtt.MessageHandler(func(c mqtt.Client, m mqtt.Message) {
  133. respChan <- m
  134. }))
  135. defer client.Unsubscribe()
  136. d, _ := json.Marshal(msg)
  137. token := client.Publish("$CONTROL/dynamic-security/v1", 2, true, d)
  138. if !token.WaitTimeout(30) || token.Error() != nil {
  139. var err error
  140. if token.Error() == nil {
  141. err = errors.New("connection timeout")
  142. } else {
  143. err = token.Error()
  144. }
  145. return resp, err
  146. }
  147. for m := range respChan {
  148. msg := DynListCLientsCmdResp{}
  149. json.Unmarshal(m.Payload(), &msg)
  150. for _, mI := range msg.Responses {
  151. if mI.Command == command {
  152. return mI.Data, nil
  153. }
  154. }
  155. }
  156. return resp, errors.New("resp not found")
  157. }
  158. // FetchNetworkAcls - fetches network acls
  159. func FetchNetworkAcls(network string) []Acl {
  160. return []Acl{
  161. {
  162. AclType: "publishClientReceive",
  163. Topic: fmt.Sprintf("update/%s/#", network),
  164. Priority: -1,
  165. Allow: true,
  166. },
  167. {
  168. AclType: "publishClientReceive",
  169. Topic: fmt.Sprintf("peers/%s/#", network),
  170. Priority: -1,
  171. Allow: true,
  172. },
  173. {
  174. AclType: "publishClientReceive",
  175. Topic: fmt.Sprintf("proxy/%s/#", network),
  176. Priority: -1,
  177. Allow: true,
  178. },
  179. {
  180. AclType: "subscribePattern",
  181. Topic: "#",
  182. Priority: -1,
  183. Allow: true,
  184. },
  185. {
  186. AclType: "unsubscribePattern",
  187. Topic: "#",
  188. Priority: -1,
  189. Allow: true,
  190. },
  191. }
  192. }
  193. // serverAcls - fetches server role related acls
  194. func fetchServerAcls() []Acl {
  195. return []Acl{
  196. {
  197. AclType: "publishClientSend",
  198. Topic: "peers/#",
  199. Priority: -1,
  200. Allow: true,
  201. },
  202. {
  203. AclType: "publishClientSend",
  204. Topic: "proxy/#",
  205. Priority: -1,
  206. Allow: true,
  207. },
  208. {
  209. AclType: "publishClientSend",
  210. Topic: "update/#",
  211. Priority: -1,
  212. Allow: true,
  213. },
  214. {
  215. AclType: "publishClientSend",
  216. Topic: "metrics_exporter",
  217. Priority: -1,
  218. Allow: true,
  219. },
  220. {
  221. AclType: "publishClientReceive",
  222. Topic: "ping/#",
  223. Priority: -1,
  224. Allow: true,
  225. },
  226. {
  227. AclType: "publishClientReceive",
  228. Topic: "update/#",
  229. Priority: -1,
  230. Allow: true,
  231. },
  232. {
  233. AclType: "publishClientReceive",
  234. Topic: "signal/#",
  235. Priority: -1,
  236. Allow: true,
  237. },
  238. {
  239. AclType: "publishClientReceive",
  240. Topic: "metrics/#",
  241. Priority: -1,
  242. Allow: true,
  243. },
  244. {
  245. AclType: "subscribePattern",
  246. Topic: "#",
  247. Priority: -1,
  248. Allow: true,
  249. },
  250. {
  251. AclType: "unsubscribePattern",
  252. Topic: "#",
  253. Priority: -1,
  254. Allow: true,
  255. },
  256. }
  257. }
  258. // fetchNodeAcls - fetches node related acls
  259. func fetchNodeAcls() []Acl {
  260. // keeping node acls generic as of now.
  261. return []Acl{
  262. {
  263. AclType: "publishClientSend",
  264. Topic: "signal/#",
  265. Priority: -1,
  266. Allow: true,
  267. },
  268. {
  269. AclType: "publishClientSend",
  270. Topic: "update/#",
  271. Priority: -1,
  272. Allow: true,
  273. },
  274. {
  275. AclType: "publishClientSend",
  276. Topic: "ping/#",
  277. Priority: -1,
  278. Allow: true,
  279. },
  280. {
  281. AclType: "publishClientSend",
  282. Topic: "metrics/#",
  283. Priority: -1,
  284. Allow: true,
  285. },
  286. {
  287. AclType: "subscribePattern",
  288. Topic: "#",
  289. Priority: -1,
  290. Allow: true,
  291. },
  292. {
  293. AclType: "unsubscribePattern",
  294. Topic: "#",
  295. Priority: -1,
  296. Allow: true,
  297. },
  298. }
  299. }
  300. // fetchExporterAcls - fetch exporter role related acls
  301. func fetchExporterAcls() []Acl {
  302. return []Acl{
  303. {
  304. AclType: "publishClientReceive",
  305. Topic: "metrics_exporter",
  306. Allow: true,
  307. Priority: -1,
  308. },
  309. {
  310. AclType: "subscribePattern",
  311. Topic: "#",
  312. Priority: -1,
  313. Allow: true,
  314. },
  315. {
  316. AclType: "unsubscribePattern",
  317. Topic: "#",
  318. Priority: -1,
  319. Allow: true,
  320. },
  321. }
  322. }
  323. // fetchAdminAcls - fetches admin role related acls
  324. func fetchAdminAcls() []Acl {
  325. return []Acl{
  326. {
  327. AclType: "publishClientSend",
  328. Topic: "$CONTROL/dynamic-security/#",
  329. Priority: -1,
  330. Allow: true,
  331. },
  332. {
  333. AclType: "publishClientReceive",
  334. Topic: "$CONTROL/dynamic-security/#",
  335. Priority: -1,
  336. Allow: true,
  337. },
  338. {
  339. AclType: "subscribePattern",
  340. Topic: "$CONTROL/dynamic-security/#",
  341. Priority: -1,
  342. Allow: true,
  343. },
  344. {
  345. AclType: "publishClientReceive",
  346. Topic: "$SYS/#",
  347. Priority: -1,
  348. Allow: true,
  349. },
  350. {
  351. AclType: "subscribePattern",
  352. Topic: "$SYS/#",
  353. Priority: -1,
  354. Allow: true,
  355. },
  356. {
  357. AclType: "publishClientReceive",
  358. Topic: "#",
  359. Priority: -1,
  360. Allow: true,
  361. },
  362. {
  363. AclType: "subscribePattern",
  364. Topic: "#",
  365. Priority: -1,
  366. Allow: true,
  367. },
  368. {
  369. AclType: "unsubscribePattern",
  370. Topic: "#",
  371. Priority: -1,
  372. Allow: true,
  373. },
  374. {
  375. AclType: "publishClientSend",
  376. Topic: "#",
  377. Priority: -1,
  378. Allow: true,
  379. },
  380. }
  381. }