2021-03-26 00:17:52 +08:00
package functions
import (
"fmt"
"time"
2021-03-26 22:35:52 +08:00
"errors"
2021-03-26 00:17:52 +08:00
"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"
2021-04-06 02:47:07 +08:00
"encoding/base64"
2021-03-26 00:17:52 +08:00
"google.golang.org/grpc/metadata"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
2021-03-26 10:29:36 +08:00
//homedir "github.com/mitchellh/go-homedir"
2021-03-26 00:17:52 +08:00
)
var (
wcclient nodepb . NodeServiceClient
)
2021-04-07 09:31:47 +08:00
func ListPorts ( ) error {
wgclient , err := wgctrl . New ( )
if err != nil {
return err
}
devices , err := wgclient . Devices ( )
if err != nil {
return err
}
fmt . Println ( "Here are your ports:" )
for _ , i := range devices {
fmt . Println ( i . ListenPort )
}
return err
}
func GetFreePort ( rangestart int32 ) ( int32 , error ) {
wgclient , err := wgctrl . New ( )
if err != nil {
return 0 , err
}
devices , err := wgclient . Devices ( )
if err != nil {
return 0 , err
}
var portno int32
portno = 0
for x := rangestart ; x <= 60000 ; x ++ {
conflict := false
for _ , i := range devices {
if int32 ( i . ListenPort ) == x {
conflict = true
break ;
}
}
if conflict {
continue
}
portno = x
break
}
return portno , err
}
2021-04-13 12:42:35 +08:00
func Install ( accesskey string , password string , server string , network string , noauto bool , accesstoken string , inputname string ) error {
2021-04-06 02:47:07 +08:00
tserver := ""
tnetwork := ""
tkey := ""
2021-04-13 11:19:01 +08:00
trange := ""
var localrange * net . IPNet
islocal := false
2021-04-13 12:42:35 +08:00
if FileExists ( "/etc/systemd/system/netclient-" + network + ".timer" ) ||
FileExists ( "/etc/netclient/netconfig-" + network ) {
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." )
2021-04-08 21:04:21 +08:00
return err
}
2021-04-06 02:47:07 +08:00
if accesstoken != "" && accesstoken != "badtoken" {
btoken , err := base64 . StdEncoding . DecodeString ( accesstoken )
if err != nil {
log . Fatalf ( "Something went wrong decoding your token: %v" , err )
}
token := string ( btoken )
2021-04-13 13:10:57 +08:00
tokenvals := strings . Split ( token , "|" )
2021-04-06 02:47:07 +08:00
tserver = tokenvals [ 0 ]
tnetwork = tokenvals [ 1 ]
tkey = tokenvals [ 2 ]
2021-04-13 11:19:01 +08:00
trange = tokenvals [ 3 ]
2021-04-13 12:42:35 +08:00
printrange := ""
if server == "localhost:50051" {
2021-04-13 11:19:01 +08:00
server = tserver
}
2021-04-13 12:42:35 +08:00
if network == "nonetwork" {
network = tnetwork
2021-04-13 11:19:01 +08:00
}
2021-04-13 12:42:35 +08:00
if accesskey == "badkey" {
2021-04-13 11:19:01 +08:00
accesskey = tkey
}
2021-04-13 13:10:57 +08:00
fmt . Println ( trange )
2021-04-13 11:19:01 +08:00
if trange != "" {
2021-04-18 00:13:26 +08:00
fmt . Println ( "This is a local network. Proceeding with local address as endpoint." )
2021-04-13 11:19:01 +08:00
islocal = true
_ , localrange , err = net . ParseCIDR ( trange )
2021-04-13 13:10:57 +08:00
if err == nil {
printrange = localrange . String ( )
} else {
//localrange = ""
}
2021-04-13 11:19:01 +08:00
} else {
2021-04-13 12:42:35 +08:00
printrange = "Not a local network. Will use public address for endpoint."
2021-04-13 11:19:01 +08:00
}
2021-04-06 02:47:07 +08:00
fmt . Println ( "Decoded values from token:" )
2021-04-13 12:42:35 +08:00
fmt . Println ( " Server: " + server )
fmt . Println ( " Network: " + network )
fmt . Println ( " Key: " + accesskey )
fmt . Println ( " Local Range: " + printrange )
2021-04-06 02:47:07 +08:00
}
2021-04-13 12:42:35 +08:00
2021-03-26 00:17:52 +08:00
wgclient , err := wgctrl . New ( )
if err != nil {
log . Fatalf ( "failed to open client: %v" , err )
}
defer wgclient . Close ( )
2021-04-13 12:42:35 +08:00
cfg , err := config . ReadConfig ( network )
2021-04-05 23:06:30 +08:00
if err != nil {
log . Printf ( "No Config Yet. Will Write: %v" , err )
}
nodecfg := cfg . Node
servercfg := cfg . Server
2021-03-26 00:17:52 +08:00
fmt . Println ( "SERVER SETTINGS:" )
if server == "" {
2021-04-06 02:47:07 +08:00
if servercfg . Address == "" && tserver == "" {
2021-03-26 00:17:52 +08:00
log . Fatal ( "no server provided" )
} else {
server = servercfg . Address
}
}
fmt . Println ( " Server: " + server )
if accesskey == "" {
2021-04-06 02:47:07 +08:00
if servercfg . AccessKey == "" && tkey == "" {
2021-03-26 00:17:52 +08:00
fmt . Println ( "no access key provided.Proceeding anyway." )
} else {
accesskey = servercfg . AccessKey
}
}
fmt . Println ( " AccessKey: " + accesskey )
2021-04-13 12:42:35 +08:00
err = config . WriteServer ( server , accesskey , network )
2021-03-26 00:17:52 +08:00
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 )
2021-04-13 12:42:35 +08:00
if network == "badnetwork" {
if nodecfg . Network == "" && tnetwork == "" {
2021-03-26 00:17:52 +08:00
//create error here
2021-04-13 12:42:35 +08:00
log . Fatal ( "no network provided" )
2021-03-26 00:17:52 +08:00
} else {
2021-04-13 12:42:35 +08:00
network = nodecfg . Network
2021-03-26 00:17:52 +08:00
}
}
2021-04-13 12:42:35 +08:00
fmt . Println ( " Network: " + network )
2021-03-26 00:17:52 +08:00
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
2021-04-15 10:59:25 +08:00
var postup string
var postdown string
2021-03-26 00:17:52 +08:00
var name string
var wginterface string
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 ( )
2021-04-13 11:19:01 +08:00
if islocal {
found = localrange . Contains ( ip )
} else {
found = true
}
2021-03-26 00:17:52 +08:00
}
case * net . IPAddr :
if ! found {
ip = v . IP
local = ip . String ( )
2021-04-13 11:19:01 +08:00
if islocal {
found = localrange . Contains ( ip )
} else {
found = true
}
2021-03-26 00:17:52 +08:00
}
}
}
}
localaddress = local
} else {
localaddress = nodecfg . LocalAddress
}
fmt . Println ( " Local Address: " + localaddress )
2021-04-18 00:13:26 +08:00
if nodecfg . Endpoint == "" {
if islocal && localaddress != "" {
endpoint = localaddress
2021-04-19 22:02:30 +08:00
fmt . Println ( "Endpoint is local. Setting to address: " + endpoint )
2021-04-18 00:13:26 +08:00
} else {
2021-04-19 22:02:30 +08:00
2021-04-18 00:13:26 +08:00
endpoint , err = getPublicIP ( )
if err != nil {
2021-04-19 22:02:30 +08:00
fmt . Println ( "Error setting endpoint." )
2021-04-18 00:13:26 +08:00
return err
}
2021-04-19 22:02:30 +08:00
fmt . Println ( "Endpoint is public. Setting to address: " + endpoint )
2021-04-18 00:13:26 +08:00
}
} else {
endpoint = nodecfg . Endpoint
2021-04-19 22:02:30 +08:00
fmt . Println ( "Endpoint set in config. Setting to address: " + endpoint )
2021-04-18 00:13:26 +08:00
}
2021-04-19 22:02:30 +08:00
fmt . Println ( " Endpoint: " + endpoint )
2021-04-18 00:13:26 +08:00
2021-03-26 00:17:52 +08:00
if nodecfg . Name != "" {
name = nodecfg . Name
}
2021-04-07 07:13:34 +08:00
if inputname != "" && inputname != "noname" {
name = inputname
}
2021-03-26 00:17:52 +08:00
fmt . Println ( " Name: " + name )
if nodecfg . Interface != "" {
wginterface = nodecfg . Interface
}
fmt . Println ( " Interface: " + wginterface )
2021-04-15 10:59:25 +08:00
if nodecfg . PostUp != "" {
postup = nodecfg . PostUp
}
fmt . Println ( " PostUp: " + postup )
if nodecfg . PostDown != "" {
postdown = nodecfg . PostDown
}
fmt . Println ( " PostDown: " + postdown )
2021-03-26 00:17:52 +08:00
if nodecfg . KeepAlive != 0 {
keepalive = nodecfg . KeepAlive
}
fmt . Println ( " KeepAlive: " + wginterface )
if nodecfg . Port != 0 {
listenport = nodecfg . Port
}
2021-04-07 09:31:47 +08:00
if listenport == 0 {
listenport , err = GetFreePort ( 51821 )
if err != nil {
fmt . Printf ( "Error retrieving port: %v" , err )
}
}
fmt . Printf ( " Port: %v" , listenport )
fmt . Println ( "" )
2021-03-26 00:17:52 +08:00
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 ,
2021-04-13 12:42:35 +08:00
Nodenetwork : network ,
2021-03-26 00:17:52 +08:00
Listenport : listenport ,
2021-04-15 10:59:25 +08:00
Postup : postup ,
Postdown : postdown ,
2021-03-26 00:17:52 +08:00
Keepalive : keepalive ,
Localaddress : localaddress ,
Interface : wginterface ,
Publickey : publickey . String ( ) ,
Name : name ,
Endpoint : endpoint ,
}
2021-03-26 10:29:36 +08:00
fmt . Println ( "Writing node settings to netconfig file." )
2021-03-26 00:17:52 +08:00
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 )
2021-04-13 12:42:35 +08:00
fmt . Println ( " Network: " + node . Nodenetwork )
2021-03-26 00:17:52 +08:00
fmt . Println ( " Public Endpoint: " + node . Endpoint )
fmt . Println ( " Local Address: " + node . Localaddress )
fmt . Println ( " Name: " + node . Name )
fmt . Println ( " Interface: " + node . Interface )
2021-04-15 10:59:25 +08:00
fmt . Println ( " PostUp: " + node . Postup )
fmt . Println ( " PostDown: " + node . Postdown )
2021-03-26 00:17:52 +08:00
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 )
2021-04-18 00:13:26 +08:00
fmt . Println ( " Is Local?: " + strconv . FormatBool ( node . Islocal ) )
fmt . Println ( " Local Range: " + node . Localrange )
if ! islocal && node . Islocal && node . Localrange != "" {
2021-04-19 22:02:30 +08:00
fmt . Println ( "Resetting local settings for local network." )
2021-04-18 00:13:26 +08:00
node . Localaddress , err = getLocalIP ( node . Localrange )
if err != nil {
return err
}
node . Endpoint = node . Localaddress
}
2021-03-26 00:17:52 +08:00
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 {
2021-03-26 10:29:36 +08:00
fmt . Println ( "Configuring Netmaker Service." )
2021-04-13 12:42:35 +08:00
err = ConfigureSystemD ( network )
2021-03-26 00:17:52 +08:00
return err
}
}
2021-04-18 00:13:26 +08:00
peers , hasGateway , gateways , err := getPeers ( node . Macaddress , network , server )
2021-03-26 00:17:52 +08:00
if err != nil {
return err
}
fmt . Println ( "retrived peers, setting wireguard config." )
2021-04-13 12:42:35 +08:00
err = storePrivKey ( privkeystring , network )
2021-03-26 00:17:52 +08:00
if err != nil {
return err
}
2021-04-18 00:13:26 +08:00
err = initWireguard ( node , privkeystring , peers , hasGateway , gateways )
2021-03-26 00:17:52 +08:00
if err != nil {
return err
}
if ! noauto {
2021-04-13 12:42:35 +08:00
err = ConfigureSystemD ( network )
2021-03-26 00:17:52 +08:00
}
if err != nil {
return err
}
return err
}
2021-03-28 00:04:44 +08:00
2021-04-18 00:13:26 +08:00
func getLocalIP ( localrange string ) ( string , error ) {
_ , localRange , err := net . ParseCIDR ( localrange )
if err != nil {
return "" , err
}
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 = localRange . Contains ( ip )
}
case * net . IPAddr :
if ! found {
ip = v . IP
local = ip . String ( )
found = localRange . Contains ( ip )
}
}
}
}
if ! found || local == "" {
return "" , errors . New ( "Failed to find local IP in range " + localrange )
}
return local , nil
}
2021-03-28 00:04:44 +08:00
func getPublicIP ( ) ( string , error ) {
iplist := [ ] string { "https://ifconfig.me" , "http://api.ipify.org" , "http://ipinfo.io/ip" }
endpoint := ""
var err error
for _ , ipserver := range iplist {
resp , err := http . Get ( ipserver )
if err != nil {
continue
}
defer resp . Body . Close ( )
if resp . StatusCode == http . StatusOK {
bodyBytes , err := ioutil . ReadAll ( resp . Body )
if err != nil {
continue
}
endpoint = string ( bodyBytes )
break
}
}
if err == nil && endpoint == "" {
err = errors . New ( "Public Address Not Found." )
}
return endpoint , err
}
2021-03-26 00:17:52 +08:00
func modConfig ( node * nodepb . Node ) error {
2021-04-13 12:42:35 +08:00
network := node . Nodenetwork
if network == "" {
return errors . New ( "No Network Provided" )
2021-04-05 23:06:30 +08:00
}
2021-04-13 12:42:35 +08:00
modconfig , err := config . ReadConfig ( network )
2021-04-05 23:06:30 +08:00
if err != nil {
return err
}
2021-03-26 00:17:52 +08:00
nodecfg := modconfig . Node
if node . Name != "" {
nodecfg . Name = node . Name
}
if node . Interface != "" {
nodecfg . Interface = node . Interface
}
2021-04-13 12:42:35 +08:00
if node . Nodenetwork != "" {
nodecfg . Network = node . Nodenetwork
2021-03-26 00:17:52 +08:00
}
if node . Macaddress != "" {
nodecfg . MacAddress = node . Macaddress
}
if node . Localaddress != "" {
nodecfg . LocalAddress = node . Localaddress
}
2021-04-15 10:59:25 +08:00
if node . Postup != "" {
nodecfg . PostUp = node . Postup
}
if node . Postdown != "" {
nodecfg . PostDown = node . Postdown
}
2021-03-26 00:17:52 +08:00
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
}
2021-04-18 00:13:26 +08:00
if node . Localrange != "" && node . Islocal {
nodecfg . IsLocal = true
nodecfg . LocalRange = node . Localrange
}
2021-03-26 00:17:52 +08:00
modconfig . Node = nodecfg
2021-04-13 12:42:35 +08:00
err = config . Write ( modconfig , network )
2021-03-26 00:17:52 +08:00
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
}
2021-04-18 00:13:26 +08:00
func initWireguard ( node * nodepb . Node , privkey string , peers [ ] wgtypes . PeerConfig , hasGateway bool , gateways [ ] string ) error {
2021-03-26 00:17:52 +08:00
ipExec , err := exec . LookPath ( "ip" )
if err != nil {
return err
}
key , err := wgtypes . ParseKey ( privkey )
if err != nil {
return err
}
wgclient , err := wgctrl . New ( )
2021-04-05 23:06:30 +08:00
//modcfg := config.Config
//modcfg.ReadConfig()
2021-04-13 12:42:35 +08:00
modcfg , err := config . ReadConfig ( node . Nodenetwork )
2021-04-05 23:06:30 +08:00
if err != nil {
return err
}
2021-03-26 00:17:52 +08:00
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 ,
}
2021-03-26 12:04:04 +08:00
currentiface , err := net . InterfaceByName ( ifacename )
if err != nil {
err = cmdIPDevLinkAdd . Run ( )
2021-03-26 00:17:52 +08:00
if err != nil && ! strings . Contains ( err . Error ( ) , "exists" ) {
fmt . Println ( "Error creating interface" )
//fmt.Println(err.Error())
//return err
}
2021-03-26 12:04:04 +08:00
}
match := false
addrs , _ := currentiface . Addrs ( )
for _ , a := range addrs {
if strings . Contains ( a . String ( ) , node . Address ) {
match = true
}
}
if ! match {
2021-03-26 00:17:52 +08:00
err = cmdIPAddrAdd . Run ( )
if err != nil {
fmt . Println ( "Error adding address" )
//return err
}
2021-03-26 12:04:04 +08:00
}
2021-03-26 00:17:52 +08:00
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 {
2021-03-26 12:04:04 +08:00
fmt . Printf ( "This is inconvenient: %v" , err )
2021-03-26 00:17:52 +08:00
}
}
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 ( )
2021-04-15 21:48:14 +08:00
if nodecfg . PostDown != "" {
runcmds := strings . Split ( nodecfg . PostDown , "; " )
err = runCmds ( runcmds )
if err != nil {
fmt . Println ( "Error encountered running PostDown: " + err . Error ( ) )
}
}
err = cmdIPLinkUp . Run ( )
2021-04-18 00:13:26 +08:00
if err != nil {
return err
}
if nodecfg . PostUp != "" {
2021-04-15 21:48:14 +08:00
runcmds := strings . Split ( nodecfg . PostUp , "; " )
err = runCmds ( runcmds )
if err != nil {
fmt . Println ( "Error encountered running PostUp: " + err . Error ( ) )
}
}
2021-04-18 00:13:26 +08:00
if ( hasGateway ) {
for _ , gateway := range gateways {
out , err := exec . Command ( ipExec , "-4" , "route" , "add" , gateway , "dev" , ifacename ) . Output ( )
fmt . Println ( string ( out ) )
if err != nil {
fmt . Println ( "Error encountered adding gateway: " + err . Error ( ) )
}
}
}
2021-03-26 00:17:52 +08:00
return err
}
2021-04-15 21:48:14 +08:00
func runCmds ( commands [ ] string ) error {
var err error
for _ , command := range commands {
fmt . Println ( "Running command: " + command )
args := strings . Fields ( command )
out , err := exec . Command ( args [ 0 ] , args [ 1 : ] ... ) . Output ( )
fmt . Println ( string ( out ) )
if err != nil {
return err
}
}
return err
}
2021-03-26 00:17:52 +08:00
2021-04-06 06:09:21 +08:00
func setWGKeyConfig ( network string , serveraddr string ) error {
ctx := context . Background ( )
var header metadata . MD
var wcclient nodepb . NodeServiceClient
var requestOpts grpc . DialOption
requestOpts = grpc . WithInsecure ( )
conn , err := grpc . Dial ( serveraddr , requestOpts )
if err != nil {
fmt . Printf ( "Cant dial GRPC server: %v" , err )
return err
}
wcclient = nodepb . NewNodeServiceClient ( conn )
fmt . Println ( "Authenticating with GRPC Server" )
ctx , err = SetJWT ( wcclient , network )
if err != nil {
fmt . Printf ( "Failed to authenticate: %v" , err )
return err
}
fmt . Println ( "Authenticated" )
node := getNode ( network )
privatekey , err := wgtypes . GeneratePrivateKey ( )
if err != nil {
return err
}
privkeystring := privatekey . String ( )
publickey := privatekey . PublicKey ( )
node . Publickey = publickey . String ( )
2021-04-06 08:47:19 +08:00
err = storePrivKey ( privkeystring , network )
2021-04-06 06:09:21 +08:00
if err != nil {
return err
}
err = modConfig ( & node )
if err != nil {
return err
}
postnode := getNode ( network )
req := & nodepb . UpdateNodeReq {
Node : & postnode ,
}
_ , err = wcclient . UpdateNode ( ctx , req , grpc . Header ( & header ) )
if err != nil {
return err
}
err = setWGConfig ( network )
if err != nil {
return err
log . Fatalf ( "Error: %v" , err )
}
return err
}
2021-04-05 23:06:30 +08:00
func setWGConfig ( network string ) error {
cfg , err := config . ReadConfig ( network )
if err != nil {
return err
}
servercfg := cfg . Server
nodecfg := cfg . Node
node := getNode ( network )
2021-03-26 00:17:52 +08:00
2021-04-18 00:13:26 +08:00
peers , hasGateway , gateways , err := getPeers ( node . Macaddress , nodecfg . Network , servercfg . Address )
2021-03-26 00:17:52 +08:00
if err != nil {
return err
}
2021-04-06 08:47:19 +08:00
privkey , err := retrievePrivKey ( network )
2021-03-26 00:17:52 +08:00
if err != nil {
return err
}
2021-04-18 00:13:26 +08:00
err = initWireguard ( & node , privkey , peers , hasGateway , gateways )
2021-03-26 00:17:52 +08:00
if err != nil {
return err
}
return err
}
2021-04-06 08:47:19 +08:00
func storePrivKey ( key string , network string ) error {
2021-03-26 00:17:52 +08:00
d1 := [ ] byte ( key )
2021-04-06 08:47:19 +08:00
err := ioutil . WriteFile ( "/etc/netclient/wgkey-" + network , d1 , 0644 )
2021-03-26 00:17:52 +08:00
return err
}
2021-04-06 08:47:19 +08:00
func retrievePrivKey ( network string ) ( string , error ) {
dat , err := ioutil . ReadFile ( "/etc/netclient/wgkey-" + network )
2021-03-26 00:17:52 +08:00
return string ( dat ) , err
}
2021-03-26 22:35:52 +08:00
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
}
2021-04-05 23:06:30 +08:00
func CheckIn ( network string ) error {
node := getNode ( network )
cfg , err := config . ReadConfig ( network )
if err != nil {
return err
}
nodecfg := cfg . Node
servercfg := cfg . Server
2021-03-26 10:29:36 +08:00
fmt . Println ( "Checking into server: " + servercfg . Address )
setupcheck := true
2021-03-26 23:14:19 +08:00
ipchange := false
2021-03-26 00:17:52 +08:00
2021-03-26 22:35:52 +08:00
if ! nodecfg . RoamingOff {
2021-04-18 00:13:26 +08:00
if ! nodecfg . IsLocal {
2021-04-19 22:02:30 +08:00
fmt . Println ( "Checking to see if public addresses have changed" )
2021-03-28 00:04:44 +08:00
extIP , err := getPublicIP ( )
2021-03-26 22:35:52 +08:00
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"
2021-03-26 23:14:19 +08:00
ipchange = true
2021-03-26 22:35:52 +08:00
}
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"
2021-03-26 23:14:19 +08:00
ipchange = true
2021-03-26 22:35:52 +08:00
}
2021-04-18 00:13:26 +08:00
} else {
2021-04-19 22:02:30 +08:00
fmt . Println ( "Checking to see if local addresses have changed" )
2021-04-18 00:13:26 +08:00
localIP , err := getLocalIP ( nodecfg . LocalRange )
if err != nil {
fmt . Printf ( "Error encountered checking ip addresses: %v" , err )
}
if nodecfg . Endpoint != localIP && localIP != "" {
fmt . Println ( "Endpoint has changed from " +
nodecfg . Endpoint + " to " + localIP )
fmt . Println ( "Updating address" )
nodecfg . Endpoint = localIP
nodecfg . LocalAddress = localIP
nodecfg . PostChanges = "true"
node . Endpoint = localIP
node . Localaddress = localIP
node . Postchanges = "true"
ipchange = true
}
}
2021-03-26 22:35:52 +08:00
if node . Postchanges != "true" {
fmt . Println ( "Addresses have not changed." )
}
}
2021-03-26 23:14:19 +08:00
if ipchange {
err := modConfig ( & node )
if err != nil {
return err
log . Fatalf ( "Error: %v" , err )
}
2021-04-05 23:06:30 +08:00
err = setWGConfig ( network )
2021-03-26 23:14:19 +08:00
if err != nil {
return err
log . Fatalf ( "Error: %v" , err )
}
2021-04-05 23:06:30 +08:00
node = getNode ( network )
cfg , err := config . ReadConfig ( network )
if err != nil {
return err
}
nodecfg = cfg . Node
2021-03-26 23:14:19 +08:00
}
2021-03-26 22:35:52 +08:00
2021-03-26 00:17:52 +08:00
var wcclient nodepb . NodeServiceClient
var requestOpts grpc . DialOption
requestOpts = grpc . WithInsecure ( )
conn , err := grpc . Dial ( servercfg . Address , requestOpts )
if err != nil {
2021-03-26 10:29:36 +08:00
fmt . Printf ( "Cant dial GRPC server: %v" , err )
2021-03-26 00:17:52 +08:00
return err
}
wcclient = nodepb . NewNodeServiceClient ( conn )
ctx := context . Background ( )
fmt . Println ( "Authenticating with GRPC Server" )
2021-04-05 23:06:30 +08:00
ctx , err = SetJWT ( wcclient , network )
2021-03-26 00:17:52 +08:00
if err != nil {
2021-03-26 10:29:36 +08:00
fmt . Printf ( "Failed to authenticate: %v" , err )
2021-03-26 00:17:52 +08:00
return err
}
fmt . Println ( "Authenticated" )
2021-03-26 10:29:36 +08:00
fmt . Println ( "Checking In." )
2021-03-26 00:17:52 +08:00
var header metadata . MD
2021-04-13 13:19:44 +08:00
node . Nodenetwork = network
2021-03-26 00:17:52 +08:00
checkinres , err := wcclient . CheckIn (
ctx ,
& nodepb . CheckInReq {
Node : & node ,
} ,
grpc . Header ( & header ) ,
)
if err != nil {
2021-03-26 10:29:36 +08:00
if checkinres != nil && checkinres . Checkinresponse . Ispending {
2021-04-05 23:06:30 +08:00
fmt . Println ( "Node is in pending status. Waiting for Admin approval of node before making further updates." )
2021-03-26 10:29:36 +08:00
return nil
}
fmt . Printf ( "Unable to process Check In request: %v" , err )
2021-03-26 00:17:52 +08:00
return err
}
fmt . Println ( "Checked in." )
if checkinres . Checkinresponse . Ispending {
2021-04-05 23:06:30 +08:00
fmt . Println ( "Node is in pending status. Waiting for Admin approval of node before making further updates." )
2021-03-26 00:17:52 +08:00
return err
}
2021-03-26 12:04:04 +08:00
2021-04-05 23:06:30 +08:00
newinterface := getNode ( network ) . Interface
2021-03-26 12:04:04 +08:00
readreq := & nodepb . ReadNodeReq {
Macaddress : node . Macaddress ,
2021-04-13 12:42:35 +08:00
Network : node . Nodenetwork ,
2021-03-26 12:04:04 +08:00
}
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 {
2021-03-26 23:14:19 +08:00
fmt . Println ( "Interface update: " + currentiface +
" >>>> " + newinterface )
2021-04-15 21:48:14 +08:00
err := DeleteInterface ( currentiface , nodecfg . PostDown )
2021-03-26 12:04:04 +08:00
if err != nil {
fmt . Println ( "ERROR DELETING INTERFACE: " + currentiface )
}
2021-04-05 23:06:30 +08:00
err = setWGConfig ( network )
2021-04-19 22:49:52 +08:00
if err != nil {
log . Printf ( "Error updating interface: %v" , err )
}
}
2021-03-26 12:04:04 +08:00
}
2021-03-26 00:17:52 +08:00
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 ,
2021-04-13 12:42:35 +08:00
Network : node . Nodenetwork ,
2021-03-26 00:17:52 +08:00
}
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 )
}
2021-04-05 23:06:30 +08:00
err = setWGConfig ( network )
2021-03-26 00:17:52 +08:00
if err != nil {
return err
log . Fatalf ( "Error: %v" , err )
}
2021-03-26 10:29:36 +08:00
setupcheck = false
2021-03-26 00:17:52 +08:00
} else if nodecfg . PostChanges == "true" {
fmt . Println ( "Node has requested to update remote config." )
fmt . Println ( "Posting local config to remote server." )
2021-04-05 23:06:30 +08:00
postnode := getNode ( network )
2021-03-26 12:04:04 +08:00
2021-03-26 00:17:52 +08:00
req := & nodepb . UpdateNodeReq {
Node : & postnode ,
}
2021-03-26 12:04:04 +08:00
res , err := wcclient . UpdateNode ( ctx , req , grpc . Header ( & header ) )
2021-03-26 00:17:52 +08:00
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 )
}
2021-04-05 23:06:30 +08:00
err = setWGConfig ( network )
2021-03-26 00:17:52 +08:00
if err != nil {
return err
log . Fatalf ( "Error: %v" , err )
}
2021-03-26 10:29:36 +08:00
setupcheck = false
2021-03-26 00:17:52 +08:00
}
2021-04-06 06:09:21 +08:00
if checkinres . Checkinresponse . Needkeyupdate {
fmt . Println ( "Server has requested that node update key pairs." )
fmt . Println ( "Proceeding to re-generate key pairs for Wiregard." )
err = setWGKeyConfig ( network , servercfg . Address )
if err != nil {
return err
log . Fatalf ( "Unable to process reset keys request: %v" , err )
}
setupcheck = false
}
2021-03-26 00:17:52 +08:00
if checkinres . Checkinresponse . Needpeerupdate {
fmt . Println ( "Server has requested that node update peer list." )
fmt . Println ( "Updating peer list from remote server." )
2021-04-05 23:06:30 +08:00
err = setWGConfig ( network )
2021-03-26 00:17:52 +08:00
if err != nil {
return err
log . Fatalf ( "Unable to process Set Peers request: %v" , err )
}
2021-03-26 10:29:36 +08:00
setupcheck = false
2021-03-26 00:17:52 +08:00
}
2021-04-06 08:47:19 +08:00
if checkinres . Checkinresponse . Needdelete {
fmt . Println ( "This machine got the delete signal. Deleting." )
err := Remove ( network )
if err != nil {
return err
log . Fatalf ( "Error: %v" , err )
}
}
2021-03-26 10:29:36 +08:00
if setupcheck {
iface := nodecfg . Interface
_ , err := net . InterfaceByName ( iface )
if err != nil {
fmt . Println ( "interface " + iface + " does not currently exist. Setting up WireGuard." )
2021-04-07 09:31:47 +08:00
err = setWGKeyConfig ( network , servercfg . Address )
2021-03-26 10:29:36 +08:00
if err != nil {
return err
log . Fatalf ( "Error: %v" , err )
}
}
}
2021-03-26 00:17:52 +08:00
return nil
}
2021-03-26 12:04:04 +08:00
2021-04-13 12:42:35 +08:00
func needInterfaceUpdate ( ctx context . Context , mac string , network string , iface string ) ( bool , string , error ) {
2021-03-26 12:04:04 +08:00
var header metadata . MD
req := & nodepb . ReadNodeReq {
Macaddress : mac ,
2021-04-13 12:42:35 +08:00
Network : network ,
2021-03-26 12:04:04 +08:00
}
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
}
2021-04-05 23:06:30 +08:00
func getNode ( network string ) nodepb . Node {
modcfg , err := config . ReadConfig ( network )
if err != nil {
log . Fatalf ( "Error: %v" , err )
}
2021-03-26 00:17:52 +08:00
nodecfg := modcfg . Node
var node nodepb . Node
node . Name = nodecfg . Name
node . Interface = nodecfg . Interface
2021-04-13 12:42:35 +08:00
node . Nodenetwork = nodecfg . Network
2021-03-26 00:17:52 +08:00
node . Localaddress = nodecfg . LocalAddress
node . Address = nodecfg . WGAddress
node . Listenport = nodecfg . Port
node . Keepalive = nodecfg . KeepAlive
node . Postup = nodecfg . PostUp
2021-04-13 14:55:49 +08:00
node . Postdown = nodecfg . PostDown
2021-03-26 00:17:52 +08:00
node . Publickey = nodecfg . PublicKey
node . Macaddress = nodecfg . MacAddress
node . Endpoint = nodecfg . Endpoint
node . Password = nodecfg . Password
//spew.Dump(node)
return node
}
2021-04-05 23:06:30 +08:00
func Remove ( network string ) error {
2021-03-26 00:17:52 +08:00
//need to implement checkin on server side
2021-04-05 23:06:30 +08:00
cfg , err := config . ReadConfig ( network )
if err != nil {
return err
}
servercfg := cfg . Server
node := cfg . Node
2021-03-26 00:17:52 +08:00
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 )
2021-03-26 10:29:36 +08:00
if err != nil {
log . Printf ( "Unable to establish client connection to " + servercfg . Address + ": %v" , err )
2021-03-28 00:04:44 +08:00
//return err
} else {
2021-03-26 00:17:52 +08:00
wcclient = nodepb . NewNodeServiceClient ( conn )
ctx := context . Background ( )
fmt . Println ( "Authenticating with GRPC Server" )
2021-04-05 23:06:30 +08:00
ctx , err = SetJWT ( wcclient , network )
2021-03-26 00:17:52 +08:00
if err != nil {
2021-03-28 00:04:44 +08:00
//return err
log . Printf ( "Failed to authenticate: %v" , err )
} else {
2021-03-26 00:17:52 +08:00
fmt . Println ( "Authenticated" )
var header metadata . MD
_ , err = wcclient . DeleteNode (
ctx ,
& nodepb . DeleteNodeReq {
Macaddress : node . MacAddress ,
2021-04-13 12:42:35 +08:00
NetworkName : node . Network ,
2021-03-26 00:17:52 +08:00
} ,
grpc . Header ( & header ) ,
)
if err != nil {
2021-03-28 00:04:44 +08:00
log . Printf ( "Encountered error deleting node: %v" , err )
2021-03-26 00:17:52 +08:00
fmt . Println ( err )
2021-03-28 00:04:44 +08:00
} else {
fmt . Println ( "Deleted node " + node . MacAddress )
}
}
}
2021-04-05 23:06:30 +08:00
err = WipeLocal ( network )
2021-03-26 00:17:52 +08:00
if err != nil {
2021-03-26 22:35:52 +08:00
log . Printf ( "Unable to wipe local config: %v" , err )
2021-03-26 00:17:52 +08:00
}
2021-04-05 23:06:30 +08:00
err = RemoveSystemDServices ( network )
2021-03-26 00:17:52 +08:00
if err != nil {
return err
2021-03-28 00:04:44 +08:00
log . Printf ( "Unable to remove systemd services: %v" , err )
2021-03-26 00:17:52 +08:00
}
2021-03-28 00:04:44 +08:00
fmt . Printf ( "Please investigate any stated errors to ensure proper removal." )
fmt . Printf ( "Failure to delete node from server via gRPC will mean node still exists and needs to be manually deleted by administrator." )
2021-03-26 00:17:52 +08:00
return nil
}
2021-04-05 23:06:30 +08:00
func WipeLocal ( network string ) error {
cfg , err := config . ReadConfig ( network )
if err != nil {
return err
}
nodecfg := cfg . Node
2021-03-26 00:17:52 +08:00
ifacename := nodecfg . Interface
2021-03-26 10:29:36 +08:00
//home, err := homedir.Dir()
home := "/etc/netclient"
2021-04-05 23:06:30 +08:00
err = os . Remove ( home + "/netconfig-" + network )
2021-03-26 00:17:52 +08:00
if err != nil {
fmt . Println ( err )
}
2021-04-07 21:53:27 +08:00
err = os . Remove ( home + "/nettoken-" + network )
2021-03-26 00:17:52 +08:00
if err != nil {
fmt . Println ( err )
}
2021-04-07 21:53:27 +08:00
err = os . Remove ( home + "/wgkey-" + network )
if err != nil {
fmt . Println ( err )
}
2021-03-26 00:17:52 +08:00
ipExec , err := exec . LookPath ( "ip" )
2021-03-26 22:35:52 +08:00
if ifacename != "" {
2021-03-26 00:17:52 +08:00
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 )
}
2021-04-15 21:48:14 +08:00
if nodecfg . PostDown != "" {
runcmds := strings . Split ( nodecfg . PostDown , "; " )
err = runCmds ( runcmds )
if err != nil {
fmt . Println ( "Error encountered running PostDown: " + err . Error ( ) )
}
}
2021-03-26 22:35:52 +08:00
}
2021-03-26 00:17:52 +08:00
return err
}
2021-04-15 21:48:14 +08:00
func DeleteInterface ( ifacename string , postdown string ) error {
2021-03-26 10:29:36 +08:00
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 )
}
2021-04-15 21:48:14 +08:00
if postdown != "" {
runcmds := strings . Split ( postdown , "; " )
err = runCmds ( runcmds )
if err != nil {
fmt . Println ( "Error encountered running PostDown: " + err . Error ( ) )
}
}
2021-03-26 10:29:36 +08:00
return err
}
2021-03-26 00:17:52 +08:00
2021-04-18 00:13:26 +08:00
func getPeers ( macaddress string , network string , server string ) ( [ ] wgtypes . PeerConfig , bool , [ ] string , error ) {
2021-03-26 00:17:52 +08:00
//need to implement checkin on server side
2021-04-18 00:13:26 +08:00
hasGateway := false
var gateways [ ] string
2021-03-26 00:17:52 +08:00
var peers [ ] wgtypes . PeerConfig
var wcclient nodepb . NodeServiceClient
2021-04-13 12:42:35 +08:00
cfg , err := config . ReadConfig ( network )
2021-04-05 23:06:30 +08:00
if err != nil {
2021-04-13 12:42:35 +08:00
log . Fatalf ( "Issue retrieving config for network: " + network + ". Please investigate: %v" , err )
2021-04-05 23:06:30 +08:00
}
nodecfg := cfg . Node
2021-03-26 00:17:52 +08:00
keepalive := nodecfg . KeepAlive
keepalivedur , err := time . ParseDuration ( strconv . FormatInt ( int64 ( keepalive ) , 10 ) + "s" )
if err != nil {
2021-03-26 10:29:36 +08:00
log . Fatalf ( "Issue with format of keepalive value. Please update netconfig: %v" , err )
2021-03-26 00:17:52 +08:00
}
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 ,
2021-04-13 12:42:35 +08:00
Network : network ,
2021-03-26 00:17:52 +08:00
}
ctx := context . Background ( )
fmt . Println ( "Authenticating with GRPC Server" )
2021-04-13 12:42:35 +08:00
ctx , err = SetJWT ( wcclient , network )
2021-03-26 00:17:52 +08:00
if err != nil {
fmt . Println ( "Failed to authenticate." )
2021-04-18 00:13:26 +08:00
return peers , hasGateway , gateways , err
2021-03-26 00:17:52 +08:00
}
var header metadata . MD
stream , err := wcclient . GetPeers ( ctx , req , grpc . Header ( & header ) )
if err != nil {
2021-04-13 22:04:31 +08:00
fmt . Println ( "Error retrieving peers" )
fmt . Println ( err )
2021-04-18 00:13:26 +08:00
return nil , hasGateway , gateways , err
2021-03-26 00:17:52 +08:00
}
2021-04-13 22:04:31 +08:00
fmt . Println ( "Parsing peers response" )
for {
2021-03-26 00:17:52 +08:00
res , err := stream . Recv ( )
// If end of stream, break the loop
if err == io . EOF {
2021-04-13 22:04:31 +08:00
break
2021-03-26 00:17:52 +08:00
}
// if err, return an error
if err != nil {
if strings . Contains ( err . Error ( ) , "mongo: no documents in result" ) {
2021-04-19 22:02:30 +08:00
continue
2021-03-26 00:17:52 +08:00
} else {
fmt . Println ( "ERROR ENCOUNTERED WITH RESPONSE" )
fmt . Println ( res )
2021-04-18 00:13:26 +08:00
return peers , hasGateway , gateways , err
2021-03-26 00:17:52 +08:00
}
}
pubkey , err := wgtypes . ParseKey ( res . Peers . Publickey )
if err != nil {
fmt . Println ( "error parsing key" )
2021-04-18 00:13:26 +08:00
return peers , hasGateway , gateways , err
2021-03-26 00:17:52 +08:00
}
2021-04-19 22:02:30 +08:00
if nodecfg . PublicKey == res . Peers . Publickey {
fmt . Println ( "Peer is self. Skipping" )
continue
}
if nodecfg . Endpoint == res . Peers . Endpoint {
fmt . Println ( "Peer is self. Skipping" )
continue
}
2021-03-26 00:17:52 +08:00
var peer wgtypes . PeerConfig
2021-04-13 14:55:49 +08:00
var peeraddr = net . IPNet {
IP : net . ParseIP ( res . Peers . Address ) ,
Mask : net . CIDRMask ( 32 , 32 ) ,
}
var allowedips [ ] net . IPNet
allowedips = append ( allowedips , peeraddr )
if res . Peers . Isgateway {
2021-04-18 00:13:26 +08:00
hasGateway = true
gateways = append ( gateways , res . Peers . Gatewayrange )
2021-04-13 14:55:49 +08:00
_ , ipnet , err := net . ParseCIDR ( res . Peers . Gatewayrange )
if err != nil {
fmt . Println ( "ERROR ENCOUNTERED SETTING GATEWAY" )
fmt . Println ( "NOT SETTING GATEWAY" )
fmt . Println ( err )
} else {
2021-04-15 01:44:47 +08:00
fmt . Println ( " Gateway Range: " + res . Peers . Gatewayrange )
2021-04-13 14:55:49 +08:00
allowedips = append ( allowedips , * ipnet )
}
}
2021-03-26 00:17:52 +08:00
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 ,
2021-04-13 14:55:49 +08:00
AllowedIPs : allowedips ,
}
2021-03-26 00:17:52 +08:00
} else {
peer = wgtypes . PeerConfig {
PublicKey : pubkey ,
Endpoint : & net . UDPAddr {
IP : net . ParseIP ( res . Peers . Endpoint ) ,
Port : int ( res . Peers . Listenport ) ,
} ,
ReplaceAllowedIPs : true ,
2021-04-13 14:55:49 +08:00
AllowedIPs : allowedips ,
}
2021-03-26 00:17:52 +08:00
}
peers = append ( peers , peer )
}
fmt . Println ( "Finished parsing peers response" )
2021-04-18 00:13:26 +08:00
return peers , hasGateway , gateways , err
2021-03-26 00:17:52 +08:00
}