grpc.go 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. package server
  2. import (
  3. "encoding/json"
  4. "log"
  5. "net"
  6. "strconv"
  7. "strings"
  8. "time"
  9. nodepb "github.com/gravitl/netmaker/grpc"
  10. "github.com/gravitl/netmaker/models"
  11. "github.com/gravitl/netmaker/netclient/auth"
  12. "github.com/gravitl/netmaker/netclient/netclientutils"
  13. "github.com/gravitl/netmaker/netclient/config"
  14. "github.com/gravitl/netmaker/netclient/local"
  15. "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
  16. "google.golang.org/grpc"
  17. "google.golang.org/grpc/metadata"
  18. )
  19. func getGrpcClient(cfg *config.ClientConfig) (nodepb.NodeServiceClient, error) {
  20. var wcclient nodepb.NodeServiceClient
  21. // == GRPC SETUP ==
  22. conn, err := grpc.Dial(cfg.Server.GRPCAddress,
  23. netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
  24. if err != nil {
  25. return nil, err
  26. }
  27. wcclient = nodepb.NewNodeServiceClient(conn)
  28. return wcclient, nil
  29. }
  30. func CheckIn(network string) (*models.Node, error) {
  31. cfg, err := config.ReadConfig(network)
  32. if err != nil {
  33. return nil, err
  34. }
  35. node := cfg.Node
  36. wcclient, err := getGrpcClient(cfg)
  37. if err != nil {
  38. return nil, err
  39. }
  40. // == run client action ==
  41. var header metadata.MD
  42. ctx, err := auth.SetJWT(wcclient, network)
  43. nodeData, err := json.Marshal(&node)
  44. if err != nil {
  45. return nil, err
  46. }
  47. response, err := wcclient.ReadNode(
  48. ctx,
  49. &nodepb.Object{
  50. Data: string(nodeData),
  51. Type: nodepb.NODE_TYPE,
  52. },
  53. grpc.Header(&header),
  54. )
  55. if err != nil {
  56. log.Printf("Encountered error checking in node: %v", err)
  57. }
  58. if err = json.Unmarshal([]byte(response.GetData()), &node); err != nil {
  59. return nil, err
  60. }
  61. return &node, err
  62. }
  63. func RemoveNetwork(network string) error {
  64. //need to implement checkin on server side
  65. cfg, err := config.ReadConfig(network)
  66. if err != nil {
  67. return err
  68. }
  69. servercfg := cfg.Server
  70. node := cfg.Node
  71. log.Println("Deleting remote node with MAC: " + node.MacAddress)
  72. var wcclient nodepb.NodeServiceClient
  73. conn, err := grpc.Dial(cfg.Server.GRPCAddress,
  74. netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
  75. if err != nil {
  76. log.Printf("Unable to establish client connection to "+servercfg.GRPCAddress+": %v", err)
  77. //return err
  78. } else {
  79. wcclient = nodepb.NewNodeServiceClient(conn)
  80. ctx, err := auth.SetJWT(wcclient, network)
  81. if err != nil {
  82. //return err
  83. log.Printf("Failed to authenticate: %v", err)
  84. } else {
  85. var header metadata.MD
  86. _, err = wcclient.DeleteNode(
  87. ctx,
  88. &nodepb.Object{
  89. Data: node.MacAddress + "###" + node.Network,
  90. Type: nodepb.STRING_TYPE,
  91. },
  92. grpc.Header(&header),
  93. )
  94. if err != nil {
  95. log.Printf("Encountered error deleting node: %v", err)
  96. log.Println(err)
  97. } else {
  98. log.Println("Deleted node " + node.MacAddress)
  99. }
  100. }
  101. }
  102. err = local.WipeLocal(network)
  103. if err != nil {
  104. log.Printf("Unable to wipe local config: %v", err)
  105. }
  106. if cfg.Daemon != "off" {
  107. err = local.RemoveSystemDServices(network)
  108. }
  109. return err
  110. }
  111. func GetPeers(macaddress string, network string, server string, dualstack bool, isIngressGateway bool) ([]wgtypes.PeerConfig, bool, []string, error) {
  112. //need to implement checkin on server side
  113. hasGateway := false
  114. var gateways []string
  115. var peers []wgtypes.PeerConfig
  116. var wcclient nodepb.NodeServiceClient
  117. cfg, err := config.ReadConfig(network)
  118. if err != nil {
  119. log.Fatalf("Issue retrieving config for network: "+network+". Please investigate: %v", err)
  120. }
  121. nodecfg := cfg.Node
  122. keepalive := nodecfg.PersistentKeepalive
  123. keepalivedur, err := time.ParseDuration(strconv.FormatInt(int64(keepalive), 10) + "s")
  124. keepaliveserver, err := time.ParseDuration(strconv.FormatInt(int64(5), 10) + "s")
  125. if err != nil {
  126. log.Fatalf("Issue with format of keepalive value. Please update netconfig: %v", err)
  127. }
  128. conn, err := grpc.Dial(cfg.Server.GRPCAddress,
  129. netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
  130. if err != nil {
  131. log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
  132. }
  133. // Instantiate the BlogServiceClient with our client connection to the server
  134. wcclient = nodepb.NewNodeServiceClient(conn)
  135. req := &nodepb.Object{
  136. Data: macaddress + "###" + network,
  137. Type: nodepb.STRING_TYPE,
  138. }
  139. ctx, err := auth.SetJWT(wcclient, network)
  140. if err != nil {
  141. log.Println("Failed to authenticate.")
  142. return peers, hasGateway, gateways, err
  143. }
  144. var header metadata.MD
  145. response, err := wcclient.GetPeers(ctx, req, grpc.Header(&header))
  146. if err != nil {
  147. log.Println("Error retrieving peers")
  148. log.Println(err)
  149. return nil, hasGateway, gateways, err
  150. }
  151. var nodes []models.Node
  152. if err := json.Unmarshal([]byte(response.GetData()), &nodes); err != nil {
  153. log.Println("Error unmarshaling data for peers")
  154. return nil, hasGateway, gateways, err
  155. }
  156. for _, node := range nodes {
  157. pubkey, err := wgtypes.ParseKey(node.PublicKey)
  158. if err != nil {
  159. log.Println("error parsing key")
  160. return peers, hasGateway, gateways, err
  161. }
  162. if nodecfg.PublicKey == node.PublicKey {
  163. continue
  164. }
  165. if nodecfg.Endpoint == node.Endpoint {
  166. if nodecfg.LocalAddress != node.LocalAddress && node.LocalAddress != "" {
  167. node.Endpoint = node.LocalAddress
  168. } else {
  169. continue
  170. }
  171. }
  172. var peer wgtypes.PeerConfig
  173. var peeraddr = net.IPNet{
  174. IP: net.ParseIP(node.Address),
  175. Mask: net.CIDRMask(32, 32),
  176. }
  177. var allowedips []net.IPNet
  178. allowedips = append(allowedips, peeraddr)
  179. // handle manually set peers
  180. for _, allowedIp := range node.AllowedIPs {
  181. if _, ipnet, err := net.ParseCIDR(allowedIp); err == nil {
  182. nodeEndpointArr := strings.Split(node.Endpoint, ":")
  183. if !ipnet.Contains(net.IP(nodeEndpointArr[0])) { // don't need to add an allowed ip that already exists..
  184. allowedips = append(allowedips, *ipnet)
  185. }
  186. }
  187. }
  188. // handle egress gateway peers
  189. if node.IsEgressGateway == "yes" {
  190. hasGateway = true
  191. ranges := node.EgressGatewayRanges
  192. for _, iprange := range ranges { // go through each cidr for egress gateway
  193. _, ipnet, err := net.ParseCIDR(iprange) // confirming it's valid cidr
  194. if err != nil {
  195. continue // if can't parse CIDR
  196. }
  197. nodeEndpointArr := strings.Split(node.Endpoint, ":") // getting the public ip of node
  198. if ipnet.Contains(net.IP(nodeEndpointArr[0])) { // ensuring egress gateway range does not contain public ip of node
  199. continue // skip adding egress range if overlaps with nodes ip
  200. }
  201. gateways = append(gateways, iprange)
  202. if err != nil {
  203. log.Println("ERROR ENCOUNTERED SETTING GATEWAY")
  204. } else {
  205. allowedips = append(allowedips, *ipnet)
  206. }
  207. }
  208. }
  209. if node.Address6 != "" && dualstack {
  210. var addr6 = net.IPNet{
  211. IP: net.ParseIP(node.Address6),
  212. Mask: net.CIDRMask(128, 128),
  213. }
  214. allowedips = append(allowedips, addr6)
  215. }
  216. if nodecfg.IsServer == "yes" {
  217. peer = wgtypes.PeerConfig{
  218. PublicKey: pubkey,
  219. PersistentKeepaliveInterval: &keepaliveserver,
  220. ReplaceAllowedIPs: true,
  221. AllowedIPs: allowedips,
  222. }
  223. } else if keepalive != 0 {
  224. peer = wgtypes.PeerConfig{
  225. PublicKey: pubkey,
  226. PersistentKeepaliveInterval: &keepalivedur,
  227. Endpoint: &net.UDPAddr{
  228. IP: net.ParseIP(node.Endpoint),
  229. Port: int(node.ListenPort),
  230. },
  231. ReplaceAllowedIPs: true,
  232. AllowedIPs: allowedips,
  233. }
  234. } else {
  235. peer = wgtypes.PeerConfig{
  236. PublicKey: pubkey,
  237. Endpoint: &net.UDPAddr{
  238. IP: net.ParseIP(node.Endpoint),
  239. Port: int(node.ListenPort),
  240. },
  241. ReplaceAllowedIPs: true,
  242. AllowedIPs: allowedips,
  243. }
  244. }
  245. peers = append(peers, peer)
  246. }
  247. if isIngressGateway {
  248. extPeers, err := GetExtPeers(macaddress, network, server, dualstack)
  249. if err == nil {
  250. peers = append(peers, extPeers...)
  251. } else {
  252. log.Println("ERROR RETRIEVING EXTERNAL PEERS",err)
  253. }
  254. }
  255. return peers, hasGateway, gateways, err
  256. }
  257. func GetExtPeers(macaddress string, network string, server string, dualstack bool) ([]wgtypes.PeerConfig, error) {
  258. var peers []wgtypes.PeerConfig
  259. var wcclient nodepb.NodeServiceClient
  260. cfg, err := config.ReadConfig(network)
  261. if err != nil {
  262. log.Fatalf("Issue retrieving config for network: "+network+". Please investigate: %v", err)
  263. }
  264. nodecfg := cfg.Node
  265. conn, err := grpc.Dial(cfg.Server.GRPCAddress,
  266. netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
  267. if err != nil {
  268. log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
  269. }
  270. // Instantiate the BlogServiceClient with our client connection to the server
  271. wcclient = nodepb.NewNodeServiceClient(conn)
  272. req := &nodepb.Object{
  273. Data: macaddress + "###" + network,
  274. Type: nodepb.STRING_TYPE,
  275. }
  276. ctx, err := auth.SetJWT(wcclient, network)
  277. if err != nil {
  278. log.Println("Failed to authenticate.")
  279. return peers, err
  280. }
  281. var header metadata.MD
  282. responseObject, err := wcclient.GetExtPeers(ctx, req, grpc.Header(&header))
  283. if err != nil {
  284. log.Println("Error retrieving peers")
  285. log.Println(err)
  286. return nil, err
  287. }
  288. var extPeers []models.Node
  289. if err = json.Unmarshal([]byte(responseObject.Data), &extPeers); err != nil {
  290. return nil, err
  291. }
  292. for _, extPeer := range extPeers {
  293. pubkey, err := wgtypes.ParseKey(extPeer.PublicKey)
  294. if err != nil {
  295. log.Println("error parsing key")
  296. return peers, err
  297. }
  298. if nodecfg.PublicKey == extPeer.PublicKey {
  299. continue
  300. }
  301. var peer wgtypes.PeerConfig
  302. var peeraddr = net.IPNet{
  303. IP: net.ParseIP(extPeer.Address),
  304. Mask: net.CIDRMask(32, 32),
  305. }
  306. var allowedips []net.IPNet
  307. allowedips = append(allowedips, peeraddr)
  308. if extPeer.Address6 != "" && dualstack {
  309. var addr6 = net.IPNet{
  310. IP: net.ParseIP(extPeer.Address6),
  311. Mask: net.CIDRMask(128, 128),
  312. }
  313. allowedips = append(allowedips, addr6)
  314. }
  315. peer = wgtypes.PeerConfig{
  316. PublicKey: pubkey,
  317. ReplaceAllowedIPs: true,
  318. AllowedIPs: allowedips,
  319. }
  320. peers = append(peers, peer)
  321. }
  322. return peers, err
  323. }