mirror of
https://github.com/gravitl/netmaker.git
synced 2025-10-05 00:43:58 +08:00
began adding macos service/daemon
This commit is contained in:
4
main.go
4
main.go
@@ -17,7 +17,7 @@ import (
|
|||||||
"github.com/gravitl/netmaker/functions"
|
"github.com/gravitl/netmaker/functions"
|
||||||
nodepb "github.com/gravitl/netmaker/grpc"
|
nodepb "github.com/gravitl/netmaker/grpc"
|
||||||
"github.com/gravitl/netmaker/models"
|
"github.com/gravitl/netmaker/models"
|
||||||
"github.com/gravitl/netmaker/netclient/local"
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
"github.com/gravitl/netmaker/servercfg"
|
"github.com/gravitl/netmaker/servercfg"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
@@ -38,7 +38,7 @@ func initialize() { // Client Mode Prereq Check
|
|||||||
}
|
}
|
||||||
log.Println("database successfully connected.")
|
log.Println("database successfully connected.")
|
||||||
if servercfg.IsClientMode() {
|
if servercfg.IsClientMode() {
|
||||||
output, err := local.RunCmd("id -u", true)
|
output, err := ncutils.RunCmd("id -u", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error running 'id -u' for prereq check. Please investigate or disable client mode.")
|
log.Println("Error running 'id -u' for prereq check. Please investigate or disable client mode.")
|
||||||
log.Fatal(output, err)
|
log.Fatal(output, err)
|
||||||
|
@@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/gravitl/netmaker/models"
|
"github.com/gravitl/netmaker/models"
|
||||||
"github.com/gravitl/netmaker/netclient/config"
|
"github.com/gravitl/netmaker/netclient/config"
|
||||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
|
|
||||||
// "os"
|
// "os"
|
||||||
"context"
|
"context"
|
||||||
@@ -20,7 +20,7 @@ import (
|
|||||||
|
|
||||||
// CreateJWT func will used to create the JWT while signing in and signing out
|
// CreateJWT func will used to create the JWT while signing in and signing out
|
||||||
func SetJWT(client nodepb.NodeServiceClient, network string) (context.Context, error) {
|
func SetJWT(client nodepb.NodeServiceClient, network string) (context.Context, error) {
|
||||||
home := netclientutils.GetNetclientPathSpecific()
|
home := ncutils.GetNetclientPathSpecific()
|
||||||
tokentext, err := ioutil.ReadFile(home + "nettoken-" + network)
|
tokentext, err := ioutil.ReadFile(home + "nettoken-" + network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = AutoLogin(client, network)
|
err = AutoLogin(client, network)
|
||||||
@@ -42,7 +42,7 @@ func SetJWT(client nodepb.NodeServiceClient, network string) (context.Context, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func AutoLogin(client nodepb.NodeServiceClient, network string) error {
|
func AutoLogin(client nodepb.NodeServiceClient, network string) error {
|
||||||
home := netclientutils.GetNetclientPathSpecific()
|
home := ncutils.GetNetclientPathSpecific()
|
||||||
cfg, err := config.ReadConfig(network)
|
cfg, err := config.ReadConfig(network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -79,12 +79,12 @@ func AutoLogin(client nodepb.NodeServiceClient, network string) error {
|
|||||||
|
|
||||||
func StoreSecret(key string, network string) error {
|
func StoreSecret(key string, network string) error {
|
||||||
d1 := []byte(key)
|
d1 := []byte(key)
|
||||||
err := ioutil.WriteFile(netclientutils.GetNetclientPathSpecific()+"secret-"+network, d1, 0644)
|
err := ioutil.WriteFile(ncutils.GetNetclientPathSpecific()+"secret-"+network, d1, 0644)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func RetrieveSecret(network string) (string, error) {
|
func RetrieveSecret(network string) (string, error) {
|
||||||
dat, err := ioutil.ReadFile(netclientutils.GetNetclientPathSpecific() + "secret-" + network)
|
dat, err := ioutil.ReadFile(ncutils.GetNetclientPathSpecific() + "secret-" + network)
|
||||||
return string(dat), err
|
return string(dat), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,9 +8,9 @@ import (
|
|||||||
|
|
||||||
nodepb "github.com/gravitl/netmaker/grpc"
|
nodepb "github.com/gravitl/netmaker/grpc"
|
||||||
"github.com/gravitl/netmaker/netclient/config"
|
"github.com/gravitl/netmaker/netclient/config"
|
||||||
|
"github.com/gravitl/netmaker/netclient/daemon"
|
||||||
"github.com/gravitl/netmaker/netclient/functions"
|
"github.com/gravitl/netmaker/netclient/functions"
|
||||||
"github.com/gravitl/netmaker/netclient/local"
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
|
||||||
"golang.zx2c4.com/wireguard/wgctrl"
|
"golang.zx2c4.com/wireguard/wgctrl"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -28,34 +28,30 @@ func Join(cfg config.ClientConfig, privateKey string) error {
|
|||||||
|
|
||||||
if err != nil && !cfg.DebugJoin {
|
if err != nil && !cfg.DebugJoin {
|
||||||
if !strings.Contains(err.Error(), "ALREADY_INSTALLED") {
|
if !strings.Contains(err.Error(), "ALREADY_INSTALLED") {
|
||||||
log.Println("Error installing: ", err)
|
ncutils.PrintLog("error installing: "+err.Error(), 1)
|
||||||
err = functions.LeaveNetwork(cfg.Network)
|
err = functions.LeaveNetwork(cfg.Network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = local.WipeLocal(cfg.Network)
|
err = functions.WipeLocal(cfg.Network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error removing artifacts: ", err)
|
ncutils.PrintLog("error removing artifacts: "+err.Error(), 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if cfg.Daemon != "off" {
|
if cfg.Daemon != "off" {
|
||||||
if netclientutils.IsLinux() {
|
if ncutils.IsLinux() {
|
||||||
err = local.RemoveSystemDServices(cfg.Network)
|
err = daemon.RemoveSystemDServices(cfg.Network)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error removing services: ", err)
|
ncutils.PrintLog("error removing services: "+err.Error(), 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ncutils.PrintLog("success", 0)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Println("joined " + cfg.Network)
|
ncutils.PrintLog("joined "+cfg.Network, 1)
|
||||||
if cfg.Daemon != "off" {
|
if cfg.Daemon != "off" {
|
||||||
if netclientutils.IsWindows() {
|
err = daemon.InstallDaemon(cfg)
|
||||||
err = local.CreateAndRunWindowsDaemon()
|
|
||||||
} else if netclientutils.IsMac() {
|
|
||||||
err = local.CreateAndRunMacDaemon()
|
|
||||||
} else {
|
|
||||||
err = functions.InstallDaemon(cfg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -75,13 +71,13 @@ func RunUserspaceDaemon() {
|
|||||||
func CheckIn(cfg config.ClientConfig) error {
|
func CheckIn(cfg config.ClientConfig) error {
|
||||||
var err error
|
var err error
|
||||||
if cfg.Network == "" {
|
if cfg.Network == "" {
|
||||||
log.Println("Required, '-n'. No network provided. Exiting.")
|
ncutils.PrintLog("required, '-n', exiting", 0)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
} else if cfg.Network == "all" {
|
} else if cfg.Network == "all" {
|
||||||
log.Println("Running CheckIn for all networks.")
|
ncutils.PrintLog("running checkin for all networks", 1)
|
||||||
networks, err := functions.GetNetworks()
|
networks, err := functions.GetNetworks()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error retrieving networks. Exiting.")
|
ncutils.PrintLog("error retrieving networks, exiting", 1)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, network := range networks {
|
for _, network := range networks {
|
||||||
@@ -91,14 +87,14 @@ func CheckIn(cfg config.ClientConfig) error {
|
|||||||
}
|
}
|
||||||
err = functions.CheckConfig(*currConf)
|
err = functions.CheckConfig(*currConf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error checking in for "+network+" network: ", err)
|
ncutils.PrintLog("error checking in for "+network+" network: "+err.Error(), 1)
|
||||||
} else {
|
} else {
|
||||||
log.Println("checked in successfully for " + network)
|
ncutils.PrintLog("checked in successfully for "+network, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(networks) == 0 {
|
if len(networks) == 0 {
|
||||||
if netclientutils.IsWindows() { // Windows specific - there are no netclients, so stop daemon process
|
if ncutils.IsWindows() { // Windows specific - there are no netclients, so stop daemon process
|
||||||
local.StopWindowsDaemon()
|
daemon.StopWindowsDaemon()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = nil
|
err = nil
|
||||||
@@ -111,43 +107,46 @@ func CheckIn(cfg config.ClientConfig) error {
|
|||||||
func Leave(cfg config.ClientConfig) error {
|
func Leave(cfg config.ClientConfig) error {
|
||||||
err := functions.LeaveNetwork(cfg.Network)
|
err := functions.LeaveNetwork(cfg.Network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error attempting to leave network " + cfg.Network)
|
ncutils.PrintLog("error attempting to leave network "+cfg.Network, 1)
|
||||||
|
} else {
|
||||||
|
ncutils.PrintLog("success", 0)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func Push(cfg config.ClientConfig) error {
|
func Push(cfg config.ClientConfig) error {
|
||||||
var err error
|
var err error
|
||||||
if cfg.Network == "all" || netclientutils.IsWindows() {
|
if cfg.Network == "all" || ncutils.IsWindows() {
|
||||||
log.Println("No network selected. Running Push for all networks.")
|
ncutils.PrintLog("pushing config to server for all networks.", 0)
|
||||||
networks, err := functions.GetNetworks()
|
networks, err := functions.GetNetworks()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error retrieving networks. Exiting.")
|
ncutils.PrintLog("error retrieving networks, exiting.", 0)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, network := range networks {
|
for _, network := range networks {
|
||||||
err = functions.Push(network)
|
err = functions.Push(network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error pushing network configs for "+network+" network: ", err)
|
log.Printf("error pushing network configs for "+network+" network: ", err)
|
||||||
} else {
|
} else {
|
||||||
log.Println("pushed network config for " + network)
|
ncutils.PrintLog("pushed network config for "+network, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = nil
|
err = nil
|
||||||
} else {
|
} else {
|
||||||
err = functions.Push(cfg.Network)
|
err = functions.Push(cfg.Network)
|
||||||
}
|
}
|
||||||
log.Println("Completed pushing network configs to remote server.")
|
ncutils.PrintLog("completed pushing network configs to remote server", 1)
|
||||||
|
ncutils.PrintLog("success", 1)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func Pull(cfg config.ClientConfig) error {
|
func Pull(cfg config.ClientConfig) error {
|
||||||
var err error
|
var err error
|
||||||
if cfg.Network == "all" {
|
if cfg.Network == "all" {
|
||||||
log.Println("No network selected. Running Pull for all networks.")
|
ncutils.PrintLog("No network selected. Running Pull for all networks.", 0)
|
||||||
networks, err := functions.GetNetworks()
|
networks, err := functions.GetNetworks()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error retrieving networks. Exiting.")
|
ncutils.PrintLog("Error retrieving networks. Exiting.", 1)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, network := range networks {
|
for _, network := range networks {
|
||||||
@@ -155,14 +154,15 @@ func Pull(cfg config.ClientConfig) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error pulling network config for "+network+" network: ", err)
|
log.Printf("Error pulling network config for "+network+" network: ", err)
|
||||||
} else {
|
} else {
|
||||||
log.Println("pulled network config for " + network)
|
ncutils.PrintLog("pulled network config for "+network, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = nil
|
err = nil
|
||||||
} else {
|
} else {
|
||||||
_, err = functions.Pull(cfg.Network, true)
|
_, err = functions.Pull(cfg.Network, true)
|
||||||
}
|
}
|
||||||
log.Println("Completed pulling network and peer configs.")
|
ncutils.PrintLog("reset network and peer configs", 1)
|
||||||
|
ncutils.PrintLog("success", 1)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ func List(cfg config.ClientConfig) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Uninstall() error {
|
func Uninstall() error {
|
||||||
log.Println("Uninstalling netclient")
|
ncutils.PrintLog("uninstalling netclient", 0)
|
||||||
err := functions.Uninstall()
|
err := functions.Uninstall()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -8,8 +8,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/models"
|
"github.com/gravitl/netmaker/models"
|
||||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
@@ -25,7 +26,7 @@ type ClientConfig struct {
|
|||||||
Network string `yaml:"network"`
|
Network string `yaml:"network"`
|
||||||
Daemon string `yaml:"daemon"`
|
Daemon string `yaml:"daemon"`
|
||||||
OperatingSystem string `yaml:"operatingsystem"`
|
OperatingSystem string `yaml:"operatingsystem"`
|
||||||
DebugJoin bool `yaml:"debugjoin"`
|
DebugJoin bool `yaml:"debugjoin"`
|
||||||
}
|
}
|
||||||
type ServerConfig struct {
|
type ServerConfig struct {
|
||||||
CoreDNSAddr string `yaml:"corednsaddr"`
|
CoreDNSAddr string `yaml:"corednsaddr"`
|
||||||
@@ -42,13 +43,13 @@ func Write(config *ClientConfig, network string) error {
|
|||||||
err := errors.New("no network provided - exiting")
|
err := errors.New("no network provided - exiting")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err := os.Stat(netclientutils.GetNetclientPath())
|
_, err := os.Stat(ncutils.GetNetclientPath())
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
os.Mkdir(netclientutils.GetNetclientPath(), 0744)
|
os.Mkdir(ncutils.GetNetclientPath(), 0744)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
home := netclientutils.GetNetclientPathSpecific()
|
home := ncutils.GetNetclientPathSpecific()
|
||||||
|
|
||||||
file := fmt.Sprintf(home + "netconfig-" + network)
|
file := fmt.Sprintf(home + "netconfig-" + network)
|
||||||
f, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
|
f, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
|
||||||
@@ -71,14 +72,14 @@ func WriteServer(server string, accesskey string, network string) error {
|
|||||||
}
|
}
|
||||||
nofile := false
|
nofile := false
|
||||||
//home, err := homedir.Dir()
|
//home, err := homedir.Dir()
|
||||||
_, err := os.Stat(netclientutils.GetNetclientPath())
|
_, err := os.Stat(ncutils.GetNetclientPath())
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
os.Mkdir(netclientutils.GetNetclientPath(), 0744)
|
os.Mkdir(ncutils.GetNetclientPath(), 0744)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
fmt.Println("couldnt find or create", netclientutils.GetNetclientPath())
|
fmt.Println("couldnt find or create", ncutils.GetNetclientPath())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
home := netclientutils.GetNetclientPathSpecific()
|
home := ncutils.GetNetclientPathSpecific()
|
||||||
|
|
||||||
file := fmt.Sprintf(home + "netconfig-" + network)
|
file := fmt.Sprintf(home + "netconfig-" + network)
|
||||||
//f, err := os.Open(file)
|
//f, err := os.Open(file)
|
||||||
@@ -151,7 +152,7 @@ func (config *ClientConfig) ReadConfig() {
|
|||||||
|
|
||||||
nofile := false
|
nofile := false
|
||||||
//home, err := homedir.Dir()
|
//home, err := homedir.Dir()
|
||||||
home := netclientutils.GetNetclientPathSpecific()
|
home := ncutils.GetNetclientPathSpecific()
|
||||||
file := fmt.Sprintf(home + "netconfig-" + config.Network)
|
file := fmt.Sprintf(home + "netconfig-" + config.Network)
|
||||||
//f, err := os.Open(file)
|
//f, err := os.Open(file)
|
||||||
f, err := os.OpenFile(file, os.O_RDONLY, 0666)
|
f, err := os.OpenFile(file, os.O_RDONLY, 0666)
|
||||||
@@ -186,7 +187,7 @@ func ModConfig(node *models.Node) error {
|
|||||||
}
|
}
|
||||||
var modconfig ClientConfig
|
var modconfig ClientConfig
|
||||||
var err error
|
var err error
|
||||||
if FileExists(netclientutils.GetNetclientPathSpecific() + "netconfig-" + network) {
|
if FileExists(ncutils.GetNetclientPathSpecific() + "netconfig-" + network) {
|
||||||
useconfig, err := ReadConfig(network)
|
useconfig, err := ReadConfig(network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -306,7 +307,7 @@ func ReadConfig(network string) (*ClientConfig, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
nofile := false
|
nofile := false
|
||||||
home := netclientutils.GetNetclientPathSpecific()
|
home := ncutils.GetNetclientPathSpecific()
|
||||||
file := fmt.Sprintf(home + "netconfig-" + network)
|
file := fmt.Sprintf(home + "netconfig-" + network)
|
||||||
f, err := os.Open(file)
|
f, err := os.Open(file)
|
||||||
|
|
||||||
|
24
netclient/daemon/common.go
Normal file
24
netclient/daemon/common.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package daemon
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/gravitl/netmaker/netclient/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InstallDaemon(cfg config.ClientConfig) error {
|
||||||
|
os := runtime.GOOS
|
||||||
|
var err error
|
||||||
|
switch os {
|
||||||
|
case "windows":
|
||||||
|
err = SetupWindowsDaemon()
|
||||||
|
case "darwin":
|
||||||
|
err = errors.New("need to implement macos daemon0")
|
||||||
|
case "linux":
|
||||||
|
err = SetupSystemDDaemon(cfg.Network)
|
||||||
|
default:
|
||||||
|
err = errors.New("this os is not yet supported for daemon mode. Run join cmd with flag '--daemon off'")
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
76
netclient/daemon/macos.go
Normal file
76
netclient/daemon/macos.go
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
package daemon
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
const MAC_SERVICE_NAME = "com.gravitl.netclient"
|
||||||
|
|
||||||
|
func CreateAndRunMacDaemon() error {
|
||||||
|
_, err := os.Stat("~/Library/LaunchAgents")
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
os.Mkdir("~/Library/LaunchAgents", 0744)
|
||||||
|
}
|
||||||
|
err = CreateMacService(MAC_SERVICE_NAME)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = ncutils.RunCmd("launchctl load ~/Library/LaunchAgents/"+MAC_SERVICE_NAME+".plist", true)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func CleanupMac() {
|
||||||
|
//StopWindowsDaemon()
|
||||||
|
//RemoveWindowsDaemon()
|
||||||
|
//os.RemoveAll(ncutils.GetNetclientPath())
|
||||||
|
log.Println("TODO: Not implemented yet")
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateMacService(servicename string) error {
|
||||||
|
tdata := MacTemplateData{
|
||||||
|
Label: servicename,
|
||||||
|
Program: "/etc/netclient/netclient",
|
||||||
|
KeepAlive: true,
|
||||||
|
RunAtLoad: true,
|
||||||
|
}
|
||||||
|
fileLoc := fmt.Sprintf("%s/Library/LaunchAgents/%s.plist", os.Getenv("HOME"), tdata.Label)
|
||||||
|
launchdFile, err := os.Open(fileLoc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
launchdTemplate := template.Must(template.New("launchdTemplate").Parse(MacTemplate()))
|
||||||
|
return launchdTemplate.Execute(launchdFile, tdata)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MacTemplate() string {
|
||||||
|
return `
|
||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\" >
|
||||||
|
<plist version='1.0'>
|
||||||
|
<dict>
|
||||||
|
<key>Label</key><string>{{.Label}}</string>
|
||||||
|
<key>Program</key><string>{{.Program}}</string>
|
||||||
|
<key>StandardOutPath</key><string>/tmp/{{.Label}}.out.log</string>
|
||||||
|
<key>StandardErrorPath</key><string>/tmp/{{.Label}}.err.log</string>
|
||||||
|
<key>KeepAlive</key><{{.KeepAlive}}/>
|
||||||
|
<key>RunAtLoad</key><{{.RunAtLoad}}/>
|
||||||
|
<key>StartCalendarInterval</key>
|
||||||
|
<dict>
|
||||||
|
<key>Minute</key>
|
||||||
|
<value>*/1</value>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MacTemplateData struct {
|
||||||
|
Label string
|
||||||
|
Program string
|
||||||
|
KeepAlive bool
|
||||||
|
RunAtLoad bool
|
||||||
|
}
|
150
netclient/daemon/systemd.go
Normal file
150
netclient/daemon/systemd.go
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
package daemon
|
||||||
|
|
||||||
|
import (
|
||||||
|
//"github.com/davecgh/go-spew/spew"
|
||||||
|
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SetupSystemDDaemon(network string) error {
|
||||||
|
if ncutils.IsWindows() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
binarypath := dir + "/netclient"
|
||||||
|
|
||||||
|
_, err = os.Stat("/etc/netclient")
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
os.Mkdir("/etc/netclient", 744)
|
||||||
|
} else if err != nil {
|
||||||
|
log.Println("couldnt find or create /etc/netclient")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ncutils.FileExists("/usr/local/bin/netclient") {
|
||||||
|
os.Symlink("/etc/netclient/netclient", "/usr/local/bin/netclient")
|
||||||
|
}
|
||||||
|
if !ncutils.FileExists("/etc/netclient/netclient") {
|
||||||
|
_, err = ncutils.Copy(binarypath, "/etc/netclient/netclient")
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
systemservice := `[Unit]
|
||||||
|
Description=Network Check
|
||||||
|
Wants=netclient.timer
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/etc/netclient/netclient checkin -n %i
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
`
|
||||||
|
|
||||||
|
systemtimer := `[Unit]
|
||||||
|
Description=Calls the Netmaker Mesh Client Service
|
||||||
|
|
||||||
|
`
|
||||||
|
systemtimer = systemtimer + "Requires=netclient@" + network + ".service"
|
||||||
|
|
||||||
|
systemtimer = systemtimer +
|
||||||
|
`
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
|
||||||
|
`
|
||||||
|
systemtimer = systemtimer + "Unit=netclient@" + network + ".service"
|
||||||
|
|
||||||
|
systemtimer = systemtimer +
|
||||||
|
`
|
||||||
|
|
||||||
|
OnCalendar=*:*:0/30
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
`
|
||||||
|
|
||||||
|
servicebytes := []byte(systemservice)
|
||||||
|
timerbytes := []byte(systemtimer)
|
||||||
|
|
||||||
|
if !ncutils.FileExists("/etc/systemd/system/netclient@.service") {
|
||||||
|
err = ioutil.WriteFile("/etc/systemd/system/netclient@.service", servicebytes, 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ncutils.FileExists("/etc/systemd/system/netclient-" + network + ".timer") {
|
||||||
|
err = ioutil.WriteFile("/etc/systemd/system/netclient-"+network+".timer", timerbytes, 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = ncutils.RunCmd("systemctl enable netclient@.service", true)
|
||||||
|
_, _ = ncutils.RunCmd("systemctl daemon-reload", true)
|
||||||
|
_, _ = ncutils.RunCmd("systemctl enable netclient-"+network+".timer", true)
|
||||||
|
_, _ = ncutils.RunCmd("systemctl start netclient-"+network+".timer", true)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemoveSystemDServices(network string) error {
|
||||||
|
//sysExec, err := exec.LookPath("systemctl")
|
||||||
|
if !ncutils.IsWindows() {
|
||||||
|
fullremove, err := isOnlyService(network)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if fullremove {
|
||||||
|
_, err = ncutils.RunCmd("systemctl disable netclient@.service", true)
|
||||||
|
}
|
||||||
|
_, _ = ncutils.RunCmd("systemctl daemon-reload", true)
|
||||||
|
|
||||||
|
if ncutils.FileExists("/etc/systemd/system/netclient-" + network + ".timer") {
|
||||||
|
_, _ = ncutils.RunCmd("systemctl disable netclient-"+network+".timer", true)
|
||||||
|
}
|
||||||
|
if fullremove {
|
||||||
|
if ncutils.FileExists("/etc/systemd/system/netclient@.service") {
|
||||||
|
err = os.Remove("/etc/systemd/system/netclient@.service")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ncutils.FileExists("/etc/systemd/system/netclient-" + network + ".timer") {
|
||||||
|
err = os.Remove("/etc/systemd/system/netclient-" + network + ".timer")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error removing file. Please investigate.")
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
_, _ = ncutils.RunCmd("systemctl daemon-reload", true)
|
||||||
|
_, _ = ncutils.RunCmd("systemctl reset-failed", true)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isOnlyService(network string) (bool, error) {
|
||||||
|
isonly := false
|
||||||
|
files, err := filepath.Glob("/etc/netclient/netconfig-*")
|
||||||
|
if err != nil {
|
||||||
|
return isonly, err
|
||||||
|
}
|
||||||
|
count := len(files)
|
||||||
|
if count == 0 {
|
||||||
|
isonly = true
|
||||||
|
}
|
||||||
|
return isonly, err
|
||||||
|
|
||||||
|
}
|
140
netclient/daemon/windows.go
Normal file
140
netclient/daemon/windows.go
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
package daemon
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SetupWindowsDaemon() error {
|
||||||
|
|
||||||
|
if !ncutils.FileExists(ncutils.GetNetclientPathSpecific() + "winsw.xml") {
|
||||||
|
if err := writeServiceConfig(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ncutils.FileExists(ncutils.GetNetclientPathSpecific() + "winsw.exe") {
|
||||||
|
ncutils.Log("performing first time daemon setup")
|
||||||
|
if !ncutils.FileExists(".\\winsw.exe") {
|
||||||
|
err := downloadWinsw()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err := copyWinswOver()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ncutils.Log("finished daemon setup")
|
||||||
|
}
|
||||||
|
// install daemon, will not overwrite
|
||||||
|
ncutils.RunCmd(strings.Replace(ncutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe install`, true)
|
||||||
|
// start daemon, will not restart or start another
|
||||||
|
ncutils.RunCmd(strings.Replace(ncutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe start`, true)
|
||||||
|
ncutils.Log(strings.Replace(ncutils.GetNetclientPathSpecific(), `\\`, `\`, -1) + `winsw.exe start`)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CleanupWindows() {
|
||||||
|
if !ncutils.FileExists(ncutils.GetNetclientPathSpecific() + "winsw.xml") {
|
||||||
|
writeServiceConfig()
|
||||||
|
}
|
||||||
|
StopWindowsDaemon()
|
||||||
|
RemoveWindowsDaemon()
|
||||||
|
os.RemoveAll(ncutils.GetNetclientPath())
|
||||||
|
log.Println("Netclient on Windows, uninstalled")
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeServiceConfig() error {
|
||||||
|
serviceConfigPath := ncutils.GetNetclientPathSpecific() + "winsw.xml"
|
||||||
|
scriptString := fmt.Sprintf(`<service>
|
||||||
|
<id>netclient</id>
|
||||||
|
<name>Netclient</name>
|
||||||
|
<description>Connects Windows nodes to one or more Netmaker networks.</description>
|
||||||
|
<executable>%v</executable>
|
||||||
|
<log mode="roll"></log>
|
||||||
|
</service>
|
||||||
|
`, strings.Replace(ncutils.GetNetclientPathSpecific()+"netclient.exe", `\\`, `\`, -1))
|
||||||
|
if !ncutils.FileExists(serviceConfigPath) {
|
||||||
|
err := ioutil.WriteFile(serviceConfigPath, []byte(scriptString), 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ncutils.Log("wrote the daemon config file to the Netclient directory")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// == Daemon ==
|
||||||
|
func StopWindowsDaemon() {
|
||||||
|
ncutils.Log("no networks detected, stopping Windows, Netclient daemon")
|
||||||
|
// stop daemon, will not overwrite
|
||||||
|
ncutils.RunCmd(strings.Replace(ncutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe stop`, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemoveWindowsDaemon() {
|
||||||
|
// uninstall daemon, will not restart or start another
|
||||||
|
ncutils.RunCmd(strings.Replace(ncutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe uninstall`, true)
|
||||||
|
ncutils.Log("uninstalled Windows, Netclient daemon")
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyWinswOver() error {
|
||||||
|
|
||||||
|
input, err := ioutil.ReadFile(".\\winsw.exe")
|
||||||
|
if err != nil {
|
||||||
|
ncutils.Log("failed to find winsw.exe")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = ioutil.WriteFile(ncutils.GetNetclientPathSpecific()+"winsw.exe", input, 0644); err != nil {
|
||||||
|
ncutils.Log("failed to copy winsw.exe to " + ncutils.GetNetclientPath())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = os.Remove(".\\winsw.exe"); err != nil {
|
||||||
|
ncutils.Log("failed to cleanup local winsw.exe, feel free to delete it")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ncutils.Log("finished copying winsw.exe")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func downloadWinsw() error {
|
||||||
|
fullURLFile := "https://github.com/winsw/winsw/releases/download/v2.11.0/WinSW-x64.exe"
|
||||||
|
fileName := "winsw.exe"
|
||||||
|
|
||||||
|
// Create the file
|
||||||
|
file, err := os.Create(fileName)
|
||||||
|
if err != nil {
|
||||||
|
ncutils.Log("could not create file on OS for Winsw")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
client := http.Client{
|
||||||
|
CheckRedirect: func(r *http.Request, via []*http.Request) error {
|
||||||
|
r.URL.Opaque = r.URL.Path
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// Put content on file
|
||||||
|
ncutils.Log("downloading service tool...")
|
||||||
|
resp, err := client.Get(fullURLFile)
|
||||||
|
if err != nil {
|
||||||
|
ncutils.Log("could not GET Winsw")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(file, resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
ncutils.Log("could not mount winsw.exe")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
ncutils.Log("finished downloading Winsw")
|
||||||
|
return nil
|
||||||
|
}
|
@@ -3,7 +3,6 @@ package functions
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -13,7 +12,7 @@ import (
|
|||||||
"github.com/gravitl/netmaker/netclient/auth"
|
"github.com/gravitl/netmaker/netclient/auth"
|
||||||
"github.com/gravitl/netmaker/netclient/config"
|
"github.com/gravitl/netmaker/netclient/config"
|
||||||
"github.com/gravitl/netmaker/netclient/local"
|
"github.com/gravitl/netmaker/netclient/local"
|
||||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
"github.com/gravitl/netmaker/netclient/wireguard"
|
"github.com/gravitl/netmaker/netclient/wireguard"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
@@ -30,37 +29,37 @@ func checkIP(node *models.Node, servercfg config.ServerConfig, cliconf config.Cl
|
|||||||
var err error
|
var err error
|
||||||
if node.Roaming == "yes" && node.IsStatic != "yes" {
|
if node.Roaming == "yes" && node.IsStatic != "yes" {
|
||||||
if node.IsLocal == "no" {
|
if node.IsLocal == "no" {
|
||||||
extIP, err := netclientutils.GetPublicIP()
|
extIP, err := ncutils.GetPublicIP()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error encountered checking ip addresses:", err)
|
ncutils.PrintLog("error encountered checking ip addresses: "+err.Error(), 1)
|
||||||
}
|
}
|
||||||
if node.Endpoint != extIP && extIP != "" {
|
if node.Endpoint != extIP && extIP != "" {
|
||||||
log.Println("Endpoint has changed from " +
|
ncutils.PrintLog("endpoint has changed from "+
|
||||||
node.Endpoint + " to " + extIP)
|
node.Endpoint+" to "+extIP, 1)
|
||||||
log.Println("Updating address")
|
ncutils.PrintLog("updating address", 1)
|
||||||
node.Endpoint = extIP
|
node.Endpoint = extIP
|
||||||
ipchange = true
|
ipchange = true
|
||||||
}
|
}
|
||||||
intIP, err := getPrivateAddr()
|
intIP, err := getPrivateAddr()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error encountered checking ip addresses:", err)
|
ncutils.PrintLog("error encountered checking ip addresses: "+err.Error(), 1)
|
||||||
}
|
}
|
||||||
if node.LocalAddress != intIP && intIP != "" {
|
if node.LocalAddress != intIP && intIP != "" {
|
||||||
log.Println("Local Address has changed from " +
|
ncutils.PrintLog("local Address has changed from "+
|
||||||
node.LocalAddress + " to " + intIP)
|
node.LocalAddress+" to "+intIP, 1)
|
||||||
log.Println("Updating address")
|
ncutils.PrintLog("updating address", 1)
|
||||||
node.LocalAddress = intIP
|
node.LocalAddress = intIP
|
||||||
ipchange = true
|
ipchange = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
localIP, err := netclientutils.GetLocalIP(node.LocalRange)
|
localIP, err := ncutils.GetLocalIP(node.LocalRange)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error encountered checking ip addresses:", err)
|
ncutils.PrintLog("error encountered checking ip addresses: "+err.Error(), 1)
|
||||||
}
|
}
|
||||||
if node.Endpoint != localIP && localIP != "" {
|
if node.Endpoint != localIP && localIP != "" {
|
||||||
log.Println("Endpoint has changed from " +
|
ncutils.PrintLog("endpoint has changed from "+
|
||||||
node.Endpoint + " to " + localIP)
|
node.Endpoint+" to "+localIP, 1)
|
||||||
log.Println("Updating address")
|
ncutils.PrintLog("updating address", 1)
|
||||||
node.Endpoint = localIP
|
node.Endpoint = localIP
|
||||||
node.LocalAddress = localIP
|
node.LocalAddress = localIP
|
||||||
ipchange = true
|
ipchange = true
|
||||||
@@ -70,12 +69,12 @@ func checkIP(node *models.Node, servercfg config.ServerConfig, cliconf config.Cl
|
|||||||
if ipchange {
|
if ipchange {
|
||||||
err = config.ModConfig(node)
|
err = config.ModConfig(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error:", err)
|
ncutils.PrintLog("error modifying config file: "+err.Error(), 1)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
err = wireguard.SetWGConfig(network, false)
|
err = wireguard.SetWGConfig(network, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error:", err)
|
ncutils.PrintLog("error setting wireguard config: "+err.Error(), 1)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,14 +95,14 @@ func checkNodeActions(node *models.Node, networkName string, servercfg config.Se
|
|||||||
node.IsStatic != "yes" {
|
node.IsStatic != "yes" {
|
||||||
err := wireguard.SetWGKeyConfig(networkName, servercfg.GRPCAddress)
|
err := wireguard.SetWGKeyConfig(networkName, servercfg.GRPCAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Unable to process reset keys request:", err)
|
ncutils.PrintLog("unable to process reset keys request: "+err.Error(), 1)
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if node.Action == models.NODE_DELETE || localNode.Action == models.NODE_DELETE {
|
if node.Action == models.NODE_DELETE || localNode.Action == models.NODE_DELETE {
|
||||||
err := RemoveLocalInstance(cfg, networkName)
|
err := RemoveLocalInstance(cfg, networkName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Error:", err)
|
ncutils.PrintLog("error deleting locally: "+err.Error(), 1)
|
||||||
}
|
}
|
||||||
return models.NODE_DELETE
|
return models.NODE_DELETE
|
||||||
}
|
}
|
||||||
@@ -161,22 +160,22 @@ func Pull(network string, manual bool) (*models.Node, error) {
|
|||||||
servercfg := cfg.Server
|
servercfg := cfg.Server
|
||||||
var header metadata.MD
|
var header metadata.MD
|
||||||
|
|
||||||
if cfg.Node.IPForwarding == "yes" && !netclientutils.IsWindows() {
|
if cfg.Node.IPForwarding == "yes" && !ncutils.IsWindows() {
|
||||||
if err = local.SetIPForwarding(); err != nil {
|
if err = local.SetIPForwarding(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Cant dial GRPC server:", err)
|
ncutils.PrintLog("Cant dial GRPC server: "+err.Error(), 1)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
wcclient := nodepb.NewNodeServiceClient(conn)
|
wcclient := nodepb.NewNodeServiceClient(conn)
|
||||||
|
|
||||||
ctx, err := auth.SetJWT(wcclient, network)
|
ctx, err := auth.SetJWT(wcclient, network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Failed to authenticate:", err)
|
ncutils.PrintLog("Failed to authenticate: "+err.Error(), 1)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +197,7 @@ func Pull(network string, manual bool) (*models.Node, error) {
|
|||||||
// check for interface change
|
// check for interface change
|
||||||
if cfg.Node.Interface != resNode.Interface {
|
if cfg.Node.Interface != resNode.Interface {
|
||||||
if err = DeleteInterface(cfg.Node.Interface, cfg.Node.PostDown); err != nil {
|
if err = DeleteInterface(cfg.Node.Interface, cfg.Node.PostDown); err != nil {
|
||||||
log.Println("could not delete old interface", cfg.Node.Interface)
|
ncutils.PrintLog("could not delete old interface "+cfg.Node.Interface, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resNode.PullChanges = "no"
|
resNode.PullChanges = "no"
|
||||||
@@ -230,7 +229,7 @@ func Pull(network string, manual bool) (*models.Node, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if netclientutils.IsLinux() {
|
if ncutils.IsLinux() {
|
||||||
setDNS(&resNode, servercfg, &cfg.Node)
|
setDNS(&resNode, servercfg, &cfg.Node)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,16 +248,16 @@ func Push(network string) error {
|
|||||||
|
|
||||||
var wcclient nodepb.NodeServiceClient
|
var wcclient nodepb.NodeServiceClient
|
||||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Cant dial GRPC server:", err)
|
ncutils.PrintLog("Cant dial GRPC server: "+err.Error(), 1)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||||
|
|
||||||
ctx, err := auth.SetJWT(wcclient, network)
|
ctx, err := auth.SetJWT(wcclient, network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Failed to authenticate:", err)
|
ncutils.PrintLog("Failed to authenticate with server: "+err.Error(), 1)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if postnode.IsPending != "yes" {
|
if postnode.IsPending != "yes" {
|
||||||
|
@@ -8,6 +8,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -15,8 +16,9 @@ import (
|
|||||||
"github.com/gravitl/netmaker/models"
|
"github.com/gravitl/netmaker/models"
|
||||||
"github.com/gravitl/netmaker/netclient/auth"
|
"github.com/gravitl/netmaker/netclient/auth"
|
||||||
"github.com/gravitl/netmaker/netclient/config"
|
"github.com/gravitl/netmaker/netclient/config"
|
||||||
"github.com/gravitl/netmaker/netclient/local"
|
"github.com/gravitl/netmaker/netclient/daemon"
|
||||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
|
"github.com/gravitl/netmaker/netclient/wireguard"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl"
|
"golang.zx2c4.com/wireguard/wgctrl"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
@@ -92,21 +94,21 @@ func GetNode(network string) models.Node {
|
|||||||
func Uninstall() error {
|
func Uninstall() error {
|
||||||
networks, err := GetNetworks()
|
networks, err := GetNetworks()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("unable to retrieve networks: ", err)
|
ncutils.PrintLog("unable to retrieve networks: "+err.Error(), 1)
|
||||||
log.Println("continuing uninstall without leaving networks")
|
ncutils.PrintLog("continuing uninstall without leaving networks", 1)
|
||||||
} else {
|
} else {
|
||||||
for _, network := range networks {
|
for _, network := range networks {
|
||||||
err = LeaveNetwork(network)
|
err = LeaveNetwork(network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Encounter issue leaving network "+network+": ", err)
|
ncutils.PrintLog("Encounter issue leaving network "+network+": "+err.Error(), 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// clean up OS specific stuff
|
// clean up OS specific stuff
|
||||||
if netclientutils.IsWindows() {
|
if ncutils.IsWindows() {
|
||||||
local.CleanupWindows()
|
daemon.CleanupWindows()
|
||||||
} else if netclientutils.IsWindows() {
|
} else if ncutils.IsWindows() {
|
||||||
local.CleanupMac()
|
daemon.CleanupMac()
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
@@ -123,7 +125,7 @@ func LeaveNetwork(network string) error {
|
|||||||
|
|
||||||
var wcclient nodepb.NodeServiceClient
|
var wcclient nodepb.NodeServiceClient
|
||||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Unable to establish client connection to "+servercfg.GRPCAddress+": %v", err)
|
log.Printf("Unable to establish client connection to "+servercfg.GRPCAddress+": %v", err)
|
||||||
} else {
|
} else {
|
||||||
@@ -134,9 +136,9 @@ func LeaveNetwork(network string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to authenticate: %v", err)
|
log.Printf("Failed to authenticate: %v", err)
|
||||||
} else {
|
} else {
|
||||||
if netclientutils.IsWindows() {
|
if !ncutils.IsKernel() {
|
||||||
local.RemoveWindowsConf(node.Interface)
|
//wireguard.RemoveConf(node.Interface, true)
|
||||||
log.Println("removed Windows tunnel " + node.Interface)
|
//ncutils.PrintLog("removed network tunnel "+node.Interface, 1)
|
||||||
}
|
}
|
||||||
node.SetID()
|
node.SetID()
|
||||||
var header metadata.MD
|
var header metadata.MD
|
||||||
@@ -149,10 +151,9 @@ func LeaveNetwork(network string) error {
|
|||||||
grpc.Header(&header),
|
grpc.Header(&header),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Encountered error deleting node: %v", err)
|
ncutils.PrintLog("encountered error deleting node: "+err.Error(), 1)
|
||||||
log.Println(err)
|
|
||||||
} else {
|
} else {
|
||||||
log.Println("Removed machine from " + node.Network + " network on remote server")
|
ncutils.PrintLog("removed machine from "+node.Network+" network on remote server", 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,17 +161,19 @@ func LeaveNetwork(network string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func RemoveLocalInstance(cfg *config.ClientConfig, networkName string) error {
|
func RemoveLocalInstance(cfg *config.ClientConfig, networkName string) error {
|
||||||
err := local.WipeLocal(networkName)
|
err := WipeLocal(networkName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Unable to wipe local config: %v", err)
|
ncutils.PrintLog("unable to wipe local config", 1)
|
||||||
} else {
|
} else {
|
||||||
log.Println("Removed " + networkName + " network locally")
|
ncutils.PrintLog("removed "+networkName+" network locally", 1)
|
||||||
}
|
}
|
||||||
if cfg.Daemon != "off" {
|
if cfg.Daemon != "off" {
|
||||||
if netclientutils.IsWindows() {
|
if ncutils.IsWindows() {
|
||||||
// TODO: Remove job?
|
// TODO: Remove job?
|
||||||
|
} else if ncutils.IsMac() {
|
||||||
|
//TODO: Delete mac daemon
|
||||||
} else {
|
} else {
|
||||||
err = local.RemoveSystemDServices(networkName)
|
err = daemon.RemoveSystemDServices(networkName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@@ -178,18 +181,18 @@ func RemoveLocalInstance(cfg *config.ClientConfig, networkName string) error {
|
|||||||
|
|
||||||
func DeleteInterface(ifacename string, postdown string) error {
|
func DeleteInterface(ifacename string, postdown string) error {
|
||||||
var err error
|
var err error
|
||||||
if netclientutils.IsWindows() {
|
if !ncutils.IsKernel() {
|
||||||
err = local.RemoveWindowsConf(ifacename)
|
err = wireguard.RemoveConf(ifacename, true)
|
||||||
} else {
|
} else {
|
||||||
ipExec, errN := exec.LookPath("ip")
|
ipExec, errN := exec.LookPath("ip")
|
||||||
err = errN
|
err = errN
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
ncutils.PrintLog(err.Error(), 1)
|
||||||
}
|
}
|
||||||
_, err = local.RunCmd(ipExec+" link del "+ifacename, false)
|
_, err = ncutils.RunCmd(ipExec+" link del "+ifacename, false)
|
||||||
if postdown != "" {
|
if postdown != "" {
|
||||||
runcmds := strings.Split(postdown, "; ")
|
runcmds := strings.Split(postdown, "; ")
|
||||||
err = local.RunCmds(runcmds, true)
|
err = ncutils.RunCmds(runcmds, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@@ -212,9 +215,9 @@ func List() error {
|
|||||||
"PrivateIPv6": cfg.Node.Address6,
|
"PrivateIPv6": cfg.Node.Address6,
|
||||||
"PublicEndpoint": cfg.Node.Endpoint,
|
"PublicEndpoint": cfg.Node.Endpoint,
|
||||||
})
|
})
|
||||||
log.Println(network + ": " + string(jsoncfg))
|
fmt.Println(network + ": " + string(jsoncfg))
|
||||||
} else {
|
} else {
|
||||||
log.Println(network + ": Could not retrieve network configuration.")
|
ncutils.PrintLog(network+": Could not retrieve network configuration.", 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -222,7 +225,7 @@ func List() error {
|
|||||||
|
|
||||||
func GetNetworks() ([]string, error) {
|
func GetNetworks() ([]string, error) {
|
||||||
var networks []string
|
var networks []string
|
||||||
files, err := ioutil.ReadDir(netclientutils.GetNetclientPath())
|
files, err := ioutil.ReadDir(ncutils.GetNetclientPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return networks, err
|
return networks, err
|
||||||
}
|
}
|
||||||
@@ -247,3 +250,107 @@ func stringAfter(original string, substring string) string {
|
|||||||
}
|
}
|
||||||
return original[adjustedPosition:len(original)]
|
return original[adjustedPosition:len(original)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WipeLocal(network string) error {
|
||||||
|
cfg, err := config.ReadConfig(network)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
nodecfg := cfg.Node
|
||||||
|
ifacename := nodecfg.Interface
|
||||||
|
|
||||||
|
if ifacename != "" {
|
||||||
|
if !ncutils.IsKernel() {
|
||||||
|
if err = wireguard.RemoveConf(ifacename, true); err == nil {
|
||||||
|
ncutils.PrintLog("removed WireGuard interface: "+ifacename, 1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ipExec, err := exec.LookPath("ip")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
out, err := ncutils.RunCmd(ipExec+" link del "+ifacename, false)
|
||||||
|
dontprint := strings.Contains(out, "does not exist") || strings.Contains(out, "Cannot find device")
|
||||||
|
if err != nil && !dontprint {
|
||||||
|
ncutils.PrintLog("error running command: "+ipExec+" link del "+ifacename, 1)
|
||||||
|
ncutils.PrintLog(out, 1)
|
||||||
|
}
|
||||||
|
if nodecfg.PostDown != "" {
|
||||||
|
runcmds := strings.Split(nodecfg.PostDown, "; ")
|
||||||
|
_ = ncutils.RunCmds(runcmds, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
home := ncutils.GetNetclientPathSpecific()
|
||||||
|
if ncutils.FileExists(home + "netconfig-" + network) {
|
||||||
|
_ = os.Remove(home + "netconfig-" + network)
|
||||||
|
}
|
||||||
|
if ncutils.FileExists(home + "nettoken-" + network) {
|
||||||
|
_ = os.Remove(home + "nettoken-" + network)
|
||||||
|
}
|
||||||
|
if ncutils.FileExists(home + "secret-" + network) {
|
||||||
|
_ = os.Remove(home + "secret-" + network)
|
||||||
|
}
|
||||||
|
if ncutils.FileExists(home + "wgkey-" + network) {
|
||||||
|
_ = os.Remove(home + "wgkey-" + network)
|
||||||
|
}
|
||||||
|
if ncutils.FileExists(home + "nm-" + network + ".conf") {
|
||||||
|
_ = os.Remove(home + "nm-" + network + ".conf")
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLocalIP(node models.Node) string {
|
||||||
|
|
||||||
|
var local string
|
||||||
|
|
||||||
|
ifaces, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
return local
|
||||||
|
}
|
||||||
|
_, localrange, err := net.ParseCIDR(node.LocalRange)
|
||||||
|
if err != nil {
|
||||||
|
return local
|
||||||
|
}
|
||||||
|
|
||||||
|
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 local
|
||||||
|
}
|
||||||
|
for _, addr := range addrs {
|
||||||
|
var ip net.IP
|
||||||
|
switch v := addr.(type) {
|
||||||
|
case *net.IPNet:
|
||||||
|
if !found {
|
||||||
|
ip = v.IP
|
||||||
|
local = ip.String()
|
||||||
|
if node.IsLocal == "yes" {
|
||||||
|
found = localrange.Contains(ip)
|
||||||
|
} else {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case *net.IPAddr:
|
||||||
|
if !found {
|
||||||
|
ip = v.IP
|
||||||
|
local = ip.String()
|
||||||
|
if node.IsLocal == "yes" {
|
||||||
|
found = localrange.Contains(ip)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return local
|
||||||
|
}
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
package functions
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gravitl/netmaker/netclient/config"
|
|
||||||
"github.com/gravitl/netmaker/netclient/local"
|
|
||||||
)
|
|
||||||
|
|
||||||
func InstallDaemon(cfg config.ClientConfig) error {
|
|
||||||
|
|
||||||
var err error
|
|
||||||
err = local.ConfigureSystemD(cfg.Network)
|
|
||||||
return err
|
|
||||||
}
|
|
@@ -11,8 +11,9 @@ import (
|
|||||||
"github.com/gravitl/netmaker/models"
|
"github.com/gravitl/netmaker/models"
|
||||||
"github.com/gravitl/netmaker/netclient/auth"
|
"github.com/gravitl/netmaker/netclient/auth"
|
||||||
"github.com/gravitl/netmaker/netclient/config"
|
"github.com/gravitl/netmaker/netclient/config"
|
||||||
|
"github.com/gravitl/netmaker/netclient/daemon"
|
||||||
"github.com/gravitl/netmaker/netclient/local"
|
"github.com/gravitl/netmaker/netclient/local"
|
||||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
"github.com/gravitl/netmaker/netclient/server"
|
"github.com/gravitl/netmaker/netclient/server"
|
||||||
"github.com/gravitl/netmaker/netclient/wireguard"
|
"github.com/gravitl/netmaker/netclient/wireguard"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
@@ -27,7 +28,7 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
netclientutils.Log("attempting to join " + cfg.Network + " at " + cfg.Server.GRPCAddress)
|
ncutils.Log("joining " + cfg.Network + " at " + cfg.Server.GRPCAddress)
|
||||||
err := config.Write(&cfg, cfg.Network)
|
err := config.Write(&cfg, cfg.Network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -42,7 +43,7 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
|
|||||||
cfg.Node.LocalAddress = getLocalIP(cfg.Node)
|
cfg.Node.LocalAddress = getLocalIP(cfg.Node)
|
||||||
}
|
}
|
||||||
if cfg.Node.Password == "" {
|
if cfg.Node.Password == "" {
|
||||||
cfg.Node.Password = netclientutils.GenPass()
|
cfg.Node.Password = ncutils.GenPass()
|
||||||
}
|
}
|
||||||
auth.StoreSecret(cfg.Node.Password, cfg.Node.Network)
|
auth.StoreSecret(cfg.Node.Password, cfg.Node.Network)
|
||||||
|
|
||||||
@@ -51,11 +52,11 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
|
|||||||
if cfg.Node.IsLocal == "yes" && cfg.Node.LocalAddress != "" {
|
if cfg.Node.IsLocal == "yes" && cfg.Node.LocalAddress != "" {
|
||||||
cfg.Node.Endpoint = cfg.Node.LocalAddress
|
cfg.Node.Endpoint = cfg.Node.LocalAddress
|
||||||
} else {
|
} else {
|
||||||
cfg.Node.Endpoint, err = netclientutils.GetPublicIP()
|
cfg.Node.Endpoint, err = ncutils.GetPublicIP()
|
||||||
|
|
||||||
}
|
}
|
||||||
if err != nil || cfg.Node.Endpoint == "" {
|
if err != nil || cfg.Node.Endpoint == "" {
|
||||||
netclientutils.Log("Error setting cfg.Node.Endpoint.")
|
ncutils.Log("Error setting cfg.Node.Endpoint.")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,7 +72,7 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
|
|||||||
|
|
||||||
// Find and set node MacAddress
|
// Find and set node MacAddress
|
||||||
if cfg.Node.MacAddress == "" {
|
if cfg.Node.MacAddress == "" {
|
||||||
macs, err := netclientutils.GetMacAddr()
|
macs, err := ncutils.GetMacAddr()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if len(macs) == 0 {
|
} else if len(macs) == 0 {
|
||||||
@@ -84,7 +85,7 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
|
|||||||
var wcclient nodepb.NodeServiceClient
|
var wcclient nodepb.NodeServiceClient
|
||||||
|
|
||||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Unable to establish client connection to "+cfg.Server.GRPCAddress+": %v", err)
|
log.Fatalf("Unable to establish client connection to "+cfg.Server.GRPCAddress+": %v", err)
|
||||||
@@ -129,7 +130,7 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Println("node created on remote server...updating configs")
|
ncutils.PrintLog("node created on remote server...updating configs", 1)
|
||||||
|
|
||||||
nodeData := res.Data
|
nodeData := res.Data
|
||||||
var node models.Node
|
var node models.Node
|
||||||
@@ -138,14 +139,14 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get free port based on returned default listen port
|
// get free port based on returned default listen port
|
||||||
node.ListenPort, err = netclientutils.GetFreePort(node.ListenPort)
|
node.ListenPort, err = ncutils.GetFreePort(node.ListenPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error retrieving port: %v", err)
|
fmt.Printf("Error retrieving port: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// safety check. If returned node from server is local, but not currently configured as local, set to local addr
|
// safety check. If returned node from server is local, but not currently configured as local, set to local addr
|
||||||
if cfg.Node.IsLocal != "yes" && node.IsLocal == "yes" && node.LocalRange != "" {
|
if cfg.Node.IsLocal != "yes" && node.IsLocal == "yes" && node.LocalRange != "" {
|
||||||
node.LocalAddress, err = netclientutils.GetLocalIP(node.LocalRange)
|
node.LocalAddress, err = ncutils.GetLocalIP(node.LocalRange)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -168,38 +169,28 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if node.IsPending == "yes" {
|
if node.IsPending == "yes" {
|
||||||
netclientutils.Log("Node is marked as PENDING.")
|
ncutils.Log("Node is marked as PENDING.")
|
||||||
netclientutils.Log("Awaiting approval from Admin before configuring WireGuard.")
|
ncutils.Log("Awaiting approval from Admin before configuring WireGuard.")
|
||||||
if cfg.Daemon != "off" {
|
if cfg.Daemon != "off" {
|
||||||
if netclientutils.IsWindows() {
|
return daemon.InstallDaemon(cfg)
|
||||||
// handle daemon here..
|
|
||||||
err = local.CreateAndRunWindowsDaemon()
|
|
||||||
} else {
|
|
||||||
err = local.ConfigureSystemD(cfg.Network)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
netclientutils.Log("retrieving remote peers")
|
ncutils.Log("retrieving remote peers")
|
||||||
peers, hasGateway, gateways, err := server.GetPeers(node.MacAddress, cfg.Network, cfg.Server.GRPCAddress, node.IsDualStack == "yes", node.IsIngressGateway == "yes")
|
peers, hasGateway, gateways, err := server.GetPeers(node.MacAddress, cfg.Network, cfg.Server.GRPCAddress, node.IsDualStack == "yes", node.IsIngressGateway == "yes")
|
||||||
|
|
||||||
if err != nil && !netclientutils.IsEmptyRecord(err) {
|
if err != nil && !ncutils.IsEmptyRecord(err) {
|
||||||
netclientutils.Log("failed to retrieve peers")
|
ncutils.Log("failed to retrieve peers")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
netclientutils.Log("starting wireguard")
|
ncutils.Log("starting wireguard")
|
||||||
err = wireguard.InitWireguard(&node, privateKey, peers, hasGateway, gateways)
|
err = wireguard.InitWireguard(&node, privateKey, peers, hasGateway, gateways)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if cfg.Daemon != "off" {
|
if cfg.Daemon != "off" {
|
||||||
if netclientutils.IsWindows() {
|
err = daemon.InstallDaemon(cfg)
|
||||||
err = local.CreateAndRunWindowsDaemon()
|
|
||||||
} else {
|
|
||||||
err = local.ConfigureSystemD(cfg.Network)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@@ -1,62 +0,0 @@
|
|||||||
package functions
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gravitl/netmaker/models"
|
|
||||||
"net"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
func getLocalIP(node models.Node) string{
|
|
||||||
|
|
||||||
var local string
|
|
||||||
|
|
||||||
ifaces, err := net.Interfaces()
|
|
||||||
if err != nil {
|
|
||||||
return local
|
|
||||||
}
|
|
||||||
_, localrange, err := net.ParseCIDR(node.LocalRange)
|
|
||||||
if err != nil {
|
|
||||||
return local
|
|
||||||
}
|
|
||||||
|
|
||||||
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 local
|
|
||||||
}
|
|
||||||
for _, addr := range addrs {
|
|
||||||
var ip net.IP
|
|
||||||
switch v := addr.(type) {
|
|
||||||
case *net.IPNet:
|
|
||||||
if !found {
|
|
||||||
ip = v.IP
|
|
||||||
local = ip.String()
|
|
||||||
if node.IsLocal == "yes" {
|
|
||||||
found = localrange.Contains(ip)
|
|
||||||
} else {
|
|
||||||
found = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case *net.IPAddr:
|
|
||||||
if !found {
|
|
||||||
ip = v.IP
|
|
||||||
local = ip.String()
|
|
||||||
if node.IsLocal == "yes" {
|
|
||||||
found = localrange.Contains(ip)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
found = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return local
|
|
||||||
}
|
|
@@ -1,12 +0,0 @@
|
|||||||
package functions
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func PrintLog(message string, loglevel int) {
|
|
||||||
log.SetFlags(log.Flags() &^ (log.Llongfile | log.Lshortfile))
|
|
||||||
if loglevel == 0 {
|
|
||||||
log.Println(message)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -9,7 +9,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetDNS(nameserver string) error {
|
func SetDNS(nameserver string) error {
|
||||||
@@ -34,7 +34,7 @@ func SetDNS(nameserver string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func UpdateDNS(ifacename string, network string, nameserver string) error {
|
func UpdateDNS(ifacename string, network string, nameserver string) error {
|
||||||
if netclientutils.IsWindows() {
|
if ncutils.IsWindows() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
_, err := exec.LookPath("resolvectl")
|
_, err := exec.LookPath("resolvectl")
|
||||||
@@ -42,15 +42,15 @@ func UpdateDNS(ifacename string, network string, nameserver string) error {
|
|||||||
log.Println(err)
|
log.Println(err)
|
||||||
log.Println("WARNING: resolvectl not present. Unable to set dns. Install resolvectl or run manually.")
|
log.Println("WARNING: resolvectl not present. Unable to set dns. Install resolvectl or run manually.")
|
||||||
} else {
|
} else {
|
||||||
_, err = RunCmd("resolvectl domain " + ifacename + " ~" + network, true)
|
_, err = ncutils.RunCmd("resolvectl domain "+ifacename+" ~"+network, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("WARNING: Error encountered setting domain on dns. Aborted setting dns.")
|
log.Println("WARNING: Error encountered setting domain on dns. Aborted setting dns.")
|
||||||
} else {
|
} else {
|
||||||
_, err = RunCmd("resolvectl default-route " + ifacename + " false", true)
|
_, err = ncutils.RunCmd("resolvectl default-route "+ifacename+" false", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("WARNING: Error encountered setting default-route on dns. Aborted setting dns.")
|
log.Println("WARNING: Error encountered setting default-route on dns. Aborted setting dns.")
|
||||||
} else {
|
} else {
|
||||||
_, err = RunCmd("resolvectl dns " + ifacename + " " + nameserver, true)
|
_, err = ncutils.RunCmd("resolvectl dns "+ifacename+" "+nameserver, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("WARNING: Error encountered running resolvectl dns " + ifacename + " " + nameserver)
|
log.Println("WARNING: Error encountered running resolvectl dns " + ifacename + " " + nameserver)
|
||||||
}
|
}
|
||||||
|
@@ -3,17 +3,11 @@ package local
|
|||||||
import (
|
import (
|
||||||
//"github.com/davecgh/go-spew/spew"
|
//"github.com/davecgh/go-spew/spew"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/netclient/config"
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetIPForwarding() error {
|
func SetIPForwarding() error {
|
||||||
@@ -22,6 +16,8 @@ func SetIPForwarding() error {
|
|||||||
switch os {
|
switch os {
|
||||||
case "linux":
|
case "linux":
|
||||||
err = SetIPForwardingLinux()
|
err = SetIPForwardingLinux()
|
||||||
|
case "darwin":
|
||||||
|
err = SetIPForwardingMac()
|
||||||
default:
|
default:
|
||||||
err = errors.New("This OS is not supported")
|
err = errors.New("This OS is not supported")
|
||||||
}
|
}
|
||||||
@@ -29,14 +25,14 @@ func SetIPForwarding() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SetIPForwardingLinux() error {
|
func SetIPForwardingLinux() error {
|
||||||
out, err := RunCmd("sysctl net.ipv4.ip_forward", true)
|
out, err := ncutils.RunCmd("sysctl net.ipv4.ip_forward", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("WARNING: Error encountered setting ip forwarding. This can break functionality.")
|
log.Println("WARNING: Error encountered setting ip forwarding. This can break functionality.")
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
s := strings.Fields(string(out))
|
s := strings.Fields(string(out))
|
||||||
if s[2] != "1" {
|
if s[2] != "1" {
|
||||||
_, err = RunCmd("sysctl -w net.ipv4.ip_forward=1", true)
|
_, err = ncutils.RunCmd("sysctl -w net.ipv4.ip_forward=1", true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("WARNING: Error encountered setting ip forwarding. You may want to investigate this.")
|
log.Println("WARNING: Error encountered setting ip forwarding. You may want to investigate this.")
|
||||||
return err
|
return err
|
||||||
@@ -46,274 +42,59 @@ func SetIPForwardingLinux() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunCmd(command string, printerr bool) (string, error) {
|
func SetIPForwardingMac() error {
|
||||||
args := strings.Fields(command)
|
_, err := ncutils.RunCmd("sysctl -w net.inet.ip.forwarding=1", true)
|
||||||
out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
|
if err != nil {
|
||||||
if err != nil && printerr {
|
log.Println("WARNING: Error encountered setting ip forwarding. This can break functionality.")
|
||||||
log.Println("error running command:",command)
|
|
||||||
log.Println(string(out))
|
|
||||||
}
|
|
||||||
return string(out), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func RunCmds(commands []string, printerr bool) error {
|
|
||||||
var err error
|
|
||||||
for _, command := range commands {
|
|
||||||
args := strings.Fields(command)
|
|
||||||
out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
|
|
||||||
if err != nil && printerr {
|
|
||||||
log.Println("error running command:",command)
|
|
||||||
log.Println(string(out))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func FileExists(f string) bool {
|
func IsWGInstalled() bool {
|
||||||
info, err := os.Stat(f)
|
out, err := ncutils.RunCmd("wg help", true)
|
||||||
if os.IsNotExist(err) {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return !info.IsDir()
|
return strings.Contains(out, "Available subcommand")
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConfigureSystemD(network string) error {
|
func GetMacIface(addr string) (string, error) {
|
||||||
/*
|
out, err := ncutils.RunCmd("route get "+addr, false)
|
||||||
path, err := os.Getwd()
|
var iface string
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
//binarypath := path + "/netclient"
|
|
||||||
if netclientutils.IsWindows() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return iface, errors.New(string(out))
|
||||||
}
|
}
|
||||||
binarypath := dir + "/netclient"
|
for _, line := range strings.Split(strings.TrimSuffix(string(out), "\n"), "\n") {
|
||||||
|
if strings.Contains(line, "interface: ") {
|
||||||
_, err = os.Stat("/etc/netclient")
|
iface = getLineAfter(string(out), "interface: ")
|
||||||
if os.IsNotExist(err) {
|
iface = strings.Split(iface, "\n")[0]
|
||||||
os.Mkdir("/etc/netclient", 744)
|
break
|
||||||
} else if err != nil {
|
|
||||||
log.Println("couldnt find or create /etc/netclient")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !FileExists("/usr/local/bin/netclient") {
|
|
||||||
os.Symlink("/etc/netclient/netclient", "/usr/local/bin/netclient")
|
|
||||||
/*
|
|
||||||
_, err = copy(binarypath, "/usr/local/bin/netclient")
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
if !FileExists("/etc/netclient/netclient") {
|
|
||||||
_, err = copy(binarypath, "/etc/netclient/netclient")
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if iface == "" {
|
||||||
systemservice := `[Unit]
|
err = errors.New("could not find iface for ip addr " + addr)
|
||||||
Description=Network Check
|
|
||||||
Wants=netclient.timer
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
ExecStart=/etc/netclient/netclient checkin -n %i
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
`
|
|
||||||
|
|
||||||
systemtimer := `[Unit]
|
|
||||||
Description=Calls the Netmaker Mesh Client Service
|
|
||||||
|
|
||||||
`
|
|
||||||
systemtimer = systemtimer + "Requires=netclient@" + network + ".service"
|
|
||||||
|
|
||||||
systemtimer = systemtimer +
|
|
||||||
`
|
|
||||||
|
|
||||||
[Timer]
|
|
||||||
|
|
||||||
`
|
|
||||||
systemtimer = systemtimer + "Unit=netclient@" + network + ".service"
|
|
||||||
|
|
||||||
systemtimer = systemtimer +
|
|
||||||
`
|
|
||||||
|
|
||||||
OnCalendar=*:*:0/30
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=timers.target
|
|
||||||
`
|
|
||||||
|
|
||||||
servicebytes := []byte(systemservice)
|
|
||||||
timerbytes := []byte(systemtimer)
|
|
||||||
|
|
||||||
if !FileExists("/etc/systemd/system/netclient@.service") {
|
|
||||||
err = ioutil.WriteFile("/etc/systemd/system/netclient@.service", servicebytes, 0644)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return iface, err
|
||||||
if !FileExists("/etc/systemd/system/netclient-" + network + ".timer") {
|
|
||||||
err = ioutil.WriteFile("/etc/systemd/system/netclient-"+network+".timer", timerbytes, 0644)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _ = RunCmd("systemctl enable netclient@.service", true)
|
|
||||||
_, _ = RunCmd("systemctl daemon-reload", true)
|
|
||||||
_, _ = RunCmd("systemctl enable netclient-" + network + ".timer", true)
|
|
||||||
_, _ = RunCmd("systemctl start netclient-" + network + ".timer", true)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func isOnlyService(network string) (bool, error) {
|
func getLineAfter(value string, a string) string {
|
||||||
isonly := false
|
// Get substring after a string.
|
||||||
files, err := filepath.Glob("/etc/netclient/netconfig-*")
|
pos := strings.LastIndex(value, a)
|
||||||
if err != nil {
|
if pos == -1 {
|
||||||
return isonly, err
|
return ""
|
||||||
}
|
}
|
||||||
count := len(files)
|
adjustedPos := pos + len(a)
|
||||||
if count == 0 {
|
if adjustedPos >= len(value) {
|
||||||
isonly = true
|
return ""
|
||||||
}
|
}
|
||||||
return isonly, err
|
return value[adjustedPos:len(value)]
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func RemoveSystemDServices(network string) error {
|
|
||||||
//sysExec, err := exec.LookPath("systemctl")
|
|
||||||
if !netclientutils.IsWindows() {
|
|
||||||
fullremove, err := isOnlyService(network)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if fullremove {
|
|
||||||
_, err = RunCmd("systemctl disable netclient@.service", true)
|
|
||||||
}
|
|
||||||
_, _ = RunCmd("systemctl daemon-reload", true)
|
|
||||||
|
|
||||||
if FileExists("/etc/systemd/system/netclient-" + network + ".timer") {
|
|
||||||
_, _ = RunCmd("systemctl disable netclient-" + network + ".timer", true)
|
|
||||||
}
|
|
||||||
if fullremove {
|
|
||||||
if FileExists("/etc/systemd/system/netclient@.service") {
|
|
||||||
err = os.Remove("/etc/systemd/system/netclient@.service")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if FileExists("/etc/systemd/system/netclient-" + network + ".timer") {
|
|
||||||
err = os.Remove("/etc/systemd/system/netclient-" + network + ".timer")
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Error removing file. Please investigate.")
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
_, _ = RunCmd("systemctl daemon-reload", true)
|
|
||||||
_, _ = RunCmd("systemctl reset-failed", true)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func WipeLocal(network string) error {
|
|
||||||
cfg, err := config.ReadConfig(network)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
nodecfg := cfg.Node
|
|
||||||
ifacename := nodecfg.Interface
|
|
||||||
|
|
||||||
home := netclientutils.GetNetclientPathSpecific()
|
|
||||||
if FileExists(home + "netconfig-" + network) {
|
|
||||||
_ = os.Remove(home + "netconfig-" + network)
|
|
||||||
}
|
|
||||||
if FileExists(home + "nettoken-" + network) {
|
|
||||||
_ = os.Remove(home + "nettoken-" + network)
|
|
||||||
}
|
|
||||||
if FileExists(home + "secret-" + network) {
|
|
||||||
_ = os.Remove(home + "secret-" + network)
|
|
||||||
}
|
|
||||||
if FileExists(home + "wgkey-" + network) {
|
|
||||||
_ = os.Remove(home + "wgkey-" + network)
|
|
||||||
}
|
|
||||||
if FileExists(home + "nm-" + network + ".conf") {
|
|
||||||
_ = os.Remove(home + "nm-" + network + ".conf")
|
|
||||||
}
|
|
||||||
|
|
||||||
if ifacename != "" {
|
|
||||||
if netclientutils.IsWindows() {
|
|
||||||
if err = RemoveWindowsConf(ifacename); err == nil {
|
|
||||||
log.Println("removed Windows interface", ifacename)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ipExec, err := exec.LookPath("ip")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
out, err := RunCmd(ipExec + " link del " + ifacename, false)
|
|
||||||
dontprint := strings.Contains(out, "does not exist") || strings.Contains(out, "Cannot find device")
|
|
||||||
if err != nil && !dontprint {
|
|
||||||
log.Println("error running command:",ipExec + " link del " + ifacename)
|
|
||||||
log.Println(out)
|
|
||||||
}
|
|
||||||
if nodecfg.PostDown != "" {
|
|
||||||
runcmds := strings.Split(nodecfg.PostDown, "; ")
|
|
||||||
_ = RunCmds(runcmds, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func HasNetwork(network string) bool {
|
func HasNetwork(network string) bool {
|
||||||
|
|
||||||
if netclientutils.IsWindows() {
|
if ncutils.IsWindows() {
|
||||||
return FileExists(netclientutils.GetNetclientPathSpecific() + "netconfig-" + network)
|
return ncutils.FileExists(ncutils.GetNetclientPathSpecific() + "netconfig-" + network)
|
||||||
}
|
}
|
||||||
return FileExists("/etc/systemd/system/netclient-"+network+".timer") ||
|
return ncutils.FileExists("/etc/systemd/system/netclient-"+network+".timer") ||
|
||||||
FileExists(netclientutils.GetNetclientPathSpecific()+"netconfig-"+network)
|
ncutils.FileExists(ncutils.GetNetclientPathSpecific()+"netconfig-"+network)
|
||||||
}
|
|
||||||
|
|
||||||
func copy(src, dst string) (int64, error) {
|
|
||||||
sourceFileStat, err := os.Stat(src)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !sourceFileStat.Mode().IsRegular() {
|
|
||||||
return 0, errors.New(src + " is not a regular file")
|
|
||||||
}
|
|
||||||
|
|
||||||
source, err := os.Open(src)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
defer source.Close()
|
|
||||||
|
|
||||||
destination, err := os.Create(dst)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
defer destination.Close()
|
|
||||||
nBytes, err := io.Copy(destination, source)
|
|
||||||
err = os.Chmod(dst, 0755)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
return nBytes, err
|
|
||||||
}
|
}
|
||||||
|
@@ -1,175 +0,0 @@
|
|||||||
package local
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
|
||||||
)
|
|
||||||
|
|
||||||
func IsWindowsWGInstalled() bool {
|
|
||||||
out, err := RunCmd("wg help", true)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return strings.Contains(out, "Available subcommand")
|
|
||||||
}
|
|
||||||
|
|
||||||
func ApplyWindowsConf(confPath string) error {
|
|
||||||
if _, err := RunCmd("wireguard.exe /installtunnelservice "+confPath, true); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func RemoveWindowsConf(ifacename string) error {
|
|
||||||
if _, err := RunCmd("wireguard.exe /uninstalltunnelservice "+ifacename, true); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeServiceConfig() error {
|
|
||||||
serviceConfigPath := netclientutils.GetNetclientPathSpecific() + "winsw.xml"
|
|
||||||
scriptString := fmt.Sprintf(`<service>
|
|
||||||
<id>netclient</id>
|
|
||||||
<name>Netclient</name>
|
|
||||||
<description>Connects Windows nodes to one or more Netmaker networks.</description>
|
|
||||||
<executable>%v</executable>
|
|
||||||
<log mode="roll"></log>
|
|
||||||
</service>
|
|
||||||
`, strings.Replace(netclientutils.GetNetclientPathSpecific()+"netclient.exe", `\\`, `\`, -1))
|
|
||||||
if !FileExists(serviceConfigPath) {
|
|
||||||
err := ioutil.WriteFile(serviceConfigPath, []byte(scriptString), 0644)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
netclientutils.Log("wrote the daemon config file to the Netclient directory")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// == Daemon ==
|
|
||||||
func StopWindowsDaemon() {
|
|
||||||
netclientutils.Log("no networks detected, stopping Windows, Netclient daemon")
|
|
||||||
// stop daemon, will not overwrite
|
|
||||||
RunCmd(strings.Replace(netclientutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe stop`, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func RemoveWindowsDaemon() {
|
|
||||||
// uninstall daemon, will not restart or start another
|
|
||||||
RunCmd(strings.Replace(netclientutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe uninstall`, true)
|
|
||||||
netclientutils.Log("uninstalled Windows, Netclient daemon")
|
|
||||||
}
|
|
||||||
|
|
||||||
func copyWinswOver() error {
|
|
||||||
|
|
||||||
input, err := ioutil.ReadFile(".\\winsw.exe")
|
|
||||||
if err != nil {
|
|
||||||
netclientutils.Log("failed to find winsw.exe")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err = ioutil.WriteFile(netclientutils.GetNetclientPathSpecific()+"winsw.exe", input, 0644); err != nil {
|
|
||||||
netclientutils.Log("failed to copy winsw.exe to " + netclientutils.GetNetclientPath())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err = os.Remove(".\\winsw.exe"); err != nil {
|
|
||||||
netclientutils.Log("failed to cleanup local winsw.exe, feel free to delete it")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
netclientutils.Log("finished copying winsw.exe")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func downloadWinsw() error {
|
|
||||||
fullURLFile := "https://github.com/winsw/winsw/releases/download/v2.11.0/WinSW-x64.exe"
|
|
||||||
fileName := "winsw.exe"
|
|
||||||
|
|
||||||
// Create the file
|
|
||||||
file, err := os.Create(fileName)
|
|
||||||
if err != nil {
|
|
||||||
netclientutils.Log("could not create file on OS for Winsw")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
client := http.Client{
|
|
||||||
CheckRedirect: func(r *http.Request, via []*http.Request) error {
|
|
||||||
r.URL.Opaque = r.URL.Path
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
// Put content on file
|
|
||||||
netclientutils.Log("downloading service tool...")
|
|
||||||
resp, err := client.Get(fullURLFile)
|
|
||||||
if err != nil {
|
|
||||||
netclientutils.Log("could not GET Winsw")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
_, err = io.Copy(file, resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
netclientutils.Log("could not mount winsw.exe")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
netclientutils.Log("finished downloading Winsw")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateAndRunMacDaemon() error {
|
|
||||||
log.Println("TODO: Create Mac Daemon")
|
|
||||||
return errors.New("no mac daemon yet")
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateAndRunWindowsDaemon() error {
|
|
||||||
|
|
||||||
if !FileExists(netclientutils.GetNetclientPathSpecific() + "winsw.xml") {
|
|
||||||
if err := writeServiceConfig(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !FileExists(netclientutils.GetNetclientPathSpecific() + "winsw.exe") {
|
|
||||||
netclientutils.Log("performing first time daemon setup")
|
|
||||||
if !FileExists(".\\winsw.exe") {
|
|
||||||
err := downloadWinsw()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := copyWinswOver()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
netclientutils.Log("finished daemon setup")
|
|
||||||
}
|
|
||||||
// install daemon, will not overwrite
|
|
||||||
RunCmd(strings.Replace(netclientutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe install`, true)
|
|
||||||
// start daemon, will not restart or start another
|
|
||||||
RunCmd(strings.Replace(netclientutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe start`, true)
|
|
||||||
netclientutils.Log(strings.Replace(netclientutils.GetNetclientPathSpecific(), `\\`, `\`, -1) + `winsw.exe start`)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CleanupWindows() {
|
|
||||||
if !FileExists(netclientutils.GetNetclientPathSpecific() + "winsw.xml") {
|
|
||||||
writeServiceConfig()
|
|
||||||
}
|
|
||||||
StopWindowsDaemon()
|
|
||||||
RemoveWindowsDaemon()
|
|
||||||
os.RemoveAll(netclientutils.GetNetclientPath())
|
|
||||||
log.Println("Netclient on Windows, uninstalled")
|
|
||||||
}
|
|
||||||
|
|
||||||
func CleanupMac() {
|
|
||||||
//StopWindowsDaemon()
|
|
||||||
//RemoveWindowsDaemon()
|
|
||||||
//os.RemoveAll(netclientutils.GetNetclientPath())
|
|
||||||
log.Println("TODO: Not implemented yet")
|
|
||||||
}
|
|
@@ -8,14 +8,15 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"runtime/debug"
|
||||||
"strconv"
|
"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
"runtime/debug"
|
|
||||||
"github.com/gravitl/netmaker/netclient/command"
|
"github.com/gravitl/netmaker/netclient/command"
|
||||||
"github.com/gravitl/netmaker/netclient/config"
|
"github.com/gravitl/netmaker/netclient/config"
|
||||||
"github.com/gravitl/netmaker/netclient/local"
|
"github.com/gravitl/netmaker/netclient/local"
|
||||||
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
"github.com/gravitl/netmaker/netclient/ncwindows"
|
"github.com/gravitl/netmaker/netclient/ncwindows"
|
||||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ func main() {
|
|||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
app.Name = "Netclient CLI"
|
app.Name = "Netclient CLI"
|
||||||
app.Usage = "Netmaker's netclient agent and CLI. Used to perform interactions with Netmaker server and set local WireGuard config."
|
app.Usage = "Netmaker's netclient agent and CLI. Used to perform interactions with Netmaker server and set local WireGuard config."
|
||||||
app.Version = "v0.7.3"
|
app.Version = "v0.8.0"
|
||||||
|
|
||||||
cliFlags := []cli.Flag{
|
cliFlags := []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
@@ -320,11 +321,11 @@ func main() {
|
|||||||
|
|
||||||
setGarbageCollection()
|
setGarbageCollection()
|
||||||
|
|
||||||
if netclientutils.IsWindows() {
|
if ncutils.IsWindows() {
|
||||||
ncwindows.InitWindows()
|
ncwindows.InitWindows()
|
||||||
} else {
|
} else {
|
||||||
// start our application
|
// start our application
|
||||||
out, err := local.RunCmd("id -u", true)
|
out, err := ncutils.RunCmd("id -u", true)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(out, err)
|
log.Fatal(out, err)
|
||||||
@@ -345,12 +346,12 @@ func main() {
|
|||||||
log.Fatal("WireGuard not installed. Please install WireGuard (wireguard-tools) and try again.")
|
log.Fatal("WireGuard not installed. Please install WireGuard (wireguard-tools) and try again.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if netclientutils.IsWindows() {
|
if !ncutils.IsKernel() {
|
||||||
if !local.IsWindowsWGInstalled() {
|
if !local.IsWGInstalled() {
|
||||||
log.Fatal("Please install Windows WireGuard before using Gravitl Netclient. https://download.wireguard.com/windows-client/wireguard-installer.exe")
|
log.Fatal("Please install Windows WireGuard before using Gravitl Netclient. https://download.wireguard.com")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(os.Args) == 1 && netclientutils.IsWindows() {
|
if len(os.Args) == 1 && ncutils.IsWindows() {
|
||||||
c := make(chan os.Signal)
|
c := make(chan os.Signal)
|
||||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||||
go func() {
|
go func() {
|
||||||
@@ -367,9 +368,9 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setGarbageCollection(){
|
func setGarbageCollection() {
|
||||||
_, gcset := os.LookupEnv("GOGC");
|
_, gcset := os.LookupEnv("GOGC")
|
||||||
if !gcset {
|
if !gcset {
|
||||||
debug.SetGCPercent(netclientutils.DEFAULT_GC_PERCENT)
|
debug.SetGCPercent(ncutils.DEFAULT_GC_PERCENT)
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,15 +1,17 @@
|
|||||||
package netclientutils
|
package ncutils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -39,13 +41,20 @@ func IsWindows() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func IsMac() bool {
|
func IsMac() bool {
|
||||||
return runtime.GOOS == "macos"
|
return runtime.GOOS == "darwin"
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsLinux() bool {
|
func IsLinux() bool {
|
||||||
return runtime.GOOS == "linux"
|
return runtime.GOOS == "linux"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsKernel() bool {
|
||||||
|
//TODO
|
||||||
|
//Replace && true with some config file value
|
||||||
|
//This value should be something like kernelmode, which should be 'on' by default.
|
||||||
|
return IsLinux() && true
|
||||||
|
}
|
||||||
|
|
||||||
// == database returned nothing error ==
|
// == database returned nothing error ==
|
||||||
func IsEmptyRecord(err error) bool {
|
func IsEmptyRecord(err error) bool {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -256,6 +265,8 @@ func GetHomeDirWindows() string {
|
|||||||
func GetNetclientPath() string {
|
func GetNetclientPath() string {
|
||||||
if IsWindows() {
|
if IsWindows() {
|
||||||
return WINDOWS_APP_DATA_PATH
|
return WINDOWS_APP_DATA_PATH
|
||||||
|
} else if IsMac() {
|
||||||
|
return "/etc/netclient/"
|
||||||
} else {
|
} else {
|
||||||
return LINUX_APP_DATA_PATH
|
return LINUX_APP_DATA_PATH
|
||||||
}
|
}
|
||||||
@@ -264,6 +275,8 @@ func GetNetclientPath() string {
|
|||||||
func GetNetclientPathSpecific() string {
|
func GetNetclientPathSpecific() string {
|
||||||
if IsWindows() {
|
if IsWindows() {
|
||||||
return WINDOWS_APP_DATA_PATH + "\\"
|
return WINDOWS_APP_DATA_PATH + "\\"
|
||||||
|
} else if IsMac() {
|
||||||
|
return "/etc/netclient/"
|
||||||
} else {
|
} else {
|
||||||
return LINUX_APP_DATA_PATH + "/"
|
return LINUX_APP_DATA_PATH + "/"
|
||||||
}
|
}
|
||||||
@@ -278,3 +291,70 @@ func GRPCRequestOpts(isSecure string) grpc.DialOption {
|
|||||||
}
|
}
|
||||||
return requestOpts
|
return requestOpts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Copy(src, dst string) (int64, error) {
|
||||||
|
sourceFileStat, err := os.Stat(src)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !sourceFileStat.Mode().IsRegular() {
|
||||||
|
return 0, errors.New(src + " is not a regular file")
|
||||||
|
}
|
||||||
|
|
||||||
|
source, err := os.Open(src)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
defer source.Close()
|
||||||
|
|
||||||
|
destination, err := os.Create(dst)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
defer destination.Close()
|
||||||
|
nBytes, err := io.Copy(destination, source)
|
||||||
|
err = os.Chmod(dst, 0755)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
return nBytes, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunCmd(command string, printerr bool) (string, error) {
|
||||||
|
args := strings.Fields(command)
|
||||||
|
out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
|
||||||
|
if err != nil && printerr {
|
||||||
|
log.Println("error running command:", command)
|
||||||
|
log.Println(strings.TrimSuffix(string(out), "\n"))
|
||||||
|
}
|
||||||
|
return string(out), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func RunCmds(commands []string, printerr bool) error {
|
||||||
|
var err error
|
||||||
|
for _, command := range commands {
|
||||||
|
args := strings.Fields(command)
|
||||||
|
out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
|
||||||
|
if err != nil && printerr {
|
||||||
|
log.Println("error running command:", command)
|
||||||
|
log.Println(strings.TrimSuffix(string(out), "\n"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func FileExists(f string) bool {
|
||||||
|
info, err := os.Stat(f)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !info.IsDir()
|
||||||
|
}
|
||||||
|
|
||||||
|
func PrintLog(message string, loglevel int) {
|
||||||
|
log.SetFlags(log.Flags() &^ (log.Llongfile | log.Lshortfile))
|
||||||
|
if loglevel < 2 {
|
||||||
|
log.Println("[netclient]", message)
|
||||||
|
}
|
||||||
|
}
|
@@ -5,21 +5,21 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Initialize windows directory & files and such
|
// Initialize windows directory & files and such
|
||||||
func InitWindows() {
|
func InitWindows() {
|
||||||
|
|
||||||
_, directoryErr := os.Stat(netclientutils.GetNetclientPath()) // Check if data directory exists or not
|
_, directoryErr := os.Stat(ncutils.GetNetclientPath()) // Check if data directory exists or not
|
||||||
if os.IsNotExist(directoryErr) { // create a data directory
|
if os.IsNotExist(directoryErr) { // create a data directory
|
||||||
os.Mkdir(netclientutils.GetNetclientPath(), 0755)
|
os.Mkdir(ncutils.GetNetclientPath(), 0755)
|
||||||
}
|
}
|
||||||
wdPath, wdErr := os.Getwd() // get the current working directory
|
wdPath, wdErr := os.Getwd() // get the current working directory
|
||||||
if wdErr != nil {
|
if wdErr != nil {
|
||||||
log.Fatal("failed to get current directory..")
|
log.Fatal("failed to get current directory..")
|
||||||
}
|
}
|
||||||
_, dataNetclientErr := os.Stat(netclientutils.GetNetclientPathSpecific() + "netclient.exe")
|
_, dataNetclientErr := os.Stat(ncutils.GetNetclientPathSpecific() + "netclient.exe")
|
||||||
_, currentNetclientErr := os.Stat(wdPath + "\\netclient.exe")
|
_, currentNetclientErr := os.Stat(wdPath + "\\netclient.exe")
|
||||||
if os.IsNotExist(dataNetclientErr) { // check and see if netclient.exe is in appdata
|
if os.IsNotExist(dataNetclientErr) { // check and see if netclient.exe is in appdata
|
||||||
if currentNetclientErr == nil { // copy it if it exists locally
|
if currentNetclientErr == nil { // copy it if it exists locally
|
||||||
@@ -28,8 +28,8 @@ func InitWindows() {
|
|||||||
log.Println("failed to find netclient.exe")
|
log.Println("failed to find netclient.exe")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = ioutil.WriteFile(netclientutils.GetNetclientPathSpecific()+"netclient.exe", input, 0644); err != nil {
|
if err = ioutil.WriteFile(ncutils.GetNetclientPathSpecific()+"netclient.exe", input, 0644); err != nil {
|
||||||
log.Println("failed to copy netclient.exe to", netclientutils.GetNetclientPath())
|
log.Println("failed to copy netclient.exe to", ncutils.GetNetclientPath())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,9 +11,8 @@ import (
|
|||||||
nodepb "github.com/gravitl/netmaker/grpc"
|
nodepb "github.com/gravitl/netmaker/grpc"
|
||||||
"github.com/gravitl/netmaker/models"
|
"github.com/gravitl/netmaker/models"
|
||||||
"github.com/gravitl/netmaker/netclient/auth"
|
"github.com/gravitl/netmaker/netclient/auth"
|
||||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
|
||||||
"github.com/gravitl/netmaker/netclient/config"
|
"github.com/gravitl/netmaker/netclient/config"
|
||||||
"github.com/gravitl/netmaker/netclient/local"
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
@@ -25,7 +24,7 @@ func getGrpcClient(cfg *config.ClientConfig) (nodepb.NodeServiceClient, error) {
|
|||||||
var wcclient nodepb.NodeServiceClient
|
var wcclient nodepb.NodeServiceClient
|
||||||
// == GRPC SETUP ==
|
// == GRPC SETUP ==
|
||||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -68,6 +67,7 @@ func CheckIn(network string) (*models.Node, error) {
|
|||||||
return &node, err
|
return &node, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func RemoveNetwork(network string) error {
|
func RemoveNetwork(network string) error {
|
||||||
//need to implement checkin on server side
|
//need to implement checkin on server side
|
||||||
cfg, err := config.ReadConfig(network)
|
cfg, err := config.ReadConfig(network)
|
||||||
@@ -80,7 +80,7 @@ func RemoveNetwork(network string) error {
|
|||||||
|
|
||||||
var wcclient nodepb.NodeServiceClient
|
var wcclient nodepb.NodeServiceClient
|
||||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Unable to establish client connection to "+servercfg.GRPCAddress+": %v", err)
|
log.Printf("Unable to establish client connection to "+servercfg.GRPCAddress+": %v", err)
|
||||||
//return err
|
//return err
|
||||||
@@ -110,16 +110,11 @@ func RemoveNetwork(network string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = local.WipeLocal(network)
|
//err = functions.RemoveLocalInstance(network)
|
||||||
if err != nil {
|
|
||||||
log.Printf("Unable to wipe local config: %v", err)
|
|
||||||
}
|
|
||||||
if cfg.Daemon != "off" {
|
|
||||||
err = local.RemoveSystemDServices(network)
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
func GetPeers(macaddress string, network string, server string, dualstack bool, isIngressGateway bool) ([]wgtypes.PeerConfig, bool, []string, error) {
|
func GetPeers(macaddress string, network string, server string, dualstack bool, isIngressGateway bool) ([]wgtypes.PeerConfig, bool, []string, error) {
|
||||||
hasGateway := false
|
hasGateway := false
|
||||||
var gateways []string
|
var gateways []string
|
||||||
@@ -138,7 +133,7 @@ func GetPeers(macaddress string, network string, server string, dualstack bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
|
log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
|
||||||
@@ -202,11 +197,11 @@ func GetPeers(macaddress string, network string, server string, dualstack bool,
|
|||||||
allowedips = append(allowedips, *ipnet)
|
allowedips = append(allowedips, *ipnet)
|
||||||
}
|
}
|
||||||
} else if appendip := net.ParseIP(allowedIp); appendip != nil && allowedIp != node.Address {
|
} else if appendip := net.ParseIP(allowedIp); appendip != nil && allowedIp != node.Address {
|
||||||
ipnet := net.IPNet{
|
ipnet := net.IPNet{
|
||||||
IP: net.ParseIP(allowedIp),
|
IP: net.ParseIP(allowedIp),
|
||||||
Mask: net.CIDRMask(32, 32),
|
Mask: net.CIDRMask(32, 32),
|
||||||
}
|
}
|
||||||
allowedips = append(allowedips, ipnet)
|
allowedips = append(allowedips, ipnet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// handle egress gateway peers
|
// handle egress gateway peers
|
||||||
@@ -273,7 +268,7 @@ func GetPeers(macaddress string, network string, server string, dualstack bool,
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
peers = append(peers, extPeers...)
|
peers = append(peers, extPeers...)
|
||||||
} else {
|
} else {
|
||||||
log.Println("ERROR RETRIEVING EXTERNAL PEERS",err)
|
log.Println("ERROR RETRIEVING EXTERNAL PEERS", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return peers, hasGateway, gateways, err
|
return peers, hasGateway, gateways, err
|
||||||
@@ -288,7 +283,7 @@ func GetExtPeers(macaddress string, network string, server string, dualstack boo
|
|||||||
nodecfg := cfg.Node
|
nodecfg := cfg.Node
|
||||||
|
|
||||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
|
log.Fatalf("Unable to establish client connection to localhost:50051: %v", err)
|
||||||
}
|
}
|
||||||
|
306
netclient/wireguard/common.go
Normal file
306
netclient/wireguard/common.go
Normal file
@@ -0,0 +1,306 @@
|
|||||||
|
package wireguard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gravitl/netmaker/models"
|
||||||
|
"github.com/gravitl/netmaker/netclient/config"
|
||||||
|
"github.com/gravitl/netmaker/netclient/local"
|
||||||
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
|
"github.com/gravitl/netmaker/netclient/server"
|
||||||
|
"golang.zx2c4.com/wireguard/wgctrl"
|
||||||
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
|
//homedir "github.com/mitchellh/go-homedir"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SetPeers(iface string, keepalive int32, peers []wgtypes.PeerConfig) error {
|
||||||
|
|
||||||
|
client, err := wgctrl.New()
|
||||||
|
if err != nil {
|
||||||
|
ncutils.PrintLog("failed to start wgctrl", 0)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
device, err := client.Device(iface)
|
||||||
|
if err != nil {
|
||||||
|
ncutils.PrintLog("failed to parse interface", 0)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
devicePeers := device.Peers
|
||||||
|
if len(devicePeers) > 1 && len(peers) == 0 {
|
||||||
|
ncutils.PrintLog("no peers pulled", 1)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, peer := range peers {
|
||||||
|
|
||||||
|
for _, currentPeer := range devicePeers {
|
||||||
|
if currentPeer.AllowedIPs[0].String() == peer.AllowedIPs[0].String() &&
|
||||||
|
currentPeer.PublicKey.String() != peer.PublicKey.String() {
|
||||||
|
_, err := ncutils.RunCmd("wg set "+iface+" peer "+currentPeer.PublicKey.String()+" remove", true)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error removing peer", peer.Endpoint.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
udpendpoint := peer.Endpoint.String()
|
||||||
|
var allowedips string
|
||||||
|
var iparr []string
|
||||||
|
for _, ipaddr := range peer.AllowedIPs {
|
||||||
|
iparr = append(iparr, ipaddr.String())
|
||||||
|
}
|
||||||
|
allowedips = strings.Join(iparr, ",")
|
||||||
|
keepAliveString := strconv.Itoa(int(keepalive))
|
||||||
|
if keepAliveString == "0" {
|
||||||
|
keepAliveString = "5"
|
||||||
|
}
|
||||||
|
if peer.Endpoint != nil {
|
||||||
|
_, err = ncutils.RunCmd("wg set "+iface+" peer "+peer.PublicKey.String()+
|
||||||
|
" endpoint "+udpendpoint+
|
||||||
|
" persistent-keepalive "+keepAliveString+
|
||||||
|
" allowed-ips "+allowedips, true)
|
||||||
|
} else {
|
||||||
|
_, err = ncutils.RunCmd("wg set "+iface+" peer "+peer.PublicKey.String()+
|
||||||
|
" persistent-keepalive "+keepAliveString+
|
||||||
|
" allowed-ips "+allowedips, true)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error setting peer", peer.PublicKey.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, currentPeer := range devicePeers {
|
||||||
|
shouldDelete := true
|
||||||
|
for _, peer := range peers {
|
||||||
|
if peer.AllowedIPs[0].String() == currentPeer.AllowedIPs[0].String() {
|
||||||
|
shouldDelete = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if shouldDelete {
|
||||||
|
output, err := ncutils.RunCmd("wg set "+iface+" peer "+currentPeer.PublicKey.String()+" remove", true)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(output, "error removing peer", currentPeer.PublicKey.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig, hasGateway bool, gateways []string) error {
|
||||||
|
|
||||||
|
key, err := wgtypes.ParseKey(privkey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
wgclient, err := wgctrl.New()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
modcfg, err := config.ReadConfig(node.Network)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
nodecfg := modcfg.Node
|
||||||
|
servercfg := modcfg.Server
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to open client: %v", err)
|
||||||
|
}
|
||||||
|
defer wgclient.Close()
|
||||||
|
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
nameserver := servercfg.CoreDNSAddr
|
||||||
|
network := node.Network
|
||||||
|
if nodecfg.Network != "" {
|
||||||
|
network = nodecfg.Network
|
||||||
|
} else if node.Network != "" {
|
||||||
|
network = node.Network
|
||||||
|
}
|
||||||
|
|
||||||
|
if ncutils.IsKernel() {
|
||||||
|
setKernelDevice(ifacename, node.Address)
|
||||||
|
}
|
||||||
|
|
||||||
|
var nodeport int
|
||||||
|
nodeport = int(node.ListenPort)
|
||||||
|
conf := wgtypes.Config{}
|
||||||
|
if nodecfg.UDPHolePunch == "yes" &&
|
||||||
|
nodecfg.IsServer == "no" &&
|
||||||
|
nodecfg.IsIngressGateway != "yes" &&
|
||||||
|
nodecfg.IsStatic != "yes" {
|
||||||
|
conf = wgtypes.Config{
|
||||||
|
PrivateKey: &key,
|
||||||
|
ReplacePeers: true,
|
||||||
|
Peers: peers,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
conf = wgtypes.Config{
|
||||||
|
PrivateKey: &key,
|
||||||
|
ListenPort: &nodeport,
|
||||||
|
ReplacePeers: true,
|
||||||
|
Peers: peers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !ncutils.IsKernel() {
|
||||||
|
var newConf string
|
||||||
|
if node.UDPHolePunch != "yes" {
|
||||||
|
newConf, _ = ncutils.CreateUserSpaceConf(node.Address, key.String(), strconv.FormatInt(int64(node.ListenPort), 10), node.MTU, node.PersistentKeepalive, peers)
|
||||||
|
} else {
|
||||||
|
newConf, _ = ncutils.CreateUserSpaceConf(node.Address, key.String(), "", node.MTU, node.PersistentKeepalive, peers)
|
||||||
|
}
|
||||||
|
confPath := ncutils.GetNetclientPathSpecific() + node.Interface + ".conf"
|
||||||
|
ncutils.PrintLog("writing wg conf file to: "+confPath, 1)
|
||||||
|
err = ioutil.WriteFile(confPath, []byte(newConf), 0644)
|
||||||
|
if err != nil {
|
||||||
|
ncutils.PrintLog("error writing wg conf file to "+confPath+": "+err.Error(), 1)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// spin up userspace / windows interface + apply the conf file
|
||||||
|
_ = RemoveConf(node.Interface, false) // remove interface first
|
||||||
|
err = ApplyConf(confPath)
|
||||||
|
if err != nil {
|
||||||
|
ncutils.PrintLog("failed to create wireguard interface", 1)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ipExec, err := exec.LookPath("ip")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========DNS Setup==========\\
|
||||||
|
if nodecfg.DNSOn == "yes" {
|
||||||
|
_ = local.UpdateDNS(ifacename, network, nameserver)
|
||||||
|
}
|
||||||
|
//=========End DNS Setup=======\\
|
||||||
|
if _, err := ncutils.RunCmd(ipExec+" link set down dev "+ifacename, false); err != nil {
|
||||||
|
ncutils.Log("attempted to remove interface before editing")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if nodecfg.PostDown != "" {
|
||||||
|
runcmds := strings.Split(nodecfg.PostDown, "; ")
|
||||||
|
_ = ncutils.RunCmds(runcmds, true)
|
||||||
|
}
|
||||||
|
// set MTU of node interface
|
||||||
|
if _, err := ncutils.RunCmd(ipExec+" link set mtu "+strconv.Itoa(int(nodecfg.MTU))+" up dev "+ifacename, true); err != nil {
|
||||||
|
ncutils.Log("failed to create interface with mtu " + ifacename)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if nodecfg.PostUp != "" {
|
||||||
|
runcmds := strings.Split(nodecfg.PostUp, "; ")
|
||||||
|
_ = ncutils.RunCmds(runcmds, true)
|
||||||
|
}
|
||||||
|
if hasGateway {
|
||||||
|
for _, gateway := range gateways {
|
||||||
|
_, _ = ncutils.RunCmd(ipExec+" -4 route add "+gateway+" dev "+ifacename, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if node.Address6 != "" && node.IsDualStack == "yes" {
|
||||||
|
log.Println("[netclient] adding address: "+node.Address6, 1)
|
||||||
|
_, _ = ncutils.RunCmd(ipExec+" address add dev "+ifacename+" "+node.Address6+"/64", true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetWGConfig(network string, peerupdate bool) error {
|
||||||
|
|
||||||
|
cfg, err := config.ReadConfig(network)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
servercfg := cfg.Server
|
||||||
|
nodecfg := cfg.Node
|
||||||
|
|
||||||
|
peers, hasGateway, gateways, err := server.GetPeers(nodecfg.MacAddress, nodecfg.Network, servercfg.GRPCAddress, nodecfg.IsDualStack == "yes", nodecfg.IsIngressGateway == "yes")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
privkey, err := RetrievePrivKey(network)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if peerupdate {
|
||||||
|
var iface string
|
||||||
|
iface = nodecfg.Interface
|
||||||
|
if ncutils.IsMac() {
|
||||||
|
iface, err = local.GetMacIface(nodecfg.Address)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = SetPeers(iface, nodecfg.PersistentKeepalive, peers)
|
||||||
|
} else {
|
||||||
|
err = InitWireguard(&nodecfg, privkey, peers, hasGateway, gateways)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemoveConf(iface string, printlog bool) error {
|
||||||
|
os := runtime.GOOS
|
||||||
|
var err error
|
||||||
|
switch os {
|
||||||
|
case "windows":
|
||||||
|
err = RemoveWindowsConf(iface, printlog)
|
||||||
|
default:
|
||||||
|
confPath := ncutils.GetNetclientPathSpecific() + iface + ".conf"
|
||||||
|
err = RemoveWGQuickConf(confPath, printlog)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ApplyConf(confPath string) error {
|
||||||
|
os := runtime.GOOS
|
||||||
|
var err error
|
||||||
|
switch os {
|
||||||
|
case "windows":
|
||||||
|
err = ApplyWindowsConf(confPath)
|
||||||
|
default:
|
||||||
|
err = ApplyWGQuickConf(confPath)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
@@ -1,325 +1,21 @@
|
|||||||
package wireguard
|
package wireguard
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gravitl/netmaker/models"
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
"github.com/gravitl/netmaker/netclient/config"
|
|
||||||
"github.com/gravitl/netmaker/netclient/local"
|
|
||||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
|
||||||
"github.com/gravitl/netmaker/netclient/server"
|
|
||||||
"golang.zx2c4.com/wireguard/wgctrl"
|
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
||||||
//homedir "github.com/mitchellh/go-homedir"
|
//homedir "github.com/mitchellh/go-homedir"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig, hasGateway bool, gateways []string) error {
|
func setKernelDevice(ifacename string, address string) error {
|
||||||
|
ipExec, err := exec.LookPath("ip")
|
||||||
key, err := wgtypes.ParseKey(privkey)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
wgclient, err := wgctrl.New()
|
_, _ = ncutils.RunCmd("ip link delete dev "+ifacename, false)
|
||||||
if err != nil {
|
_, _ = ncutils.RunCmd(ipExec+" link add dev "+ifacename+" type wireguard", true)
|
||||||
return err
|
_, _ = ncutils.RunCmd(ipExec+" address add dev "+ifacename+" "+address+"/24", true)
|
||||||
}
|
|
||||||
modcfg, err := config.ReadConfig(node.Network)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
nodecfg := modcfg.Node
|
|
||||||
servercfg := modcfg.Server
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed to open client: %v", err)
|
|
||||||
}
|
|
||||||
defer wgclient.Close()
|
|
||||||
|
|
||||||
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")
|
|
||||||
}
|
|
||||||
nameserver := servercfg.CoreDNSAddr
|
|
||||||
network := node.Network
|
|
||||||
if nodecfg.Network != "" {
|
|
||||||
network = nodecfg.Network
|
|
||||||
} else if node.Network != "" {
|
|
||||||
network = node.Network
|
|
||||||
}
|
|
||||||
|
|
||||||
if !netclientutils.IsWindows() {
|
|
||||||
|
|
||||||
ipExec, err := exec.LookPath("ip")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _ = local.RunCmd("ip link delete dev " + ifacename, false)
|
|
||||||
_, _ = local.RunCmd(ipExec + " link add dev " + ifacename + " type wireguard", true)
|
|
||||||
_, _ = local.RunCmd(ipExec + " address add dev " + ifacename + " " + node.Address + "/24", true)
|
|
||||||
}
|
|
||||||
var nodeport int
|
|
||||||
nodeport = int(node.ListenPort)
|
|
||||||
conf := wgtypes.Config{}
|
|
||||||
if nodecfg.UDPHolePunch == "yes" &&
|
|
||||||
nodecfg.IsServer == "no" &&
|
|
||||||
nodecfg.IsIngressGateway != "yes" &&
|
|
||||||
nodecfg.IsStatic != "yes" {
|
|
||||||
conf = wgtypes.Config{
|
|
||||||
PrivateKey: &key,
|
|
||||||
ReplacePeers: true,
|
|
||||||
Peers: peers,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
conf = wgtypes.Config{
|
|
||||||
PrivateKey: &key,
|
|
||||||
ListenPort: &nodeport,
|
|
||||||
ReplacePeers: true,
|
|
||||||
Peers: peers,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if netclientutils.IsWindows() {
|
|
||||||
var newConf string
|
|
||||||
if node.UDPHolePunch != "yes" {
|
|
||||||
newConf, _ = netclientutils.CreateUserSpaceConf(node.Address, key.String(), strconv.FormatInt(int64(node.ListenPort), 10), node.MTU, node.PersistentKeepalive, peers)
|
|
||||||
} else {
|
|
||||||
newConf, _ = netclientutils.CreateUserSpaceConf(node.Address, key.String(), "", node.MTU, node.PersistentKeepalive, peers)
|
|
||||||
}
|
|
||||||
confPath := netclientutils.GetNetclientPathSpecific() + node.Interface + ".conf"
|
|
||||||
err = ioutil.WriteFile(confPath, []byte(newConf), 0644)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// spin up userspace / windows interface + apply the conf file
|
|
||||||
err := local.RemoveWindowsConf(node.Interface) // remove interface first
|
|
||||||
if err != nil {
|
|
||||||
log.Println("attempted to remove pre-existing windows interface before updating")
|
|
||||||
}
|
|
||||||
local.ApplyWindowsConf(confPath)
|
|
||||||
} else {
|
|
||||||
ipExec, err := exec.LookPath("ip")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//=========DNS Setup==========\\
|
|
||||||
if nodecfg.DNSOn == "yes" {
|
|
||||||
_ = local.UpdateDNS(ifacename, network, nameserver)
|
|
||||||
}
|
|
||||||
//=========End DNS Setup=======\\
|
|
||||||
if _, err := local.RunCmd(ipExec + " link set down dev " + ifacename, false); err != nil {
|
|
||||||
netclientutils.Log("attempted to remove interface before editing")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if nodecfg.PostDown != "" {
|
|
||||||
runcmds := strings.Split(nodecfg.PostDown, "; ")
|
|
||||||
err = local.RunCmds(runcmds, true)
|
|
||||||
}
|
|
||||||
// set MTU of node interface
|
|
||||||
if _, err := local.RunCmd(ipExec + " link set mtu " + strconv.Itoa(int(nodecfg.MTU)) + " up dev " + ifacename, true); err != nil {
|
|
||||||
netclientutils.Log("failed to create interface with mtu " + ifacename)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if nodecfg.PostUp != "" {
|
|
||||||
runcmds := strings.Split(nodecfg.PostUp, "; ")
|
|
||||||
err = local.RunCmds(runcmds, true)
|
|
||||||
}
|
|
||||||
if hasGateway {
|
|
||||||
for _, gateway := range gateways {
|
|
||||||
_, _ = local.RunCmd(ipExec + " -4 route add " + gateway + " dev " + ifacename, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if node.Address6 != "" && node.IsDualStack == "yes" {
|
|
||||||
log.Println("[netclient] adding address: " + node.Address6, 1)
|
|
||||||
_, _ = local.RunCmd(ipExec + " address add dev " + ifacename + " " + node.Address6 + "/64", true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetWGKeyConfig(network string, serveraddr string) error {
|
|
||||||
|
|
||||||
cfg, err := config.ReadConfig(network)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
node := cfg.Node
|
|
||||||
|
|
||||||
privatekey, err := wgtypes.GeneratePrivateKey()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
privkeystring := privatekey.String()
|
|
||||||
publickey := privatekey.PublicKey()
|
|
||||||
|
|
||||||
node.PublicKey = publickey.String()
|
|
||||||
|
|
||||||
err = StorePrivKey(privkeystring, network)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if node.Action == models.NODE_UPDATE_KEY {
|
|
||||||
node.Action = models.NODE_NOOP
|
|
||||||
}
|
|
||||||
err = config.ModConfig(&node)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = SetWGConfig(network, false)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetWGConfig(network string, peerupdate bool) error {
|
|
||||||
|
|
||||||
cfg, err := config.ReadConfig(network)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
servercfg := cfg.Server
|
|
||||||
nodecfg := cfg.Node
|
|
||||||
|
|
||||||
peers, hasGateway, gateways, err := server.GetPeers(nodecfg.MacAddress, nodecfg.Network, servercfg.GRPCAddress, nodecfg.IsDualStack == "yes", nodecfg.IsIngressGateway == "yes")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
privkey, err := RetrievePrivKey(network)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if peerupdate {
|
|
||||||
err = SetPeers(nodecfg.Interface, nodecfg.PersistentKeepalive, peers)
|
|
||||||
} else {
|
|
||||||
err = InitWireguard(&nodecfg, privkey, peers, hasGateway, gateways)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetPeers(iface string, keepalive int32, peers []wgtypes.PeerConfig) error {
|
|
||||||
|
|
||||||
client, err := wgctrl.New()
|
|
||||||
if err != nil {
|
|
||||||
log.Println("failed to start wgctrl")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
device, err := client.Device(iface)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("failed to parse interface")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
devicePeers := device.Peers
|
|
||||||
if len(devicePeers) > 1 && len(peers) == 0 {
|
|
||||||
log.Println("no peers pulled")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, peer := range peers {
|
|
||||||
|
|
||||||
for _, currentPeer := range devicePeers {
|
|
||||||
if currentPeer.AllowedIPs[0].String() == peer.AllowedIPs[0].String() &&
|
|
||||||
currentPeer.PublicKey.String() != peer.PublicKey.String() {
|
|
||||||
_, err := local.RunCmd("wg set " + iface + " peer " + currentPeer.PublicKey.String() + " remove", true)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("error removing peer", peer.Endpoint.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
udpendpoint := peer.Endpoint.String()
|
|
||||||
var allowedips string
|
|
||||||
var iparr []string
|
|
||||||
for _, ipaddr := range peer.AllowedIPs {
|
|
||||||
iparr = append(iparr, ipaddr.String())
|
|
||||||
}
|
|
||||||
allowedips = strings.Join(iparr, ",")
|
|
||||||
keepAliveString := strconv.Itoa(int(keepalive))
|
|
||||||
if keepAliveString == "0" {
|
|
||||||
keepAliveString = "5"
|
|
||||||
}
|
|
||||||
if peer.Endpoint != nil {
|
|
||||||
_, err = local.RunCmd("wg set " + iface + " peer " + peer.PublicKey.String() +
|
|
||||||
" endpoint " + udpendpoint +
|
|
||||||
" persistent-keepalive " + keepAliveString +
|
|
||||||
" allowed-ips " + allowedips, true)
|
|
||||||
} else {
|
|
||||||
_, err = local.RunCmd("wg set " + iface + " peer " + peer.PublicKey.String() +
|
|
||||||
" persistent-keepalive " + keepAliveString +
|
|
||||||
" allowed-ips " + allowedips, true)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
log.Println("error setting peer", peer.PublicKey.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, currentPeer := range devicePeers {
|
|
||||||
shouldDelete := true
|
|
||||||
for _, peer := range peers {
|
|
||||||
if peer.AllowedIPs[0].String() == currentPeer.AllowedIPs[0].String() {
|
|
||||||
shouldDelete = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if shouldDelete {
|
|
||||||
output, err := local.RunCmd("wg set " + iface + " peer " + currentPeer.PublicKey.String() + " remove", true)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(output, "error removing peer", currentPeer.PublicKey.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func StorePrivKey(key string, network string) error {
|
|
||||||
d1 := []byte(key)
|
|
||||||
err := ioutil.WriteFile(netclientutils.GetNetclientPathSpecific()+"wgkey-"+network, d1, 0644)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func RetrievePrivKey(network string) (string, error) {
|
|
||||||
dat, err := ioutil.ReadFile(netclientutils.GetNetclientPathSpecific() + "wgkey-" + network)
|
|
||||||
return string(dat), err
|
|
||||||
}
|
|
||||||
|
74
netclient/wireguard/unix.go
Normal file
74
netclient/wireguard/unix.go
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
package wireguard
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/gravitl/netmaker/models"
|
||||||
|
"github.com/gravitl/netmaker/netclient/config"
|
||||||
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
|
//homedir "github.com/mitchellh/go-homedir"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SetWGKeyConfig(network string, serveraddr string) error {
|
||||||
|
|
||||||
|
cfg, err := config.ReadConfig(network)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
node := cfg.Node
|
||||||
|
|
||||||
|
privatekey, err := wgtypes.GeneratePrivateKey()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
privkeystring := privatekey.String()
|
||||||
|
publickey := privatekey.PublicKey()
|
||||||
|
|
||||||
|
node.PublicKey = publickey.String()
|
||||||
|
|
||||||
|
err = StorePrivKey(privkeystring, network)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if node.Action == models.NODE_UPDATE_KEY {
|
||||||
|
node.Action = models.NODE_NOOP
|
||||||
|
}
|
||||||
|
err = config.ModConfig(&node)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = SetWGConfig(network, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ApplyWGQuickConf(confPath string) error {
|
||||||
|
if _, err := ncutils.RunCmd("wg-quick up "+confPath, true); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemoveWGQuickConf(confPath string, printlog bool) error {
|
||||||
|
if _, err := ncutils.RunCmd("wg-quick down "+confPath, printlog); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func StorePrivKey(key string, network string) error {
|
||||||
|
d1 := []byte(key)
|
||||||
|
err := ioutil.WriteFile(ncutils.GetNetclientPathSpecific()+"wgkey-"+network, d1, 0644)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func RetrievePrivKey(network string) (string, error) {
|
||||||
|
dat, err := ioutil.ReadFile(ncutils.GetNetclientPathSpecific() + "wgkey-" + network)
|
||||||
|
return string(dat), err
|
||||||
|
}
|
17
netclient/wireguard/windows.go
Normal file
17
netclient/wireguard/windows.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package wireguard
|
||||||
|
|
||||||
|
import "github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
|
|
||||||
|
func ApplyWindowsConf(confPath string) error {
|
||||||
|
if _, err := ncutils.RunCmd("wireguard.exe /installtunnelservice "+confPath, true); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemoveWindowsConf(ifacename string, printlog bool) error {
|
||||||
|
if _, err := ncutils.RunCmd("wireguard.exe /uninstalltunnelservice "+ifacename, printlog); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@@ -73,7 +73,7 @@ func GetAPIConnString() string {
|
|||||||
return conn
|
return conn
|
||||||
}
|
}
|
||||||
func GetVersion() string {
|
func GetVersion() string {
|
||||||
version := "0.7.3"
|
version := "0.8.0"
|
||||||
if config.Config.Server.Version != "" {
|
if config.Config.Server.Version != "" {
|
||||||
version = config.Config.Server.Version
|
version = config.Config.Server.Version
|
||||||
}
|
}
|
||||||
|
@@ -11,8 +11,7 @@ import (
|
|||||||
"github.com/gravitl/netmaker/database"
|
"github.com/gravitl/netmaker/database"
|
||||||
"github.com/gravitl/netmaker/functions"
|
"github.com/gravitl/netmaker/functions"
|
||||||
"github.com/gravitl/netmaker/models"
|
"github.com/gravitl/netmaker/models"
|
||||||
"github.com/gravitl/netmaker/netclient/local"
|
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
|
||||||
"github.com/gravitl/netmaker/servercfg"
|
"github.com/gravitl/netmaker/servercfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -33,10 +32,10 @@ func GetServerWGConf() (models.IntClient, error) {
|
|||||||
|
|
||||||
func InstallNetclient() error {
|
func InstallNetclient() error {
|
||||||
|
|
||||||
netclientPath := netclientutils.GetNetclientPathSpecific()
|
netclientPath := ncutils.GetNetclientPathSpecific()
|
||||||
if !FileExists(netclientPath + "netclient") {
|
if !FileExists(netclientPath + "netclient") {
|
||||||
var err error
|
var err error
|
||||||
if netclientutils.IsWindows() {
|
if ncutils.IsWindows() {
|
||||||
_, err = copy(".\\netclient\\netclient", netclientPath+"netclient")
|
_, err = copy(".\\netclient\\netclient", netclientPath+"netclient")
|
||||||
} else {
|
} else {
|
||||||
_, err = copy("./netclient/netclient", netclientPath+"netclient")
|
_, err = copy("./netclient/netclient", netclientPath+"netclient")
|
||||||
@@ -87,13 +86,13 @@ func copy(src, dst string) (int64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func RemoveNetwork(network string) (bool, error) {
|
func RemoveNetwork(network string) (bool, error) {
|
||||||
netclientPath := netclientutils.GetNetclientPathSpecific()
|
netclientPath := ncutils.GetNetclientPathSpecific()
|
||||||
_, err := os.Stat(netclientPath + "netclient")
|
_, err := os.Stat(netclientPath + "netclient")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("could not find " + netclientPath + "netclient")
|
log.Println("could not find " + netclientPath + "netclient")
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
_, err = local.RunCmd(netclientPath+"netclient leave -n "+network, true)
|
_, err = ncutils.RunCmd(netclientPath+"netclient leave -n "+network, true)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
log.Println("Server removed from network " + network)
|
log.Println("Server removed from network " + network)
|
||||||
}
|
}
|
||||||
@@ -107,8 +106,8 @@ func AddNetwork(network string) (bool, error) {
|
|||||||
log.Println("could not get public IP.")
|
log.Println("could not get public IP.")
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
netclientDir := netclientutils.GetNetclientPath()
|
netclientDir := ncutils.GetNetclientPath()
|
||||||
netclientPath := netclientutils.GetNetclientPathSpecific()
|
netclientPath := ncutils.GetNetclientPathSpecific()
|
||||||
_, err = os.Stat(netclientDir)
|
_, err = os.Stat(netclientDir)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
os.Mkdir(netclientDir, 744)
|
os.Mkdir(netclientDir, 744)
|
||||||
|
Reference in New Issue
Block a user