checkin.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. package functions
  2. import (
  3. "google.golang.org/grpc/credentials"
  4. "crypto/tls"
  5. "context"
  6. "strings"
  7. "log"
  8. "net"
  9. "os/exec"
  10. "github.com/gravitl/netmaker/netclient/config"
  11. "github.com/gravitl/netmaker/netclient/local"
  12. "github.com/gravitl/netmaker/netclient/wireguard"
  13. "github.com/gravitl/netmaker/netclient/server"
  14. "github.com/gravitl/netmaker/netclient/auth"
  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 CheckIn(cliconf config.ClientConfig) error {
  21. network := cliconf.Network
  22. node := server.GetNode(network)
  23. cfg, err := config.ReadConfig(network)
  24. if err != nil {
  25. return err
  26. }
  27. nodecfg := cfg.Node
  28. servercfg := cfg.Server
  29. log.Println("Checking into server at " + servercfg.GRPCAddress)
  30. setupcheck := true
  31. ipchange := false
  32. if nodecfg.DNS == "on" || cliconf.Node.DNS == "on" {
  33. log.Println("setting dns")
  34. ifacename := node.Interface
  35. nameserver := servercfg.CoreDNSAddr
  36. network := node.Nodenetwork
  37. _ = local.UpdateDNS(ifacename, network, nameserver)
  38. }
  39. if !(nodecfg.IPForwarding == "off") {
  40. out, err := exec.Command("sysctl", "net.ipv4.ip_forward").Output()
  41. if err != nil {
  42. log.Println(err)
  43. log.Println("WARNING: Error encountered setting ip forwarding. This can break functionality.")
  44. } else {
  45. s := strings.Fields(string(out))
  46. if s[2] != "1" {
  47. _, err = exec.Command("sysctl", "-w", "net.ipv4.ip_forward=1").Output()
  48. if err != nil {
  49. log.Println(err)
  50. log.Println("WARNING: Error encountered setting ip forwarding. You may want to investigate this.")
  51. }
  52. }
  53. }
  54. }
  55. if nodecfg.Roaming != "off" {
  56. if nodecfg.IsLocal != "yes" {
  57. log.Println("Checking to see if public addresses have changed")
  58. extIP, err := getPublicIP()
  59. if err != nil {
  60. log.Println("Error encountered checking ip addresses: %v", err)
  61. }
  62. if nodecfg.Endpoint != extIP && extIP != "" {
  63. log.Println("Endpoint has changed from " +
  64. nodecfg.Endpoint + " to " + extIP)
  65. log.Println("Updating address")
  66. nodecfg.Endpoint = extIP
  67. nodecfg.PostChanges = "true"
  68. node.Endpoint = extIP
  69. node.Postchanges = "true"
  70. ipchange = true
  71. }
  72. intIP, err := getPrivateAddr()
  73. if err != nil {
  74. log.Println("Error encountered checking ip addresses: %v", err)
  75. }
  76. if nodecfg.LocalAddress != intIP && intIP != "" {
  77. log.Println("Local Address has changed from " +
  78. nodecfg.LocalAddress + " to " + intIP)
  79. log.Println("Updating address")
  80. nodecfg.LocalAddress = intIP
  81. nodecfg.PostChanges = "true"
  82. node.Localaddress = intIP
  83. node.Postchanges = "true"
  84. ipchange = true
  85. }
  86. } else {
  87. log.Println("Checking to see if local addresses have changed")
  88. localIP, err := getLocalIP(nodecfg.LocalRange)
  89. if err != nil {
  90. log.Println("Error encountered checking ip addresses: %v", err)
  91. }
  92. if nodecfg.Endpoint != localIP && localIP != "" {
  93. log.Println("Endpoint has changed from " +
  94. nodecfg.Endpoint + " to " + localIP)
  95. log.Println("Updating address")
  96. nodecfg.Endpoint = localIP
  97. nodecfg.LocalAddress = localIP
  98. nodecfg.PostChanges = "true"
  99. node.Endpoint = localIP
  100. node.Localaddress = localIP
  101. node.Postchanges = "true"
  102. ipchange = true
  103. }
  104. }
  105. if node.Postchanges != "true" {
  106. log.Println("Addresses have not changed.")
  107. }
  108. }
  109. if ipchange {
  110. err := config.ModConfig(&node)
  111. if err != nil {
  112. return err
  113. log.Fatalf("Error: %v", err)
  114. }
  115. err = wireguard.SetWGConfig(network, false)
  116. if err != nil {
  117. return err
  118. log.Fatalf("Error: %v", err)
  119. }
  120. node = server.GetNode(network)
  121. cfg, err := config.ReadConfig(network)
  122. if err != nil {
  123. return err
  124. }
  125. nodecfg = cfg.Node
  126. }
  127. var wcclient nodepb.NodeServiceClient
  128. var requestOpts grpc.DialOption
  129. requestOpts = grpc.WithInsecure()
  130. if servercfg.GRPCSSL == "on" {
  131. log.Println("using SSL")
  132. h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
  133. requestOpts = grpc.WithTransportCredentials(h2creds)
  134. } else {
  135. log.Println("using insecure GRPC connection")
  136. }
  137. conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
  138. if err != nil {
  139. log.Println("Cant dial GRPC server: %v", err)
  140. return err
  141. }
  142. wcclient = nodepb.NewNodeServiceClient(conn)
  143. ctx := context.Background()
  144. log.Println("Authenticating with GRPC Server")
  145. ctx, err = auth.SetJWT(wcclient, network)
  146. if err != nil {
  147. log.Println("Failed to authenticate: %v", err)
  148. return err
  149. }
  150. log.Println("Authenticated")
  151. log.Println("Checking In.")
  152. var header metadata.MD
  153. node.Nodenetwork = network
  154. checkinres, err := wcclient.CheckIn(
  155. ctx,
  156. &nodepb.CheckInReq{
  157. Node: &node,
  158. },
  159. grpc.Header(&header),
  160. )
  161. if err != nil {
  162. if checkinres != nil && checkinres.Checkinresponse.Ispending {
  163. log.Println("Node is in pending status. Waiting for Admin approval of node before making further updates.")
  164. return nil
  165. }
  166. log.Println("Unable to process Check In request: %v", err)
  167. return err
  168. }
  169. log.Println("Checked in.")
  170. if checkinres.Checkinresponse.Ispending {
  171. log.Println("Node is in pending status. Waiting for Admin approval of node before making further updates.")
  172. return err
  173. }
  174. newinterface := server.GetNode(network).Interface
  175. readreq := &nodepb.ReadNodeReq{
  176. Macaddress: node.Macaddress,
  177. Network: node.Nodenetwork,
  178. }
  179. readres, err := wcclient.ReadNode(ctx, readreq, grpc.Header(&header))
  180. if err != nil {
  181. log.Println("Error: %v", err)
  182. } else {
  183. currentiface := readres.Node.Interface
  184. ifaceupdate := newinterface != currentiface
  185. if err != nil {
  186. log.Println("Error retrieving interface: %v", err)
  187. }
  188. if ifaceupdate {
  189. log.Println("Interface update: " + currentiface +
  190. " >>>> " + newinterface)
  191. err := DeleteInterface(currentiface, nodecfg.PostDown)
  192. if err != nil {
  193. log.Println("ERROR DELETING INTERFACE: " + currentiface)
  194. }
  195. err = wireguard.SetWGConfig(network, false)
  196. if err != nil {
  197. log.Println("Error updating interface: %v", err)
  198. }
  199. }
  200. }
  201. if checkinres.Checkinresponse.Needconfigupdate {
  202. log.Println("Server has requested that node update config.")
  203. log.Println("Updating config from remote server.")
  204. req := &nodepb.ReadNodeReq{
  205. Macaddress: node.Macaddress,
  206. Network: node.Nodenetwork,
  207. }
  208. readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
  209. if err != nil {
  210. return err
  211. log.Fatalf("Error: %v", err)
  212. }
  213. err = config.ModConfig(readres.Node)
  214. if err != nil {
  215. return err
  216. log.Fatalf("Error: %v", err)
  217. }
  218. err = wireguard.SetWGConfig(network, false)
  219. if err != nil {
  220. return err
  221. log.Fatalf("Error: %v", err)
  222. }
  223. setupcheck = false
  224. } else if nodecfg.PostChanges == "true" {
  225. log.Println("Node has requested to update remote config.")
  226. log.Println("Posting local config to remote server.")
  227. postnode := server.GetNode(network)
  228. log.Println("POSTING NODE: ",postnode.Macaddress,postnode.Saveconfig)
  229. req := &nodepb.UpdateNodeReq{
  230. Node: &postnode,
  231. }
  232. res, err := wcclient.UpdateNode(ctx, req, grpc.Header(&header))
  233. if err != nil {
  234. return err
  235. log.Fatalf("Error: %v", err)
  236. }
  237. res.Node.Postchanges = "false"
  238. err = config.ModConfig(res.Node)
  239. if err != nil {
  240. return err
  241. log.Fatalf("Error: %v", err)
  242. }
  243. if err != nil {
  244. return err
  245. log.Fatalf("Error: %v", err)
  246. }
  247. setupcheck = false
  248. }
  249. if checkinres.Checkinresponse.Needkeyupdate {
  250. log.Println("Server has requested that node update key pairs.")
  251. log.Println("Proceeding to re-generate key pairs for Wiregard.")
  252. err = wireguard.SetWGKeyConfig(network, servercfg.GRPCAddress)
  253. if err != nil {
  254. return err
  255. log.Fatalf("Unable to process reset keys request: %v", err)
  256. }
  257. setupcheck = false
  258. }
  259. if checkinres.Checkinresponse.Needpeerupdate {
  260. log.Println("Server has requested that node update peer list.")
  261. log.Println("Updating peer list from remote server.")
  262. err = wireguard.SetWGConfig(network, true)
  263. if err != nil {
  264. return err
  265. log.Fatalf("Unable to process Set Peers request: %v", err)
  266. }
  267. setupcheck = false
  268. }
  269. if checkinres.Checkinresponse.Needdelete {
  270. log.Println("This machine got the delete signal. Deleting.")
  271. err := LeaveNetwork(network)
  272. if err != nil {
  273. return err
  274. log.Fatalf("Error: %v", err)
  275. }
  276. }
  277. if setupcheck {
  278. iface := nodecfg.Interface
  279. _, err := net.InterfaceByName(iface)
  280. if err != nil {
  281. log.Println("interface " + iface + " does not currently exist. Setting up WireGuard.")
  282. err = wireguard.SetWGKeyConfig(network, servercfg.GRPCAddress)
  283. if err != nil {
  284. return err
  285. log.Fatalf("Error: %v", err)
  286. }
  287. }
  288. }
  289. //err = Pull(network)
  290. return err
  291. }
  292. func Pull (network string) error{
  293. node := server.GetNode(network)
  294. cfg, err := config.ReadConfig(network)
  295. if err != nil {
  296. return err
  297. }
  298. servercfg := cfg.Server
  299. var header metadata.MD
  300. var wcclient nodepb.NodeServiceClient
  301. var requestOpts grpc.DialOption
  302. requestOpts = grpc.WithInsecure()
  303. if cfg.Server.GRPCSSL == "on" {
  304. h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
  305. requestOpts = grpc.WithTransportCredentials(h2creds)
  306. }
  307. conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
  308. if err != nil {
  309. log.Println("Cant dial GRPC server: %v", err)
  310. return err
  311. }
  312. wcclient = nodepb.NewNodeServiceClient(conn)
  313. ctx := context.Background()
  314. ctx, err = auth.SetJWT(wcclient, network)
  315. if err != nil {
  316. log.Println("Failed to authenticate: %v", err)
  317. return err
  318. }
  319. req := &nodepb.ReadNodeReq{
  320. Macaddress: node.Macaddress,
  321. Network: node.Nodenetwork,
  322. }
  323. readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
  324. if err != nil {
  325. return err
  326. }
  327. err = config.ModConfig(readres.Node)
  328. if err != nil {
  329. return err
  330. }
  331. err = wireguard.SetWGConfig(network, false)
  332. if err != nil {
  333. return err
  334. }
  335. return err
  336. }
  337. func Push (network string) error{
  338. postnode := server.GetNode(network)
  339. cfg, err := config.ReadConfig(network)
  340. if err != nil {
  341. return err
  342. }
  343. servercfg := cfg.Server
  344. var header metadata.MD
  345. var wcclient nodepb.NodeServiceClient
  346. var requestOpts grpc.DialOption
  347. requestOpts = grpc.WithInsecure()
  348. if cfg.Server.GRPCSSL == "on" {
  349. h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
  350. requestOpts = grpc.WithTransportCredentials(h2creds)
  351. }
  352. conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
  353. if err != nil {
  354. log.Println("Cant dial GRPC server: %v", err)
  355. return err
  356. }
  357. wcclient = nodepb.NewNodeServiceClient(conn)
  358. ctx := context.Background()
  359. ctx, err = auth.SetJWT(wcclient, network)
  360. if err != nil {
  361. log.Println("Failed to authenticate: %v", err)
  362. return err
  363. }
  364. req := &nodepb.UpdateNodeReq{
  365. Node: &postnode,
  366. }
  367. _, err = wcclient.UpdateNode(ctx, req, grpc.Header(&header))
  368. return err
  369. }