grpc.go 10 KB

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