grpc.go 12 KB

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