mirror of
https://github.com/gravitl/netmaker.git
synced 2025-02-25 08:34:47 +08:00
transplanted setwgconfig and pull
This commit is contained in:
parent
3f2e4ab764
commit
340f50c535
6 changed files with 249 additions and 55 deletions
|
@ -2,8 +2,11 @@ package logic
|
|||
|
||||
import (
|
||||
"net"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
)
|
||||
|
||||
// GetLocalIP - gets the local ip
|
||||
|
@ -61,3 +64,50 @@ func GetLocalIP(node models.Node) string {
|
|||
}
|
||||
return local
|
||||
}
|
||||
|
||||
// == Private ==
|
||||
|
||||
func deleteInterface(ifacename string, postdown string) error {
|
||||
var err error
|
||||
if !ncutils.IsKernel() {
|
||||
err = RemoveConf(ifacename, true)
|
||||
} else {
|
||||
ipExec, errN := exec.LookPath("ip")
|
||||
err = errN
|
||||
if err != nil {
|
||||
ncutils.PrintLog(err.Error(), 1)
|
||||
}
|
||||
_, err = ncutils.RunCmd(ipExec+" link del "+ifacename, false)
|
||||
if postdown != "" {
|
||||
runcmds := strings.Split(postdown, "; ")
|
||||
err = ncutils.RunCmds(runcmds, true)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func isInterfacePresent(iface string, address string) (string, bool) {
|
||||
var interfaces []net.Interface
|
||||
var err error
|
||||
interfaces, err = net.Interfaces()
|
||||
if err != nil {
|
||||
Log("ERROR: could not read interfaces", 0)
|
||||
return "", true
|
||||
}
|
||||
for _, currIface := range interfaces {
|
||||
var currAddrs []net.Addr
|
||||
currAddrs, err = currIface.Addrs()
|
||||
if err != nil || len(currAddrs) == 0 {
|
||||
continue
|
||||
}
|
||||
for _, addr := range currAddrs {
|
||||
Log("looking at addresses "+addr.String()+" compared to "+address, 0)
|
||||
if addr.String() == address && currIface.Name != iface {
|
||||
Log("found it", 0)
|
||||
// return old iface and false
|
||||
return currIface.Name, false
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", true
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"errors"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -35,7 +36,7 @@ func ServerJoin(cfg config.ClientConfig, privateKey string) error {
|
|||
cfg.Node.Endpoint, err = ncutils.GetPublicIP()
|
||||
}
|
||||
if err != nil || cfg.Node.Endpoint == "" {
|
||||
ncutils.Log("Error setting cfg.Node.Endpoint.")
|
||||
Log("Error setting cfg.Node.Endpoint.", 0)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -117,9 +118,9 @@ func ServerJoin(cfg config.ClientConfig, privateKey string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
peers, hasGateway, gateways, err := GetServerPeers(node.MacAddress, cfg.Network, cfg.Server.GRPCAddress, node.IsDualStack == "yes", node.IsIngressGateway == "yes", node.IsServer == "yes")
|
||||
peers, hasGateway, gateways, err := GetServerPeers(node.MacAddress, cfg.Network, node.IsDualStack == "yes", node.IsIngressGateway == "yes")
|
||||
if err != nil && !ncutils.IsEmptyRecord(err) {
|
||||
ncutils.Log("failed to retrieve peers")
|
||||
Log("failed to retrieve peers", 1)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -131,22 +132,84 @@ func ServerJoin(cfg config.ClientConfig, privateKey string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ServerPull - pulls current config/peers for server
|
||||
func ServerPull(mac string, network string) error {
|
||||
|
||||
var serverNode models.Node
|
||||
var err error
|
||||
serverNode, err = GetNode(mac, network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if serverNode.IPForwarding == "yes" {
|
||||
if err = setIPForwardingLinux(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
serverNode.OS = runtime.GOOS
|
||||
|
||||
if serverNode.PullChanges == "yes" {
|
||||
// check for interface change
|
||||
var isIfacePresent bool
|
||||
var oldIfaceName string
|
||||
// checks if address is in use by another interface
|
||||
oldIfaceName, isIfacePresent = isInterfacePresent(serverNode.Interface, serverNode.Address)
|
||||
if !isIfacePresent {
|
||||
if err = deleteInterface(oldIfaceName, serverNode.PostDown); err != nil {
|
||||
Log("could not delete old interface "+oldIfaceName, 1)
|
||||
}
|
||||
}
|
||||
serverNode.PullChanges = "no"
|
||||
if err = setWGConfig(serverNode, network, false); err != nil {
|
||||
return err
|
||||
}
|
||||
// handle server side update
|
||||
if err = serverNode.Update(&serverNode); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err = setWGConfig(serverNode, network, true); err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return ServerPull(serverNode.MacAddress, serverNode.Network)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ServerPush - pushes config changes for server checkins/join
|
||||
func ServerPush(mac string, network string) error {
|
||||
|
||||
var serverNode models.Node
|
||||
var err error
|
||||
serverNode, err = GetNode(mac, network)
|
||||
if err != nil && !ncutils.IsEmptyRecord(err) {
|
||||
if err != nil /* && !ncutils.IsEmptyRecord(err) May not be necessary */ {
|
||||
return err
|
||||
}
|
||||
serverNode.OS = runtime.GOOS
|
||||
serverNode.SetLastCheckIn()
|
||||
err = serverNode.Update(&serverNode)
|
||||
return err
|
||||
return serverNode.Update(&serverNode)
|
||||
}
|
||||
|
||||
func GetServerPeers(macaddress string, network string, server string, dualstack bool, isIngressGateway bool, isServer bool) ([]wgtypes.PeerConfig, bool, []string, error) {
|
||||
// ServerLeave - removes a server node
|
||||
func ServerLeave(mac string, network string) error {
|
||||
|
||||
var serverNode models.Node
|
||||
var err error
|
||||
serverNode, err = GetNode(mac, network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
serverNode.SetID()
|
||||
return DeleteNode(serverNode.ID, true)
|
||||
}
|
||||
|
||||
// GetServerPeers - gets peers of server
|
||||
func GetServerPeers(macaddress string, network string, dualstack bool, isIngressGateway bool) ([]wgtypes.PeerConfig, bool, []string, error) {
|
||||
hasGateway := false
|
||||
var err error
|
||||
var gateways []string
|
||||
|
@ -277,7 +340,7 @@ func GetServerPeers(macaddress string, network string, server string, dualstack
|
|||
peers = append(peers, peer)
|
||||
}
|
||||
if isIngressGateway {
|
||||
extPeers, err := GetServerExtPeers(macaddress, network, server, dualstack)
|
||||
extPeers, err := GetServerExtPeers(macaddress, network, dualstack)
|
||||
if err == nil {
|
||||
peers = append(peers, extPeers...)
|
||||
} else {
|
||||
|
@ -288,7 +351,7 @@ func GetServerPeers(macaddress string, network string, server string, dualstack
|
|||
}
|
||||
|
||||
// GetServerExtPeers - gets the extpeers for a client
|
||||
func GetServerExtPeers(macaddress string, network string, server string, dualstack bool) ([]wgtypes.PeerConfig, error) {
|
||||
func GetServerExtPeers(macaddress string, network string, dualstack bool) ([]wgtypes.PeerConfig, error) {
|
||||
var peers []wgtypes.PeerConfig
|
||||
var nodecfg models.Node
|
||||
var extPeers []models.Node
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/gravitl/netmaker/dnslogic"
|
||||
"github.com/gravitl/netmaker/functions"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/relay"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
@ -296,6 +297,26 @@ func setPeerInfo(node models.Node) models.Node {
|
|||
func Log(message string, loglevel int) {
|
||||
log.SetFlags(log.Flags() &^ (log.Llongfile | log.Lshortfile))
|
||||
if int32(loglevel) <= servercfg.GetVerbose() && servercfg.GetVerbose() != 0 {
|
||||
log.Println(message)
|
||||
log.Println("[netmaker] " + message)
|
||||
}
|
||||
}
|
||||
|
||||
// == Private Methods ==
|
||||
|
||||
func setIPForwardingLinux() error {
|
||||
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 = 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
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/local"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"golang.zx2c4.com/wireguard/wgctrl"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
|
@ -38,6 +37,27 @@ func GetSystemPeers(node *models.Node) (map[string]string, error) {
|
|||
return peers, nil
|
||||
}
|
||||
|
||||
func setWGConfig(node models.Node, network string, peerupdate bool) error {
|
||||
|
||||
node.SetID()
|
||||
peers, hasGateway, gateways, err := GetServerPeers(node.MacAddress, node.Network, node.IsDualStack == "yes", node.IsIngressGateway == "yes")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
privkey, err := FetchPrivKey(node.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if peerupdate {
|
||||
var iface string
|
||||
iface = node.Interface
|
||||
err = setServerPeers(iface, node.PersistentKeepalive, peers)
|
||||
} else {
|
||||
err = initWireguard(&node, privkey, peers, hasGateway, gateways)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func initWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig, hasGateway bool, gateways []string) error {
|
||||
|
||||
key, err := wgtypes.ParseKey(privkey)
|
||||
|
@ -90,12 +110,7 @@ func initWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
|
|||
}
|
||||
// spin up userspace + apply the conf file
|
||||
var deviceiface string
|
||||
if ncutils.IsMac() {
|
||||
deviceiface, err = local.GetMacIface(node.Address)
|
||||
if err != nil || deviceiface == "" {
|
||||
deviceiface = ifacename
|
||||
}
|
||||
}
|
||||
deviceiface = ifacename
|
||||
d, _ := wgclient.Device(deviceiface)
|
||||
for d != nil && d.Name == deviceiface {
|
||||
_ = RemoveConf(ifacename, false) // remove interface first
|
||||
|
@ -104,7 +119,7 @@ func initWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
|
|||
}
|
||||
err = applyWGQuickConf(confPath)
|
||||
if err != nil {
|
||||
ncutils.PrintLog("failed to create wireguard interface", 1)
|
||||
Log("failed to create wireguard interface", 1)
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
|
@ -202,3 +217,77 @@ func removeWGQuickConf(confPath string, printlog bool) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setServerPeers(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
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"strings"
|
||||
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/auth"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
|
@ -197,11 +196,6 @@ func Pull(network string, manual bool) (*models.Node, error) {
|
|||
if err = json.Unmarshal([]byte(readres.Data), &resNode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else { // handle server side read
|
||||
resNode, err = logic.GetNode(node.MacAddress, node.Network)
|
||||
if err != nil && !ncutils.IsEmptyRecord(err) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// ensure that the OS never changes
|
||||
resNode.OS = runtime.GOOS
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
nccommand "github.com/gravitl/netmaker/netclient/command"
|
||||
"github.com/gravitl/netmaker/netclient/config"
|
||||
|
@ -31,30 +32,6 @@ func GetServerWGConf() (models.IntClient, error) {
|
|||
return models.IntClient{}, errors.New("could not find comms server")
|
||||
}
|
||||
|
||||
// InstallNetclient netclient installation for server - depricated
|
||||
func InstallNetclient() error {
|
||||
|
||||
netclientPath := ncutils.GetNetclientPath()
|
||||
if ncutils.IsWindows() {
|
||||
netclientPath += "\\"
|
||||
} else {
|
||||
netclientPath += "/"
|
||||
}
|
||||
if !FileExists(netclientPath + "netclient") {
|
||||
var err error
|
||||
if ncutils.IsWindows() {
|
||||
_, err = copy(".\\netclient\\netclient", netclientPath+"netclient")
|
||||
} else {
|
||||
_, err = copy("./netclient/netclient", netclientPath+"netclient")
|
||||
}
|
||||
if err != nil {
|
||||
log.Println("could not create " + netclientPath + "netclient")
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// FileExists - checks if local file exists
|
||||
func FileExists(f string) bool {
|
||||
info, err := os.Stat(f)
|
||||
|
@ -95,7 +72,7 @@ func copy(src, dst string) (int64, error) {
|
|||
|
||||
// RemoveNetwork - removes a network locally on server
|
||||
func RemoveNetwork(network string) (bool, error) {
|
||||
err := nccommand.Leave(config.ClientConfig{Network: network})
|
||||
err := logic.ServerLeave(servercfg.GetNodeID(), network)
|
||||
return true, err
|
||||
}
|
||||
|
||||
|
@ -188,15 +165,15 @@ func SyncNetworks(servernets []models.Network) error {
|
|||
|
||||
// AddNetwork - add a network to server in client mode
|
||||
func AddNetwork(network string) (bool, error) {
|
||||
err := nccommand.Join(config.ClientConfig{
|
||||
err := logic.ServerJoin(config.ClientConfig{
|
||||
Network: network,
|
||||
Daemon: "off",
|
||||
Node: models.Node{
|
||||
Network: network,
|
||||
IsServer: "yes",
|
||||
DNSOn: "no",
|
||||
Name: models.NODE_SERVER_NAME,
|
||||
MacAddress: servercfg.GetNodeID(),
|
||||
Network: network,
|
||||
IsServer: "yes",
|
||||
DNSOn: "no",
|
||||
Name: models.NODE_SERVER_NAME,
|
||||
MacAddress: servercfg.GetNodeID(),
|
||||
},
|
||||
}, "")
|
||||
log.Println("[netmaker] Server added to network " + network)
|
||||
|
|
Loading…
Reference in a new issue