grpc.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  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. fmt.Println("Authenticating with GRPC Server")
  78. ctx, err = auth.SetJWT(wcclient, network)
  79. if err != nil {
  80. //return err
  81. log.Printf("Failed to authenticate: %v", err)
  82. } else {
  83. fmt.Println("Authenticated")
  84. var header metadata.MD
  85. _, err = wcclient.DeleteNode(
  86. ctx,
  87. &nodepb.DeleteNodeReq{
  88. Macaddress: node.MacAddress,
  89. NetworkName: node.Network,
  90. },
  91. grpc.Header(&header),
  92. )
  93. if err != nil {
  94. log.Printf("Encountered error deleting node: %v", err)
  95. fmt.Println(err)
  96. } else {
  97. fmt.Println("Deleted node " + node.MacAddress)
  98. }
  99. }
  100. }
  101. err = local.WipeLocal(network)
  102. if err != nil {
  103. log.Printf("Unable to wipe local config: %v", err)
  104. }
  105. err = local.RemoveSystemDServices(network)
  106. if err != nil {
  107. return err
  108. log.Printf("Unable to remove systemd services: %v", err)
  109. }
  110. fmt.Printf("Please investigate any stated errors to ensure proper removal.")
  111. fmt.Printf("Failure to delete node from server via gRPC will mean node still exists and needs to be manually deleted by administrator.")
  112. return nil
  113. }
  114. func GetPeers(macaddress string, network string, server string, dualstack bool, isIngressGateway bool) ([]wgtypes.PeerConfig, bool, []string, error) {
  115. //need to implement checkin on server side
  116. hasGateway := false
  117. var gateways []string
  118. var peers []wgtypes.PeerConfig
  119. var wcclient nodepb.NodeServiceClient
  120. cfg, err := config.ReadConfig(network)
  121. if err != nil {
  122. log.Fatalf("Issue retrieving config for network: " + network + ". Please investigate: %v", err)
  123. }
  124. nodecfg := cfg.Node
  125. keepalive := nodecfg.KeepAlive
  126. keepalivedur, err := time.ParseDuration(strconv.FormatInt(int64(keepalive), 10) + "s")
  127. if err != nil {
  128. log.Fatalf("Issue with format of keepalive value. Please update netconfig: %v", err)
  129. }
  130. requestOpts := grpc.WithInsecure()
  131. conn, err := grpc.Dial(server, requestOpts)
  132. if err != nil {
  133. log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
  134. }
  135. // Instantiate the BlogServiceClient with our client connection to the server
  136. wcclient = nodepb.NewNodeServiceClient(conn)
  137. req := &nodepb.GetPeersReq{
  138. Macaddress: macaddress,
  139. Network: network,
  140. }
  141. ctx := context.Background()
  142. ctx, err = auth.SetJWT(wcclient, network)
  143. if err != nil {
  144. fmt.Println("Failed to authenticate.")
  145. return peers, hasGateway, gateways, err
  146. }
  147. var header metadata.MD
  148. stream, err := wcclient.GetPeers(ctx, req, grpc.Header(&header))
  149. if err != nil {
  150. fmt.Println("Error retrieving peers")
  151. fmt.Println(err)
  152. return nil, hasGateway, gateways, err
  153. }
  154. for {
  155. res, err := stream.Recv()
  156. // If end of stream, break the loop
  157. if err == io.EOF {
  158. break
  159. }
  160. // if err, return an error
  161. if err != nil {
  162. if strings.Contains(err.Error(), "mongo: no documents in result") {
  163. continue
  164. } else {
  165. fmt.Println("ERROR ENCOUNTERED WITH RESPONSE")
  166. fmt.Println(res)
  167. return peers, hasGateway, gateways, err
  168. }
  169. }
  170. pubkey, err := wgtypes.ParseKey(res.Peers.Publickey)
  171. if err != nil {
  172. fmt.Println("error parsing key")
  173. return peers, hasGateway, gateways, err
  174. }
  175. if nodecfg.PublicKey == res.Peers.Publickey {
  176. continue
  177. }
  178. if nodecfg.Endpoint == res.Peers.Endpoint {
  179. continue
  180. }
  181. var peer wgtypes.PeerConfig
  182. var peeraddr = net.IPNet{
  183. IP: net.ParseIP(res.Peers.Address),
  184. Mask: net.CIDRMask(32, 32),
  185. }
  186. var allowedips []net.IPNet
  187. allowedips = append(allowedips, peeraddr)
  188. if res.Peers.Isegressgateway {
  189. hasGateway = true
  190. gateways = append(gateways,res.Peers.Egressgatewayrange)
  191. _, ipnet, err := net.ParseCIDR(res.Peers.Egressgatewayrange)
  192. if err != nil {
  193. fmt.Println("ERROR ENCOUNTERED SETTING GATEWAY")
  194. fmt.Println("NOT SETTING GATEWAY")
  195. fmt.Println(err)
  196. } else {
  197. fmt.Println(" Gateway Range: " + res.Peers.Egressgatewayrange)
  198. allowedips = append(allowedips, *ipnet)
  199. }
  200. }
  201. if res.Peers.Address6 != "" && dualstack {
  202. var addr6 = net.IPNet{
  203. IP: net.ParseIP(res.Peers.Address6),
  204. Mask: net.CIDRMask(128, 128),
  205. }
  206. allowedips = append(allowedips, addr6)
  207. }
  208. if keepalive != 0 {
  209. peer = wgtypes.PeerConfig{
  210. PublicKey: pubkey,
  211. PersistentKeepaliveInterval: &keepalivedur,
  212. Endpoint: &net.UDPAddr{
  213. IP: net.ParseIP(res.Peers.Endpoint),
  214. Port: int(res.Peers.Listenport),
  215. },
  216. ReplaceAllowedIPs: true,
  217. AllowedIPs: allowedips,
  218. }
  219. } else {
  220. peer = wgtypes.PeerConfig{
  221. PublicKey: pubkey,
  222. Endpoint: &net.UDPAddr{
  223. IP: net.ParseIP(res.Peers.Endpoint),
  224. Port: int(res.Peers.Listenport),
  225. },
  226. ReplaceAllowedIPs: true,
  227. AllowedIPs: allowedips,
  228. }
  229. }
  230. peers = append(peers, peer)
  231. }
  232. if isIngressGateway {
  233. extPeers, err := GetExtPeers(macaddress, network, server, dualstack)
  234. if err == nil {
  235. peers = append(peers, extPeers...)
  236. fmt.Println("Added " + strconv.Itoa(len(extPeers)) + " external clients.")
  237. } else {
  238. fmt.Println("ERROR RETRIEVING EXTERNAL PEERS")
  239. fmt.Println(err)
  240. }
  241. }
  242. return peers, hasGateway, gateways, err
  243. }
  244. func GetExtPeers(macaddress string, network string, server string, dualstack bool) ([]wgtypes.PeerConfig, error) {
  245. var peers []wgtypes.PeerConfig
  246. var wcclient nodepb.NodeServiceClient
  247. cfg, err := config.ReadConfig(network)
  248. if err != nil {
  249. log.Fatalf("Issue retrieving config for network: " + network + ". Please investigate: %v", err)
  250. }
  251. nodecfg := cfg.Node
  252. fmt.Println("Registering with GRPC Server")
  253. requestOpts := grpc.WithInsecure()
  254. conn, err := grpc.Dial(server, requestOpts)
  255. if err != nil {
  256. log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
  257. }
  258. // Instantiate the BlogServiceClient with our client connection to the server
  259. wcclient = nodepb.NewNodeServiceClient(conn)
  260. req := &nodepb.GetExtPeersReq{
  261. Macaddress: macaddress,
  262. Network: network,
  263. }
  264. ctx := context.Background()
  265. ctx, err = auth.SetJWT(wcclient, network)
  266. if err != nil {
  267. fmt.Println("Failed to authenticate.")
  268. return peers, err
  269. }
  270. var header metadata.MD
  271. stream, err := wcclient.GetExtPeers(ctx, req, grpc.Header(&header))
  272. if err != nil {
  273. fmt.Println("Error retrieving peers")
  274. fmt.Println(err)
  275. return nil, err
  276. }
  277. for {
  278. res, err := stream.Recv()
  279. // If end of stream, break the loop
  280. if err == io.EOF {
  281. break
  282. }
  283. // if err, return an error
  284. if err != nil {
  285. if strings.Contains(err.Error(), "mongo: no documents in result") {
  286. continue
  287. } else {
  288. fmt.Println("ERROR ENCOUNTERED WITH RESPONSE")
  289. fmt.Println(res)
  290. return peers, err
  291. }
  292. }
  293. pubkey, err := wgtypes.ParseKey(res.Extpeers.Publickey)
  294. if err != nil {
  295. fmt.Println("error parsing key")
  296. return peers, err
  297. }
  298. if nodecfg.PublicKey == res.Extpeers.Publickey {
  299. continue
  300. }
  301. var peer wgtypes.PeerConfig
  302. var peeraddr = net.IPNet{
  303. IP: net.ParseIP(res.Extpeers.Address),
  304. Mask: net.CIDRMask(32, 32),
  305. }
  306. var allowedips []net.IPNet
  307. allowedips = append(allowedips, peeraddr)
  308. if res.Extpeers.Address6 != "" && dualstack {
  309. var addr6 = net.IPNet{
  310. IP: net.ParseIP(res.Extpeers.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. }