mirror of
				https://github.com/gravitl/netmaker.git
				synced 2025-10-31 20:22:44 +08:00 
			
		
		
		
	subscribed message handlers implemented
This commit is contained in:
		
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							| @@ -48,4 +48,5 @@ require ( | |||||||
| 	github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect | 	github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect | ||||||
| 	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect | 	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect | ||||||
| 	google.golang.org/appengine v1.4.0 // indirect | 	google.golang.org/appengine v1.4.0 // indirect | ||||||
|  | 	gopkg.in/ini.v1 v1.66.2 // indirect | ||||||
| ) | ) | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								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 h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= | ||||||
| gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= | 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/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.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
| gopkg.in/yaml.v2 v2.2.3/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= | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								models/mqtt.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								models/mqtt.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | package models | ||||||
|  |  | ||||||
|  | import "golang.zx2c4.com/wireguard/wgctrl/wgtypes" | ||||||
|  |  | ||||||
|  | type PeerUpdate struct { | ||||||
|  | 	Network   string | ||||||
|  | 	Interface string | ||||||
|  | 	Peers     []wgtypes.Peer | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type KeyUpdate struct { | ||||||
|  | 	Network   string | ||||||
|  | 	Interface string | ||||||
|  | } | ||||||
| @@ -11,9 +11,12 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	mqtt "github.com/eclipse/paho.mqtt.golang" | 	mqtt "github.com/eclipse/paho.mqtt.golang" | ||||||
|  | 	"github.com/gravitl/netmaker/models" | ||||||
| 	"github.com/gravitl/netmaker/netclient/config" | 	"github.com/gravitl/netmaker/netclient/config" | ||||||
| 	"github.com/gravitl/netmaker/netclient/ncutils" | 	"github.com/gravitl/netmaker/netclient/ncutils" | ||||||
|  | 	"github.com/gravitl/netmaker/netclient/wireguard" | ||||||
| 	"golang.zx2c4.com/wireguard/wgctrl" | 	"golang.zx2c4.com/wireguard/wgctrl" | ||||||
|  | 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Daemon runs netclient daemon from command line | // Daemon runs netclient daemon from command line | ||||||
| @@ -81,16 +84,88 @@ var All mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) { | |||||||
| // NodeUpdate -- mqtt message handler for /update/<NodeID> topic | // NodeUpdate -- mqtt message handler for /update/<NodeID> topic | ||||||
| var NodeUpdate mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) { | var NodeUpdate mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) { | ||||||
| 	ncutils.Log("received message to update node " + string(msg.Payload())) | 	ncutils.Log("received message to update node " + string(msg.Payload())) | ||||||
|  | 	//potentiall blocking i/o so do this in a go routine | ||||||
|  | 	go func() { | ||||||
|  | 		var data models.Node | ||||||
|  | 		err := json.Unmarshal(msg.Payload(), &data) | ||||||
|  | 		if err != nil { | ||||||
|  | 			ncutils.Log("error unmarshalling node update data" + err.Error()) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		var cfg config.ClientConfig | ||||||
|  | 		cfg.Network = data.Network | ||||||
|  | 		cfg.ReadConfig() | ||||||
|  | 		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 | ||||||
|  | 		err = wireguard.ApplyWGQuickConf("/etc/netclient/config/" + cfg.Node.Interface + ".conf") | ||||||
|  | 		if err != nil { | ||||||
|  | 			ncutils.Log("error restarting wg after peer update " + err.Error()) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
| } | } | ||||||
|  |  | ||||||
| // UpdatePeers -- mqtt message handler for /update/peers/<NodeID> topic | // UpdatePeers -- mqtt message handler for /update/peers/<NodeID> topic | ||||||
| var UpdatePeers mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) { | var UpdatePeers mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) { | ||||||
| 	ncutils.Log("received message to update peers " + string(msg.Payload())) | 	ncutils.Log("received message to update peers " + string(msg.Payload())) | ||||||
|  | 	//potentiall blocking i/o so do this in a go routine | ||||||
|  | 	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/<NodeID> topic | // UpdateKeys -- mqtt message handler for /update/keys/<NodeID> topic | ||||||
| var UpdateKeys mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) { | var UpdateKeys mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) { | ||||||
| 	ncutils.Log("received message to update keys " + string(msg.Payload())) | 	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) | ||||||
|  | 	}() | ||||||
| } | } | ||||||
|  |  | ||||||
| // Checkin  -- go routine that checks for public or local ip changes, publishes changes | // Checkin  -- go routine that checks for public or local ip changes, publishes changes | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ import ( | |||||||
| 	"github.com/gravitl/netmaker/netclient/server" | 	"github.com/gravitl/netmaker/netclient/server" | ||||||
| 	"golang.zx2c4.com/wireguard/wgctrl" | 	"golang.zx2c4.com/wireguard/wgctrl" | ||||||
| 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes" | 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes" | ||||||
|  | 	"gopkg.in/ini.v1" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // SetPeers - sets peers on a given WireGuard interface | // SetPeers - sets peers on a given WireGuard interface | ||||||
| @@ -289,3 +290,125 @@ func ApplyConf(node models.Node, ifacename string, confPath string) error { | |||||||
| 	} | 	} | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // WriteWgConfig - creates a wireguard config file | ||||||
|  | func WriteWgConfig(cfg config.ClientConfig, privateKey string, peers []wgtypes.Peer) error { | ||||||
|  | 	options := ini.LoadOptions{ | ||||||
|  | 		AllowNonUniqueSections: true, | ||||||
|  | 		AllowShadows:           true, | ||||||
|  | 	} | ||||||
|  | 	wireguard := ini.Empty(options) | ||||||
|  | 	wireguard.Section("Interface").Key("PrivateKey").SetValue(privateKey) | ||||||
|  | 	wireguard.Section("Interface").Key("ListenPort").SetValue(strconv.Itoa(int(cfg.Node.ListenPort))) | ||||||
|  | 	if cfg.Node.Address != "" { | ||||||
|  | 		wireguard.Section("Interface").Key("Address").SetValue(cfg.Node.Address) | ||||||
|  | 	} | ||||||
|  | 	if cfg.Node.Address6 != "" { | ||||||
|  | 		wireguard.Section("Interface").Key("Address").SetValue(cfg.Node.Address6) | ||||||
|  | 	} | ||||||
|  | 	if cfg.Node.DNSOn == "yes" { | ||||||
|  | 		wireguard.Section("Interface").Key("DNS").SetValue(cfg.Server.CoreDNSAddr) | ||||||
|  | 	} | ||||||
|  | 	if cfg.Node.PostUp != "" { | ||||||
|  | 		wireguard.Section("Interface").Key("PostUp").SetValue(cfg.Node.PostUp) | ||||||
|  | 	} | ||||||
|  | 	if cfg.Node.PostDown != "" { | ||||||
|  | 		wireguard.Section("Interface").Key("PostDown").SetValue(cfg.Node.PostDown) | ||||||
|  | 	} | ||||||
|  | 	for i, peer := range peers { | ||||||
|  | 		wireguard.SectionWithIndex("Peer", i).Key("PublicKey").SetValue(peer.PublicKey.String()) | ||||||
|  | 		if peer.PresharedKey.String() != "" { | ||||||
|  | 			wireguard.SectionWithIndex("Peer", i).Key("PreSharedKey").SetValue(peer.PresharedKey.String()) | ||||||
|  | 		} | ||||||
|  | 		if peer.AllowedIPs != nil { | ||||||
|  | 			var allowedIPs string | ||||||
|  | 			for _, ip := range peer.AllowedIPs { | ||||||
|  | 				allowedIPs = allowedIPs + ", " + ip.String() | ||||||
|  | 			} | ||||||
|  | 			wireguard.SectionWithIndex("Peer", i).Key("AllowedIps").SetValue(allowedIPs) | ||||||
|  | 		} | ||||||
|  | 		if peer.Endpoint != nil { | ||||||
|  | 			wireguard.SectionWithIndex("Peer", i).Key("Endpoint").SetValue(peer.Endpoint.String()) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if err := wireguard.SaveTo("/etc/netclient/config" + cfg.Node.Interface + ".conf"); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // UpdateWgPeers - updates the peers of a network | ||||||
|  | func UpdateWgPeers(wgInterface string, peers []wgtypes.Peer) error { | ||||||
|  | 	//update to get path properly | ||||||
|  | 	file := "/etc/netclient/config/" + wgInterface + ".conf" | ||||||
|  | 	wireguard, err := ini.ShadowLoad(file) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	for i, peer := range peers { | ||||||
|  | 		wireguard.SectionWithIndex("Peer", i).Key("PublicKey").SetValue(peer.PublicKey.String()) | ||||||
|  | 		if peer.PresharedKey.String() != "" { | ||||||
|  | 			wireguard.SectionWithIndex("Peer", i).Key("PreSharedKey").SetValue(peer.PresharedKey.String()) | ||||||
|  | 		} | ||||||
|  | 		if peer.AllowedIPs != nil { | ||||||
|  | 			var allowedIPs string | ||||||
|  | 			for _, ip := range peer.AllowedIPs { | ||||||
|  | 				allowedIPs = allowedIPs + ", " + ip.String() | ||||||
|  | 			} | ||||||
|  | 			wireguard.SectionWithIndex("Peer", i).Key("AllowedIps").SetValue(allowedIPs) | ||||||
|  | 		} | ||||||
|  | 		if peer.Endpoint != nil { | ||||||
|  | 			wireguard.SectionWithIndex("Peer", i).Key("Endpoint").SetValue(peer.Endpoint.String()) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if err := wireguard.SaveTo(file); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // UpdateWgInterface - updates the interface section of a wireguard config file | ||||||
|  | func UpdateWgInterface(wgInterface, privateKey, nameserver string, node models.Node) error { | ||||||
|  | 	//update to get path properly | ||||||
|  | 	file := "/etc/netclient/config/" + wgInterface + ".conf" | ||||||
|  | 	wireguard, err := ini.ShadowLoad(file) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	wireguard.Section("Interface").Key("PrivateKey").SetValue(privateKey) | ||||||
|  | 	wireguard.Section("Interface").Key("ListenPort").SetValue(strconv.Itoa(int(node.ListenPort))) | ||||||
|  | 	if node.Address != "" { | ||||||
|  | 		wireguard.Section("Interface").Key("Address").SetValue(node.Address) | ||||||
|  | 	} | ||||||
|  | 	if node.Address6 != "" { | ||||||
|  | 		wireguard.Section("Interface").Key("Address").SetValue(node.Address6) | ||||||
|  | 	} | ||||||
|  | 	if node.DNSOn == "yes" { | ||||||
|  | 		wireguard.Section("Interface").Key("DNS").SetValue(nameserver) | ||||||
|  | 	} | ||||||
|  | 	if node.PostUp != "" { | ||||||
|  | 		wireguard.Section("Interface").Key("PostUp").SetValue(node.PostUp) | ||||||
|  | 	} | ||||||
|  | 	if node.PostDown != "" { | ||||||
|  | 		wireguard.Section("Interface").Key("PostDown").SetValue(node.PostDown) | ||||||
|  | 	} | ||||||
|  | 	if err := wireguard.SaveTo(file); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // UpdatePrivateKey - updates the private key of a wireguard config file | ||||||
|  | func UpdatePrivateKey(wgInterface, privateKey string) error { | ||||||
|  | 	//update to get path properly | ||||||
|  | 	file := "/etc/netclient/config/" + wgInterface + ".conf" | ||||||
|  | 	wireguard, err := ini.ShadowLoad(file) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	wireguard.Section("Interface").Key("PrivateKey").SetValue(privateKey) | ||||||
|  | 	if err := wireguard.SaveTo(file); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Matthew R Kasun
					Matthew R Kasun