diff --git a/go.mod b/go.mod index 8c49b6bb..781d86a6 100644 --- a/go.mod +++ b/go.mod @@ -49,4 +49,5 @@ require ( github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect google.golang.org/appengine v1.4.0 // indirect + gopkg.in/ini.v1 v1.66.2 // indirect ) diff --git a/go.sum b/go.sum index 5b8fecb5..a1efc4e7 100644 --- a/go.sum +++ b/go.sum @@ -292,6 +292,8 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= +gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/netclient/functions/daemon.go b/netclient/functions/daemon.go index 6e212c77..fc926bda 100644 --- a/netclient/functions/daemon.go +++ b/netclient/functions/daemon.go @@ -6,7 +6,6 @@ import ( "log" "os" "os/signal" - "runtime" "strings" "syscall" "time" @@ -68,8 +67,7 @@ func Netclient(ctx context.Context, network string) { } client.AddRoute("update/"+cfg.Node.ID, NodeUpdate) client.AddRoute("update/peers/"+cfg.Node.ID, UpdatePeers) - //handle key updates in node update - //client.AddRoute("update/keys/"+cfg.Node.ID, UpdateKeys) + client.AddRoute("update/keys/"+cfg.Node.ID, UpdateKeys) defer client.Disconnect(250) go Checkin(ctx, cfg, network) go Metrics(ctx, cfg, network) @@ -88,85 +86,19 @@ var NodeUpdate mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) ncutils.Log("received message to update node " + string(msg.Payload())) //potentiall blocking i/o so do this in a go routine go func() { - var newNode models.Node - var cfg config.ClientConfig - cfg.Network = newNode.Network - cfg.ReadConfig() - err := json.Unmarshal(msg.Payload(), &newNode) + var data models.Node + err := json.Unmarshal(msg.Payload(), &data) if err != nil { ncutils.Log("error unmarshalling node update data" + err.Error()) return } - //check if interface name has changed if so delete. - if cfg.Node.Interface != newNode.Interface { - if err = wireguard.RemoveConf(cfg.Node.Interface, true); err != nil { - ncutils.PrintLog("could not delete old interface "+cfg.Node.Interface+": "+err.Error(), 1) - } - } - newNode.PullChanges = "no" - //ensure that OS never changes - newNode.OS = runtime.GOOS - cfg.Node = newNode - switch newNode.Action { - case models.NODE_DELETE: - if err := RemoveLocalInstance(&cfg, cfg.Network); err != nil { - ncutils.PrintLog("error deleting local instance: "+err.Error(), 1) - return - } - case models.NODE_UPDATE_KEY: - UpdateKeys(&cfg, client) - case models.NODE_NOOP: - default: - } - //Save new config - if err := config.Write(&cfg, cfg.Network); err != nil { - ncutils.PrintLog("error updating node configuration: "+err.Error(), 1) - } - nameserver := cfg.Server.CoreDNSAddr - privateKey, err := wireguard.RetrievePrivKey(newNode.Network) - if err != nil { - ncutils.Log("error reading PrivateKey " + err.Error()) - return - } - if err := wireguard.UpdateWgInterface(cfg.Node.Interface, privateKey, nameserver, newNode); err != nil { - ncutils.Log("error updating wireguard config " + err.Error()) - return - } - // path hardcoded for now... should be updated - err = wireguard.ApplyWGQuickConf("/etc/netclient/config/" + cfg.Node.Interface + ".conf") - if err != nil { - ncutils.Log("error restarting wg after node update " + err.Error()) - return - } - }() -} - -// UpdatePeers -- mqtt message handler for /update/peers/ topic -var UpdatePeers mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) { - ncutils.Log("received message to update peers " + string(msg.Payload())) - go func() { - var peerUpdate models.PeerUpdate - err := json.Unmarshal(msg.Payload(), &peerUpdate) - if err != nil { - ncutils.Log("error unmarshalling peer data") - return - } var cfg config.ClientConfig - cfg.Network = peerUpdate.Network + cfg.Network = data.Network cfg.ReadConfig() - peers, err := CalculatePeers(cfg.Node, peerUpdate.Nodes, cfg.Node.IsDualStack, cfg.Node.IsEgressGateway, cfg.Node.IsServer) - if err != nil { - ncutils.Log("error calculating Peers " + err.Error()) - return - } - extpeers, err := CalculateExtPeers(cfg.Node, peerUpdate.ExtPeers) - if err != nil { - ncutils.Log("error updated external wireguard peers " + err.Error()) - } - peers = append(peers, extpeers...) - err = wireguard.UpdateWgPeers(cfg.Node.Interface, peers) - if err != nil { - ncutils.Log("error updating wireguard peers" + err.Error()) + nameserver := cfg.Server.CoreDNSAddr + privateKey, err := wireguard.RetrievePrivKey(data.Network) + if err := wireguard.UpdateWgInterface(cfg.Node.Interface, privateKey, nameserver, data); err != nil { + ncutils.Log("error updating wireguard config " + err.Error()) return } // path hardcoded for now... should be updated @@ -178,29 +110,62 @@ var UpdatePeers mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) }() } -// UpdateKeys -- updates private key and returns new publickey -func UpdateKeys(cfg *config.ClientConfig, client mqtt.Client) (*config.ClientConfig, error) { - ncutils.Log("received message to update keys") +// UpdatePeers -- mqtt message handler for /update/peers/ topic +var UpdatePeers mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) { + ncutils.Log("received message to update peers " + string(msg.Payload())) //potentiall blocking i/o so do this in a go routine - key, err := wgtypes.GeneratePrivateKey() - if err != nil { - ncutils.Log("error generating privatekey " + err.Error()) - return cfg, err - } - if err := wireguard.UpdatePrivateKey(cfg.Node.Interface, key.String()); err != nil { - ncutils.Log("error updating wireguard key " + err.Error()) - return cfg, err - } - publicKey := key.PublicKey() - if token := client.Publish("update/publickey/"+cfg.Node.ID, 0, false, publicKey.String()); token.Wait() && token.Error() != nil { - ncutils.Log("error publishing publickey update " + token.Error().Error()) + go func() { + var peerUpdate models.PeerUpdate + err := json.Unmarshal(msg.Payload(), &peerUpdate) + if err != nil { + ncutils.Log("error unmarshalling peer data") + return + } + var cfg config.ClientConfig + cfg.Network = peerUpdate.Network + cfg.ReadConfig() + err = wireguard.UpdateWgPeers(cfg.Node.Interface, peerUpdate.Peers) + if err != nil { + ncutils.Log("error updating peers" + err.Error()) + return + } + // path hardcoded for now... should be updated + err = wireguard.ApplyWGQuickConf("/etc/netclient/config/" + cfg.Node.Interface + ".conf") + if err != nil { + ncutils.Log("error restarting wg after peer update " + err.Error()) + return + } + }() +} + +// UpdateKeys -- mqtt message handler for /update/keys/ topic +var UpdateKeys mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) { + ncutils.Log("received message to update keys " + string(msg.Payload())) + //potentiall blocking i/o so do this in a go routine + go func() { + var data models.KeyUpdate + if err := json.Unmarshal(msg.Payload(), &data); err != nil { + ncutils.Log("error unmarshalling key update data" + err.Error()) + return + } + var cfg config.ClientConfig + cfg.Network = data.Network + cfg.ReadConfig() + key, err := wgtypes.GeneratePrivateKey() + if err != nil { + ncutils.Log("error generating privatekey " + err.Error()) + return + } + if err := wireguard.UpdatePrivateKey(data.Interface, key.String()); err != nil { + ncutils.Log("error updating wireguard key " + err.Error()) + return + } + publicKey := key.PublicKey() + if token := client.Publish("update/publickey/"+cfg.Node.ID, 0, false, publicKey.String()); token.Wait() && token.Error() != nil { + ncutils.Log("error publishing publickey update " + token.Error().Error()) + } client.Disconnect(250) - return cfg, err - } - if err := config.ModConfig(&cfg.Node); err != nil { - ncutils.Log("error updating local config " + err.Error()) - } - return cfg, nil + }() } // Checkin -- go routine that checks for public or local ip changes, publishes changes @@ -214,11 +179,6 @@ func Checkin(ctx context.Context, cfg config.ClientConfig, network string) { //delay should be configuraable -> use cfg.Node.NetworkSettings.DefaultCheckInInterval ?? case <-time.After(time.Second * 10): ncutils.Log("Checkin running") - //read latest config - cfg.ReadConfig() - //fix NodeID to remove ### so NodeID can be used as message topic - //remove with GRA-73 - cfg.Node.ID = strings.Replace(cfg.Node.ID, "###", "-", 1) if cfg.Node.Roaming == "yes" && cfg.Node.IsStatic != "yes" { extIP, err := ncutils.GetPublicIP() if err != nil { @@ -259,10 +219,6 @@ func UpdateEndpoint(cfg config.ClientConfig, network, ip string) { if token := client.Publish("update/ip/"+cfg.Node.ID, 0, false, ip); token.Wait() && token.Error() != nil { ncutils.Log("error publishing endpoint update " + token.Error().Error()) } - cfg.Node.Endpoint = ip - if err := config.Write(&cfg, cfg.Network); err != nil { - ncutils.Log("error updating local config " + err.Error()) - } client.Disconnect(250) } @@ -273,19 +229,13 @@ func UpdateLocalAddress(cfg config.ClientConfig, network, ip string) { if token := client.Publish("update/localaddress/"+cfg.Node.ID, 0, false, ip); token.Wait() && token.Error() != nil { ncutils.Log("error publishing local address update " + token.Error().Error()) } - cfg.Node.LocalAddress = ip - ncutils.Log("updating local address in local config to: " + cfg.Node.LocalAddress) - if err := config.Write(&cfg, cfg.Network); err != nil { - ncutils.Log("error updating local config " + err.Error()) - } client.Disconnect(250) } // Hello -- ping the broker to let server know node is alive and doing fine func Hello(cfg config.ClientConfig, network string) { client := SetupMQTT(cfg) - ncutils.Log("sending ping " + cfg.Node.ID) - if token := client.Publish("ping/"+cfg.Node.ID, 2, false, "hello world!"); token.Wait() && token.Error() != nil { + if token := client.Publish("ping/"+cfg.Node.ID, 0, false, "hello world!"); token.Wait() && token.Error() != nil { ncutils.Log("error publishing ping " + token.Error().Error()) } client.Disconnect(250)