common.go 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451
  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(" Local Range: " + node.Localrange)
  387. if node.Dnsoff==true && !nodecfg.DNSOff {
  388. nodecfg.DNSOff = true
  389. }
  390. if !islocal && node.Islocal && node.Localrange != "" {
  391. fmt.Println("Resetting local settings for local network.")
  392. node.Localaddress, err = getLocalIP(node.Localrange)
  393. if err != nil {
  394. return err
  395. }
  396. node.Endpoint = node.Localaddress
  397. }
  398. err = modConfig(node)
  399. if err != nil {
  400. return err
  401. }
  402. if node.Ispending {
  403. fmt.Println("Node is marked as PENDING.")
  404. fmt.Println("Awaiting approval from Admin before configuring WireGuard.")
  405. if !noauto {
  406. fmt.Println("Configuring Netmaker Service.")
  407. err = ConfigureSystemD(network)
  408. return err
  409. }
  410. }
  411. peers, hasGateway, gateways, err := getPeers(node.Macaddress, network, server, node.Isdualstack, node.Isingressgateway)
  412. if err != nil {
  413. return err
  414. }
  415. fmt.Println("retrived peers, setting wireguard config.")
  416. err = storePrivKey(privkeystring, network)
  417. if err != nil {
  418. return err
  419. }
  420. err = initWireguard(node, privkeystring, peers, hasGateway, gateways)
  421. if err != nil {
  422. return err
  423. }
  424. if !noauto {
  425. err = ConfigureSystemD(network)
  426. }
  427. if err != nil {
  428. return err
  429. }
  430. return err
  431. }
  432. func getLocalIP(localrange string) (string, error) {
  433. _, localRange, err := net.ParseCIDR(localrange)
  434. if err != nil {
  435. return "", err
  436. }
  437. ifaces, err := net.Interfaces()
  438. if err != nil {
  439. return "", err
  440. }
  441. var local string
  442. found := false
  443. for _, i := range ifaces {
  444. if i.Flags&net.FlagUp == 0 {
  445. continue // interface down
  446. }
  447. if i.Flags&net.FlagLoopback != 0 {
  448. continue // loopback interface
  449. }
  450. addrs, err := i.Addrs()
  451. if err != nil {
  452. return "", err
  453. }
  454. for _, addr := range addrs {
  455. var ip net.IP
  456. switch v := addr.(type) {
  457. case *net.IPNet:
  458. if !found {
  459. ip = v.IP
  460. local = ip.String()
  461. found = localRange.Contains(ip)
  462. }
  463. case *net.IPAddr:
  464. if !found {
  465. ip = v.IP
  466. local = ip.String()
  467. found = localRange.Contains(ip)
  468. }
  469. }
  470. }
  471. }
  472. if !found || local == "" {
  473. return "", errors.New("Failed to find local IP in range " + localrange)
  474. }
  475. return local, nil
  476. }
  477. func getPublicIP() (string, error) {
  478. iplist := []string{"http://ip.client.gravitl.com","https://ifconfig.me", "http://api.ipify.org", "http://ipinfo.io/ip"}
  479. endpoint := ""
  480. var err error
  481. for _, ipserver := range iplist {
  482. resp, err := http.Get(ipserver)
  483. if err != nil {
  484. continue
  485. }
  486. defer resp.Body.Close()
  487. if resp.StatusCode == http.StatusOK {
  488. bodyBytes, err := ioutil.ReadAll(resp.Body)
  489. if err != nil {
  490. continue
  491. }
  492. endpoint = string(bodyBytes)
  493. break
  494. }
  495. }
  496. if err == nil && endpoint == "" {
  497. err = errors.New("Public Address Not Found.")
  498. }
  499. return endpoint, err
  500. }
  501. func modConfig(node *nodepb.Node) error{
  502. network := node.Nodenetwork
  503. if network == "" {
  504. return errors.New("No Network Provided")
  505. }
  506. modconfig, err := config.ReadConfig(network)
  507. if err != nil {
  508. return err
  509. }
  510. nodecfg := modconfig.Node
  511. if node.Name != ""{
  512. nodecfg.Name = node.Name
  513. }
  514. if node.Interface != ""{
  515. nodecfg.Interface = node.Interface
  516. }
  517. if node.Nodenetwork != ""{
  518. nodecfg.Network = node.Nodenetwork
  519. }
  520. if node.Macaddress != ""{
  521. nodecfg.MacAddress = node.Macaddress
  522. }
  523. if node.Localaddress != ""{
  524. nodecfg.LocalAddress = node.Localaddress
  525. }
  526. if node.Postup != ""{
  527. nodecfg.PostUp = node.Postup
  528. }
  529. if node.Postdown != ""{
  530. nodecfg.PostDown = node.Postdown
  531. }
  532. if node.Listenport != 0{
  533. nodecfg.Port = node.Listenport
  534. }
  535. if node.Keepalive != 0{
  536. nodecfg.KeepAlive = node.Keepalive
  537. }
  538. if node.Publickey != ""{
  539. nodecfg.PublicKey = node.Publickey
  540. }
  541. if node.Endpoint != ""{
  542. nodecfg.Endpoint = node.Endpoint
  543. }
  544. if node.Password != ""{
  545. nodecfg.Password = node.Password
  546. }
  547. if node.Address != ""{
  548. nodecfg.WGAddress = node.Address
  549. }
  550. if node.Address6 != ""{
  551. nodecfg.WGAddress6 = node.Address6
  552. }
  553. if node.Postchanges != "" {
  554. nodecfg.PostChanges = node.Postchanges
  555. }
  556. if node.Dnsoff == true {
  557. nodecfg.DNSOff = node.Dnsoff
  558. }
  559. if node.Isdualstack == true {
  560. nodecfg.IsDualStack = true
  561. }
  562. if node.Localrange != "" && node.Islocal {
  563. nodecfg.IsLocal = true
  564. nodecfg.LocalRange = node.Localrange
  565. }
  566. modconfig.Node = nodecfg
  567. err = config.Write(modconfig, network)
  568. return err
  569. }
  570. func getMacAddr() ([]string, error) {
  571. ifas, err := net.Interfaces()
  572. if err != nil {
  573. return nil, err
  574. }
  575. var as []string
  576. for _, ifa := range ifas {
  577. a := ifa.HardwareAddr.String()
  578. if a != "" {
  579. as = append(as, a)
  580. }
  581. }
  582. return as, nil
  583. }
  584. func initWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig, hasGateway bool, gateways []string) error {
  585. ipExec, err := exec.LookPath("ip")
  586. if err != nil {
  587. return err
  588. }
  589. key, err := wgtypes.ParseKey(privkey)
  590. if err != nil {
  591. return err
  592. }
  593. wgclient, err := wgctrl.New()
  594. //modcfg := config.Config
  595. //modcfg.ReadConfig()
  596. modcfg, err := config.ReadConfig(node.Nodenetwork)
  597. if err != nil {
  598. return err
  599. }
  600. nodecfg := modcfg.Node
  601. servercfg := modcfg.Server
  602. fmt.Println("beginning local WG config")
  603. if err != nil {
  604. log.Fatalf("failed to open client: %v", err)
  605. }
  606. defer wgclient.Close()
  607. fmt.Println("setting local settings")
  608. ifacename := node.Interface
  609. if nodecfg.Interface != "" {
  610. ifacename = nodecfg.Interface
  611. } else if node.Interface != "" {
  612. ifacename = node.Interface
  613. } else {
  614. log.Fatal("no interface to configure")
  615. }
  616. if node.Address == "" {
  617. log.Fatal("no address to configure")
  618. }
  619. nameserver := servercfg.Address
  620. nameserver = strings.Split(nameserver, ":")[0]
  621. network := node.Nodenetwork
  622. if nodecfg.Network != "" {
  623. network = nodecfg.Network
  624. } else if node.Nodenetwork != "" {
  625. network = node.Nodenetwork
  626. }
  627. cmdIPDevLinkAdd := &exec.Cmd {
  628. Path: ipExec,
  629. Args: []string{ ipExec, "link", "add", "dev", ifacename, "type", "wireguard" },
  630. Stdout: os.Stdout,
  631. Stderr: os.Stdout,
  632. }
  633. cmdIPAddrAdd := &exec.Cmd {
  634. Path: ipExec,
  635. Args: []string{ ipExec, "address", "add", "dev", ifacename, node.Address+"/24"},
  636. Stdout: os.Stdout,
  637. Stderr: os.Stdout,
  638. }
  639. currentiface, err := net.InterfaceByName(ifacename)
  640. if err != nil {
  641. err = cmdIPDevLinkAdd.Run()
  642. if err != nil && !strings.Contains(err.Error(), "exists") {
  643. fmt.Println("Error creating interface")
  644. //fmt.Println(err.Error())
  645. //return err
  646. }
  647. }
  648. match := false
  649. addrs, _ := currentiface.Addrs()
  650. for _, a := range addrs {
  651. if strings.Contains(a.String(), node.Address){
  652. match = true
  653. }
  654. }
  655. if !match {
  656. err = cmdIPAddrAdd.Run()
  657. if err != nil {
  658. fmt.Println("Error adding address")
  659. //return err
  660. }
  661. }
  662. var nodeport int
  663. nodeport = int(node.Listenport)
  664. fmt.Println("setting WG config from node and peers")
  665. //pubkey := privkey.PublicKey()
  666. conf := wgtypes.Config{
  667. PrivateKey: &key,
  668. ListenPort: &nodeport,
  669. ReplacePeers: true,
  670. Peers: peers,
  671. }
  672. _, err = wgclient.Device(ifacename)
  673. if err != nil {
  674. if os.IsNotExist(err) {
  675. fmt.Println("Device does not exist: ")
  676. fmt.Println(err)
  677. } else {
  678. log.Fatalf("Unknown config error: %v", err)
  679. }
  680. }
  681. fmt.Println("configuring WG device")
  682. err = wgclient.ConfigureDevice(ifacename, conf)
  683. if err != nil {
  684. if os.IsNotExist(err) {
  685. fmt.Println("Device does not exist: ")
  686. fmt.Println(err)
  687. } else {
  688. fmt.Printf("This is inconvenient: %v", err)
  689. }
  690. }
  691. //=========DNS Setup==========\\
  692. if nodecfg.DNSOff != true {
  693. _, err := exec.LookPath("resolvectl")
  694. if err != nil {
  695. fmt.Println(err)
  696. fmt.Println("WARNING: resolvectl not present. Unable to set dns. Install resolvectl or run manually.")
  697. } else {
  698. _, err = exec.Command("resolvectl", "domain", ifacename, "~"+network).Output()
  699. if err != nil {
  700. fmt.Println(err)
  701. fmt.Println("WARNING: Error encountered setting dns. Aborted setting dns.")
  702. } else {
  703. _, err = exec.Command("resolvectl", "default-route", ifacename, "false").Output()
  704. if err != nil {
  705. fmt.Println(err)
  706. fmt.Println("WARNING: Error encountered setting dns. Aborted setting dns.")
  707. } else {
  708. _, err = exec.Command("resolvectl", "dns", ifacename, nameserver).Output()
  709. fmt.Println(err)
  710. }
  711. }
  712. }
  713. }
  714. //=========End DNS Setup=======\\
  715. cmdIPLinkUp := &exec.Cmd {
  716. Path: ipExec,
  717. Args: []string{ ipExec, "link", "set", "up", "dev", ifacename},
  718. Stdout: os.Stdout,
  719. Stderr: os.Stdout,
  720. }
  721. cmdIPLinkDown := &exec.Cmd {
  722. Path: ipExec,
  723. Args: []string{ ipExec, "link", "set", "down", "dev", ifacename},
  724. Stdout: os.Stdout,
  725. Stderr: os.Stdout,
  726. }
  727. err = cmdIPLinkDown.Run()
  728. if nodecfg.PostDown != "" {
  729. runcmds := strings.Split(nodecfg.PostDown, "; ")
  730. err = runCmds(runcmds)
  731. if err != nil {
  732. fmt.Println("Error encountered running PostDown: " + err.Error())
  733. }
  734. }
  735. err = cmdIPLinkUp.Run()
  736. if err != nil {
  737. return err
  738. }
  739. if nodecfg.PostUp != "" {
  740. runcmds := strings.Split(nodecfg.PostUp, "; ")
  741. err = runCmds(runcmds)
  742. if err != nil {
  743. fmt.Println("Error encountered running PostUp: " + err.Error())
  744. }
  745. }
  746. if (hasGateway) {
  747. for _, gateway := range gateways {
  748. out, err := exec.Command(ipExec,"-4","route","add",gateway,"dev",ifacename).Output()
  749. fmt.Println(string(out))
  750. if err != nil {
  751. fmt.Println("Error encountered adding gateway: " + err.Error())
  752. }
  753. }
  754. }
  755. if (node.Address6 != "" && node.Isdualstack) {
  756. fmt.Println("Adding address: " + node.Address6)
  757. out, err := exec.Command(ipExec, "address", "add", "dev", ifacename, node.Address6+"/64").Output()
  758. if err != nil {
  759. fmt.Println(out)
  760. fmt.Println("Error encountered adding ipv6: " + err.Error())
  761. }
  762. }
  763. return err
  764. }
  765. func runCmds(commands []string) error {
  766. var err error
  767. for _, command := range commands {
  768. fmt.Println("Running command: " + command)
  769. args := strings.Fields(command)
  770. out, err := exec.Command(args[0], args[1:]...).Output()
  771. fmt.Println(string(out))
  772. if err != nil {
  773. return err
  774. }
  775. }
  776. return err
  777. }
  778. func setWGKeyConfig(network string, serveraddr string) error {
  779. ctx := context.Background()
  780. var header metadata.MD
  781. var wcclient nodepb.NodeServiceClient
  782. var requestOpts grpc.DialOption
  783. requestOpts = grpc.WithInsecure()
  784. conn, err := grpc.Dial(serveraddr, requestOpts)
  785. if err != nil {
  786. fmt.Printf("Cant dial GRPC server: %v", err)
  787. return err
  788. }
  789. wcclient = nodepb.NewNodeServiceClient(conn)
  790. fmt.Println("Authenticating with GRPC Server")
  791. ctx, err = SetJWT(wcclient, network)
  792. if err != nil {
  793. fmt.Printf("Failed to authenticate: %v", err)
  794. return err
  795. }
  796. fmt.Println("Authenticated")
  797. node := getNode(network)
  798. privatekey, err := wgtypes.GeneratePrivateKey()
  799. if err != nil {
  800. return err
  801. }
  802. privkeystring := privatekey.String()
  803. publickey := privatekey.PublicKey()
  804. node.Publickey = publickey.String()
  805. err = storePrivKey(privkeystring, network)
  806. if err != nil {
  807. return err
  808. }
  809. err = modConfig(&node)
  810. if err != nil {
  811. return err
  812. }
  813. postnode := getNode(network)
  814. req := &nodepb.UpdateNodeReq{
  815. Node: &postnode,
  816. }
  817. _, err = wcclient.UpdateNode(ctx, req, grpc.Header(&header))
  818. if err != nil {
  819. return err
  820. }
  821. err = setWGConfig(network)
  822. if err != nil {
  823. return err
  824. log.Fatalf("Error: %v", err)
  825. }
  826. return err
  827. }
  828. func setWGConfig(network string) error {
  829. cfg, err := config.ReadConfig(network)
  830. if err != nil {
  831. return err
  832. }
  833. servercfg := cfg.Server
  834. nodecfg := cfg.Node
  835. node := getNode(network)
  836. peers, hasGateway, gateways, err := getPeers(node.Macaddress, nodecfg.Network, servercfg.Address, node.Isdualstack, node.Isingressgateway)
  837. if err != nil {
  838. return err
  839. }
  840. privkey, err := retrievePrivKey(network)
  841. if err != nil {
  842. return err
  843. }
  844. err = initWireguard(&node, privkey, peers, hasGateway, gateways)
  845. if err != nil {
  846. return err
  847. }
  848. return err
  849. }
  850. func storePrivKey(key string, network string) error{
  851. d1 := []byte(key)
  852. err := ioutil.WriteFile("/etc/netclient/wgkey-" + network, d1, 0644)
  853. return err
  854. }
  855. func retrievePrivKey(network string) (string, error) {
  856. dat, err := ioutil.ReadFile("/etc/netclient/wgkey-" + network)
  857. return string(dat), err
  858. }
  859. func getPrivateAddr() (string, error) {
  860. ifaces, err := net.Interfaces()
  861. if err != nil {
  862. return "", err
  863. }
  864. var local string
  865. found := false
  866. for _, i := range ifaces {
  867. if i.Flags&net.FlagUp == 0 {
  868. continue // interface down
  869. }
  870. if i.Flags&net.FlagLoopback != 0 {
  871. continue // loopback interface
  872. }
  873. addrs, err := i.Addrs()
  874. if err != nil {
  875. return "", err
  876. }
  877. for _, addr := range addrs {
  878. var ip net.IP
  879. switch v := addr.(type) {
  880. case *net.IPNet:
  881. if !found {
  882. ip = v.IP
  883. local = ip.String()
  884. found = true
  885. }
  886. case *net.IPAddr:
  887. if !found {
  888. ip = v.IP
  889. local = ip.String()
  890. found = true
  891. }
  892. }
  893. }
  894. }
  895. if !found {
  896. err := errors.New("Local Address Not Found.")
  897. return "", err
  898. }
  899. return local, err
  900. }
  901. func CheckIn(network string) error {
  902. node := getNode(network)
  903. cfg, err := config.ReadConfig(network)
  904. if err != nil {
  905. return err
  906. }
  907. nodecfg := cfg.Node
  908. servercfg := cfg.Server
  909. fmt.Println("Checking into server: " + servercfg.Address)
  910. setupcheck := true
  911. ipchange := false
  912. if !(nodecfg.IPForwarding == "off") {
  913. out, err := exec.Command("sysctl", "net.ipv4.ip_forward").Output()
  914. if err != nil {
  915. fmt.Println(err)
  916. fmt.Println("WARNING: Error encountered setting ip forwarding. This can break functionality.")
  917. } else {
  918. s := strings.Fields(string(out))
  919. if s[2] != "1" {
  920. _, err = exec.Command("sysctl", "-w", "net.ipv4.ip_forward=1").Output()
  921. if err != nil {
  922. fmt.Println(err)
  923. fmt.Println("WARNING: Error encountered setting ip forwarding. You may want to investigate this.")
  924. }
  925. }
  926. }
  927. }
  928. if !nodecfg.RoamingOff {
  929. if !nodecfg.IsLocal {
  930. fmt.Println("Checking to see if public addresses have changed")
  931. extIP, err := getPublicIP()
  932. if err != nil {
  933. fmt.Printf("Error encountered checking ip addresses: %v", err)
  934. }
  935. if nodecfg.Endpoint != extIP && extIP != "" {
  936. fmt.Println("Endpoint has changed from " +
  937. nodecfg.Endpoint + " to " + extIP)
  938. fmt.Println("Updating address")
  939. nodecfg.Endpoint = extIP
  940. nodecfg.PostChanges = "true"
  941. node.Endpoint = extIP
  942. node.Postchanges = "true"
  943. ipchange = true
  944. }
  945. intIP, err := getPrivateAddr()
  946. if err != nil {
  947. fmt.Printf("Error encountered checking ip addresses: %v", err)
  948. }
  949. if nodecfg.LocalAddress != intIP && intIP != "" {
  950. fmt.Println("Local Address has changed from " +
  951. nodecfg.LocalAddress + " to " + intIP)
  952. fmt.Println("Updating address")
  953. nodecfg.LocalAddress = intIP
  954. nodecfg.PostChanges = "true"
  955. node.Localaddress = intIP
  956. node.Postchanges = "true"
  957. ipchange = true
  958. }
  959. } else {
  960. fmt.Println("Checking to see if local addresses have changed")
  961. localIP, err := getLocalIP(nodecfg.LocalRange)
  962. if err != nil {
  963. fmt.Printf("Error encountered checking ip addresses: %v", err)
  964. }
  965. if nodecfg.Endpoint != localIP && localIP != "" {
  966. fmt.Println("Endpoint has changed from " +
  967. nodecfg.Endpoint + " to " + localIP)
  968. fmt.Println("Updating address")
  969. nodecfg.Endpoint = localIP
  970. nodecfg.LocalAddress = localIP
  971. nodecfg.PostChanges = "true"
  972. node.Endpoint = localIP
  973. node.Localaddress = localIP
  974. node.Postchanges = "true"
  975. ipchange = true
  976. }
  977. }
  978. if node.Postchanges != "true" {
  979. fmt.Println("Addresses have not changed.")
  980. }
  981. }
  982. if ipchange {
  983. err := modConfig(&node)
  984. if err != nil {
  985. return err
  986. log.Fatalf("Error: %v", err)
  987. }
  988. err = setWGConfig(network)
  989. if err != nil {
  990. return err
  991. log.Fatalf("Error: %v", err)
  992. }
  993. node = getNode(network)
  994. cfg, err := config.ReadConfig(network)
  995. if err != nil {
  996. return err
  997. }
  998. nodecfg = cfg.Node
  999. }
  1000. var wcclient nodepb.NodeServiceClient
  1001. var requestOpts grpc.DialOption
  1002. requestOpts = grpc.WithInsecure()
  1003. conn, err := grpc.Dial(servercfg.Address, requestOpts)
  1004. if err != nil {
  1005. fmt.Printf("Cant dial GRPC server: %v", err)
  1006. return err
  1007. }
  1008. wcclient = nodepb.NewNodeServiceClient(conn)
  1009. ctx := context.Background()
  1010. fmt.Println("Authenticating with GRPC Server")
  1011. ctx, err = SetJWT(wcclient, network)
  1012. if err != nil {
  1013. fmt.Printf("Failed to authenticate: %v", err)
  1014. return err
  1015. }
  1016. fmt.Println("Authenticated")
  1017. fmt.Println("Checking In.")
  1018. var header metadata.MD
  1019. node.Nodenetwork = network
  1020. checkinres, err := wcclient.CheckIn(
  1021. ctx,
  1022. &nodepb.CheckInReq{
  1023. Node: &node,
  1024. },
  1025. grpc.Header(&header),
  1026. )
  1027. if err != nil {
  1028. if checkinres != nil && checkinres.Checkinresponse.Ispending {
  1029. fmt.Println("Node is in pending status. Waiting for Admin approval of node before making further updates.")
  1030. return nil
  1031. }
  1032. fmt.Printf("Unable to process Check In request: %v", err)
  1033. return err
  1034. }
  1035. fmt.Println("Checked in.")
  1036. if checkinres.Checkinresponse.Ispending {
  1037. fmt.Println("Node is in pending status. Waiting for Admin approval of node before making further updates.")
  1038. return err
  1039. }
  1040. newinterface := getNode(network).Interface
  1041. readreq := &nodepb.ReadNodeReq{
  1042. Macaddress: node.Macaddress,
  1043. Network: node.Nodenetwork,
  1044. }
  1045. readres, err := wcclient.ReadNode(ctx, readreq, grpc.Header(&header))
  1046. if err != nil {
  1047. fmt.Printf("Error: %v", err)
  1048. } else {
  1049. currentiface := readres.Node.Interface
  1050. ifaceupdate := newinterface != currentiface
  1051. if err != nil {
  1052. log.Printf("Error retrieving interface: %v", err)
  1053. }
  1054. if ifaceupdate {
  1055. fmt.Println("Interface update: " + currentiface +
  1056. " >>>> " + newinterface)
  1057. err := DeleteInterface(currentiface, nodecfg.PostDown)
  1058. if err != nil {
  1059. fmt.Println("ERROR DELETING INTERFACE: " + currentiface)
  1060. }
  1061. err = setWGConfig(network)
  1062. if err != nil {
  1063. log.Printf("Error updating interface: %v", err)
  1064. }
  1065. }
  1066. }
  1067. if checkinres.Checkinresponse.Needconfigupdate {
  1068. fmt.Println("Server has requested that node update config.")
  1069. fmt.Println("Updating config from remote server.")
  1070. req := &nodepb.ReadNodeReq{
  1071. Macaddress: node.Macaddress,
  1072. Network: node.Nodenetwork,
  1073. }
  1074. readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
  1075. if err != nil {
  1076. return err
  1077. log.Fatalf("Error: %v", err)
  1078. }
  1079. err = modConfig(readres.Node)
  1080. if err != nil {
  1081. return err
  1082. log.Fatalf("Error: %v", err)
  1083. }
  1084. err = setWGConfig(network)
  1085. if err != nil {
  1086. return err
  1087. log.Fatalf("Error: %v", err)
  1088. }
  1089. setupcheck = false
  1090. } else if nodecfg.PostChanges == "true" {
  1091. fmt.Println("Node has requested to update remote config.")
  1092. fmt.Println("Posting local config to remote server.")
  1093. postnode := getNode(network)
  1094. req := &nodepb.UpdateNodeReq{
  1095. Node: &postnode,
  1096. }
  1097. res, err := wcclient.UpdateNode(ctx, req, grpc.Header(&header))
  1098. if err != nil {
  1099. return err
  1100. log.Fatalf("Error: %v", err)
  1101. }
  1102. res.Node.Postchanges = "false"
  1103. err = modConfig(res.Node)
  1104. if err != nil {
  1105. return err
  1106. log.Fatalf("Error: %v", err)
  1107. }
  1108. err = setWGConfig(network)
  1109. if err != nil {
  1110. return err
  1111. log.Fatalf("Error: %v", err)
  1112. }
  1113. setupcheck = false
  1114. }
  1115. if checkinres.Checkinresponse.Needkeyupdate {
  1116. fmt.Println("Server has requested that node update key pairs.")
  1117. fmt.Println("Proceeding to re-generate key pairs for Wiregard.")
  1118. err = setWGKeyConfig(network, servercfg.Address)
  1119. if err != nil {
  1120. return err
  1121. log.Fatalf("Unable to process reset keys request: %v", err)
  1122. }
  1123. setupcheck = false
  1124. }
  1125. if checkinres.Checkinresponse.Needpeerupdate {
  1126. fmt.Println("Server has requested that node update peer list.")
  1127. fmt.Println("Updating peer list from remote server.")
  1128. err = setWGConfig(network)
  1129. if err != nil {
  1130. return err
  1131. log.Fatalf("Unable to process Set Peers request: %v", err)
  1132. }
  1133. setupcheck = false
  1134. }
  1135. if checkinres.Checkinresponse.Needdelete {
  1136. fmt.Println("This machine got the delete signal. Deleting.")
  1137. err := Remove(network)
  1138. if err != nil {
  1139. return err
  1140. log.Fatalf("Error: %v", err)
  1141. }
  1142. }
  1143. if setupcheck {
  1144. iface := nodecfg.Interface
  1145. _, err := net.InterfaceByName(iface)
  1146. if err != nil {
  1147. fmt.Println("interface " + iface + " does not currently exist. Setting up WireGuard.")
  1148. err = setWGKeyConfig(network, servercfg.Address)
  1149. if err != nil {
  1150. return err
  1151. log.Fatalf("Error: %v", err)
  1152. }
  1153. }
  1154. }
  1155. return nil
  1156. }
  1157. func needInterfaceUpdate(ctx context.Context, mac string, network string, iface string) (bool, string, error) {
  1158. var header metadata.MD
  1159. req := &nodepb.ReadNodeReq{
  1160. Macaddress: mac,
  1161. Network: network,
  1162. }
  1163. readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
  1164. if err != nil {
  1165. return false, "", err
  1166. log.Fatalf("Error: %v", err)
  1167. }
  1168. oldiface := readres.Node.Interface
  1169. return iface != oldiface, oldiface, err
  1170. }
  1171. func getNode(network string) nodepb.Node {
  1172. modcfg, err := config.ReadConfig(network)
  1173. if err != nil {
  1174. log.Fatalf("Error: %v", err)
  1175. }
  1176. nodecfg := modcfg.Node
  1177. var node nodepb.Node
  1178. node.Name = nodecfg.Name
  1179. node.Interface = nodecfg.Interface
  1180. node.Nodenetwork = nodecfg.Network
  1181. node.Localaddress = nodecfg.LocalAddress
  1182. node.Address = nodecfg.WGAddress
  1183. node.Address6 = nodecfg.WGAddress6
  1184. node.Listenport = nodecfg.Port
  1185. node.Keepalive = nodecfg.KeepAlive
  1186. node.Postup = nodecfg.PostUp
  1187. node.Postdown = nodecfg.PostDown
  1188. node.Publickey = nodecfg.PublicKey
  1189. node.Macaddress = nodecfg.MacAddress
  1190. node.Endpoint = nodecfg.Endpoint
  1191. node.Password = nodecfg.Password
  1192. node.Dnsoff = nodecfg.DNSOff
  1193. node.Isdualstack = nodecfg.IsDualStack
  1194. return node
  1195. }
  1196. func Remove(network string) error {
  1197. //need to implement checkin on server side
  1198. cfg, err := config.ReadConfig(network)
  1199. if err != nil {
  1200. return err
  1201. }
  1202. servercfg := cfg.Server
  1203. node := cfg.Node
  1204. fmt.Println("Deleting remote node with MAC: " + node.MacAddress)
  1205. var wcclient nodepb.NodeServiceClient
  1206. var requestOpts grpc.DialOption
  1207. requestOpts = grpc.WithInsecure()
  1208. conn, err := grpc.Dial(servercfg.Address, requestOpts)
  1209. if err != nil {
  1210. log.Printf("Unable to establish client connection to " + servercfg.Address + ": %v", err)
  1211. //return err
  1212. }else {
  1213. wcclient = nodepb.NewNodeServiceClient(conn)
  1214. ctx := context.Background()
  1215. fmt.Println("Authenticating with GRPC Server")
  1216. ctx, err = SetJWT(wcclient, network)
  1217. if err != nil {
  1218. //return err
  1219. log.Printf("Failed to authenticate: %v", err)
  1220. } else {
  1221. fmt.Println("Authenticated")
  1222. var header metadata.MD
  1223. _, err = wcclient.DeleteNode(
  1224. ctx,
  1225. &nodepb.DeleteNodeReq{
  1226. Macaddress: node.MacAddress,
  1227. NetworkName: node.Network,
  1228. },
  1229. grpc.Header(&header),
  1230. )
  1231. if err != nil {
  1232. log.Printf("Encountered error deleting node: %v", err)
  1233. fmt.Println(err)
  1234. } else {
  1235. fmt.Println("Deleted node " + node.MacAddress)
  1236. }
  1237. }
  1238. }
  1239. err = WipeLocal(network)
  1240. if err != nil {
  1241. log.Printf("Unable to wipe local config: %v", err)
  1242. }
  1243. err = RemoveSystemDServices(network)
  1244. if err != nil {
  1245. return err
  1246. log.Printf("Unable to remove systemd services: %v", err)
  1247. }
  1248. fmt.Printf("Please investigate any stated errors to ensure proper removal.")
  1249. fmt.Printf("Failure to delete node from server via gRPC will mean node still exists and needs to be manually deleted by administrator.")
  1250. return nil
  1251. }
  1252. func WipeLocal(network string) error{
  1253. cfg, err := config.ReadConfig(network)
  1254. if err != nil {
  1255. return err
  1256. }
  1257. nodecfg := cfg.Node
  1258. ifacename := nodecfg.Interface
  1259. //home, err := homedir.Dir()
  1260. home := "/etc/netclient"
  1261. err = os.Remove(home + "/netconfig-" + network)
  1262. if err != nil {
  1263. fmt.Println(err)
  1264. }
  1265. err = os.Remove(home + "/nettoken-" + network)
  1266. if err != nil {
  1267. fmt.Println(err)
  1268. }
  1269. err = os.Remove(home + "/wgkey-" + network)
  1270. if err != nil {
  1271. fmt.Println(err)
  1272. }
  1273. ipExec, err := exec.LookPath("ip")
  1274. if ifacename != "" {
  1275. cmdIPLinkDel := &exec.Cmd {
  1276. Path: ipExec,
  1277. Args: []string{ ipExec, "link", "del", ifacename },
  1278. Stdout: os.Stdout,
  1279. Stderr: os.Stdout,
  1280. }
  1281. err = cmdIPLinkDel.Run()
  1282. if err != nil {
  1283. fmt.Println(err)
  1284. }
  1285. if nodecfg.PostDown != "" {
  1286. runcmds := strings.Split(nodecfg.PostDown, "; ")
  1287. err = runCmds(runcmds)
  1288. if err != nil {
  1289. fmt.Println("Error encountered running PostDown: " + err.Error())
  1290. }
  1291. }
  1292. }
  1293. return err
  1294. }
  1295. func DeleteInterface(ifacename string, postdown string) error{
  1296. ipExec, err := exec.LookPath("ip")
  1297. cmdIPLinkDel := &exec.Cmd {
  1298. Path: ipExec,
  1299. Args: []string{ ipExec, "link", "del", ifacename },
  1300. Stdout: os.Stdout,
  1301. Stderr: os.Stdout,
  1302. }
  1303. err = cmdIPLinkDel.Run()
  1304. if err != nil {
  1305. fmt.Println(err)
  1306. }
  1307. if postdown != "" {
  1308. runcmds := strings.Split(postdown, "; ")
  1309. err = runCmds(runcmds)
  1310. if err != nil {
  1311. fmt.Println("Error encountered running PostDown: " + err.Error())
  1312. }
  1313. }
  1314. return err
  1315. }