grpc.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. package server
  2. import (
  3. "fmt"
  4. "context"
  5. "log"
  6. "strings"
  7. "strconv"
  8. "net"
  9. "time"
  10. "io"
  11. "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
  12. "github.com/gravitl/netmaker/netclient/config"
  13. "github.com/gravitl/netmaker/netclient/auth"
  14. "github.com/gravitl/netmaker/netclient/local"
  15. nodepb "github.com/gravitl/netmaker/grpc"
  16. "google.golang.org/grpc"
  17. "google.golang.org/grpc/metadata"
  18. //homedir "github.com/mitchellh/go-homedir"
  19. )
  20. func GetNode(network string) nodepb.Node {
  21. modcfg, err := config.ReadConfig(network)
  22. if err != nil {
  23. log.Fatalf("Error: %v", err)
  24. }
  25. nodecfg := modcfg.Node
  26. var node nodepb.Node
  27. node.Name = nodecfg.Name
  28. node.Interface = nodecfg.Interface
  29. node.Nodenetwork = nodecfg.Network
  30. node.Localaddress = nodecfg.LocalAddress
  31. node.Address = nodecfg.WGAddress
  32. node.Address6 = nodecfg.WGAddress6
  33. node.Listenport = nodecfg.Port
  34. node.Keepalive = nodecfg.KeepAlive
  35. node.Postup = nodecfg.PostUp
  36. node.Postdown = nodecfg.PostDown
  37. node.Publickey = nodecfg.PublicKey
  38. node.Macaddress = nodecfg.MacAddress
  39. node.Endpoint = nodecfg.Endpoint
  40. node.Password = nodecfg.Password
  41. if nodecfg.DNS == "on" {
  42. node.Dnsoff = false
  43. } else {
  44. node.Dnsoff = true
  45. }
  46. if nodecfg.IsDualStack == "yes" {
  47. node.Isdualstack = true
  48. } else {
  49. node.Isdualstack = false
  50. }
  51. if nodecfg.IsIngressGateway == "yes" {
  52. node.Isingressgateway= true
  53. } else {
  54. node.Isingressgateway = false
  55. }
  56. return node
  57. }
  58. func RemoveNetwork(network string) error {
  59. //need to implement checkin on server side
  60. cfg, err := config.ReadConfig(network)
  61. if err != nil {
  62. return err
  63. }
  64. servercfg := cfg.Server
  65. node := cfg.Node
  66. fmt.Println("Deleting remote node with MAC: " + node.MacAddress)
  67. var wcclient nodepb.NodeServiceClient
  68. var requestOpts grpc.DialOption
  69. requestOpts = grpc.WithInsecure()
  70. conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
  71. if err != nil {
  72. log.Printf("Unable to establish client connection to " + servercfg.GRPCAddress + ": %v", err)
  73. //return err
  74. }else {
  75. wcclient = nodepb.NewNodeServiceClient(conn)
  76. ctx := context.Background()
  77. ctx, err = auth.SetJWT(wcclient, network)
  78. if err != nil {
  79. //return err
  80. log.Printf("Failed to authenticate: %v", err)
  81. } else {
  82. var header metadata.MD
  83. _, err = wcclient.DeleteNode(
  84. ctx,
  85. &nodepb.DeleteNodeReq{
  86. Macaddress: node.MacAddress,
  87. NetworkName: node.Network,
  88. },
  89. grpc.Header(&header),
  90. )
  91. if err != nil {
  92. log.Printf("Encountered error deleting node: %v", err)
  93. fmt.Println(err)
  94. } else {
  95. fmt.Println("Deleted node " + node.MacAddress)
  96. }
  97. }
  98. }
  99. err = local.WipeLocal(network)
  100. if err != nil {
  101. log.Printf("Unable to wipe local config: %v", err)
  102. }
  103. if cfg.Daemon != "off" {
  104. err = local.RemoveSystemDServices(network)
  105. }
  106. return err
  107. }
  108. func GetPeers(macaddress string, network string, server string, dualstack bool, isIngressGateway bool) ([]wgtypes.PeerConfig, bool, []string, error) {
  109. //need to implement checkin on server side
  110. hasGateway := false
  111. var gateways []string
  112. var peers []wgtypes.PeerConfig
  113. var wcclient nodepb.NodeServiceClient
  114. cfg, err := config.ReadConfig(network)
  115. if err != nil {
  116. log.Fatalf("Issue retrieving config for network: " + network + ". Please investigate: %v", err)
  117. }
  118. nodecfg := cfg.Node
  119. keepalive := nodecfg.KeepAlive
  120. keepalivedur, err := time.ParseDuration(strconv.FormatInt(int64(keepalive), 10) + "s")
  121. if err != nil {
  122. log.Fatalf("Issue with format of keepalive value. Please update netconfig: %v", err)
  123. }
  124. requestOpts := grpc.WithInsecure()
  125. conn, err := grpc.Dial(server, requestOpts)
  126. if err != nil {
  127. log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
  128. }
  129. // Instantiate the BlogServiceClient with our client connection to the server
  130. wcclient = nodepb.NewNodeServiceClient(conn)
  131. req := &nodepb.GetPeersReq{
  132. Macaddress: macaddress,
  133. Network: network,
  134. }
  135. ctx := context.Background()
  136. ctx, err = auth.SetJWT(wcclient, network)
  137. if err != nil {
  138. fmt.Println("Failed to authenticate.")
  139. return peers, hasGateway, gateways, err
  140. }
  141. var header metadata.MD
  142. stream, err := wcclient.GetPeers(ctx, req, grpc.Header(&header))
  143. if err != nil {
  144. fmt.Println("Error retrieving peers")
  145. fmt.Println(err)
  146. return nil, hasGateway, gateways, err
  147. }
  148. for {
  149. res, err := stream.Recv()
  150. // If end of stream, break the loop
  151. if err == io.EOF {
  152. break
  153. }
  154. // if err, return an error
  155. if err != nil {
  156. if strings.Contains(err.Error(), "mongo: no documents in result") {
  157. continue
  158. } else {
  159. fmt.Println("ERROR ENCOUNTERED WITH RESPONSE")
  160. fmt.Println(res)
  161. return peers, hasGateway, gateways, err
  162. }
  163. }
  164. pubkey, err := wgtypes.ParseKey(res.Peers.Publickey)
  165. if err != nil {
  166. fmt.Println("error parsing key")
  167. return peers, hasGateway, gateways, err
  168. }
  169. if nodecfg.PublicKey == res.Peers.Publickey {
  170. continue
  171. }
  172. if nodecfg.Endpoint == res.Peers.Endpoint {
  173. continue
  174. }
  175. var peer wgtypes.PeerConfig
  176. var peeraddr = net.IPNet{
  177. IP: net.ParseIP(res.Peers.Address),
  178. Mask: net.CIDRMask(32, 32),
  179. }
  180. var allowedips []net.IPNet
  181. allowedips = append(allowedips, peeraddr)
  182. if res.Peers.Isegressgateway {
  183. hasGateway = true
  184. gateways = append(gateways,res.Peers.Egressgatewayrange)
  185. _, ipnet, err := net.ParseCIDR(res.Peers.Egressgatewayrange)
  186. if err != nil {
  187. fmt.Println("ERROR ENCOUNTERED SETTING GATEWAY")
  188. fmt.Println("NOT SETTING GATEWAY")
  189. fmt.Println(err)
  190. } else {
  191. fmt.Println(" Gateway Range: " + res.Peers.Egressgatewayrange)
  192. allowedips = append(allowedips, *ipnet)
  193. }
  194. }
  195. if res.Peers.Address6 != "" && dualstack {
  196. var addr6 = net.IPNet{
  197. IP: net.ParseIP(res.Peers.Address6),
  198. Mask: net.CIDRMask(128, 128),
  199. }
  200. allowedips = append(allowedips, addr6)
  201. }
  202. if keepalive != 0 {
  203. peer = wgtypes.PeerConfig{
  204. PublicKey: pubkey,
  205. PersistentKeepaliveInterval: &keepalivedur,
  206. Endpoint: &net.UDPAddr{
  207. IP: net.ParseIP(res.Peers.Endpoint),
  208. Port: int(res.Peers.Listenport),
  209. },
  210. ReplaceAllowedIPs: true,
  211. AllowedIPs: allowedips,
  212. }
  213. } else {
  214. peer = wgtypes.PeerConfig{
  215. PublicKey: pubkey,
  216. Endpoint: &net.UDPAddr{
  217. IP: net.ParseIP(res.Peers.Endpoint),
  218. Port: int(res.Peers.Listenport),
  219. },
  220. ReplaceAllowedIPs: true,
  221. AllowedIPs: allowedips,
  222. }
  223. }
  224. peers = append(peers, peer)
  225. }
  226. if isIngressGateway {
  227. extPeers, err := GetExtPeers(macaddress, network, server, dualstack)
  228. if err == nil {
  229. peers = append(peers, extPeers...)
  230. } else {
  231. fmt.Println("ERROR RETRIEVING EXTERNAL PEERS")
  232. fmt.Println(err)
  233. }
  234. }
  235. return peers, hasGateway, gateways, err
  236. }
  237. func GetExtPeers(macaddress string, network string, server string, dualstack bool) ([]wgtypes.PeerConfig, error) {
  238. var peers []wgtypes.PeerConfig
  239. var wcclient nodepb.NodeServiceClient
  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. requestOpts := grpc.WithInsecure()
  246. conn, err := grpc.Dial(server, requestOpts)
  247. if err != nil {
  248. log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
  249. }
  250. // Instantiate the BlogServiceClient with our client connection to the server
  251. wcclient = nodepb.NewNodeServiceClient(conn)
  252. req := &nodepb.GetExtPeersReq{
  253. Macaddress: macaddress,
  254. Network: network,
  255. }
  256. ctx := context.Background()
  257. ctx, err = auth.SetJWT(wcclient, network)
  258. if err != nil {
  259. fmt.Println("Failed to authenticate.")
  260. return peers, err
  261. }
  262. var header metadata.MD
  263. stream, err := wcclient.GetExtPeers(ctx, req, grpc.Header(&header))
  264. if err != nil {
  265. fmt.Println("Error retrieving peers")
  266. fmt.Println(err)
  267. return nil, err
  268. }
  269. for {
  270. res, err := stream.Recv()
  271. // If end of stream, break the loop
  272. if err == io.EOF {
  273. break
  274. }
  275. // if err, return an error
  276. if err != nil {
  277. if strings.Contains(err.Error(), "mongo: no documents in result") {
  278. continue
  279. } else {
  280. fmt.Println("ERROR ENCOUNTERED WITH RESPONSE")
  281. fmt.Println(res)
  282. return peers, err
  283. }
  284. }
  285. pubkey, err := wgtypes.ParseKey(res.Extpeers.Publickey)
  286. if err != nil {
  287. fmt.Println("error parsing key")
  288. return peers, err
  289. }
  290. if nodecfg.PublicKey == res.Extpeers.Publickey {
  291. continue
  292. }
  293. var peer wgtypes.PeerConfig
  294. var peeraddr = net.IPNet{
  295. IP: net.ParseIP(res.Extpeers.Address),
  296. Mask: net.CIDRMask(32, 32),
  297. }
  298. var allowedips []net.IPNet
  299. allowedips = append(allowedips, peeraddr)
  300. if res.Extpeers.Address6 != "" && dualstack {
  301. var addr6 = net.IPNet{
  302. IP: net.ParseIP(res.Extpeers.Address6),
  303. Mask: net.CIDRMask(128, 128),
  304. }
  305. allowedips = append(allowedips, addr6)
  306. }
  307. peer = wgtypes.PeerConfig{
  308. PublicKey: pubkey,
  309. ReplaceAllowedIPs: true,
  310. AllowedIPs: allowedips,
  311. }
  312. peers = append(peers, peer)
  313. }
  314. return peers, err
  315. }