common.go 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453
  1. package functions
  2. import (
  3. "fmt"
  4. "errors"
  5. "context"
  6. "net/http"
  7. "io/ioutil"
  8. "strings"
  9. "log"
  10. "net"
  11. "os"
  12. "strconv"
  13. "os/exec"
  14. "github.com/gravitl/netmaker/netclient/config"
  15. nodepb "github.com/gravitl/netmaker/grpc"
  16. "golang.zx2c4.com/wireguard/wgctrl"
  17. "google.golang.org/grpc"
  18. "encoding/base64"
  19. "google.golang.org/grpc/metadata"
  20. "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
  21. //homedir "github.com/mitchellh/go-homedir"
  22. )
  23. var (
  24. wcclient nodepb.NodeServiceClient
  25. )
  26. func ListPorts() error{
  27. wgclient, err := wgctrl.New()
  28. if err != nil {
  29. return err
  30. }
  31. devices, err := wgclient.Devices()
  32. if err != nil {
  33. return err
  34. }
  35. fmt.Println("Here are your ports:")
  36. for _, i := range devices {
  37. fmt.Println(i.ListenPort)
  38. }
  39. return err
  40. }
  41. func GetFreePort(rangestart int32) (int32, error){
  42. wgclient, err := wgctrl.New()
  43. if err != nil {
  44. return 0, err
  45. }
  46. devices, err := wgclient.Devices()
  47. if err != nil {
  48. return 0, err
  49. }
  50. var portno int32
  51. portno = 0
  52. for x := rangestart; x <= 60000; x++ {
  53. conflict := false
  54. for _, i := range devices {
  55. if int32(i.ListenPort) == x {
  56. conflict = true
  57. break;
  58. }
  59. }
  60. if conflict {
  61. continue
  62. }
  63. portno = x
  64. break
  65. }
  66. return portno, err
  67. }
  68. func Install(accesskey string, password string, server string, network string, noauto bool, accesstoken string, inputname string, pubip string, dnsoff bool, ipforward string) error {
  69. tserver := ""
  70. tnetwork := ""
  71. tkey := ""
  72. trange := ""
  73. var localrange *net.IPNet
  74. islocal := false
  75. if FileExists("/etc/systemd/system/netclient-"+network+".timer") ||
  76. FileExists("/etc/netclient/netconfig-"+network) {
  77. err := errors.New("ALREADY_INSTALLED. Netclient appears to already be installed for network " + network + ". To re-install, please remove by executing 'sudo netclient -c remove -n " + network + "'. Then re-run the install command.")
  78. return err
  79. }
  80. if accesstoken != "" && accesstoken != "badtoken" {
  81. btoken, err := base64.StdEncoding.DecodeString(accesstoken)
  82. if err != nil {
  83. log.Fatalf("Something went wrong decoding your token: %v", err)
  84. }
  85. token := string(btoken)
  86. tokenvals := strings.Split(token, "|")
  87. tserver = tokenvals[0]
  88. tnetwork = tokenvals[1]
  89. tkey = tokenvals[2]
  90. trange = tokenvals[3]
  91. printrange := ""
  92. if server == "localhost:50051" {
  93. server = tserver
  94. }
  95. if network == "nonetwork" {
  96. network = tnetwork
  97. }
  98. if accesskey == "badkey" {
  99. accesskey = tkey
  100. }
  101. fmt.Println(trange)
  102. if trange != "" {
  103. fmt.Println("This is a local network. Proceeding with local address as endpoint.")
  104. islocal = true
  105. _, localrange, err = net.ParseCIDR(trange)
  106. if err == nil {
  107. printrange = localrange.String()
  108. } else {
  109. //localrange = ""
  110. }
  111. } else {
  112. printrange = "Not a local network. Will use public address for endpoint."
  113. }
  114. fmt.Println("Decoded values from token:")
  115. fmt.Println(" Server: " + server)
  116. fmt.Println(" Network: " + network)
  117. fmt.Println(" Key: " + accesskey)
  118. fmt.Println(" Local Range: " + printrange)
  119. }
  120. wgclient, err := wgctrl.New()
  121. if err != nil {
  122. log.Fatalf("failed to open client: %v", err)
  123. }
  124. defer wgclient.Close()
  125. cfg, err := config.ReadConfig(network)
  126. if err != nil {
  127. log.Printf("No Config Yet. Will Write: %v", err)
  128. }
  129. nodecfg := cfg.Node
  130. servercfg := cfg.Server
  131. fmt.Println("SERVER SETTINGS:")
  132. nodecfg.DNSOff = dnsoff
  133. nodecfg.IPForwarding = ipforward
  134. if server == "" {
  135. if servercfg.Address == "" && tserver == "" {
  136. log.Fatal("no server provided")
  137. } else {
  138. server = servercfg.Address
  139. }
  140. }
  141. fmt.Println(" Server: " + server)
  142. if accesskey == "" {
  143. if servercfg.AccessKey == "" && tkey == "" {
  144. fmt.Println("no access key provided.Proceeding anyway.")
  145. } else {
  146. accesskey = servercfg.AccessKey
  147. }
  148. }
  149. fmt.Println(" AccessKey: " + accesskey)
  150. err = config.WriteServer(server, accesskey, network)
  151. if err != nil {
  152. fmt.Println("Error encountered while writing Server Config.")
  153. return err
  154. }
  155. fmt.Println("NODE REQUESTING SETTINGS:")
  156. if password == "" {
  157. if nodecfg.Password == "" {
  158. //create error here
  159. log.Fatal("no password provided")
  160. } else {
  161. password = nodecfg.Password
  162. }
  163. }
  164. fmt.Println(" Password: " + password)
  165. if network == "badnetwork" {
  166. if nodecfg.Network == "" && tnetwork == "" {
  167. //create error here
  168. log.Fatal("no network provided")
  169. } else {
  170. network = nodecfg.Network
  171. }
  172. }
  173. fmt.Println(" Network: " + network)
  174. var macaddress string
  175. var localaddress string
  176. var listenport int32
  177. var keepalive int32
  178. var publickey wgtypes.Key
  179. var privatekey wgtypes.Key
  180. var privkeystring string
  181. var endpoint string
  182. var postup string
  183. var postdown string
  184. var name string
  185. var wginterface string
  186. if nodecfg.LocalAddress == "" {
  187. ifaces, err := net.Interfaces()
  188. if err != nil {
  189. return err
  190. }
  191. var local string
  192. found := false
  193. for _, i := range ifaces {
  194. if i.Flags&net.FlagUp == 0 {
  195. continue // interface down
  196. }
  197. if i.Flags&net.FlagLoopback != 0 {
  198. continue // loopback interface
  199. }
  200. addrs, err := i.Addrs()
  201. if err != nil {
  202. return err
  203. }
  204. for _, addr := range addrs {
  205. var ip net.IP
  206. switch v := addr.(type) {
  207. case *net.IPNet:
  208. if !found {
  209. ip = v.IP
  210. local = ip.String()
  211. if islocal {
  212. found = localrange.Contains(ip)
  213. } else {
  214. found = true
  215. }
  216. }
  217. case *net.IPAddr:
  218. if !found {
  219. ip = v.IP
  220. local = ip.String()
  221. if islocal {
  222. found = localrange.Contains(ip)
  223. } else {
  224. found = true
  225. }
  226. }
  227. }
  228. }
  229. }
  230. localaddress = local
  231. } else {
  232. localaddress = nodecfg.LocalAddress
  233. }
  234. fmt.Println(" Local Address: " + localaddress)
  235. if pubip != "" && pubip != "nopubip" {
  236. endpoint = pubip
  237. } else {
  238. if nodecfg.Endpoint == "" {
  239. if islocal && localaddress != "" {
  240. endpoint = localaddress
  241. fmt.Println("Endpoint is local. Setting to address: " + endpoint)
  242. } else {
  243. endpoint, err = getPublicIP()
  244. if err != nil {
  245. fmt.Println("Error setting endpoint.")
  246. return err
  247. }
  248. fmt.Println("Endpoint is public. Setting to address: " + endpoint)
  249. }
  250. } else {
  251. endpoint = nodecfg.Endpoint
  252. fmt.Println("Endpoint set in config. Setting to address: " + endpoint)
  253. }
  254. }
  255. fmt.Println(" Endpoint: " + endpoint)
  256. if nodecfg.Name != "" {
  257. name = nodecfg.Name
  258. }
  259. if inputname != "" && inputname != "noname" {
  260. name = inputname
  261. }
  262. fmt.Println(" Name: " + name)
  263. if nodecfg.Interface != "" {
  264. wginterface = nodecfg.Interface
  265. }
  266. fmt.Println(" Interface: " + wginterface)
  267. if nodecfg.PostUp != "" {
  268. postup = nodecfg.PostUp
  269. }
  270. fmt.Println(" PostUp: " + postup)
  271. if nodecfg.PostDown!= "" {
  272. postdown = nodecfg.PostDown
  273. }
  274. fmt.Println(" PostDown: " + postdown)
  275. if nodecfg.KeepAlive != 0 {
  276. keepalive = nodecfg.KeepAlive
  277. }
  278. fmt.Println(" KeepAlive: " + wginterface)
  279. if nodecfg.Port != 0 {
  280. listenport = nodecfg.Port
  281. }
  282. if listenport == 0 {
  283. listenport, err = GetFreePort(51821)
  284. if err != nil {
  285. fmt.Printf("Error retrieving port: %v", err)
  286. }
  287. }
  288. fmt.Printf(" Port: %v", listenport)
  289. fmt.Println("")
  290. if nodecfg.PrivateKey != "" {
  291. privkeystring = nodecfg.PrivateKey
  292. privatekey, err := wgtypes.ParseKey(nodecfg.PrivateKey)
  293. if err != nil {
  294. log.Fatal(err)
  295. }
  296. if nodecfg.PublicKey != "" {
  297. publickey, err = wgtypes.ParseKey(nodecfg.PublicKey)
  298. if err != nil {
  299. log.Fatal(err)
  300. }
  301. } else {
  302. publickey = privatekey.PublicKey()
  303. }
  304. } else {
  305. privatekey, err := wgtypes.GeneratePrivateKey()
  306. if err != nil {
  307. log.Fatal(err)
  308. }
  309. privkeystring = privatekey.String()
  310. publickey = privatekey.PublicKey()
  311. }
  312. if nodecfg.MacAddress != "" {
  313. macaddress = nodecfg.MacAddress
  314. } else {
  315. macs, err := getMacAddr()
  316. if err != nil {
  317. return err
  318. } else if len(macs) == 0 {
  319. log.Fatal()
  320. } else {
  321. macaddress = macs[0]
  322. }
  323. }
  324. fmt.Println(" Mac Address: " + macaddress)
  325. fmt.Println(" Private Key: " + privatekey.String())
  326. fmt.Println(" Public Key: " + publickey.String())
  327. var wcclient nodepb.NodeServiceClient
  328. var requestOpts grpc.DialOption
  329. requestOpts = grpc.WithInsecure()
  330. conn, err := grpc.Dial(server, requestOpts)
  331. if err != nil {
  332. log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
  333. }
  334. wcclient = nodepb.NewNodeServiceClient(conn)
  335. postnode := &nodepb.Node{
  336. Password: password,
  337. Macaddress: macaddress,
  338. Accesskey: accesskey,
  339. Nodenetwork: network,
  340. Listenport: listenport,
  341. Postup: postup,
  342. Postdown: postdown,
  343. Keepalive: keepalive,
  344. Localaddress: localaddress,
  345. Interface: wginterface,
  346. Publickey: publickey.String(),
  347. Name: name,
  348. Endpoint: endpoint,
  349. }
  350. fmt.Println("Writing node settings to netconfig file.")
  351. err = modConfig(postnode)
  352. if err != nil {
  353. return err
  354. }
  355. res, err := wcclient.CreateNode(
  356. context.TODO(),
  357. &nodepb.CreateNodeReq{
  358. Node: postnode,
  359. },
  360. )
  361. if err != nil {
  362. return err
  363. }
  364. node := res.Node
  365. fmt.Println("Setting local config from server response")
  366. if err != nil {
  367. return err
  368. }
  369. fmt.Println("NODE RECIEVED SETTINGS: ")
  370. fmt.Println(" Password: " + node.Password)
  371. fmt.Println(" WG Address: " + node.Address)
  372. fmt.Println(" WG ipv6 Address: " + node.Address6)
  373. fmt.Println(" Network: " + node.Nodenetwork)
  374. fmt.Println(" Public Endpoint: " + node.Endpoint)
  375. fmt.Println(" Local Address: " + node.Localaddress)
  376. fmt.Println(" Name: " + node.Name)
  377. fmt.Println(" Interface: " + node.Interface)
  378. fmt.Println(" PostUp: " + node.Postup)
  379. fmt.Println(" PostDown: " + node.Postdown)
  380. fmt.Println(" Port: " + strconv.FormatInt(int64(node.Listenport), 10))
  381. fmt.Println(" KeepAlive: " + strconv.FormatInt(int64(node.Keepalive), 10))
  382. fmt.Println(" Public Key: " + node.Publickey)
  383. fmt.Println(" Mac Address: " + node.Macaddress)
  384. fmt.Println(" Is Local?: " + strconv.FormatBool(node.Islocal))
  385. fmt.Println(" Is Dual Stack?: " + strconv.FormatBool(node.Isdualstack))
  386. fmt.Println(" Is Ingress Gateway?: " + strconv.FormatBool(node.Isingressgateway))
  387. fmt.Println(" Local Range: " + node.Localrange)
  388. if node.Dnsoff==true && !nodecfg.DNSOff {
  389. nodecfg.DNSOff = true
  390. }
  391. if !islocal && node.Islocal && node.Localrange != "" {
  392. fmt.Println("Resetting local settings for local network.")
  393. node.Localaddress, err = getLocalIP(node.Localrange)
  394. if err != nil {
  395. return err
  396. }
  397. node.Endpoint = node.Localaddress
  398. }
  399. err = modConfig(node)
  400. if err != nil {
  401. return err
  402. }
  403. if node.Ispending {
  404. fmt.Println("Node is marked as PENDING.")
  405. fmt.Println("Awaiting approval from Admin before configuring WireGuard.")
  406. if !noauto {
  407. fmt.Println("Configuring Netmaker Service.")
  408. err = ConfigureSystemD(network)
  409. return err
  410. }
  411. }
  412. peers, hasGateway, gateways, err := getPeers(node.Macaddress, network, server, node.Isdualstack, node.Isingressgateway)
  413. if err != nil {
  414. return err
  415. }
  416. fmt.Println("retrived peers, setting wireguard config.")
  417. err = storePrivKey(privkeystring, network)
  418. if err != nil {
  419. return err
  420. }
  421. err = initWireguard(node, privkeystring, peers, hasGateway, gateways)
  422. if err != nil {
  423. return err
  424. }
  425. if !noauto {
  426. err = ConfigureSystemD(network)
  427. }
  428. if err != nil {
  429. return err
  430. }
  431. return err
  432. }
  433. func getLocalIP(localrange string) (string, error) {
  434. _, localRange, err := net.ParseCIDR(localrange)
  435. if err != nil {
  436. return "", err
  437. }
  438. ifaces, err := net.Interfaces()
  439. if err != nil {
  440. return "", err
  441. }
  442. var local string
  443. found := false
  444. for _, i := range ifaces {
  445. if i.Flags&net.FlagUp == 0 {
  446. continue // interface down
  447. }
  448. if i.Flags&net.FlagLoopback != 0 {
  449. continue // loopback interface
  450. }
  451. addrs, err := i.Addrs()
  452. if err != nil {
  453. return "", err
  454. }
  455. for _, addr := range addrs {
  456. var ip net.IP
  457. switch v := addr.(type) {
  458. case *net.IPNet:
  459. if !found {
  460. ip = v.IP
  461. local = ip.String()
  462. found = localRange.Contains(ip)
  463. }
  464. case *net.IPAddr:
  465. if !found {
  466. ip = v.IP
  467. local = ip.String()
  468. found = localRange.Contains(ip)
  469. }
  470. }
  471. }
  472. }
  473. if !found || local == "" {
  474. return "", errors.New("Failed to find local IP in range " + localrange)
  475. }
  476. return local, nil
  477. }
  478. func getPublicIP() (string, error) {
  479. iplist := []string{"http://ip.client.gravitl.com","https://ifconfig.me", "http://api.ipify.org", "http://ipinfo.io/ip"}
  480. endpoint := ""
  481. var err error
  482. for _, ipserver := range iplist {
  483. resp, err := http.Get(ipserver)
  484. if err != nil {
  485. continue
  486. }
  487. defer resp.Body.Close()
  488. if resp.StatusCode == http.StatusOK {
  489. bodyBytes, err := ioutil.ReadAll(resp.Body)
  490. if err != nil {
  491. continue
  492. }
  493. endpoint = string(bodyBytes)
  494. break
  495. }
  496. }
  497. if err == nil && endpoint == "" {
  498. err = errors.New("Public Address Not Found.")
  499. }
  500. return endpoint, err
  501. }
  502. func modConfig(node *nodepb.Node) error{
  503. network := node.Nodenetwork
  504. if network == "" {
  505. return errors.New("No Network Provided")
  506. }
  507. modconfig, err := config.ReadConfig(network)
  508. if err != nil {
  509. return err
  510. }
  511. nodecfg := modconfig.Node
  512. if node.Name != ""{
  513. nodecfg.Name = node.Name
  514. }
  515. if node.Interface != ""{
  516. nodecfg.Interface = node.Interface
  517. }
  518. if node.Nodenetwork != ""{
  519. nodecfg.Network = node.Nodenetwork
  520. }
  521. if node.Macaddress != ""{
  522. nodecfg.MacAddress = node.Macaddress
  523. }
  524. if node.Localaddress != ""{
  525. nodecfg.LocalAddress = node.Localaddress
  526. }
  527. if node.Postup != ""{
  528. nodecfg.PostUp = node.Postup
  529. }
  530. if node.Postdown != ""{
  531. nodecfg.PostDown = node.Postdown
  532. }
  533. if node.Listenport != 0{
  534. nodecfg.Port = node.Listenport
  535. }
  536. if node.Keepalive != 0{
  537. nodecfg.KeepAlive = node.Keepalive
  538. }
  539. if node.Publickey != ""{
  540. nodecfg.PublicKey = node.Publickey
  541. }
  542. if node.Endpoint != ""{
  543. nodecfg.Endpoint = node.Endpoint
  544. }
  545. if node.Password != ""{
  546. nodecfg.Password = node.Password
  547. }
  548. if node.Address != ""{
  549. nodecfg.WGAddress = node.Address
  550. }
  551. if node.Address6 != ""{
  552. nodecfg.WGAddress6 = node.Address6
  553. }
  554. if node.Postchanges != "" {
  555. nodecfg.PostChanges = node.Postchanges
  556. }
  557. if node.Dnsoff == true {
  558. nodecfg.DNSOff = node.Dnsoff
  559. }
  560. if node.Isdualstack == true {
  561. nodecfg.IsDualStack = true
  562. }
  563. nodecfg.IsIngressGateway = node.Isingressgateway
  564. if node.Localrange != "" && node.Islocal {
  565. nodecfg.IsLocal = true
  566. nodecfg.LocalRange = node.Localrange
  567. }
  568. modconfig.Node = nodecfg
  569. err = config.Write(modconfig, network)
  570. return err
  571. }
  572. func getMacAddr() ([]string, error) {
  573. ifas, err := net.Interfaces()
  574. if err != nil {
  575. return nil, err
  576. }
  577. var as []string
  578. for _, ifa := range ifas {
  579. a := ifa.HardwareAddr.String()
  580. if a != "" {
  581. as = append(as, a)
  582. }
  583. }
  584. return as, nil
  585. }
  586. func initWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig, hasGateway bool, gateways []string) error {
  587. ipExec, err := exec.LookPath("ip")
  588. if err != nil {
  589. return err
  590. }
  591. key, err := wgtypes.ParseKey(privkey)
  592. if err != nil {
  593. return err
  594. }
  595. wgclient, err := wgctrl.New()
  596. //modcfg := config.Config
  597. //modcfg.ReadConfig()
  598. modcfg, err := config.ReadConfig(node.Nodenetwork)
  599. if err != nil {
  600. return err
  601. }
  602. nodecfg := modcfg.Node
  603. servercfg := modcfg.Server
  604. fmt.Println("beginning local WG config")
  605. if err != nil {
  606. log.Fatalf("failed to open client: %v", err)
  607. }
  608. defer wgclient.Close()
  609. fmt.Println("setting local settings")
  610. ifacename := node.Interface
  611. if nodecfg.Interface != "" {
  612. ifacename = nodecfg.Interface
  613. } else if node.Interface != "" {
  614. ifacename = node.Interface
  615. } else {
  616. log.Fatal("no interface to configure")
  617. }
  618. if node.Address == "" {
  619. log.Fatal("no address to configure")
  620. }
  621. nameserver := servercfg.Address
  622. nameserver = strings.Split(nameserver, ":")[0]
  623. network := node.Nodenetwork
  624. if nodecfg.Network != "" {
  625. network = nodecfg.Network
  626. } else if node.Nodenetwork != "" {
  627. network = node.Nodenetwork
  628. }
  629. cmdIPDevLinkAdd := &exec.Cmd {
  630. Path: ipExec,
  631. Args: []string{ ipExec, "link", "add", "dev", ifacename, "type", "wireguard" },
  632. Stdout: os.Stdout,
  633. Stderr: os.Stdout,
  634. }
  635. cmdIPAddrAdd := &exec.Cmd {
  636. Path: ipExec,
  637. Args: []string{ ipExec, "address", "add", "dev", ifacename, node.Address+"/24"},
  638. Stdout: os.Stdout,
  639. Stderr: os.Stdout,
  640. }
  641. currentiface, err := net.InterfaceByName(ifacename)
  642. if err != nil {
  643. err = cmdIPDevLinkAdd.Run()
  644. if err != nil && !strings.Contains(err.Error(), "exists") {
  645. fmt.Println("Error creating interface")
  646. //fmt.Println(err.Error())
  647. //return err
  648. }
  649. }
  650. match := false
  651. addrs, _ := currentiface.Addrs()
  652. for _, a := range addrs {
  653. if strings.Contains(a.String(), node.Address){
  654. match = true
  655. }
  656. }
  657. if !match {
  658. err = cmdIPAddrAdd.Run()
  659. if err != nil {
  660. fmt.Println("Error adding address")
  661. //return err
  662. }
  663. }
  664. var nodeport int
  665. nodeport = int(node.Listenport)
  666. fmt.Println("setting WG config from node and peers")
  667. //pubkey := privkey.PublicKey()
  668. conf := wgtypes.Config{
  669. PrivateKey: &key,
  670. ListenPort: &nodeport,
  671. ReplacePeers: true,
  672. Peers: peers,
  673. }
  674. _, err = wgclient.Device(ifacename)
  675. if err != nil {
  676. if os.IsNotExist(err) {
  677. fmt.Println("Device does not exist: ")
  678. fmt.Println(err)
  679. } else {
  680. log.Fatalf("Unknown config error: %v", err)
  681. }
  682. }
  683. fmt.Println("configuring WG device")
  684. err = wgclient.ConfigureDevice(ifacename, conf)
  685. if err != nil {
  686. if os.IsNotExist(err) {
  687. fmt.Println("Device does not exist: ")
  688. fmt.Println(err)
  689. } else {
  690. fmt.Printf("This is inconvenient: %v", err)
  691. }
  692. }
  693. //=========DNS Setup==========\\
  694. if nodecfg.DNSOff != true {
  695. _, err := exec.LookPath("resolvectl")
  696. if err != nil {
  697. fmt.Println(err)
  698. fmt.Println("WARNING: resolvectl not present. Unable to set dns. Install resolvectl or run manually.")
  699. } else {
  700. _, err = exec.Command("resolvectl", "domain", ifacename, "~"+network).Output()
  701. if err != nil {
  702. fmt.Println(err)
  703. fmt.Println("WARNING: Error encountered setting dns. Aborted setting dns.")
  704. } else {
  705. _, err = exec.Command("resolvectl", "default-route", ifacename, "false").Output()
  706. if err != nil {
  707. fmt.Println(err)
  708. fmt.Println("WARNING: Error encountered setting dns. Aborted setting dns.")
  709. } else {
  710. _, err = exec.Command("resolvectl", "dns", ifacename, nameserver).Output()
  711. fmt.Println(err)
  712. }
  713. }
  714. }
  715. }
  716. //=========End DNS Setup=======\\
  717. cmdIPLinkUp := &exec.Cmd {
  718. Path: ipExec,
  719. Args: []string{ ipExec, "link", "set", "up", "dev", ifacename},
  720. Stdout: os.Stdout,
  721. Stderr: os.Stdout,
  722. }
  723. cmdIPLinkDown := &exec.Cmd {
  724. Path: ipExec,
  725. Args: []string{ ipExec, "link", "set", "down", "dev", ifacename},
  726. Stdout: os.Stdout,
  727. Stderr: os.Stdout,
  728. }
  729. err = cmdIPLinkDown.Run()
  730. if nodecfg.PostDown != "" {
  731. runcmds := strings.Split(nodecfg.PostDown, "; ")
  732. err = runCmds(runcmds)
  733. if err != nil {
  734. fmt.Println("Error encountered running PostDown: " + err.Error())
  735. }
  736. }
  737. err = cmdIPLinkUp.Run()
  738. if err != nil {
  739. return err
  740. }
  741. if nodecfg.PostUp != "" {
  742. runcmds := strings.Split(nodecfg.PostUp, "; ")
  743. err = runCmds(runcmds)
  744. if err != nil {
  745. fmt.Println("Error encountered running PostUp: " + err.Error())
  746. }
  747. }
  748. if (hasGateway) {
  749. for _, gateway := range gateways {
  750. out, err := exec.Command(ipExec,"-4","route","add",gateway,"dev",ifacename).Output()
  751. fmt.Println(string(out))
  752. if err != nil {
  753. fmt.Println("Error encountered adding gateway: " + err.Error())
  754. }
  755. }
  756. }
  757. if (node.Address6 != "" && node.Isdualstack) {
  758. fmt.Println("Adding address: " + node.Address6)
  759. out, err := exec.Command(ipExec, "address", "add", "dev", ifacename, node.Address6+"/64").Output()
  760. if err != nil {
  761. fmt.Println(out)
  762. fmt.Println("Error encountered adding ipv6: " + err.Error())
  763. }
  764. }
  765. return err
  766. }
  767. func runCmds(commands []string) error {
  768. var err error
  769. for _, command := range commands {
  770. fmt.Println("Running command: " + command)
  771. args := strings.Fields(command)
  772. out, err := exec.Command(args[0], args[1:]...).Output()
  773. fmt.Println(string(out))
  774. if err != nil {
  775. return err
  776. }
  777. }
  778. return err
  779. }
  780. func setWGKeyConfig(network string, serveraddr string) error {
  781. ctx := context.Background()
  782. var header metadata.MD
  783. var wcclient nodepb.NodeServiceClient
  784. var requestOpts grpc.DialOption
  785. requestOpts = grpc.WithInsecure()
  786. conn, err := grpc.Dial(serveraddr, requestOpts)
  787. if err != nil {
  788. fmt.Printf("Cant dial GRPC server: %v", err)
  789. return err
  790. }
  791. wcclient = nodepb.NewNodeServiceClient(conn)
  792. fmt.Println("Authenticating with GRPC Server")
  793. ctx, err = SetJWT(wcclient, network)
  794. if err != nil {
  795. fmt.Printf("Failed to authenticate: %v", err)
  796. return err
  797. }
  798. fmt.Println("Authenticated")
  799. node := getNode(network)
  800. privatekey, err := wgtypes.GeneratePrivateKey()
  801. if err != nil {
  802. return err
  803. }
  804. privkeystring := privatekey.String()
  805. publickey := privatekey.PublicKey()
  806. node.Publickey = publickey.String()
  807. err = storePrivKey(privkeystring, network)
  808. if err != nil {
  809. return err
  810. }
  811. err = modConfig(&node)
  812. if err != nil {
  813. return err
  814. }
  815. postnode := getNode(network)
  816. req := &nodepb.UpdateNodeReq{
  817. Node: &postnode,
  818. }
  819. _, err = wcclient.UpdateNode(ctx, req, grpc.Header(&header))
  820. if err != nil {
  821. return err
  822. }
  823. err = setWGConfig(network)
  824. if err != nil {
  825. return err
  826. log.Fatalf("Error: %v", err)
  827. }
  828. return err
  829. }
  830. func setWGConfig(network string) error {
  831. cfg, err := config.ReadConfig(network)
  832. if err != nil {
  833. return err
  834. }
  835. servercfg := cfg.Server
  836. nodecfg := cfg.Node
  837. node := getNode(network)
  838. peers, hasGateway, gateways, err := getPeers(node.Macaddress, nodecfg.Network, servercfg.Address, node.Isdualstack, node.Isingressgateway)
  839. if err != nil {
  840. return err
  841. }
  842. privkey, err := retrievePrivKey(network)
  843. if err != nil {
  844. return err
  845. }
  846. err = initWireguard(&node, privkey, peers, hasGateway, gateways)
  847. if err != nil {
  848. return err
  849. }
  850. return err
  851. }
  852. func storePrivKey(key string, network string) error{
  853. d1 := []byte(key)
  854. err := ioutil.WriteFile("/etc/netclient/wgkey-" + network, d1, 0644)
  855. return err
  856. }
  857. func retrievePrivKey(network string) (string, error) {
  858. dat, err := ioutil.ReadFile("/etc/netclient/wgkey-" + network)
  859. return string(dat), err
  860. }
  861. func getPrivateAddr() (string, error) {
  862. ifaces, err := net.Interfaces()
  863. if err != nil {
  864. return "", err
  865. }
  866. var local string
  867. found := false
  868. for _, i := range ifaces {
  869. if i.Flags&net.FlagUp == 0 {
  870. continue // interface down
  871. }
  872. if i.Flags&net.FlagLoopback != 0 {
  873. continue // loopback interface
  874. }
  875. addrs, err := i.Addrs()
  876. if err != nil {
  877. return "", err
  878. }
  879. for _, addr := range addrs {
  880. var ip net.IP
  881. switch v := addr.(type) {
  882. case *net.IPNet:
  883. if !found {
  884. ip = v.IP
  885. local = ip.String()
  886. found = true
  887. }
  888. case *net.IPAddr:
  889. if !found {
  890. ip = v.IP
  891. local = ip.String()
  892. found = true
  893. }
  894. }
  895. }
  896. }
  897. if !found {
  898. err := errors.New("Local Address Not Found.")
  899. return "", err
  900. }
  901. return local, err
  902. }
  903. func CheckIn(network string) error {
  904. node := getNode(network)
  905. cfg, err := config.ReadConfig(network)
  906. if err != nil {
  907. return err
  908. }
  909. nodecfg := cfg.Node
  910. servercfg := cfg.Server
  911. fmt.Println("Checking into server: " + servercfg.Address)
  912. setupcheck := true
  913. ipchange := false
  914. if !(nodecfg.IPForwarding == "off") {
  915. out, err := exec.Command("sysctl", "net.ipv4.ip_forward").Output()
  916. if err != nil {
  917. fmt.Println(err)
  918. fmt.Println("WARNING: Error encountered setting ip forwarding. This can break functionality.")
  919. } else {
  920. s := strings.Fields(string(out))
  921. if s[2] != "1" {
  922. _, err = exec.Command("sysctl", "-w", "net.ipv4.ip_forward=1").Output()
  923. if err != nil {
  924. fmt.Println(err)
  925. fmt.Println("WARNING: Error encountered setting ip forwarding. You may want to investigate this.")
  926. }
  927. }
  928. }
  929. }
  930. if !nodecfg.RoamingOff {
  931. if !nodecfg.IsLocal {
  932. fmt.Println("Checking to see if public addresses have changed")
  933. extIP, err := getPublicIP()
  934. if err != nil {
  935. fmt.Printf("Error encountered checking ip addresses: %v", err)
  936. }
  937. if nodecfg.Endpoint != extIP && extIP != "" {
  938. fmt.Println("Endpoint has changed from " +
  939. nodecfg.Endpoint + " to " + extIP)
  940. fmt.Println("Updating address")
  941. nodecfg.Endpoint = extIP
  942. nodecfg.PostChanges = "true"
  943. node.Endpoint = extIP
  944. node.Postchanges = "true"
  945. ipchange = true
  946. }
  947. intIP, err := getPrivateAddr()
  948. if err != nil {
  949. fmt.Printf("Error encountered checking ip addresses: %v", err)
  950. }
  951. if nodecfg.LocalAddress != intIP && intIP != "" {
  952. fmt.Println("Local Address has changed from " +
  953. nodecfg.LocalAddress + " to " + intIP)
  954. fmt.Println("Updating address")
  955. nodecfg.LocalAddress = intIP
  956. nodecfg.PostChanges = "true"
  957. node.Localaddress = intIP
  958. node.Postchanges = "true"
  959. ipchange = true
  960. }
  961. } else {
  962. fmt.Println("Checking to see if local addresses have changed")
  963. localIP, err := getLocalIP(nodecfg.LocalRange)
  964. if err != nil {
  965. fmt.Printf("Error encountered checking ip addresses: %v", err)
  966. }
  967. if nodecfg.Endpoint != localIP && localIP != "" {
  968. fmt.Println("Endpoint has changed from " +
  969. nodecfg.Endpoint + " to " + localIP)
  970. fmt.Println("Updating address")
  971. nodecfg.Endpoint = localIP
  972. nodecfg.LocalAddress = localIP
  973. nodecfg.PostChanges = "true"
  974. node.Endpoint = localIP
  975. node.Localaddress = localIP
  976. node.Postchanges = "true"
  977. ipchange = true
  978. }
  979. }
  980. if node.Postchanges != "true" {
  981. fmt.Println("Addresses have not changed.")
  982. }
  983. }
  984. if ipchange {
  985. err := modConfig(&node)
  986. if err != nil {
  987. return err
  988. log.Fatalf("Error: %v", err)
  989. }
  990. err = setWGConfig(network)
  991. if err != nil {
  992. return err
  993. log.Fatalf("Error: %v", err)
  994. }
  995. node = getNode(network)
  996. cfg, err := config.ReadConfig(network)
  997. if err != nil {
  998. return err
  999. }
  1000. nodecfg = cfg.Node
  1001. }
  1002. var wcclient nodepb.NodeServiceClient
  1003. var requestOpts grpc.DialOption
  1004. requestOpts = grpc.WithInsecure()
  1005. conn, err := grpc.Dial(servercfg.Address, requestOpts)
  1006. if err != nil {
  1007. fmt.Printf("Cant dial GRPC server: %v", err)
  1008. return err
  1009. }
  1010. wcclient = nodepb.NewNodeServiceClient(conn)
  1011. ctx := context.Background()
  1012. fmt.Println("Authenticating with GRPC Server")
  1013. ctx, err = SetJWT(wcclient, network)
  1014. if err != nil {
  1015. fmt.Printf("Failed to authenticate: %v", err)
  1016. return err
  1017. }
  1018. fmt.Println("Authenticated")
  1019. fmt.Println("Checking In.")
  1020. var header metadata.MD
  1021. node.Nodenetwork = network
  1022. checkinres, err := wcclient.CheckIn(
  1023. ctx,
  1024. &nodepb.CheckInReq{
  1025. Node: &node,
  1026. },
  1027. grpc.Header(&header),
  1028. )
  1029. if err != nil {
  1030. if checkinres != nil && checkinres.Checkinresponse.Ispending {
  1031. fmt.Println("Node is in pending status. Waiting for Admin approval of node before making further updates.")
  1032. return nil
  1033. }
  1034. fmt.Printf("Unable to process Check In request: %v", err)
  1035. return err
  1036. }
  1037. fmt.Println("Checked in.")
  1038. if checkinres.Checkinresponse.Ispending {
  1039. fmt.Println("Node is in pending status. Waiting for Admin approval of node before making further updates.")
  1040. return err
  1041. }
  1042. newinterface := getNode(network).Interface
  1043. readreq := &nodepb.ReadNodeReq{
  1044. Macaddress: node.Macaddress,
  1045. Network: node.Nodenetwork,
  1046. }
  1047. readres, err := wcclient.ReadNode(ctx, readreq, grpc.Header(&header))
  1048. if err != nil {
  1049. fmt.Printf("Error: %v", err)
  1050. } else {
  1051. currentiface := readres.Node.Interface
  1052. ifaceupdate := newinterface != currentiface
  1053. if err != nil {
  1054. log.Printf("Error retrieving interface: %v", err)
  1055. }
  1056. if ifaceupdate {
  1057. fmt.Println("Interface update: " + currentiface +
  1058. " >>>> " + newinterface)
  1059. err := DeleteInterface(currentiface, nodecfg.PostDown)
  1060. if err != nil {
  1061. fmt.Println("ERROR DELETING INTERFACE: " + currentiface)
  1062. }
  1063. err = setWGConfig(network)
  1064. if err != nil {
  1065. log.Printf("Error updating interface: %v", err)
  1066. }
  1067. }
  1068. }
  1069. if checkinres.Checkinresponse.Needconfigupdate {
  1070. fmt.Println("Server has requested that node update config.")
  1071. fmt.Println("Updating config from remote server.")
  1072. req := &nodepb.ReadNodeReq{
  1073. Macaddress: node.Macaddress,
  1074. Network: node.Nodenetwork,
  1075. }
  1076. readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
  1077. if err != nil {
  1078. return err
  1079. log.Fatalf("Error: %v", err)
  1080. }
  1081. err = modConfig(readres.Node)
  1082. if err != nil {
  1083. return err
  1084. log.Fatalf("Error: %v", err)
  1085. }
  1086. err = setWGConfig(network)
  1087. if err != nil {
  1088. return err
  1089. log.Fatalf("Error: %v", err)
  1090. }
  1091. setupcheck = false
  1092. } else if nodecfg.PostChanges == "true" {
  1093. fmt.Println("Node has requested to update remote config.")
  1094. fmt.Println("Posting local config to remote server.")
  1095. postnode := getNode(network)
  1096. req := &nodepb.UpdateNodeReq{
  1097. Node: &postnode,
  1098. }
  1099. res, err := wcclient.UpdateNode(ctx, req, grpc.Header(&header))
  1100. if err != nil {
  1101. return err
  1102. log.Fatalf("Error: %v", err)
  1103. }
  1104. res.Node.Postchanges = "false"
  1105. err = modConfig(res.Node)
  1106. if err != nil {
  1107. return err
  1108. log.Fatalf("Error: %v", err)
  1109. }
  1110. err = setWGConfig(network)
  1111. if err != nil {
  1112. return err
  1113. log.Fatalf("Error: %v", err)
  1114. }
  1115. setupcheck = false
  1116. }
  1117. if checkinres.Checkinresponse.Needkeyupdate {
  1118. fmt.Println("Server has requested that node update key pairs.")
  1119. fmt.Println("Proceeding to re-generate key pairs for Wiregard.")
  1120. err = setWGKeyConfig(network, servercfg.Address)
  1121. if err != nil {
  1122. return err
  1123. log.Fatalf("Unable to process reset keys request: %v", err)
  1124. }
  1125. setupcheck = false
  1126. }
  1127. if checkinres.Checkinresponse.Needpeerupdate {
  1128. fmt.Println("Server has requested that node update peer list.")
  1129. fmt.Println("Updating peer list from remote server.")
  1130. err = setWGConfig(network)
  1131. if err != nil {
  1132. return err
  1133. log.Fatalf("Unable to process Set Peers request: %v", err)
  1134. }
  1135. setupcheck = false
  1136. }
  1137. if checkinres.Checkinresponse.Needdelete {
  1138. fmt.Println("This machine got the delete signal. Deleting.")
  1139. err := Remove(network)
  1140. if err != nil {
  1141. return err
  1142. log.Fatalf("Error: %v", err)
  1143. }
  1144. }
  1145. if setupcheck {
  1146. iface := nodecfg.Interface
  1147. _, err := net.InterfaceByName(iface)
  1148. if err != nil {
  1149. fmt.Println("interface " + iface + " does not currently exist. Setting up WireGuard.")
  1150. err = setWGKeyConfig(network, servercfg.Address)
  1151. if err != nil {
  1152. return err
  1153. log.Fatalf("Error: %v", err)
  1154. }
  1155. }
  1156. }
  1157. return nil
  1158. }
  1159. func needInterfaceUpdate(ctx context.Context, mac string, network string, iface string) (bool, string, error) {
  1160. var header metadata.MD
  1161. req := &nodepb.ReadNodeReq{
  1162. Macaddress: mac,
  1163. Network: network,
  1164. }
  1165. readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
  1166. if err != nil {
  1167. return false, "", err
  1168. log.Fatalf("Error: %v", err)
  1169. }
  1170. oldiface := readres.Node.Interface
  1171. return iface != oldiface, oldiface, err
  1172. }
  1173. func getNode(network string) nodepb.Node {
  1174. modcfg, err := config.ReadConfig(network)
  1175. if err != nil {
  1176. log.Fatalf("Error: %v", err)
  1177. }
  1178. nodecfg := modcfg.Node
  1179. var node nodepb.Node
  1180. node.Name = nodecfg.Name
  1181. node.Interface = nodecfg.Interface
  1182. node.Nodenetwork = nodecfg.Network
  1183. node.Localaddress = nodecfg.LocalAddress
  1184. node.Address = nodecfg.WGAddress
  1185. node.Address6 = nodecfg.WGAddress6
  1186. node.Listenport = nodecfg.Port
  1187. node.Keepalive = nodecfg.KeepAlive
  1188. node.Postup = nodecfg.PostUp
  1189. node.Postdown = nodecfg.PostDown
  1190. node.Publickey = nodecfg.PublicKey
  1191. node.Macaddress = nodecfg.MacAddress
  1192. node.Endpoint = nodecfg.Endpoint
  1193. node.Password = nodecfg.Password
  1194. node.Dnsoff = nodecfg.DNSOff
  1195. node.Isdualstack = nodecfg.IsDualStack
  1196. node.Isingressgateway = nodecfg.IsIngressGateway
  1197. return node
  1198. }
  1199. func Remove(network string) error {
  1200. //need to implement checkin on server side
  1201. cfg, err := config.ReadConfig(network)
  1202. if err != nil {
  1203. return err
  1204. }
  1205. servercfg := cfg.Server
  1206. node := cfg.Node
  1207. fmt.Println("Deleting remote node with MAC: " + node.MacAddress)
  1208. var wcclient nodepb.NodeServiceClient
  1209. var requestOpts grpc.DialOption
  1210. requestOpts = grpc.WithInsecure()
  1211. conn, err := grpc.Dial(servercfg.Address, requestOpts)
  1212. if err != nil {
  1213. log.Printf("Unable to establish client connection to " + servercfg.Address + ": %v", err)
  1214. //return err
  1215. }else {
  1216. wcclient = nodepb.NewNodeServiceClient(conn)
  1217. ctx := context.Background()
  1218. fmt.Println("Authenticating with GRPC Server")
  1219. ctx, err = SetJWT(wcclient, network)
  1220. if err != nil {
  1221. //return err
  1222. log.Printf("Failed to authenticate: %v", err)
  1223. } else {
  1224. fmt.Println("Authenticated")
  1225. var header metadata.MD
  1226. _, err = wcclient.DeleteNode(
  1227. ctx,
  1228. &nodepb.DeleteNodeReq{
  1229. Macaddress: node.MacAddress,
  1230. NetworkName: node.Network,
  1231. },
  1232. grpc.Header(&header),
  1233. )
  1234. if err != nil {
  1235. log.Printf("Encountered error deleting node: %v", err)
  1236. fmt.Println(err)
  1237. } else {
  1238. fmt.Println("Deleted node " + node.MacAddress)
  1239. }
  1240. }
  1241. }
  1242. err = WipeLocal(network)
  1243. if err != nil {
  1244. log.Printf("Unable to wipe local config: %v", err)
  1245. }
  1246. err = RemoveSystemDServices(network)
  1247. if err != nil {
  1248. return err
  1249. log.Printf("Unable to remove systemd services: %v", err)
  1250. }
  1251. fmt.Printf("Please investigate any stated errors to ensure proper removal.")
  1252. fmt.Printf("Failure to delete node from server via gRPC will mean node still exists and needs to be manually deleted by administrator.")
  1253. return nil
  1254. }
  1255. func WipeLocal(network string) error{
  1256. cfg, err := config.ReadConfig(network)
  1257. if err != nil {
  1258. return err
  1259. }
  1260. nodecfg := cfg.Node
  1261. ifacename := nodecfg.Interface
  1262. //home, err := homedir.Dir()
  1263. home := "/etc/netclient"
  1264. err = os.Remove(home + "/netconfig-" + network)
  1265. if err != nil {
  1266. fmt.Println(err)
  1267. }
  1268. err = os.Remove(home + "/nettoken-" + network)
  1269. if err != nil {
  1270. fmt.Println(err)
  1271. }
  1272. err = os.Remove(home + "/wgkey-" + network)
  1273. if err != nil {
  1274. fmt.Println(err)
  1275. }
  1276. ipExec, err := exec.LookPath("ip")
  1277. if ifacename != "" {
  1278. cmdIPLinkDel := &exec.Cmd {
  1279. Path: ipExec,
  1280. Args: []string{ ipExec, "link", "del", ifacename },
  1281. Stdout: os.Stdout,
  1282. Stderr: os.Stdout,
  1283. }
  1284. err = cmdIPLinkDel.Run()
  1285. if err != nil {
  1286. fmt.Println(err)
  1287. }
  1288. if nodecfg.PostDown != "" {
  1289. runcmds := strings.Split(nodecfg.PostDown, "; ")
  1290. err = runCmds(runcmds)
  1291. if err != nil {
  1292. fmt.Println("Error encountered running PostDown: " + err.Error())
  1293. }
  1294. }
  1295. }
  1296. return err
  1297. }
  1298. func DeleteInterface(ifacename string, postdown string) error{
  1299. ipExec, err := exec.LookPath("ip")
  1300. cmdIPLinkDel := &exec.Cmd {
  1301. Path: ipExec,
  1302. Args: []string{ ipExec, "link", "del", ifacename },
  1303. Stdout: os.Stdout,
  1304. Stderr: os.Stdout,
  1305. }
  1306. err = cmdIPLinkDel.Run()
  1307. if err != nil {
  1308. fmt.Println(err)
  1309. }
  1310. if postdown != "" {
  1311. runcmds := strings.Split(postdown, "; ")
  1312. err = runCmds(runcmds)
  1313. if err != nil {
  1314. fmt.Println("Error encountered running PostDown: " + err.Error())
  1315. }
  1316. }
  1317. return err
  1318. }