grpc.go 9.7 KB

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