mirror of
https://github.com/gravitl/netmaker.git
synced 2025-10-04 16:33:49 +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"
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
@@ -38,7 +38,7 @@ func initialize() { // Client Mode Prereq Check
|
||||
}
|
||||
log.Println("database successfully connected.")
|
||||
if servercfg.IsClientMode() {
|
||||
output, err := local.RunCmd("id -u", true)
|
||||
output, err := ncutils.RunCmd("id -u", true)
|
||||
if err != nil {
|
||||
log.Println("Error running 'id -u' for prereq check. Please investigate or disable client mode.")
|
||||
log.Fatal(output, err)
|
||||
|
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
|
||||
// "os"
|
||||
"context"
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
|
||||
// CreateJWT func will used to create the JWT while signing in and signing out
|
||||
func SetJWT(client nodepb.NodeServiceClient, network string) (context.Context, error) {
|
||||
home := netclientutils.GetNetclientPathSpecific()
|
||||
home := ncutils.GetNetclientPathSpecific()
|
||||
tokentext, err := ioutil.ReadFile(home + "nettoken-" + network)
|
||||
if err != nil {
|
||||
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 {
|
||||
home := netclientutils.GetNetclientPathSpecific()
|
||||
home := ncutils.GetNetclientPathSpecific()
|
||||
cfg, err := config.ReadConfig(network)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -79,12 +79,12 @@ func AutoLogin(client nodepb.NodeServiceClient, network string) error {
|
||||
|
||||
func StoreSecret(key string, network string) error {
|
||||
d1 := []byte(key)
|
||||
err := ioutil.WriteFile(netclientutils.GetNetclientPathSpecific()+"secret-"+network, d1, 0644)
|
||||
err := ioutil.WriteFile(ncutils.GetNetclientPathSpecific()+"secret-"+network, d1, 0644)
|
||||
return err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@@ -8,9 +8,9 @@ import (
|
||||
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/daemon"
|
||||
"github.com/gravitl/netmaker/netclient/functions"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"golang.zx2c4.com/wireguard/wgctrl"
|
||||
)
|
||||
|
||||
@@ -28,34 +28,30 @@ func Join(cfg config.ClientConfig, privateKey string) error {
|
||||
|
||||
if err != nil && !cfg.DebugJoin {
|
||||
if !strings.Contains(err.Error(), "ALREADY_INSTALLED") {
|
||||
log.Println("Error installing: ", err)
|
||||
ncutils.PrintLog("error installing: "+err.Error(), 1)
|
||||
err = functions.LeaveNetwork(cfg.Network)
|
||||
if err != nil {
|
||||
err = local.WipeLocal(cfg.Network)
|
||||
err = functions.WipeLocal(cfg.Network)
|
||||
if err != nil {
|
||||
log.Println("Error removing artifacts: ", err)
|
||||
ncutils.PrintLog("error removing artifacts: "+err.Error(), 1)
|
||||
}
|
||||
}
|
||||
if cfg.Daemon != "off" {
|
||||
if netclientutils.IsLinux() {
|
||||
err = local.RemoveSystemDServices(cfg.Network)
|
||||
if ncutils.IsLinux() {
|
||||
err = daemon.RemoveSystemDServices(cfg.Network)
|
||||
}
|
||||
if err != nil {
|
||||
log.Println("Error removing services: ", err)
|
||||
ncutils.PrintLog("error removing services: "+err.Error(), 1)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ncutils.PrintLog("success", 0)
|
||||
}
|
||||
return err
|
||||
}
|
||||
log.Println("joined " + cfg.Network)
|
||||
ncutils.PrintLog("joined "+cfg.Network, 1)
|
||||
if cfg.Daemon != "off" {
|
||||
if netclientutils.IsWindows() {
|
||||
err = local.CreateAndRunWindowsDaemon()
|
||||
} else if netclientutils.IsMac() {
|
||||
err = local.CreateAndRunMacDaemon()
|
||||
} else {
|
||||
err = functions.InstallDaemon(cfg)
|
||||
}
|
||||
err = daemon.InstallDaemon(cfg)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -75,13 +71,13 @@ func RunUserspaceDaemon() {
|
||||
func CheckIn(cfg config.ClientConfig) error {
|
||||
var err error
|
||||
if cfg.Network == "" {
|
||||
log.Println("Required, '-n'. No network provided. Exiting.")
|
||||
ncutils.PrintLog("required, '-n', exiting", 0)
|
||||
os.Exit(1)
|
||||
} else if cfg.Network == "all" {
|
||||
log.Println("Running CheckIn for all networks.")
|
||||
ncutils.PrintLog("running checkin for all networks", 1)
|
||||
networks, err := functions.GetNetworks()
|
||||
if err != nil {
|
||||
log.Println("Error retrieving networks. Exiting.")
|
||||
ncutils.PrintLog("error retrieving networks, exiting", 1)
|
||||
return err
|
||||
}
|
||||
for _, network := range networks {
|
||||
@@ -91,14 +87,14 @@ func CheckIn(cfg config.ClientConfig) error {
|
||||
}
|
||||
err = functions.CheckConfig(*currConf)
|
||||
if err != nil {
|
||||
log.Printf("Error checking in for "+network+" network: ", err)
|
||||
ncutils.PrintLog("error checking in for "+network+" network: "+err.Error(), 1)
|
||||
} else {
|
||||
log.Println("checked in successfully for " + network)
|
||||
ncutils.PrintLog("checked in successfully for "+network, 1)
|
||||
}
|
||||
}
|
||||
if len(networks) == 0 {
|
||||
if netclientutils.IsWindows() { // Windows specific - there are no netclients, so stop daemon process
|
||||
local.StopWindowsDaemon()
|
||||
if ncutils.IsWindows() { // Windows specific - there are no netclients, so stop daemon process
|
||||
daemon.StopWindowsDaemon()
|
||||
}
|
||||
}
|
||||
err = nil
|
||||
@@ -111,43 +107,46 @@ func CheckIn(cfg config.ClientConfig) error {
|
||||
func Leave(cfg config.ClientConfig) error {
|
||||
err := functions.LeaveNetwork(cfg.Network)
|
||||
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
|
||||
}
|
||||
|
||||
func Push(cfg config.ClientConfig) error {
|
||||
var err error
|
||||
if cfg.Network == "all" || netclientutils.IsWindows() {
|
||||
log.Println("No network selected. Running Push for all networks.")
|
||||
if cfg.Network == "all" || ncutils.IsWindows() {
|
||||
ncutils.PrintLog("pushing config to server for all networks.", 0)
|
||||
networks, err := functions.GetNetworks()
|
||||
if err != nil {
|
||||
log.Println("Error retrieving networks. Exiting.")
|
||||
ncutils.PrintLog("error retrieving networks, exiting.", 0)
|
||||
return err
|
||||
}
|
||||
for _, network := range networks {
|
||||
err = functions.Push(network)
|
||||
if err != nil {
|
||||
log.Printf("Error pushing network configs for "+network+" network: ", err)
|
||||
log.Printf("error pushing network configs for "+network+" network: ", err)
|
||||
} else {
|
||||
log.Println("pushed network config for " + network)
|
||||
ncutils.PrintLog("pushed network config for "+network, 1)
|
||||
}
|
||||
}
|
||||
err = nil
|
||||
} else {
|
||||
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
|
||||
}
|
||||
|
||||
func Pull(cfg config.ClientConfig) error {
|
||||
var err error
|
||||
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()
|
||||
if err != nil {
|
||||
log.Println("Error retrieving networks. Exiting.")
|
||||
ncutils.PrintLog("Error retrieving networks. Exiting.", 1)
|
||||
return err
|
||||
}
|
||||
for _, network := range networks {
|
||||
@@ -155,14 +154,15 @@ func Pull(cfg config.ClientConfig) error {
|
||||
if err != nil {
|
||||
log.Printf("Error pulling network config for "+network+" network: ", err)
|
||||
} else {
|
||||
log.Println("pulled network config for " + network)
|
||||
ncutils.PrintLog("pulled network config for "+network, 1)
|
||||
}
|
||||
}
|
||||
err = nil
|
||||
} else {
|
||||
_, 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
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ func List(cfg config.ClientConfig) error {
|
||||
}
|
||||
|
||||
func Uninstall() error {
|
||||
log.Println("Uninstalling netclient")
|
||||
ncutils.PrintLog("uninstalling netclient", 0)
|
||||
err := functions.Uninstall()
|
||||
return err
|
||||
}
|
||||
|
@@ -8,8 +8,9 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/urfave/cli/v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
@@ -25,7 +26,7 @@ type ClientConfig struct {
|
||||
Network string `yaml:"network"`
|
||||
Daemon string `yaml:"daemon"`
|
||||
OperatingSystem string `yaml:"operatingsystem"`
|
||||
DebugJoin bool `yaml:"debugjoin"`
|
||||
DebugJoin bool `yaml:"debugjoin"`
|
||||
}
|
||||
type ServerConfig struct {
|
||||
CoreDNSAddr string `yaml:"corednsaddr"`
|
||||
@@ -42,13 +43,13 @@ func Write(config *ClientConfig, network string) error {
|
||||
err := errors.New("no network provided - exiting")
|
||||
return err
|
||||
}
|
||||
_, err := os.Stat(netclientutils.GetNetclientPath())
|
||||
_, err := os.Stat(ncutils.GetNetclientPath())
|
||||
if os.IsNotExist(err) {
|
||||
os.Mkdir(netclientutils.GetNetclientPath(), 0744)
|
||||
os.Mkdir(ncutils.GetNetclientPath(), 0744)
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
home := netclientutils.GetNetclientPathSpecific()
|
||||
home := ncutils.GetNetclientPathSpecific()
|
||||
|
||||
file := fmt.Sprintf(home + "netconfig-" + network)
|
||||
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
|
||||
//home, err := homedir.Dir()
|
||||
_, err := os.Stat(netclientutils.GetNetclientPath())
|
||||
_, err := os.Stat(ncutils.GetNetclientPath())
|
||||
if os.IsNotExist(err) {
|
||||
os.Mkdir(netclientutils.GetNetclientPath(), 0744)
|
||||
os.Mkdir(ncutils.GetNetclientPath(), 0744)
|
||||
} else if err != nil {
|
||||
fmt.Println("couldnt find or create", netclientutils.GetNetclientPath())
|
||||
fmt.Println("couldnt find or create", ncutils.GetNetclientPath())
|
||||
return err
|
||||
}
|
||||
home := netclientutils.GetNetclientPathSpecific()
|
||||
home := ncutils.GetNetclientPathSpecific()
|
||||
|
||||
file := fmt.Sprintf(home + "netconfig-" + network)
|
||||
//f, err := os.Open(file)
|
||||
@@ -151,7 +152,7 @@ func (config *ClientConfig) ReadConfig() {
|
||||
|
||||
nofile := false
|
||||
//home, err := homedir.Dir()
|
||||
home := netclientutils.GetNetclientPathSpecific()
|
||||
home := ncutils.GetNetclientPathSpecific()
|
||||
file := fmt.Sprintf(home + "netconfig-" + config.Network)
|
||||
//f, err := os.Open(file)
|
||||
f, err := os.OpenFile(file, os.O_RDONLY, 0666)
|
||||
@@ -186,7 +187,7 @@ func ModConfig(node *models.Node) error {
|
||||
}
|
||||
var modconfig ClientConfig
|
||||
var err error
|
||||
if FileExists(netclientutils.GetNetclientPathSpecific() + "netconfig-" + network) {
|
||||
if FileExists(ncutils.GetNetclientPathSpecific() + "netconfig-" + network) {
|
||||
useconfig, err := ReadConfig(network)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -306,7 +307,7 @@ func ReadConfig(network string) (*ClientConfig, error) {
|
||||
return nil, err
|
||||
}
|
||||
nofile := false
|
||||
home := netclientutils.GetNetclientPathSpecific()
|
||||
home := ncutils.GetNetclientPathSpecific()
|
||||
file := fmt.Sprintf(home + "netconfig-" + network)
|
||||
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 (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -13,7 +12,7 @@ import (
|
||||
"github.com/gravitl/netmaker/netclient/auth"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/netclient/wireguard"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
"google.golang.org/grpc"
|
||||
@@ -30,37 +29,37 @@ func checkIP(node *models.Node, servercfg config.ServerConfig, cliconf config.Cl
|
||||
var err error
|
||||
if node.Roaming == "yes" && node.IsStatic != "yes" {
|
||||
if node.IsLocal == "no" {
|
||||
extIP, err := netclientutils.GetPublicIP()
|
||||
extIP, err := ncutils.GetPublicIP()
|
||||
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 != "" {
|
||||
log.Println("Endpoint has changed from " +
|
||||
node.Endpoint + " to " + extIP)
|
||||
log.Println("Updating address")
|
||||
ncutils.PrintLog("endpoint has changed from "+
|
||||
node.Endpoint+" to "+extIP, 1)
|
||||
ncutils.PrintLog("updating address", 1)
|
||||
node.Endpoint = extIP
|
||||
ipchange = true
|
||||
}
|
||||
intIP, err := getPrivateAddr()
|
||||
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 != "" {
|
||||
log.Println("Local Address has changed from " +
|
||||
node.LocalAddress + " to " + intIP)
|
||||
log.Println("Updating address")
|
||||
ncutils.PrintLog("local Address has changed from "+
|
||||
node.LocalAddress+" to "+intIP, 1)
|
||||
ncutils.PrintLog("updating address", 1)
|
||||
node.LocalAddress = intIP
|
||||
ipchange = true
|
||||
}
|
||||
} else {
|
||||
localIP, err := netclientutils.GetLocalIP(node.LocalRange)
|
||||
localIP, err := ncutils.GetLocalIP(node.LocalRange)
|
||||
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 != "" {
|
||||
log.Println("Endpoint has changed from " +
|
||||
node.Endpoint + " to " + localIP)
|
||||
log.Println("Updating address")
|
||||
ncutils.PrintLog("endpoint has changed from "+
|
||||
node.Endpoint+" to "+localIP, 1)
|
||||
ncutils.PrintLog("updating address", 1)
|
||||
node.Endpoint = localIP
|
||||
node.LocalAddress = localIP
|
||||
ipchange = true
|
||||
@@ -70,12 +69,12 @@ func checkIP(node *models.Node, servercfg config.ServerConfig, cliconf config.Cl
|
||||
if ipchange {
|
||||
err = config.ModConfig(node)
|
||||
if err != nil {
|
||||
log.Println("Error:", err)
|
||||
ncutils.PrintLog("error modifying config file: "+err.Error(), 1)
|
||||
return false
|
||||
}
|
||||
err = wireguard.SetWGConfig(network, false)
|
||||
if err != nil {
|
||||
log.Println("Error:", err)
|
||||
ncutils.PrintLog("error setting wireguard config: "+err.Error(), 1)
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -96,14 +95,14 @@ func checkNodeActions(node *models.Node, networkName string, servercfg config.Se
|
||||
node.IsStatic != "yes" {
|
||||
err := wireguard.SetWGKeyConfig(networkName, servercfg.GRPCAddress)
|
||||
if err != nil {
|
||||
log.Println("Unable to process reset keys request:", err)
|
||||
ncutils.PrintLog("unable to process reset keys request: "+err.Error(), 1)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
if node.Action == models.NODE_DELETE || localNode.Action == models.NODE_DELETE {
|
||||
err := RemoveLocalInstance(cfg, networkName)
|
||||
if err != nil {
|
||||
log.Println("Error:", err)
|
||||
ncutils.PrintLog("error deleting locally: "+err.Error(), 1)
|
||||
}
|
||||
return models.NODE_DELETE
|
||||
}
|
||||
@@ -161,22 +160,22 @@ func Pull(network string, manual bool) (*models.Node, error) {
|
||||
servercfg := cfg.Server
|
||||
var header metadata.MD
|
||||
|
||||
if cfg.Node.IPForwarding == "yes" && !netclientutils.IsWindows() {
|
||||
if cfg.Node.IPForwarding == "yes" && !ncutils.IsWindows() {
|
||||
if err = local.SetIPForwarding(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
if err != nil {
|
||||
log.Println("Cant dial GRPC server:", err)
|
||||
ncutils.PrintLog("Cant dial GRPC server: "+err.Error(), 1)
|
||||
return nil, err
|
||||
}
|
||||
wcclient := nodepb.NewNodeServiceClient(conn)
|
||||
|
||||
ctx, err := auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
log.Println("Failed to authenticate:", err)
|
||||
ncutils.PrintLog("Failed to authenticate: "+err.Error(), 1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -198,7 +197,7 @@ func Pull(network string, manual bool) (*models.Node, error) {
|
||||
// check for interface change
|
||||
if cfg.Node.Interface != resNode.Interface {
|
||||
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"
|
||||
@@ -230,7 +229,7 @@ func Pull(network string, manual bool) (*models.Node, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if netclientutils.IsLinux() {
|
||||
if ncutils.IsLinux() {
|
||||
setDNS(&resNode, servercfg, &cfg.Node)
|
||||
}
|
||||
|
||||
@@ -249,16 +248,16 @@ func Push(network string) error {
|
||||
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
if err != nil {
|
||||
log.Println("Cant dial GRPC server:", err)
|
||||
ncutils.PrintLog("Cant dial GRPC server: "+err.Error(), 1)
|
||||
return err
|
||||
}
|
||||
wcclient = nodepb.NewNodeServiceClient(conn)
|
||||
|
||||
ctx, err := auth.SetJWT(wcclient, network)
|
||||
if err != nil {
|
||||
log.Println("Failed to authenticate:", err)
|
||||
ncutils.PrintLog("Failed to authenticate with server: "+err.Error(), 1)
|
||||
return err
|
||||
}
|
||||
if postnode.IsPending != "yes" {
|
||||
|
@@ -8,6 +8,7 @@ import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
@@ -15,8 +16,9 @@ import (
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/auth"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
||||
"github.com/gravitl/netmaker/netclient/daemon"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/netclient/wireguard"
|
||||
"golang.zx2c4.com/wireguard/wgctrl"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
@@ -92,21 +94,21 @@ func GetNode(network string) models.Node {
|
||||
func Uninstall() error {
|
||||
networks, err := GetNetworks()
|
||||
if err != nil {
|
||||
log.Println("unable to retrieve networks: ", err)
|
||||
log.Println("continuing uninstall without leaving networks")
|
||||
ncutils.PrintLog("unable to retrieve networks: "+err.Error(), 1)
|
||||
ncutils.PrintLog("continuing uninstall without leaving networks", 1)
|
||||
} else {
|
||||
for _, network := range networks {
|
||||
err = LeaveNetwork(network)
|
||||
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
|
||||
if netclientutils.IsWindows() {
|
||||
local.CleanupWindows()
|
||||
} else if netclientutils.IsWindows() {
|
||||
local.CleanupMac()
|
||||
if ncutils.IsWindows() {
|
||||
daemon.CleanupWindows()
|
||||
} else if ncutils.IsWindows() {
|
||||
daemon.CleanupMac()
|
||||
}
|
||||
|
||||
return err
|
||||
@@ -123,7 +125,7 @@ func LeaveNetwork(network string) error {
|
||||
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
if err != nil {
|
||||
log.Printf("Unable to establish client connection to "+servercfg.GRPCAddress+": %v", err)
|
||||
} else {
|
||||
@@ -134,9 +136,9 @@ func LeaveNetwork(network string) error {
|
||||
if err != nil {
|
||||
log.Printf("Failed to authenticate: %v", err)
|
||||
} else {
|
||||
if netclientutils.IsWindows() {
|
||||
local.RemoveWindowsConf(node.Interface)
|
||||
log.Println("removed Windows tunnel " + node.Interface)
|
||||
if !ncutils.IsKernel() {
|
||||
//wireguard.RemoveConf(node.Interface, true)
|
||||
//ncutils.PrintLog("removed network tunnel "+node.Interface, 1)
|
||||
}
|
||||
node.SetID()
|
||||
var header metadata.MD
|
||||
@@ -149,10 +151,9 @@ func LeaveNetwork(network string) error {
|
||||
grpc.Header(&header),
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Encountered error deleting node: %v", err)
|
||||
log.Println(err)
|
||||
ncutils.PrintLog("encountered error deleting node: "+err.Error(), 1)
|
||||
} 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 {
|
||||
err := local.WipeLocal(networkName)
|
||||
err := WipeLocal(networkName)
|
||||
if err != nil {
|
||||
log.Printf("Unable to wipe local config: %v", err)
|
||||
ncutils.PrintLog("unable to wipe local config", 1)
|
||||
} else {
|
||||
log.Println("Removed " + networkName + " network locally")
|
||||
ncutils.PrintLog("removed "+networkName+" network locally", 1)
|
||||
}
|
||||
if cfg.Daemon != "off" {
|
||||
if netclientutils.IsWindows() {
|
||||
if ncutils.IsWindows() {
|
||||
// TODO: Remove job?
|
||||
} else if ncutils.IsMac() {
|
||||
//TODO: Delete mac daemon
|
||||
} else {
|
||||
err = local.RemoveSystemDServices(networkName)
|
||||
err = daemon.RemoveSystemDServices(networkName)
|
||||
}
|
||||
}
|
||||
return err
|
||||
@@ -178,18 +181,18 @@ func RemoveLocalInstance(cfg *config.ClientConfig, networkName string) error {
|
||||
|
||||
func DeleteInterface(ifacename string, postdown string) error {
|
||||
var err error
|
||||
if netclientutils.IsWindows() {
|
||||
err = local.RemoveWindowsConf(ifacename)
|
||||
if !ncutils.IsKernel() {
|
||||
err = wireguard.RemoveConf(ifacename, true)
|
||||
} else {
|
||||
ipExec, errN := exec.LookPath("ip")
|
||||
err = errN
|
||||
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 != "" {
|
||||
runcmds := strings.Split(postdown, "; ")
|
||||
err = local.RunCmds(runcmds, true)
|
||||
err = ncutils.RunCmds(runcmds, true)
|
||||
}
|
||||
}
|
||||
return err
|
||||
@@ -212,9 +215,9 @@ func List() error {
|
||||
"PrivateIPv6": cfg.Node.Address6,
|
||||
"PublicEndpoint": cfg.Node.Endpoint,
|
||||
})
|
||||
log.Println(network + ": " + string(jsoncfg))
|
||||
fmt.Println(network + ": " + string(jsoncfg))
|
||||
} else {
|
||||
log.Println(network + ": Could not retrieve network configuration.")
|
||||
ncutils.PrintLog(network+": Could not retrieve network configuration.", 1)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -222,7 +225,7 @@ func List() error {
|
||||
|
||||
func GetNetworks() ([]string, error) {
|
||||
var networks []string
|
||||
files, err := ioutil.ReadDir(netclientutils.GetNetclientPath())
|
||||
files, err := ioutil.ReadDir(ncutils.GetNetclientPath())
|
||||
if err != nil {
|
||||
return networks, err
|
||||
}
|
||||
@@ -247,3 +250,107 @@ func stringAfter(original string, substring string) string {
|
||||
}
|
||||
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/netclient/auth"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/daemon"
|
||||
"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/wireguard"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
@@ -27,7 +28,7 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -42,7 +43,7 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
|
||||
cfg.Node.LocalAddress = getLocalIP(cfg.Node)
|
||||
}
|
||||
if cfg.Node.Password == "" {
|
||||
cfg.Node.Password = netclientutils.GenPass()
|
||||
cfg.Node.Password = ncutils.GenPass()
|
||||
}
|
||||
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 != "" {
|
||||
cfg.Node.Endpoint = cfg.Node.LocalAddress
|
||||
} else {
|
||||
cfg.Node.Endpoint, err = netclientutils.GetPublicIP()
|
||||
cfg.Node.Endpoint, err = ncutils.GetPublicIP()
|
||||
|
||||
}
|
||||
if err != nil || cfg.Node.Endpoint == "" {
|
||||
netclientutils.Log("Error setting cfg.Node.Endpoint.")
|
||||
ncutils.Log("Error setting cfg.Node.Endpoint.")
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -71,7 +72,7 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
|
||||
|
||||
// Find and set node MacAddress
|
||||
if cfg.Node.MacAddress == "" {
|
||||
macs, err := netclientutils.GetMacAddr()
|
||||
macs, err := ncutils.GetMacAddr()
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(macs) == 0 {
|
||||
@@ -84,7 +85,7 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
|
||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
|
||||
if err != nil {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
log.Println("node created on remote server...updating configs")
|
||||
ncutils.PrintLog("node created on remote server...updating configs", 1)
|
||||
|
||||
nodeData := res.Data
|
||||
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
|
||||
node.ListenPort, err = netclientutils.GetFreePort(node.ListenPort)
|
||||
node.ListenPort, err = ncutils.GetFreePort(node.ListenPort)
|
||||
if err != nil {
|
||||
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
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
@@ -168,38 +169,28 @@ func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
|
||||
}
|
||||
|
||||
if node.IsPending == "yes" {
|
||||
netclientutils.Log("Node is marked as PENDING.")
|
||||
netclientutils.Log("Awaiting approval from Admin before configuring WireGuard.")
|
||||
ncutils.Log("Node is marked as PENDING.")
|
||||
ncutils.Log("Awaiting approval from Admin before configuring WireGuard.")
|
||||
if cfg.Daemon != "off" {
|
||||
if netclientutils.IsWindows() {
|
||||
// handle daemon here..
|
||||
err = local.CreateAndRunWindowsDaemon()
|
||||
} else {
|
||||
err = local.ConfigureSystemD(cfg.Network)
|
||||
}
|
||||
return err
|
||||
return daemon.InstallDaemon(cfg)
|
||||
}
|
||||
}
|
||||
|
||||
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")
|
||||
|
||||
if err != nil && !netclientutils.IsEmptyRecord(err) {
|
||||
netclientutils.Log("failed to retrieve peers")
|
||||
if err != nil && !ncutils.IsEmptyRecord(err) {
|
||||
ncutils.Log("failed to retrieve peers")
|
||||
return err
|
||||
}
|
||||
|
||||
netclientutils.Log("starting wireguard")
|
||||
ncutils.Log("starting wireguard")
|
||||
err = wireguard.InitWireguard(&node, privateKey, peers, hasGateway, gateways)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cfg.Daemon != "off" {
|
||||
if netclientutils.IsWindows() {
|
||||
err = local.CreateAndRunWindowsDaemon()
|
||||
} else {
|
||||
err = local.ConfigureSystemD(cfg.Network)
|
||||
}
|
||||
err = daemon.InstallDaemon(cfg)
|
||||
}
|
||||
if err != nil {
|
||||
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"
|
||||
"os/exec"
|
||||
|
||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
)
|
||||
|
||||
func SetDNS(nameserver string) error {
|
||||
@@ -34,7 +34,7 @@ func SetDNS(nameserver string) error {
|
||||
}
|
||||
|
||||
func UpdateDNS(ifacename string, network string, nameserver string) error {
|
||||
if netclientutils.IsWindows() {
|
||||
if ncutils.IsWindows() {
|
||||
return nil
|
||||
}
|
||||
_, err := exec.LookPath("resolvectl")
|
||||
@@ -42,15 +42,15 @@ func UpdateDNS(ifacename string, network string, nameserver string) error {
|
||||
log.Println(err)
|
||||
log.Println("WARNING: resolvectl not present. Unable to set dns. Install resolvectl or run manually.")
|
||||
} else {
|
||||
_, err = RunCmd("resolvectl domain " + ifacename + " ~" + network, true)
|
||||
_, err = ncutils.RunCmd("resolvectl domain "+ifacename+" ~"+network, true)
|
||||
if err != nil {
|
||||
log.Println("WARNING: Error encountered setting domain on dns. Aborted setting dns.")
|
||||
} else {
|
||||
_, err = RunCmd("resolvectl default-route " + ifacename + " false", true)
|
||||
_, err = ncutils.RunCmd("resolvectl default-route "+ifacename+" false", true)
|
||||
if err != nil {
|
||||
log.Println("WARNING: Error encountered setting default-route on dns. Aborted setting dns.")
|
||||
} else {
|
||||
_, err = RunCmd("resolvectl dns " + ifacename + " " + nameserver, true)
|
||||
_, err = ncutils.RunCmd("resolvectl dns "+ifacename+" "+nameserver, true)
|
||||
if err != nil {
|
||||
log.Println("WARNING: Error encountered running resolvectl dns " + ifacename + " " + nameserver)
|
||||
}
|
||||
|
@@ -3,17 +3,11 @@ package local
|
||||
import (
|
||||
//"github.com/davecgh/go-spew/spew"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
)
|
||||
|
||||
func SetIPForwarding() error {
|
||||
@@ -22,6 +16,8 @@ func SetIPForwarding() error {
|
||||
switch os {
|
||||
case "linux":
|
||||
err = SetIPForwardingLinux()
|
||||
case "darwin":
|
||||
err = SetIPForwardingMac()
|
||||
default:
|
||||
err = errors.New("This OS is not supported")
|
||||
}
|
||||
@@ -29,14 +25,14 @@ func SetIPForwarding() 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 {
|
||||
log.Println("WARNING: Error encountered setting ip forwarding. This can break functionality.")
|
||||
return err
|
||||
} else {
|
||||
s := strings.Fields(string(out))
|
||||
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 {
|
||||
log.Println("WARNING: Error encountered setting ip forwarding. You may want to investigate this.")
|
||||
return err
|
||||
@@ -46,274 +42,59 @@ func SetIPForwardingLinux() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
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(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))
|
||||
}
|
||||
func SetIPForwardingMac() error {
|
||||
_, err := ncutils.RunCmd("sysctl -w net.inet.ip.forwarding=1", true)
|
||||
if err != nil {
|
||||
log.Println("WARNING: Error encountered setting ip forwarding. This can break functionality.")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func FileExists(f string) bool {
|
||||
info, err := os.Stat(f)
|
||||
if os.IsNotExist(err) {
|
||||
func IsWGInstalled() bool {
|
||||
out, err := ncutils.RunCmd("wg help", true)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return !info.IsDir()
|
||||
return strings.Contains(out, "Available subcommand")
|
||||
}
|
||||
|
||||
func ConfigureSystemD(network string) error {
|
||||
/*
|
||||
path, err := os.Getwd()
|
||||
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]))
|
||||
func GetMacIface(addr string) (string, error) {
|
||||
out, err := ncutils.RunCmd("route get "+addr, false)
|
||||
var iface string
|
||||
if err != nil {
|
||||
return err
|
||||
return iface, errors.New(string(out))
|
||||
}
|
||||
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 !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
|
||||
for _, line := range strings.Split(strings.TrimSuffix(string(out), "\n"), "\n") {
|
||||
if strings.Contains(line, "interface: ") {
|
||||
iface = getLineAfter(string(out), "interface: ")
|
||||
iface = strings.Split(iface, "\n")[0]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
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 !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 iface == "" {
|
||||
err = errors.New("could not find iface for ip addr " + addr)
|
||||
}
|
||||
|
||||
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
|
||||
return iface, err
|
||||
}
|
||||
|
||||
func isOnlyService(network string) (bool, error) {
|
||||
isonly := false
|
||||
files, err := filepath.Glob("/etc/netclient/netconfig-*")
|
||||
if err != nil {
|
||||
return isonly, err
|
||||
func getLineAfter(value string, a string) string {
|
||||
// Get substring after a string.
|
||||
pos := strings.LastIndex(value, a)
|
||||
if pos == -1 {
|
||||
return ""
|
||||
}
|
||||
count := len(files)
|
||||
if count == 0 {
|
||||
isonly = true
|
||||
adjustedPos := pos + len(a)
|
||||
if adjustedPos >= len(value) {
|
||||
return ""
|
||||
}
|
||||
return isonly, err
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
return value[adjustedPos:len(value)]
|
||||
}
|
||||
|
||||
func HasNetwork(network string) bool {
|
||||
|
||||
if netclientutils.IsWindows() {
|
||||
return FileExists(netclientutils.GetNetclientPathSpecific() + "netconfig-" + network)
|
||||
if ncutils.IsWindows() {
|
||||
return ncutils.FileExists(ncutils.GetNetclientPathSpecific() + "netconfig-" + network)
|
||||
}
|
||||
return FileExists("/etc/systemd/system/netclient-"+network+".timer") ||
|
||||
FileExists(netclientutils.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
|
||||
return ncutils.FileExists("/etc/systemd/system/netclient-"+network+".timer") ||
|
||||
ncutils.FileExists(ncutils.GetNetclientPathSpecific()+"netconfig-"+network)
|
||||
}
|
||||
|
@@ -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/exec"
|
||||
"os/signal"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"runtime/debug"
|
||||
|
||||
"github.com/gravitl/netmaker/netclient/command"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/netclient/ncwindows"
|
||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
@@ -23,7 +24,7 @@ func main() {
|
||||
app := cli.NewApp()
|
||||
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.Version = "v0.7.3"
|
||||
app.Version = "v0.8.0"
|
||||
|
||||
cliFlags := []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
@@ -320,11 +321,11 @@ func main() {
|
||||
|
||||
setGarbageCollection()
|
||||
|
||||
if netclientutils.IsWindows() {
|
||||
if ncutils.IsWindows() {
|
||||
ncwindows.InitWindows()
|
||||
} else {
|
||||
// start our application
|
||||
out, err := local.RunCmd("id -u", true)
|
||||
out, err := ncutils.RunCmd("id -u", true)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(out, err)
|
||||
@@ -345,12 +346,12 @@ func main() {
|
||||
log.Fatal("WireGuard not installed. Please install WireGuard (wireguard-tools) and try again.")
|
||||
}
|
||||
}
|
||||
if netclientutils.IsWindows() {
|
||||
if !local.IsWindowsWGInstalled() {
|
||||
log.Fatal("Please install Windows WireGuard before using Gravitl Netclient. https://download.wireguard.com/windows-client/wireguard-installer.exe")
|
||||
if !ncutils.IsKernel() {
|
||||
if !local.IsWGInstalled() {
|
||||
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)
|
||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||
go func() {
|
||||
@@ -367,9 +368,9 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func setGarbageCollection(){
|
||||
_, gcset := os.LookupEnv("GOGC");
|
||||
func setGarbageCollection() {
|
||||
_, gcset := os.LookupEnv("GOGC")
|
||||
if !gcset {
|
||||
debug.SetGCPercent(netclientutils.DEFAULT_GC_PERCENT)
|
||||
debug.SetGCPercent(ncutils.DEFAULT_GC_PERCENT)
|
||||
}
|
||||
}
|
@@ -1,15 +1,17 @@
|
||||
package netclientutils
|
||||
package ncutils
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -39,13 +41,20 @@ func IsWindows() bool {
|
||||
}
|
||||
|
||||
func IsMac() bool {
|
||||
return runtime.GOOS == "macos"
|
||||
return runtime.GOOS == "darwin"
|
||||
}
|
||||
|
||||
func IsLinux() bool {
|
||||
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 ==
|
||||
func IsEmptyRecord(err error) bool {
|
||||
if err == nil {
|
||||
@@ -256,6 +265,8 @@ func GetHomeDirWindows() string {
|
||||
func GetNetclientPath() string {
|
||||
if IsWindows() {
|
||||
return WINDOWS_APP_DATA_PATH
|
||||
} else if IsMac() {
|
||||
return "/etc/netclient/"
|
||||
} else {
|
||||
return LINUX_APP_DATA_PATH
|
||||
}
|
||||
@@ -264,6 +275,8 @@ func GetNetclientPath() string {
|
||||
func GetNetclientPathSpecific() string {
|
||||
if IsWindows() {
|
||||
return WINDOWS_APP_DATA_PATH + "\\"
|
||||
} else if IsMac() {
|
||||
return "/etc/netclient/"
|
||||
} else {
|
||||
return LINUX_APP_DATA_PATH + "/"
|
||||
}
|
||||
@@ -278,3 +291,70 @@ func GRPCRequestOpts(isSecure string) grpc.DialOption {
|
||||
}
|
||||
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"
|
||||
"os"
|
||||
|
||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
)
|
||||
|
||||
// Initialize windows directory & files and such
|
||||
func InitWindows() {
|
||||
|
||||
_, directoryErr := os.Stat(netclientutils.GetNetclientPath()) // Check if data directory exists or not
|
||||
if os.IsNotExist(directoryErr) { // create a data directory
|
||||
os.Mkdir(netclientutils.GetNetclientPath(), 0755)
|
||||
_, directoryErr := os.Stat(ncutils.GetNetclientPath()) // Check if data directory exists or not
|
||||
if os.IsNotExist(directoryErr) { // create a data directory
|
||||
os.Mkdir(ncutils.GetNetclientPath(), 0755)
|
||||
}
|
||||
wdPath, wdErr := os.Getwd() // get the current working directory
|
||||
if wdErr != nil {
|
||||
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")
|
||||
if os.IsNotExist(dataNetclientErr) { // check and see if netclient.exe is in appdata
|
||||
if currentNetclientErr == nil { // copy it if it exists locally
|
||||
@@ -28,8 +28,8 @@ func InitWindows() {
|
||||
log.Println("failed to find netclient.exe")
|
||||
return
|
||||
}
|
||||
if err = ioutil.WriteFile(netclientutils.GetNetclientPathSpecific()+"netclient.exe", input, 0644); err != nil {
|
||||
log.Println("failed to copy netclient.exe to", netclientutils.GetNetclientPath())
|
||||
if err = ioutil.WriteFile(ncutils.GetNetclientPathSpecific()+"netclient.exe", input, 0644); err != nil {
|
||||
log.Println("failed to copy netclient.exe to", ncutils.GetNetclientPath())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@@ -11,9 +11,8 @@ import (
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/auth"
|
||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/metadata"
|
||||
@@ -25,7 +24,7 @@ func getGrpcClient(cfg *config.ClientConfig) (nodepb.NodeServiceClient, error) {
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
// == GRPC SETUP ==
|
||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -68,6 +67,7 @@ func CheckIn(network string) (*models.Node, error) {
|
||||
return &node, err
|
||||
}
|
||||
|
||||
/*
|
||||
func RemoveNetwork(network string) error {
|
||||
//need to implement checkin on server side
|
||||
cfg, err := config.ReadConfig(network)
|
||||
@@ -80,7 +80,7 @@ func RemoveNetwork(network string) error {
|
||||
|
||||
var wcclient nodepb.NodeServiceClient
|
||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
if err != nil {
|
||||
log.Printf("Unable to establish client connection to "+servercfg.GRPCAddress+": %v", err)
|
||||
//return err
|
||||
@@ -110,16 +110,11 @@ func RemoveNetwork(network string) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
err = local.WipeLocal(network)
|
||||
if err != nil {
|
||||
log.Printf("Unable to wipe local config: %v", err)
|
||||
}
|
||||
if cfg.Daemon != "off" {
|
||||
err = local.RemoveSystemDServices(network)
|
||||
}
|
||||
//err = functions.RemoveLocalInstance(network)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
*/
|
||||
func GetPeers(macaddress string, network string, server string, dualstack bool, isIngressGateway bool) ([]wgtypes.PeerConfig, bool, []string, error) {
|
||||
hasGateway := false
|
||||
var gateways []string
|
||||
@@ -138,7 +133,7 @@ func GetPeers(macaddress string, network string, server string, dualstack bool,
|
||||
}
|
||||
|
||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
} else if appendip := net.ParseIP(allowedIp); appendip != nil && allowedIp != node.Address {
|
||||
ipnet := net.IPNet{
|
||||
IP: net.ParseIP(allowedIp),
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
}
|
||||
allowedips = append(allowedips, ipnet)
|
||||
ipnet := net.IPNet{
|
||||
IP: net.ParseIP(allowedIp),
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
}
|
||||
allowedips = append(allowedips, ipnet)
|
||||
}
|
||||
}
|
||||
// handle egress gateway peers
|
||||
@@ -273,7 +268,7 @@ func GetPeers(macaddress string, network string, server string, dualstack bool,
|
||||
if err == nil {
|
||||
peers = append(peers, extPeers...)
|
||||
} else {
|
||||
log.Println("ERROR RETRIEVING EXTERNAL PEERS",err)
|
||||
log.Println("ERROR RETRIEVING EXTERNAL PEERS", err)
|
||||
}
|
||||
}
|
||||
return peers, hasGateway, gateways, err
|
||||
@@ -288,7 +283,7 @@ func GetExtPeers(macaddress string, network string, server string, dualstack boo
|
||||
nodecfg := cfg.Node
|
||||
|
||||
conn, err := grpc.Dial(cfg.Server.GRPCAddress,
|
||||
netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
ncutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
|
||||
if err != nil {
|
||||
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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"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"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
//homedir "github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig, hasGateway bool, gateways []string) error {
|
||||
|
||||
key, err := wgtypes.ParseKey(privkey)
|
||||
func setKernelDevice(ifacename string, address string) error {
|
||||
ipExec, err := exec.LookPath("ip")
|
||||
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 !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())
|
||||
}
|
||||
}
|
||||
}
|
||||
_, _ = ncutils.RunCmd("ip link delete dev "+ifacename, false)
|
||||
_, _ = ncutils.RunCmd(ipExec+" link add dev "+ifacename+" type wireguard", true)
|
||||
_, _ = ncutils.RunCmd(ipExec+" address add dev "+ifacename+" "+address+"/24", true)
|
||||
|
||||
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
|
||||
}
|
||||
func GetVersion() string {
|
||||
version := "0.7.3"
|
||||
version := "0.8.0"
|
||||
if config.Config.Server.Version != "" {
|
||||
version = config.Config.Server.Version
|
||||
}
|
||||
|
@@ -11,8 +11,7 @@ import (
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/functions"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/netclient/netclientutils"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
)
|
||||
|
||||
@@ -33,10 +32,10 @@ func GetServerWGConf() (models.IntClient, error) {
|
||||
|
||||
func InstallNetclient() error {
|
||||
|
||||
netclientPath := netclientutils.GetNetclientPathSpecific()
|
||||
netclientPath := ncutils.GetNetclientPathSpecific()
|
||||
if !FileExists(netclientPath + "netclient") {
|
||||
var err error
|
||||
if netclientutils.IsWindows() {
|
||||
if ncutils.IsWindows() {
|
||||
_, err = copy(".\\netclient\\netclient", netclientPath+"netclient")
|
||||
} else {
|
||||
_, err = copy("./netclient/netclient", netclientPath+"netclient")
|
||||
@@ -87,13 +86,13 @@ func copy(src, dst string) (int64, error) {
|
||||
}
|
||||
|
||||
func RemoveNetwork(network string) (bool, error) {
|
||||
netclientPath := netclientutils.GetNetclientPathSpecific()
|
||||
netclientPath := ncutils.GetNetclientPathSpecific()
|
||||
_, err := os.Stat(netclientPath + "netclient")
|
||||
if err != nil {
|
||||
log.Println("could not find " + netclientPath + "netclient")
|
||||
return false, err
|
||||
}
|
||||
_, err = local.RunCmd(netclientPath+"netclient leave -n "+network, true)
|
||||
_, err = ncutils.RunCmd(netclientPath+"netclient leave -n "+network, true)
|
||||
if err == nil {
|
||||
log.Println("Server removed from network " + network)
|
||||
}
|
||||
@@ -107,8 +106,8 @@ func AddNetwork(network string) (bool, error) {
|
||||
log.Println("could not get public IP.")
|
||||
return false, err
|
||||
}
|
||||
netclientDir := netclientutils.GetNetclientPath()
|
||||
netclientPath := netclientutils.GetNetclientPathSpecific()
|
||||
netclientDir := ncutils.GetNetclientPath()
|
||||
netclientPath := ncutils.GetNetclientPathSpecific()
|
||||
_, err = os.Stat(netclientDir)
|
||||
if os.IsNotExist(err) {
|
||||
os.Mkdir(netclientDir, 744)
|
||||
|
Reference in New Issue
Block a user