relay.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. package logic
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "net"
  7. "github.com/gravitl/netmaker/database"
  8. "github.com/gravitl/netmaker/logger"
  9. "github.com/gravitl/netmaker/logic/acls/nodeacls"
  10. "github.com/gravitl/netmaker/models"
  11. "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
  12. )
  13. // CreateRelay - creates a relay
  14. func CreateRelay(relay models.RelayRequest) ([]models.Client, models.Node, error) {
  15. var relayedClients []models.Client
  16. node, err := GetNodeByID(relay.NodeID)
  17. if err != nil {
  18. return relayedClients, models.Node{}, err
  19. }
  20. host, err := GetHost(node.HostID.String())
  21. if err != nil {
  22. return relayedClients, models.Node{}, err
  23. }
  24. if host.OS != "linux" {
  25. return relayedClients, models.Node{}, fmt.Errorf("only linux machines can be relay nodes")
  26. }
  27. err = ValidateRelay(relay)
  28. if err != nil {
  29. return relayedClients, models.Node{}, err
  30. }
  31. node.IsRelay = true
  32. node.RelayedNodes = relay.RelayedNodes
  33. node.SetLastModified()
  34. nodeData, err := json.Marshal(&node)
  35. if err != nil {
  36. return relayedClients, node, err
  37. }
  38. if err = database.Insert(node.ID.String(), string(nodeData), database.NODES_TABLE_NAME); err != nil {
  39. return relayedClients, models.Node{}, err
  40. }
  41. relayedClients = SetRelayedNodes(true, relay.NodeID, relay.RelayedNodes)
  42. for _, relayed := range relayedClients {
  43. data, err := json.Marshal(&relayed.Node)
  44. if err != nil {
  45. logger.Log(0, "marshalling relayed node", err.Error())
  46. continue
  47. }
  48. if err := database.Insert(relayed.Node.ID.String(), string(data), database.NODES_TABLE_NAME); err != nil {
  49. logger.Log(0, "inserting relayed node", err.Error())
  50. continue
  51. }
  52. }
  53. return relayedClients, node, nil
  54. }
  55. // SetRelayedNodes- sets and saves node as relayed
  56. func SetRelayedNodes(setRelayed bool, relay string, relayed []string) []models.Client {
  57. var returnnodes []models.Client
  58. for _, id := range relayed {
  59. node, err := GetNodeByID(id)
  60. if err != nil {
  61. logger.Log(0, "setRelayedNodes.GetNodebyID", err.Error())
  62. continue
  63. }
  64. node.IsRelayed = setRelayed
  65. if node.IsRelayed {
  66. node.RelayedBy = relay
  67. } else {
  68. node.RelayedBy = ""
  69. }
  70. node.SetLastModified()
  71. data, err := json.Marshal(&node)
  72. if err != nil {
  73. logger.Log(0, "setRelayedNodes.Marshal", err.Error())
  74. continue
  75. }
  76. if err := database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME); err != nil {
  77. logger.Log(0, "setRelayedNodes.Insert", err.Error())
  78. continue
  79. }
  80. host, err := GetHost(node.HostID.String())
  81. if err == nil {
  82. returnnodes = append(returnnodes, models.Client{
  83. Host: *host,
  84. Node: node,
  85. })
  86. }
  87. }
  88. return returnnodes
  89. }
  90. // ValidateRelay - checks if relay is valid
  91. func ValidateRelay(relay models.RelayRequest) error {
  92. var err error
  93. //isIp := functions.IsIpCIDR(gateway.RangeString)
  94. empty := len(relay.RelayedNodes) == 0
  95. if empty {
  96. err = errors.New("relayed nodes cannot be empty")
  97. }
  98. return err
  99. }
  100. // UpdateRelayed - updates relay nodes
  101. func UpdateRelayed(relay string, oldNodes []string, newNodes []string) []models.Client {
  102. _ = SetRelayedNodes(false, relay, oldNodes)
  103. return SetRelayedNodes(true, relay, newNodes)
  104. }
  105. // DeleteRelay - deletes a relay
  106. func DeleteRelay(network, nodeid string) ([]models.Client, models.Node, error) {
  107. var returnClients []models.Client
  108. node, err := GetNodeByID(nodeid)
  109. if err != nil {
  110. return returnClients, models.Node{}, err
  111. }
  112. returnClients = SetRelayedNodes(false, nodeid, node.RelayedNodes)
  113. node.IsRelay = false
  114. node.RelayedNodes = []string{}
  115. node.SetLastModified()
  116. data, err := json.Marshal(&node)
  117. if err != nil {
  118. return returnClients, models.Node{}, err
  119. }
  120. if err = database.Insert(nodeid, string(data), database.NODES_TABLE_NAME); err != nil {
  121. return returnClients, models.Node{}, err
  122. }
  123. return returnClients, node, nil
  124. }
  125. func getRelayedAddresses(id string) []net.IPNet {
  126. addrs := []net.IPNet{}
  127. node, err := GetNodeByID(id)
  128. if err != nil {
  129. logger.Log(0, "getRelayedAddresses: "+err.Error())
  130. return addrs
  131. }
  132. if node.Address.IP != nil {
  133. node.Address.Mask = net.CIDRMask(32, 32)
  134. addrs = append(addrs, node.Address)
  135. }
  136. if node.Address6.IP != nil {
  137. node.Address6.Mask = net.CIDRMask(128, 128)
  138. addrs = append(addrs, node.Address6)
  139. }
  140. return addrs
  141. }
  142. // peerUpdateForRelayed - returns the peerConfig for a relayed node
  143. func peerUpdateForRelayed(client *models.Client, peers []models.Client) []wgtypes.PeerConfig {
  144. peerConfig := []wgtypes.PeerConfig{}
  145. if !client.Node.IsRelayed {
  146. logger.Log(0, "GetPeerUpdateForRelayed called for non-relayed node ", client.Host.Name)
  147. return []wgtypes.PeerConfig{}
  148. }
  149. relayNode, err := GetNodeByID(client.Node.RelayedBy)
  150. if err != nil {
  151. logger.Log(0, "error retrieving relay node", err.Error())
  152. return []wgtypes.PeerConfig{}
  153. }
  154. host, err := GetHost(relayNode.HostID.String())
  155. if err != nil {
  156. return []wgtypes.PeerConfig{}
  157. }
  158. relay := models.Client{
  159. Host: *host,
  160. Node: relayNode,
  161. }
  162. for _, peer := range peers {
  163. if peer.Host.ID == client.Host.ID {
  164. continue
  165. }
  166. if peer.Host.ID == relay.Host.ID { // add relay as a peer
  167. update := peerUpdateForRelayedByRelay(client, &relay)
  168. peerConfig = append(peerConfig, update)
  169. continue
  170. }
  171. update := wgtypes.PeerConfig{
  172. PublicKey: peer.Host.PublicKey,
  173. Remove: true,
  174. }
  175. peerConfig = append(peerConfig, update)
  176. }
  177. return peerConfig
  178. }
  179. // peerUpdateForRelayedByRelay - returns the peerConfig for a node relayed by relay
  180. func peerUpdateForRelayedByRelay(relayed, relay *models.Client) wgtypes.PeerConfig {
  181. if relayed.Node.RelayedBy != relay.Node.ID.String() {
  182. logger.Log(0, "peerUpdateForRelayedByRelay called with invalid parameters")
  183. return wgtypes.PeerConfig{}
  184. }
  185. update := wgtypes.PeerConfig{
  186. PublicKey: relay.Host.PublicKey,
  187. ReplaceAllowedIPs: true,
  188. Endpoint: &net.UDPAddr{
  189. IP: relay.Host.EndpointIP,
  190. Port: relay.Host.ListenPort,
  191. },
  192. PersistentKeepaliveInterval: &relay.Node.PersistentKeepalive,
  193. }
  194. if relay.Node.Address.IP != nil {
  195. relay.Node.Address.Mask = net.CIDRMask(32, 32)
  196. update.AllowedIPs = append(update.AllowedIPs, relay.Node.Address)
  197. }
  198. if relay.Node.Address6.IP != nil {
  199. relay.Node.Address6.Mask = net.CIDRMask(128, 128)
  200. update.AllowedIPs = append(update.AllowedIPs, relay.Node.Address6)
  201. }
  202. if relay.Node.IsEgressGateway {
  203. update.AllowedIPs = append(update.AllowedIPs, getEgressIPs(relay)...)
  204. }
  205. if relay.Node.IsIngressGateway {
  206. update.AllowedIPs = append(update.AllowedIPs, getIngressIPs(relay)...)
  207. }
  208. peers, err := GetNetworkClients(relay.Node.Network)
  209. if err != nil {
  210. logger.Log(0, "error getting network clients", err.Error())
  211. return update
  212. }
  213. for _, peer := range peers {
  214. if peer.Host.ID == relayed.Host.ID || peer.Host.ID == relay.Host.ID {
  215. continue
  216. }
  217. if nodeacls.AreNodesAllowed(nodeacls.NetworkID(relayed.Node.Network), nodeacls.NodeID(relayed.Node.ID.String()), nodeacls.NodeID(peer.Node.ID.String())) {
  218. update.AllowedIPs = append(update.AllowedIPs, AddAllowedIPs(&peer)...)
  219. }
  220. }
  221. return update
  222. }
  223. // peerUpdateForRelay - returns the peerConfig for a relay
  224. func peerUpdateForRelay(relay *models.Client, peers []models.Client) []wgtypes.PeerConfig {
  225. peerConfig := []wgtypes.PeerConfig{}
  226. if !relay.Node.IsRelay {
  227. logger.Log(0, "GetPeerUpdateForRelay called for non-relay node ", relay.Host.Name)
  228. return []wgtypes.PeerConfig{}
  229. }
  230. for _, peer := range peers {
  231. if peer.Host.ID == relay.Host.ID {
  232. continue
  233. }
  234. update := wgtypes.PeerConfig{
  235. PublicKey: peer.Host.PublicKey,
  236. ReplaceAllowedIPs: true,
  237. Remove: false,
  238. Endpoint: &net.UDPAddr{
  239. IP: peer.Host.EndpointIP,
  240. Port: peer.Host.ListenPort,
  241. },
  242. PersistentKeepaliveInterval: &peer.Node.PersistentKeepalive,
  243. }
  244. if nodeacls.AreNodesAllowed(nodeacls.NetworkID(relay.Node.Network), nodeacls.NodeID(relay.Node.ID.String()), nodeacls.NodeID(peer.Node.ID.String())) {
  245. update.AllowedIPs = append(update.AllowedIPs, AddAllowedIPs(&peer)...)
  246. peerConfig = append(peerConfig, update)
  247. }
  248. }
  249. return peerConfig
  250. }