1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060 |
- package functions
- import (
- //"github.com/davecgh/go-spew/spew"
- "fmt"
- "time"
- "errors"
- "context"
- "net/http"
- "io/ioutil"
- "io"
- "strings"
- "log"
- "net"
- "os"
- "strconv"
- "os/exec"
- "github.com/gravitl/netmaker/netclient/config"
- nodepb "github.com/gravitl/netmaker/grpc"
- "golang.zx2c4.com/wireguard/wgctrl"
- "google.golang.org/grpc"
- "google.golang.org/grpc/metadata"
- "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
- //homedir "github.com/mitchellh/go-homedir"
- )
- var (
- wcclient nodepb.NodeServiceClient
- )
- func Install(accesskey string, password string, server string, group string, noauto bool) error {
- wgclient, err := wgctrl.New()
- if err != nil {
- log.Fatalf("failed to open client: %v", err)
- }
- defer wgclient.Close()
- nodecfg := config.Config.Node
- servercfg := config.Config.Server
- fmt.Println("SERVER SETTINGS:")
- if server == "" {
- if servercfg.Address == "" {
- log.Fatal("no server provided")
- } else {
- server = servercfg.Address
- }
- }
- fmt.Println(" Server: " + server)
- if accesskey == "" {
- if servercfg.AccessKey == "" {
- fmt.Println("no access key provided.Proceeding anyway.")
- } else {
- accesskey = servercfg.AccessKey
- }
- }
- fmt.Println(" AccessKey: " + accesskey)
- err = config.WriteServer(server, accesskey)
- if err != nil {
- fmt.Println("Error encountered while writing Server Config.")
- return err
- }
- fmt.Println("NODE REQUESTING SETTINGS:")
- if password == "" {
- if nodecfg.Password == "" {
- //create error here
- log.Fatal("no password provided")
- } else {
- password = nodecfg.Password
- }
- }
- fmt.Println(" Password: " + password)
- if group == "badgroup" {
- if nodecfg.Group == "" {
- //create error here
- log.Fatal("no group provided")
- } else {
- group = nodecfg.Group
- }
- }
- fmt.Println(" Group: " + group)
- var macaddress string
- var localaddress string
- var listenport int32
- var keepalive int32
- var publickey wgtypes.Key
- var privatekey wgtypes.Key
- var privkeystring string
- var endpoint string
- var name string
- var wginterface string
- if nodecfg.Endpoint == "" {
- resp, err := http.Get("https://ifconfig.me")
- if err != nil {
- return err
- }
- defer resp.Body.Close()
- if resp.StatusCode == http.StatusOK {
- bodyBytes, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return err
- }
- endpoint = string(bodyBytes)
- }
- } else {
- endpoint = nodecfg.Endpoint
- }
- fmt.Println(" Public Endpoint: " + endpoint)
- if nodecfg.LocalAddress == "" {
- ifaces, err := net.Interfaces()
- if err != nil {
- return err
- }
- var local string
- found := false
- for _, i := range ifaces {
- if i.Flags&net.FlagUp == 0 {
- continue // interface down
- }
- if i.Flags&net.FlagLoopback != 0 {
- continue // loopback interface
- }
- addrs, err := i.Addrs()
- if err != nil {
- return err
- }
- for _, addr := range addrs {
- var ip net.IP
- switch v := addr.(type) {
- case *net.IPNet:
- if !found {
- ip = v.IP
- local = ip.String()
- found = true
- }
- case *net.IPAddr:
- if !found {
- ip = v.IP
- local = ip.String()
- found = true
- }
- }
- }
- }
- localaddress = local
- } else {
- localaddress = nodecfg.LocalAddress
- }
- fmt.Println(" Local Address: " + localaddress)
- if nodecfg.Name != "" {
- name = nodecfg.Name
- }
- fmt.Println(" Name: " + name)
- if nodecfg.Interface != "" {
- wginterface = nodecfg.Interface
- }
- fmt.Println(" Interface: " + wginterface)
- if nodecfg.KeepAlive != 0 {
- keepalive = nodecfg.KeepAlive
- }
- fmt.Println(" KeepAlive: " + wginterface)
- if nodecfg.Port != 0 {
- listenport = nodecfg.Port
- }
- fmt.Println(" Port: " + string(listenport))
- if nodecfg.PrivateKey != "" {
- privkeystring = nodecfg.PrivateKey
- privatekey, err := wgtypes.ParseKey(nodecfg.PrivateKey)
- if err != nil {
- log.Fatal(err)
- }
- if nodecfg.PublicKey != "" {
- publickey, err = wgtypes.ParseKey(nodecfg.PublicKey)
- if err != nil {
- log.Fatal(err)
- }
- } else {
- publickey = privatekey.PublicKey()
- }
- } else {
- privatekey, err := wgtypes.GeneratePrivateKey()
- if err != nil {
- log.Fatal(err)
- }
- privkeystring = privatekey.String()
- publickey = privatekey.PublicKey()
- }
- if nodecfg.MacAddress != "" {
- macaddress = nodecfg.MacAddress
- } else {
- macs, err := getMacAddr()
- if err != nil {
- return err
- } else if len(macs) == 0 {
- log.Fatal()
- } else {
- macaddress = macs[0]
- }
- }
- fmt.Println(" Mac Address: " + macaddress)
- fmt.Println(" Private Key: " + privatekey.String())
- fmt.Println(" Public Key: " + publickey.String())
- var wcclient nodepb.NodeServiceClient
- var requestOpts grpc.DialOption
- requestOpts = grpc.WithInsecure()
- conn, err := grpc.Dial(server, requestOpts)
- if err != nil {
- log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
- }
- wcclient = nodepb.NewNodeServiceClient(conn)
- postnode := &nodepb.Node{
- Password: password,
- Macaddress: macaddress,
- Accesskey: accesskey,
- Nodegroup: group,
- Listenport: listenport,
- Keepalive: keepalive,
- Localaddress: localaddress,
- Interface: wginterface,
- Publickey: publickey.String(),
- Name: name,
- Endpoint: endpoint,
- }
- fmt.Println("Writing node settings to netconfig file.")
- err = modConfig(postnode)
- if err != nil {
- return err
- }
- res, err := wcclient.CreateNode(
- context.TODO(),
- &nodepb.CreateNodeReq{
- Node: postnode,
- },
- )
- if err != nil {
- return err
- }
- node := res.Node
- fmt.Println("Setting local config from server response")
- if err != nil {
- return err
- }
- fmt.Println("NODE RECIEVED SETTINGS: ")
- fmt.Println(" Password: " + node.Password)
- fmt.Println(" WG Address: " + node.Address)
- fmt.Println(" Group: " + node.Nodegroup)
- fmt.Println(" Public Endpoint: " + node.Endpoint)
- fmt.Println(" Local Address: " + node.Localaddress)
- fmt.Println(" Name: " + node.Name)
- fmt.Println(" Interface: " + node.Interface)
- fmt.Println(" Port: " + strconv.FormatInt(int64(node.Listenport), 10))
- fmt.Println(" KeepAlive: " + strconv.FormatInt(int64(node.Keepalive), 10))
- fmt.Println(" Public Key: " + node.Publickey)
- fmt.Println(" Mac Address: " + node.Macaddress)
- err = modConfig(node)
- if err != nil {
- return err
- }
- if node.Ispending {
- fmt.Println("Node is marked as PENDING.")
- fmt.Println("Awaiting approval from Admin before configuring WireGuard.")
- if !noauto {
- fmt.Println("Configuring Netmaker Service.")
- err = ConfigureSystemD()
- return err
- }
- }
- peers, err := getPeers(node.Macaddress, node.Nodegroup, server)
- if err != nil {
- return err
- }
- fmt.Println("retrived peers, setting wireguard config.")
- err = storePrivKey(privkeystring)
- if err != nil {
- return err
- }
- err = initWireguard(node, privkeystring, peers)
- if err != nil {
- return err
- }
- if !noauto {
- err = ConfigureSystemD()
- }
- if err != nil {
- return err
- }
- return err
- }
- func modConfig(node *nodepb.Node) error{
- modconfig := config.Config
- modconfig.ReadConfig()
- nodecfg := modconfig.Node
- if node.Name != ""{
- nodecfg.Name = node.Name
- }
- if node.Interface != ""{
- nodecfg.Interface = node.Interface
- }
- if node.Nodegroup != ""{
- nodecfg.Group = node.Nodegroup
- }
- if node.Macaddress != ""{
- nodecfg.MacAddress = node.Macaddress
- }
- if node.Localaddress != ""{
- nodecfg.LocalAddress = node.Localaddress
- }
- if node.Listenport != 0{
- nodecfg.Port = node.Listenport
- }
- if node.Keepalive != 0{
- nodecfg.KeepAlive = node.Keepalive
- }
- if node.Publickey != ""{
- nodecfg.PublicKey = node.Publickey
- }
- if node.Endpoint != ""{
- nodecfg.Endpoint = node.Endpoint
- }
- if node.Password != ""{
- nodecfg.Password = node.Password
- }
- if node.Address != ""{
- nodecfg.WGAddress = node.Address
- }
- if node.Postchanges != "" {
- nodecfg.PostChanges = node.Postchanges
- }
- modconfig.Node = nodecfg
- err := config.Write(modconfig)
- return err
- }
- func getMacAddr() ([]string, error) {
- ifas, err := net.Interfaces()
- if err != nil {
- return nil, err
- }
- var as []string
- for _, ifa := range ifas {
- a := ifa.HardwareAddr.String()
- if a != "" {
- as = append(as, a)
- }
- }
- return as, nil
- }
- /*
- func read(macaddress string, group string) error {
- //this would be used for retrieving state as set by the server.
- }
- func checkLocalConfigChange() error {
- }
- */
- func initWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig) error {
- ipExec, err := exec.LookPath("ip")
- if err != nil {
- return err
- }
- key, err := wgtypes.ParseKey(privkey)
- if err != nil {
- return err
- }
- wgclient, err := wgctrl.New()
- modcfg := config.Config
- modcfg.ReadConfig()
- nodecfg := modcfg.Node
- fmt.Println("beginning local WG config")
- if err != nil {
- log.Fatalf("failed to open client: %v", err)
- }
- defer wgclient.Close()
- fmt.Println("setting local settings")
- ifacename := node.Interface
- if nodecfg.Interface != "" {
- ifacename = nodecfg.Interface
- } else if node.Interface != "" {
- ifacename = node.Interface
- } else {
- log.Fatal("no interface to configure")
- }
- if node.Address == "" {
- log.Fatal("no address to configure")
- }
- cmdIPDevLinkAdd := &exec.Cmd {
- Path: ipExec,
- Args: []string{ ipExec, "link", "add", "dev", ifacename, "type", "wireguard" },
- Stdout: os.Stdout,
- Stderr: os.Stdout,
- }
- cmdIPAddrAdd := &exec.Cmd {
- Path: ipExec,
- Args: []string{ ipExec, "address", "add", "dev", ifacename, node.Address+"/24"},
- Stdout: os.Stdout,
- Stderr: os.Stdout,
- }
- currentiface, err := net.InterfaceByName(ifacename)
- if err != nil {
- err = cmdIPDevLinkAdd.Run()
- if err != nil && !strings.Contains(err.Error(), "exists") {
- fmt.Println("Error creating interface")
- //fmt.Println(err.Error())
- //return err
- }
- }
- match := false
- addrs, _ := currentiface.Addrs()
- for _, a := range addrs {
- if strings.Contains(a.String(), node.Address){
- match = true
- }
- }
- if !match {
- err = cmdIPAddrAdd.Run()
- if err != nil {
- fmt.Println("Error adding address")
- //return err
- }
- }
- var nodeport int
- nodeport = int(node.Listenport)
- fmt.Println("setting WG config from node and peers")
- //pubkey := privkey.PublicKey()
- conf := wgtypes.Config{
- PrivateKey: &key,
- ListenPort: &nodeport,
- ReplacePeers: true,
- Peers: peers,
- }
- _, err = wgclient.Device(ifacename)
- if err != nil {
- if os.IsNotExist(err) {
- fmt.Println("Device does not exist: ")
- fmt.Println(err)
- } else {
- log.Fatalf("Unknown config error: %v", err)
- }
- }
- fmt.Println("configuring WG device")
- err = wgclient.ConfigureDevice(ifacename, conf)
- if err != nil {
- if os.IsNotExist(err) {
- fmt.Println("Device does not exist: ")
- fmt.Println(err)
- } else {
- fmt.Printf("This is inconvenient: %v", err)
- }
- }
- cmdIPLinkUp := &exec.Cmd {
- Path: ipExec,
- Args: []string{ ipExec, "link", "set", "up", "dev", ifacename},
- Stdout: os.Stdout,
- Stderr: os.Stdout,
- }
- cmdIPLinkDown := &exec.Cmd {
- Path: ipExec,
- Args: []string{ ipExec, "link", "set", "down", "dev", ifacename},
- Stdout: os.Stdout,
- Stderr: os.Stdout,
- }
- err = cmdIPLinkDown.Run()
- err = cmdIPLinkUp.Run()
- if err != nil {
- return err
- }
- return err
- }
- func setWGConfig() error {
- servercfg := config.Config.Server
- nodecfg := config.Config.Node
- node := getNode()
- peers, err := getPeers(node.Macaddress, nodecfg.Group, servercfg.Address)
- if err != nil {
- return err
- }
- privkey, err := retrievePrivKey()
- if err != nil {
- return err
- }
- err = initWireguard(&node, privkey, peers)
- if err != nil {
- return err
- }
- return err
- }
- func storePrivKey(key string) error{
- d1 := []byte(key)
- err := ioutil.WriteFile("/root/.wckey", d1, 0644)
- return err
- }
- func retrievePrivKey() (string, error) {
- dat, err := ioutil.ReadFile("/root/.wckey")
- return string(dat), err
- }
- func getPublicAddr() (string, error) {
- resp, err := http.Get("https://ifconfig.me")
- if err != nil {
- return "", err
- }
- defer resp.Body.Close()
- endpoint := ""
- if resp.StatusCode == http.StatusOK {
- bodyBytes, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return "", err
- }
- endpoint = string(bodyBytes)
- }
- return endpoint, err
- }
- func getPrivateAddr() (string, error) {
- ifaces, err := net.Interfaces()
- if err != nil {
- return "", err
- }
- var local string
- found := false
- for _, i := range ifaces {
- if i.Flags&net.FlagUp == 0 {
- continue // interface down
- }
- if i.Flags&net.FlagLoopback != 0 {
- continue // loopback interface
- }
- addrs, err := i.Addrs()
- if err != nil {
- return "", err
- }
- for _, addr := range addrs {
- var ip net.IP
- switch v := addr.(type) {
- case *net.IPNet:
- if !found {
- ip = v.IP
- local = ip.String()
- found = true
- }
- case *net.IPAddr:
- if !found {
- ip = v.IP
- local = ip.String()
- found = true
- }
- }
- }
- }
- if !found {
- err := errors.New("Local Address Not Found.")
- return "", err
- }
- return local, err
- }
- func CheckIn() error {
- node := getNode()
- nodecfg := config.Config.Node
- servercfg := config.Config.Server
- fmt.Println("Checking into server: " + servercfg.Address)
- setupcheck := true
- ipchange := false
- if !nodecfg.RoamingOff {
- fmt.Println("Checking to see if addresses have changed")
- extIP, err := getPublicAddr()
- if err != nil {
- fmt.Printf("Error encountered checking ip addresses: %v", err)
- }
- if nodecfg.Endpoint != extIP && extIP != "" {
- fmt.Println("Endpoint has changed from " +
- nodecfg.Endpoint + " to " + extIP)
- fmt.Println("Updating address")
- nodecfg.Endpoint = extIP
- nodecfg.PostChanges = "true"
- node.Endpoint = extIP
- node.Postchanges = "true"
- ipchange = true
- }
- intIP, err := getPrivateAddr()
- if err != nil {
- fmt.Printf("Error encountered checking ip addresses: %v", err)
- }
- if nodecfg.LocalAddress != intIP && intIP != "" {
- fmt.Println("Local Address has changed from " +
- nodecfg.LocalAddress + " to " + intIP)
- fmt.Println("Updating address")
- nodecfg.LocalAddress = intIP
- nodecfg.PostChanges = "true"
- node.Localaddress = intIP
- node.Postchanges = "true"
- ipchange = true
- }
- if node.Postchanges != "true" {
- fmt.Println("Addresses have not changed.")
- }
- }
- if ipchange {
- err := modConfig(&node)
- if err != nil {
- return err
- log.Fatalf("Error: %v", err)
- }
- err = setWGConfig()
- if err != nil {
- return err
- log.Fatalf("Error: %v", err)
- }
- node = getNode()
- nodecfg = config.Config.Node
- }
- var wcclient nodepb.NodeServiceClient
- var requestOpts grpc.DialOption
- requestOpts = grpc.WithInsecure()
- conn, err := grpc.Dial(servercfg.Address, requestOpts)
- if err != nil {
- fmt.Printf("Cant dial GRPC server: %v", err)
- return err
- }
- wcclient = nodepb.NewNodeServiceClient(conn)
- ctx := context.Background()
- fmt.Println("Authenticating with GRPC Server")
- ctx, err = SetJWT(wcclient)
- if err != nil {
- fmt.Printf("Failed to authenticate: %v", err)
- return err
- }
- fmt.Println("Authenticated")
- fmt.Println("Checking In.")
- var header metadata.MD
- checkinres, err := wcclient.CheckIn(
- ctx,
- &nodepb.CheckInReq{
- Node: &node,
- },
- grpc.Header(&header),
- )
- if err != nil {
- if checkinres != nil && checkinres.Checkinresponse.Ispending {
- fmt.Println("Node is in pending status. Waiting for Admin approval of node before making furtherupdates.")
- return nil
- }
- fmt.Printf("Unable to process Check In request: %v", err)
- return err
- }
- fmt.Println("Checked in.")
- if checkinres.Checkinresponse.Ispending {
- fmt.Println("Node is in pending status. Waiting for Admin approval of node before making furtherupdates.")
- return err
- }
- newinterface := getNode().Interface
- readreq := &nodepb.ReadNodeReq{
- Macaddress: node.Macaddress,
- Group: node.Nodegroup,
- }
- readres, err := wcclient.ReadNode(ctx, readreq, grpc.Header(&header))
- if err != nil {
- fmt.Printf("Error: %v", err)
- } else {
- currentiface := readres.Node.Interface
- ifaceupdate := newinterface != currentiface
- if err != nil {
- log.Printf("Error retrieving interface: %v", err)
- }
- if ifaceupdate {
- fmt.Println("Interface update: " + currentiface +
- " >>>> " + newinterface)
- err := DeleteInterface(currentiface)
- if err != nil {
- fmt.Println("ERROR DELETING INTERFACE: " + currentiface)
- }
- }
- err = setWGConfig()
- }
- if checkinres.Checkinresponse.Needconfigupdate {
- fmt.Println("Server has requested that node update config.")
- fmt.Println("Updating config from remote server.")
- req := &nodepb.ReadNodeReq{
- Macaddress: node.Macaddress,
- Group: node.Nodegroup,
- }
- readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
- if err != nil {
- return err
- log.Fatalf("Error: %v", err)
- }
- err = modConfig(readres.Node)
- if err != nil {
- return err
- log.Fatalf("Error: %v", err)
- }
- err = setWGConfig()
- if err != nil {
- return err
- log.Fatalf("Error: %v", err)
- }
- setupcheck = false
- } else if nodecfg.PostChanges == "true" {
- fmt.Println("Node has requested to update remote config.")
- fmt.Println("Posting local config to remote server.")
- postnode := getNode()
- req := &nodepb.UpdateNodeReq{
- Node: &postnode,
- }
- res, err := wcclient.UpdateNode(ctx, req, grpc.Header(&header))
- if err != nil {
- return err
- log.Fatalf("Error: %v", err)
- }
- res.Node.Postchanges = "false"
- err = modConfig(res.Node)
- if err != nil {
- return err
- log.Fatalf("Error: %v", err)
- }
- err = setWGConfig()
- if err != nil {
- return err
- log.Fatalf("Error: %v", err)
- }
- setupcheck = false
- }
- if checkinres.Checkinresponse.Needpeerupdate {
- fmt.Println("Server has requested that node update peer list.")
- fmt.Println("Updating peer list from remote server.")
- err = setWGConfig()
- if err != nil {
- return err
- log.Fatalf("Unable to process Set Peers request: %v", err)
- }
- setupcheck = false
- }
- if setupcheck {
- iface := nodecfg.Interface
- _, err := net.InterfaceByName(iface)
- if err != nil {
- fmt.Println("interface " + iface + " does not currently exist. Setting up WireGuard.")
- err = setWGConfig()
- if err != nil {
- return err
- log.Fatalf("Error: %v", err)
- }
- }
- }
- return nil
- }
- func needInterfaceUpdate(ctx context.Context, mac string, group string, iface string) (bool, string, error) {
- var header metadata.MD
- req := &nodepb.ReadNodeReq{
- Macaddress: mac,
- Group: group,
- }
- readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
- if err != nil {
- return false, "", err
- log.Fatalf("Error: %v", err)
- }
- oldiface := readres.Node.Interface
- return iface != oldiface, oldiface, err
- }
- func getNode() nodepb.Node {
- modcfg := config.Config
- modcfg.ReadConfig()
- nodecfg := modcfg.Node
- var node nodepb.Node
- node.Name = nodecfg.Name
- node.Interface = nodecfg.Interface
- node.Nodegroup = nodecfg.Group
- node.Localaddress = nodecfg.LocalAddress
- node.Address = nodecfg.WGAddress
- node.Listenport = nodecfg.Port
- node.Keepalive = nodecfg.KeepAlive
- node.Postup = nodecfg.PostUp
- node.Preup = nodecfg.PreUp
- node.Publickey = nodecfg.PublicKey
- node.Macaddress = nodecfg.MacAddress
- node.Endpoint = nodecfg.Endpoint
- node.Password = nodecfg.Password
- //spew.Dump(node)
- return node
- }
- func Remove() error {
- //need to implement checkin on server side
- servercfg := config.Config.Server
- node := config.Config.Node
- fmt.Println("Deleting remote node with MAC: " + node.MacAddress)
- var wcclient nodepb.NodeServiceClient
- var requestOpts grpc.DialOption
- requestOpts = grpc.WithInsecure()
- conn, err := grpc.Dial(servercfg.Address, requestOpts)
- if err != nil {
- log.Printf("Unable to establish client connection to " + servercfg.Address + ": %v", err)
- return err
- }
- wcclient = nodepb.NewNodeServiceClient(conn)
- ctx := context.Background()
- fmt.Println("Authenticating with GRPC Server")
- ctx, err = SetJWT(wcclient)
- if err != nil {
- return err
- log.Fatalf("Failed to authenticate: %v", err)
- }
- fmt.Println("Authenticated")
- var header metadata.MD
- _, err = wcclient.DeleteNode(
- ctx,
- &nodepb.DeleteNodeReq{
- Macaddress: node.MacAddress,
- GroupName: node.Group,
- },
- grpc.Header(&header),
- )
- if err != nil {
- fmt.Println("Encountered error deleting node.")
- fmt.Println(err)
- //return err
- //log.Fatalf("Unable to process Delete request: %v", err)
- }
- fmt.Println("Deleted node " + node.MacAddress)
- err = WipeLocal()
- if err != nil {
- //return err
- log.Printf("Unable to wipe local config: %v", err)
- }
- err = RemoveSystemDServices()
- if err != nil {
- return err
- log.Fatalf("Unable to remove systemd services: %v", err)
- }
- return nil
- }
- func WipeLocal() error{
- nodecfg := config.Config.Node
- ifacename := nodecfg.Interface
- //home, err := homedir.Dir()
- home := "/etc/netclient"
- err := os.Remove(home + "/.netconfig")
- if err != nil {
- fmt.Println(err)
- }
- err = os.Remove(home + "/.nettoken")
- if err != nil {
- fmt.Println(err)
- }
- ipExec, err := exec.LookPath("ip")
- if ifacename != "" {
- cmdIPLinkDel := &exec.Cmd {
- Path: ipExec,
- Args: []string{ ipExec, "link", "del", ifacename },
- Stdout: os.Stdout,
- Stderr: os.Stdout,
- }
- err = cmdIPLinkDel.Run()
- if err != nil {
- fmt.Println(err)
- }
- }
- return err
- }
- func DeleteInterface(ifacename string) error{
- ipExec, err := exec.LookPath("ip")
- cmdIPLinkDel := &exec.Cmd {
- Path: ipExec,
- Args: []string{ ipExec, "link", "del", ifacename },
- Stdout: os.Stdout,
- Stderr: os.Stdout,
- }
- err = cmdIPLinkDel.Run()
- if err != nil {
- fmt.Println(err)
- }
- return err
- }
- func getPeers(macaddress string, group string, server string) ([]wgtypes.PeerConfig, error) {
- //need to implement checkin on server side
- var peers []wgtypes.PeerConfig
- var wcclient nodepb.NodeServiceClient
- modcfg := config.Config
- modcfg.ReadConfig()
- nodecfg := modcfg.Node
- keepalive := nodecfg.KeepAlive
- keepalivedur, err := time.ParseDuration(strconv.FormatInt(int64(keepalive), 10) + "s")
- if err != nil {
- log.Fatalf("Issue with format of keepalive value. Please update netconfig: %v", err)
- }
- fmt.Println("Registering with GRPC Server")
- requestOpts := grpc.WithInsecure()
- conn, err := grpc.Dial(server, requestOpts)
- if err != nil {
- log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
- }
- // Instantiate the BlogServiceClient with our client connection to the server
- wcclient = nodepb.NewNodeServiceClient(conn)
- req := &nodepb.GetPeersReq{
- Macaddress: macaddress,
- Group: group,
- }
- ctx := context.Background()
- fmt.Println("Authenticating with GRPC Server")
- ctx, err = SetJWT(wcclient)
- if err != nil {
- fmt.Println("Failed to authenticate.")
- return peers, err
- }
- var header metadata.MD
- stream, err := wcclient.GetPeers(ctx, req, grpc.Header(&header))
- if err != nil {
- return nil, err
- }
- fmt.Println("Parsing peers response")
- for {
- // stream.Recv returns a pointer to a ListBlogRes at the current iteration
- res, err := stream.Recv()
- // If end of stream, break the loop
- if err == io.EOF {
- break
- }
- // if err, return an error
- if err != nil {
- if strings.Contains(err.Error(), "mongo: no documents in result") {
- break
- } else {
- fmt.Println("ERROR ENCOUNTERED WITH RESPONSE")
- fmt.Println(res)
- return peers, err
- }
- }
- pubkey, err := wgtypes.ParseKey(res.Peers.Publickey)
- if err != nil {
- fmt.Println("error parsing key")
- return peers, err
- }
- var peer wgtypes.PeerConfig
- if keepalive != 0 {
- peer = wgtypes.PeerConfig{
- PublicKey: pubkey,
- PersistentKeepaliveInterval: &keepalivedur,
- Endpoint: &net.UDPAddr{
- IP: net.ParseIP(res.Peers.Endpoint),
- Port: int(res.Peers.Listenport),
- },
- ReplaceAllowedIPs: true,
- AllowedIPs: []net.IPNet{{
- IP: net.ParseIP(res.Peers.Address),
- Mask: net.CIDRMask(32, 32),
- }},
- }
- } else {
- peer = wgtypes.PeerConfig{
- PublicKey: pubkey,
- Endpoint: &net.UDPAddr{
- IP: net.ParseIP(res.Peers.Endpoint),
- Port: int(res.Peers.Listenport),
- },
- ReplaceAllowedIPs: true,
- AllowedIPs: []net.IPNet{{
- IP: net.ParseIP(res.Peers.Address),
- Mask: net.CIDRMask(32, 32),
- }},
- }
- }
- peers = append(peers, peer)
- }
- fmt.Println("Finished parsing peers response")
- return peers, err
- }
|