common.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. package functions
  2. import (
  3. "errors"
  4. "fmt"
  5. "log"
  6. "net"
  7. "os"
  8. nodepb "github.com/gravitl/netmaker/grpc"
  9. "github.com/gravitl/netmaker/models"
  10. "github.com/gravitl/netmaker/netclient/auth"
  11. "github.com/gravitl/netmaker/netclient/config"
  12. "github.com/gravitl/netmaker/netclient/daemon"
  13. "github.com/gravitl/netmaker/netclient/ncutils"
  14. "github.com/gravitl/netmaker/netclient/wireguard"
  15. "golang.zx2c4.com/wireguard/wgctrl"
  16. "google.golang.org/grpc"
  17. "google.golang.org/grpc/metadata"
  18. )
  19. // ListPorts - lists ports of WireGuard devices
  20. func ListPorts() error {
  21. wgclient, err := wgctrl.New()
  22. if err != nil {
  23. return err
  24. }
  25. defer wgclient.Close()
  26. devices, err := wgclient.Devices()
  27. if err != nil {
  28. return err
  29. }
  30. fmt.Println("Here are your ports:")
  31. for _, i := range devices {
  32. fmt.Println(i.ListenPort)
  33. }
  34. return err
  35. }
  36. func getPrivateAddr() (string, error) {
  37. var local string
  38. conn, err := net.Dial("udp", "8.8.8.8:80")
  39. if err != nil {
  40. log.Fatal(err)
  41. }
  42. defer conn.Close()
  43. localAddr := conn.LocalAddr().(*net.UDPAddr)
  44. localIP := localAddr.IP
  45. local = localIP.String()
  46. if local == "" {
  47. local, err = getPrivateAddrBackup()
  48. }
  49. if local == "" {
  50. err = errors.New("could not find local ip")
  51. }
  52. return local, err
  53. }
  54. func getPrivateAddrBackup() (string, error) {
  55. ifaces, err := net.Interfaces()
  56. if err != nil {
  57. return "", err
  58. }
  59. var local string
  60. found := false
  61. for _, i := range ifaces {
  62. if i.Flags&net.FlagUp == 0 {
  63. continue // interface down
  64. }
  65. if i.Flags&net.FlagLoopback != 0 {
  66. continue // loopback interface
  67. }
  68. addrs, err := i.Addrs()
  69. if err != nil {
  70. return "", err
  71. }
  72. for _, addr := range addrs {
  73. var ip net.IP
  74. switch v := addr.(type) {
  75. case *net.IPNet:
  76. if !found {
  77. ip = v.IP
  78. local = ip.String()
  79. found = true
  80. }
  81. case *net.IPAddr:
  82. if !found {
  83. ip = v.IP
  84. local = ip.String()
  85. found = true
  86. }
  87. }
  88. }
  89. }
  90. if !found {
  91. err := errors.New("local ip address not found")
  92. return "", err
  93. }
  94. return local, err
  95. }
  96. // GetNode - gets node locally
  97. func GetNode(network string) models.Node {
  98. modcfg, err := config.ReadConfig(network)
  99. if err != nil {
  100. log.Fatalf("Error: %v", err)
  101. }
  102. return modcfg.Node
  103. }
  104. // Uninstall - uninstalls networks from client
  105. func Uninstall() error {
  106. networks, err := ncutils.GetSystemNetworks()
  107. if err != nil {
  108. ncutils.PrintLog("unable to retrieve networks: "+err.Error(), 1)
  109. ncutils.PrintLog("continuing uninstall without leaving networks", 1)
  110. } else {
  111. for _, network := range networks {
  112. err = LeaveNetwork(network)
  113. if err != nil {
  114. ncutils.PrintLog("Encounter issue leaving network "+network+": "+err.Error(), 1)
  115. }
  116. }
  117. }
  118. // clean up OS specific stuff
  119. if ncutils.IsWindows() {
  120. daemon.CleanupWindows()
  121. } else if ncutils.IsMac() {
  122. daemon.CleanupMac()
  123. } else if ncutils.IsLinux() {
  124. daemon.CleanupLinux()
  125. } else if !ncutils.IsKernel() {
  126. ncutils.PrintLog("manual cleanup required", 1)
  127. }
  128. return err
  129. }
  130. // LeaveNetwork - client exits a network
  131. func LeaveNetwork(network string) error {
  132. cfg, err := config.ReadConfig(network)
  133. if err != nil {
  134. return err
  135. }
  136. servercfg := cfg.Server
  137. node := cfg.Node
  138. if node.IsServer != "yes" {
  139. var wcclient nodepb.NodeServiceClient
  140. conn, err := grpc.Dial(cfg.Server.GRPCAddress,
  141. ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
  142. if err != nil {
  143. log.Printf("Unable to establish client connection to "+servercfg.GRPCAddress+": %v", err)
  144. }
  145. defer conn.Close()
  146. wcclient = nodepb.NewNodeServiceClient(conn)
  147. ctx, err := auth.SetJWT(wcclient, network)
  148. if err != nil {
  149. log.Printf("Failed to authenticate: %v", err)
  150. } else { // handle client side
  151. var header metadata.MD
  152. _, err = wcclient.DeleteNode(
  153. ctx,
  154. &nodepb.Object{
  155. Data: node.ID,
  156. Type: nodepb.STRING_TYPE,
  157. },
  158. grpc.Header(&header),
  159. )
  160. if err != nil {
  161. ncutils.PrintLog("encountered error deleting node: "+err.Error(), 1)
  162. } else {
  163. ncutils.PrintLog("removed machine from "+node.Network+" network on remote server", 1)
  164. }
  165. }
  166. }
  167. //extra network route setting required for freebsd and windows
  168. if ncutils.IsWindows() {
  169. ip, mask, err := ncutils.GetNetworkIPMask(node.NetworkSettings.AddressRange)
  170. if err != nil {
  171. ncutils.PrintLog(err.Error(), 1)
  172. }
  173. _, _ = ncutils.RunCmd("route delete "+ip+" mask "+mask+" "+node.Address, true)
  174. } else if ncutils.IsFreeBSD() {
  175. _, _ = ncutils.RunCmd("route del -net "+node.NetworkSettings.AddressRange+" -interface "+node.Interface, true)
  176. } else if ncutils.IsLinux() {
  177. _, _ = ncutils.RunCmd("ip -4 route del "+node.NetworkSettings.AddressRange+" dev "+node.Interface, false)
  178. }
  179. return RemoveLocalInstance(cfg, network)
  180. }
  181. // RemoveLocalInstance - remove all netclient files locally for a network
  182. func RemoveLocalInstance(cfg *config.ClientConfig, networkName string) error {
  183. err := WipeLocal(networkName)
  184. if err != nil {
  185. ncutils.PrintLog("unable to wipe local config", 1)
  186. } else {
  187. ncutils.PrintLog("removed "+networkName+" network locally", 1)
  188. }
  189. if cfg.Daemon != "off" {
  190. if ncutils.IsWindows() {
  191. // TODO: Remove job?
  192. } else if ncutils.IsMac() {
  193. //TODO: Delete mac daemon
  194. } else {
  195. err = daemon.RemoveSystemDServices()
  196. }
  197. }
  198. return err
  199. }
  200. // DeleteInterface - delete an interface of a network
  201. func DeleteInterface(ifacename string, postdown string) error {
  202. return wireguard.RemoveConf(ifacename, true)
  203. }
  204. // WipeLocal - wipes local instance
  205. func WipeLocal(network string) error {
  206. cfg, err := config.ReadConfig(network)
  207. if err != nil {
  208. return err
  209. }
  210. nodecfg := cfg.Node
  211. ifacename := nodecfg.Interface
  212. if ifacename != "" {
  213. if err = wireguard.RemoveConf(ifacename, true); err == nil {
  214. ncutils.PrintLog("removed WireGuard interface: "+ifacename, 1)
  215. }
  216. }
  217. home := ncutils.GetNetclientPathSpecific()
  218. if ncutils.FileExists(home + "netconfig-" + network) {
  219. _ = os.Remove(home + "netconfig-" + network)
  220. }
  221. if ncutils.FileExists(home + "backup.netconfig-" + network) {
  222. _ = os.Remove(home + "backup.netconfig-" + network)
  223. }
  224. if ncutils.FileExists(home + "nettoken-" + network) {
  225. _ = os.Remove(home + "nettoken-" + network)
  226. }
  227. if ncutils.FileExists(home + "secret-" + network) {
  228. _ = os.Remove(home + "secret-" + network)
  229. }
  230. if ncutils.FileExists(home + "wgkey-" + network) {
  231. _ = os.Remove(home + "wgkey-" + network)
  232. }
  233. if ncutils.FileExists(home + "nm-" + network + ".conf") {
  234. _ = os.Remove(home + "nm-" + network + ".conf")
  235. }
  236. return err
  237. }
  238. func getLocalIP(node models.Node) string {
  239. var local string
  240. ifaces, err := net.Interfaces()
  241. if err != nil {
  242. return local
  243. }
  244. _, localrange, err := net.ParseCIDR(node.LocalRange)
  245. if err != nil {
  246. return local
  247. }
  248. found := false
  249. for _, i := range ifaces {
  250. if i.Flags&net.FlagUp == 0 {
  251. continue // interface down
  252. }
  253. if i.Flags&net.FlagLoopback != 0 {
  254. continue // loopback interface
  255. }
  256. addrs, err := i.Addrs()
  257. if err != nil {
  258. return local
  259. }
  260. for _, addr := range addrs {
  261. var ip net.IP
  262. switch v := addr.(type) {
  263. case *net.IPNet:
  264. if !found {
  265. ip = v.IP
  266. local = ip.String()
  267. if node.IsLocal == "yes" {
  268. found = localrange.Contains(ip)
  269. } else {
  270. found = true
  271. }
  272. }
  273. case *net.IPAddr:
  274. if !found {
  275. ip = v.IP
  276. local = ip.String()
  277. if node.IsLocal == "yes" {
  278. found = localrange.Contains(ip)
  279. } else {
  280. found = true
  281. }
  282. }
  283. }
  284. }
  285. }
  286. return local
  287. }