join.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. package functions
  2. import (
  3. "fmt"
  4. "errors"
  5. "context"
  6. "log"
  7. "net"
  8. "strconv"
  9. "github.com/gravitl/netmaker/netclient/config"
  10. "github.com/gravitl/netmaker/netclient/wireguard"
  11. "github.com/gravitl/netmaker/netclient/server"
  12. "github.com/gravitl/netmaker/netclient/local"
  13. nodepb "github.com/gravitl/netmaker/grpc"
  14. "golang.zx2c4.com/wireguard/wgctrl"
  15. "google.golang.org/grpc"
  16. "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
  17. //homedir "github.com/mitchellh/go-homedir"
  18. )
  19. func JoinNetwork(cfg config.ClientConfig) error {
  20. hasnet := local.HasNetwork(cfg.Network)
  21. if hasnet {
  22. err := errors.New("ALREADY_INSTALLED. Netclient appears to already be installed for cfg.Network " + cfg.Network + ". To re-install, please remove by executing 'sudo netclient -c remove -n " + cfg.Network + "'. Then re-run the install command.")
  23. return err
  24. }
  25. err := config.Write(&cfg, cfg.Network)
  26. if err != nil {
  27. return err
  28. }
  29. wgclient, err := wgctrl.New()
  30. if err != nil {
  31. return err
  32. }
  33. defer wgclient.Close()
  34. if cfg.Node.LocalRange != "" {
  35. if cfg.Node.LocalAddress == "" {
  36. ifaces, err := net.Interfaces()
  37. if err != nil {
  38. return err
  39. }
  40. _, localrange, err := net.ParseCIDR(cfg.Node.LocalRange)
  41. if err != nil {
  42. return err
  43. }
  44. var local string
  45. found := false
  46. for _, i := range ifaces {
  47. if i.Flags&net.FlagUp == 0 {
  48. continue // interface down
  49. }
  50. if i.Flags&net.FlagLoopback != 0 {
  51. continue // loopback interface
  52. }
  53. addrs, err := i.Addrs()
  54. if err != nil {
  55. return err
  56. }
  57. for _, addr := range addrs {
  58. var ip net.IP
  59. switch v := addr.(type) {
  60. case *net.IPNet:
  61. if !found {
  62. ip = v.IP
  63. local = ip.String()
  64. if cfg.Node.IsLocal == "yes" {
  65. found = localrange.Contains(ip)
  66. } else {
  67. found = true
  68. }
  69. }
  70. case *net.IPAddr:
  71. if !found {
  72. ip = v.IP
  73. local = ip.String()
  74. if cfg.Node.IsLocal == "yes" {
  75. found = localrange.Contains(ip)
  76. } else {
  77. found = true
  78. }
  79. }
  80. }
  81. }
  82. }
  83. cfg.Node.LocalAddress = local
  84. }
  85. }
  86. if cfg.Node.Endpoint == "" {
  87. if cfg.Node.IsLocal == "yes" && cfg.Node.LocalAddress != "" {
  88. cfg.Node.Endpoint = cfg.Node.LocalAddress
  89. } else {
  90. cfg.Node.Endpoint, err = getPublicIP()
  91. if err != nil {
  92. fmt.Println("Error setting cfg.Node.Endpoint.")
  93. return err
  94. }
  95. }
  96. } else {
  97. cfg.Node.Endpoint = cfg.Node.Endpoint
  98. fmt.Println("Endpoint set in config. Setting to address: " + cfg.Node.Endpoint)
  99. }
  100. if cfg.Node.PrivateKey == "" {
  101. privatekey, err := wgtypes.GeneratePrivateKey()
  102. if err != nil {
  103. log.Fatal(err)
  104. }
  105. cfg.Node.PrivateKey = privatekey.String()
  106. cfg.Node.PublicKey = privatekey.PublicKey().String()
  107. }
  108. if cfg.Node.MacAddress == "" {
  109. macs, err := getMacAddr()
  110. if err != nil {
  111. return err
  112. } else if len(macs) == 0 {
  113. log.Fatal()
  114. } else {
  115. cfg.Node.MacAddress = macs[0]
  116. }
  117. }
  118. var wcclient nodepb.NodeServiceClient
  119. var requestOpts grpc.DialOption
  120. requestOpts = grpc.WithInsecure()
  121. conn, err := grpc.Dial(cfg.Server.Address, requestOpts)
  122. if err != nil {
  123. log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
  124. }
  125. wcclient = nodepb.NewNodeServiceClient(conn)
  126. postnode := &nodepb.Node{
  127. Password: cfg.Node.Password,
  128. Macaddress: cfg.Node.MacAddress,
  129. Accesskey: cfg.Server.AccessKey,
  130. Nodenetwork: cfg.Network,
  131. Listenport: cfg.Node.Port,
  132. Postup: cfg.Node.PostUp,
  133. Postdown: cfg.Node.PostDown,
  134. Keepalive: cfg.Node.KeepAlive,
  135. Localaddress: cfg.Node.LocalAddress,
  136. Interface: cfg.Node.Interface,
  137. Publickey: cfg.Node.PublicKey,
  138. Name: cfg.Node.Name,
  139. Endpoint: cfg.Node.Endpoint,
  140. }
  141. err = config.ModConfig(postnode)
  142. if err != nil {
  143. return err
  144. }
  145. res, err := wcclient.CreateNode(
  146. context.TODO(),
  147. &nodepb.CreateNodeReq{
  148. Node: postnode,
  149. },
  150. )
  151. if err != nil {
  152. return err
  153. }
  154. node := res.Node
  155. if err != nil {
  156. return err
  157. }
  158. fmt.Println("Node Settings: ")
  159. fmt.Println(" Password: " + node.Password)
  160. fmt.Println(" WG Address: " + node.Address)
  161. fmt.Println(" WG ipv6 Address: " + node.Address6)
  162. fmt.Println(" Network: " + node.Nodenetwork)
  163. fmt.Println(" Public Endpoint: " + node.Endpoint)
  164. fmt.Println(" Local Address: " + node.Localaddress)
  165. fmt.Println(" Name: " + node.Name)
  166. fmt.Println(" Interface: " + node.Interface)
  167. fmt.Println(" PostUp: " + node.Postup)
  168. fmt.Println(" PostDown: " + node.Postdown)
  169. fmt.Println(" Port: " + strconv.FormatInt(int64(node.Listenport), 10))
  170. fmt.Println(" KeepAlive: " + strconv.FormatInt(int64(node.Keepalive), 10))
  171. fmt.Println(" Public Key: " + node.Publickey)
  172. fmt.Println(" Mac Address: " + node.Macaddress)
  173. fmt.Println(" Is Local?: " + strconv.FormatBool(node.Islocal))
  174. fmt.Println(" Is Dual Stack?: " + strconv.FormatBool(node.Isdualstack))
  175. fmt.Println(" Is Ingress Gateway?: " + strconv.FormatBool(node.Isingressgateway))
  176. fmt.Println(" Local Range: " + node.Localrange)
  177. if node.Dnsoff==true {
  178. cfg.Node.DNS = "yes"
  179. }
  180. if !(cfg.Node.IsLocal == "yes") && node.Islocal && node.Localrange != "" {
  181. node.Localaddress, err = getLocalIP(node.Localrange)
  182. if err != nil {
  183. return err
  184. }
  185. node.Endpoint = node.Localaddress
  186. }
  187. err = config.ModConfig(node)
  188. if err != nil {
  189. return err
  190. }
  191. if node.Ispending {
  192. fmt.Println("Node is marked as PENDING.")
  193. fmt.Println("Awaiting approval from Admin before configuring WireGuard.")
  194. if cfg.Daemon != "no" {
  195. fmt.Println("Configuring Netmaker Service.")
  196. err = local.ConfigureSystemD(cfg.Network)
  197. return err
  198. }
  199. }
  200. peers, hasGateway, gateways, err := server.GetPeers(node.Macaddress, cfg.Network, cfg.Server.Address, node.Isdualstack, node.Isingressgateway)
  201. if err != nil {
  202. return err
  203. }
  204. err = wireguard.StorePrivKey(cfg.Node.PrivateKey, cfg.Network)
  205. if err != nil {
  206. return err
  207. }
  208. err = wireguard.InitWireguard(node, cfg.Node.PrivateKey, peers, hasGateway, gateways)
  209. if err != nil {
  210. return err
  211. }
  212. if cfg.Daemon == "off" {
  213. err = local.ConfigureSystemD(cfg.Network)
  214. }
  215. if err != nil {
  216. return err
  217. }
  218. return err
  219. }