Browse Source

adding gateway routes for peers

afeiszli 3 years ago
parent
commit
4d9a07bf00

+ 4 - 7
controllers/ipservice.go

@@ -7,6 +7,7 @@ import (
 	"strings"
 	"strings"
 
 
 	"github.com/gorilla/mux"
 	"github.com/gorilla/mux"
+	"github.com/gravitl/netmaker/netclient/ncutils"
 )
 )
 
 
 func ipHandlers(r *mux.Router) {
 func ipHandlers(r *mux.Router) {
@@ -38,7 +39,7 @@ func parseIP(r *http.Request) (string, error) {
 	// Get Public IP from header
 	// Get Public IP from header
 	ip := r.Header.Get("X-REAL-IP")
 	ip := r.Header.Get("X-REAL-IP")
 	ipnet := net.ParseIP(ip)
 	ipnet := net.ParseIP(ip)
-	if ipnet != nil && !ipIsPrivate(ipnet) {
+	if ipnet != nil && !ncutils.IpIsPrivate(ipnet) {
 		return ip, nil
 		return ip, nil
 	}
 	}
 
 
@@ -47,7 +48,7 @@ func parseIP(r *http.Request) (string, error) {
 	iplist := strings.Split(forwardips, ",")
 	iplist := strings.Split(forwardips, ",")
 	for _, ip := range iplist {
 	for _, ip := range iplist {
 		ipnet := net.ParseIP(ip)
 		ipnet := net.ParseIP(ip)
-		if ipnet != nil && !ipIsPrivate(ipnet) {
+		if ipnet != nil && !ncutils.IpIsPrivate(ipnet) {
 			return ip, nil
 			return ip, nil
 		}
 		}
 	}
 	}
@@ -59,14 +60,10 @@ func parseIP(r *http.Request) (string, error) {
 	}
 	}
 	ipnet = net.ParseIP(ip)
 	ipnet = net.ParseIP(ip)
 	if ipnet != nil {
 	if ipnet != nil {
-		if ipIsPrivate(ipnet) {
+		if ncutils.IpIsPrivate(ipnet) {
 			return ip, fmt.Errorf("ip is a private address")
 			return ip, fmt.Errorf("ip is a private address")
 		}
 		}
 		return ip, nil
 		return ip, nil
 	}
 	}
 	return "", fmt.Errorf("no ip found")
 	return "", fmt.Errorf("no ip found")
 }
 }
-
-func ipIsPrivate(ipnet net.IP) bool {
-	return ipnet.IsPrivate() || ipnet.IsLoopback()
-}

+ 54 - 0
netclient/local/routes.go

@@ -12,6 +12,17 @@ import (
 
 
 // SetPeerRoutes - sets/removes ip routes for each peer on a network
 // SetPeerRoutes - sets/removes ip routes for each peer on a network
 func SetPeerRoutes(iface string, oldPeers map[string]bool, newPeers []wgtypes.PeerConfig) {
 func SetPeerRoutes(iface string, oldPeers map[string]bool, newPeers []wgtypes.PeerConfig) {
+
+	// get the default route
+	var hasRoute bool
+	gwIP, gwIface, err := GetDefaultRoute()
+	if err != nil {
+		logger.Log(0, "error getting default route:", err.Error())
+	}
+	if gwIP != "" && gwIface != "" && err == nil {
+		hasRoute = true
+	}
+
 	// traverse through all recieved peers
 	// traverse through all recieved peers
 	for _, peer := range newPeers {
 	for _, peer := range newPeers {
 		for _, allowedIP := range peer.AllowedIPs {
 		for _, allowedIP := range peer.AllowedIPs {
@@ -23,6 +34,13 @@ func SetPeerRoutes(iface string, oldPeers map[string]bool, newPeers []wgtypes.Pe
 				delete(oldPeers, allowedIP.String())
 				delete(oldPeers, allowedIP.String())
 			}
 			}
 		}
 		}
+		if hasRoute && !ncutils.IpIsPrivate(peer.Endpoint.IP) {
+			ipNet, err := ncutils.GetIPNetFromString(peer.Endpoint.IP.String())
+			if err != nil {
+				logger.Log(0, "error parsing ip:", err.Error())
+			}
+			setRoute(gwIface, &ipNet, gwIP)
+		}
 	}
 	}
 	// traverse through all remaining existing peers
 	// traverse through all remaining existing peers
 	for i := range oldPeers {
 	for i := range oldPeers {
@@ -37,19 +55,55 @@ func SetPeerRoutes(iface string, oldPeers map[string]bool, newPeers []wgtypes.Pe
 
 
 // SetCurrentPeerRoutes - sets all the current peers
 // SetCurrentPeerRoutes - sets all the current peers
 func SetCurrentPeerRoutes(iface, currentAddr string, peers []wgtypes.PeerConfig) {
 func SetCurrentPeerRoutes(iface, currentAddr string, peers []wgtypes.PeerConfig) {
+
+	// get the default route
+	var hasRoute bool
+	gwIP, gwIface, err := GetDefaultRoute()
+	if err != nil {
+		logger.Log(0, "error getting default route:", err.Error())
+	}
+	if gwIP != "" && gwIface != "" && err == nil {
+		hasRoute = true
+	}
+
+	// traverse through all recieved peers
 	for _, peer := range peers {
 	for _, peer := range peers {
 		for _, allowedIP := range peer.AllowedIPs {
 		for _, allowedIP := range peer.AllowedIPs {
 			setRoute(iface, &allowedIP, currentAddr)
 			setRoute(iface, &allowedIP, currentAddr)
 		}
 		}
+		if hasRoute && !ncutils.IpIsPrivate(peer.Endpoint.IP) {
+			ipNet, err := ncutils.GetIPNetFromString(peer.Endpoint.IP.String())
+			if err != nil {
+				logger.Log(0, "error parsing ip:", err.Error())
+			}
+			setRoute(gwIface, &ipNet, gwIP)
+		}
 	}
 	}
 }
 }
 
 
 // FlushPeerRoutes - removes all current peer routes
 // FlushPeerRoutes - removes all current peer routes
 func FlushPeerRoutes(iface, currentAddr string, peers []wgtypes.Peer) {
 func FlushPeerRoutes(iface, currentAddr string, peers []wgtypes.Peer) {
+	// get the default route
+	var hasRoute bool
+	gwIP, gwIface, err := GetDefaultRoute()
+	if err != nil {
+		logger.Log(0, "error getting default route:", err.Error())
+	}
+	if gwIP != "" && gwIface != "" && err == nil {
+		hasRoute = true
+	}
+
 	for _, peer := range peers {
 	for _, peer := range peers {
 		for _, allowedIP := range peer.AllowedIPs {
 		for _, allowedIP := range peer.AllowedIPs {
 			deleteRoute(iface, &allowedIP, currentAddr)
 			deleteRoute(iface, &allowedIP, currentAddr)
 		}
 		}
+		if hasRoute && !ncutils.IpIsPrivate(peer.Endpoint.IP) {
+			ipNet, err := ncutils.GetIPNetFromString(peer.Endpoint.IP.String())
+			if err != nil {
+				logger.Log(0, "error parsing ip:", err.Error())
+			}
+			deleteRoute(gwIface, &ipNet, gwIP)
+		}
 	}
 	}
 }
 }
 
 

+ 38 - 0
netclient/local/routes_darwin.go

@@ -9,6 +9,44 @@ import (
 	"github.com/gravitl/netmaker/netclient/ncutils"
 	"github.com/gravitl/netmaker/netclient/ncutils"
 )
 )
 
 
+// GetDefaultRoute - Gets the default route (ip and interface) on a mac machine
+func GetDefaultRoute() (string, string, error) {
+	var ipaddr string
+	var iface string
+	var err error
+	var outLine string
+	output, err := ncutils.RunCmd("netstat -nr", false)
+	for _, line := range strings.Split(strings.TrimSuffix(output, "\n"), "\n") {
+		if strings.Contains(line, "default") {
+			outLine = line
+			break
+		}
+	}
+	space := regexp.MustCompile(`\s+`)
+	outFormatted := space.ReplaceAllString(outLine, " ")
+	if err != nil {
+		return ipaddr, iface, err
+	}
+	outputSlice := strings.Split(string(outFormatted), " ")
+	if !strings.Contains(outputSlice[0], "default") {
+		return ipaddr, iface, fmt.Errorf("could not find default gateway")
+	}
+	ipaddr = outputSlice[1]
+	if err = checkIPAddress(ipaddr); err != nil {
+		return ipaddr, iface, err
+	}
+	iface = outputSlice[3]
+
+	return ipaddr, iface, err
+}
+
+func checkIPAddress(ip string) error {
+	if net.ParseIP(ip) == nil {
+		return fmt.Errorf("IP Address: %s - Invalid", ip)
+	}
+	return nil
+}
+
 // route -n add -net 10.0.0.0/8 192.168.0.254
 // route -n add -net 10.0.0.0/8 192.168.0.254
 // networksetup -setadditionalroutes Ethernet 192.168.1.0 255.255.255.0 10.0.0.2 persistent
 // networksetup -setadditionalroutes Ethernet 192.168.1.0 255.255.255.0 10.0.0.2 persistent
 func setRoute(iface string, addr *net.IPNet, address string) error {
 func setRoute(iface string, addr *net.IPNet, address string) error {

+ 26 - 0
netclient/local/routes_freebsd.go

@@ -8,6 +8,32 @@ import (
 	"github.com/gravitl/netmaker/netclient/ncutils"
 	"github.com/gravitl/netmaker/netclient/ncutils"
 )
 )
 
 
+// GetDefaultRoute - Gets the default route (ip and interface) on a freebsd machine
+func GetDefaultRoute() (string, string, error) {
+	var ipaddr string
+	var iface string
+	var err error
+
+	output, err := ncutils.RunCmd("route show default", true)
+	if err != nil {
+		return ipaddr, iface, err
+	}
+	outFormatted := strings.ReplaceAll(output, "\n", "")
+	if !strings.Contains(outFormatted, "default") && !strings.Contains(outFormatted, "interface:") {
+		return ipaddr, iface, fmt.Errorf("could not find default gateway")
+	}
+	outputSlice := strings.Split(string(outFormatted), " ")
+	for i, outString := range outputSlice {
+		if outString == "gateway:" {
+			ipaddr = outputSlice[i+1]
+		}
+		if outString == "interface:" {
+			iface = outputSlice[i+1]
+		}
+	}
+	return ipaddr, iface, err
+}
+
 func setRoute(iface string, addr *net.IPNet, address string) error {
 func setRoute(iface string, addr *net.IPNet, address string) error {
 	var err error
 	var err error
 	_, _ = ncutils.RunCmd("route add -net "+addr.String()+" -interface "+iface, false)
 	_, _ = ncutils.RunCmd("route add -net "+addr.String()+" -interface "+iface, false)

+ 24 - 0
netclient/local/routes_linux.go

@@ -12,6 +12,30 @@ import (
 	"github.com/gravitl/netmaker/netclient/ncutils"
 	"github.com/gravitl/netmaker/netclient/ncutils"
 )
 )
 
 
+// GetDefaultRoute - Gets the default route (ip and interface) on a linux machine
+func GetDefaultRoute() (string, string, error) {
+	var ipaddr string
+	var iface string
+	var err error
+	output, err := ncutils.RunCmd("ip route show default", false)
+	if err != nil {
+		return ipaddr, iface, err
+	}
+	outputSlice := strings.Split(output, " ")
+	if !strings.Contains(outputSlice[0], "default") {
+		return ipaddr, iface, fmt.Errorf("could not find default gateway")
+	}
+	for i, outString := range outputSlice {
+		if outString == "via" {
+			ipaddr = outputSlice[i+1]
+		}
+		if outString == "dev" {
+			iface = outputSlice[i+1]
+		}
+	}
+	return ipaddr, iface, err
+}
+
 func setRoute(iface string, addr *net.IPNet, address string) error {
 func setRoute(iface string, addr *net.IPNet, address string) error {
 	out, err := ncutils.RunCmd(fmt.Sprintf("ip route get %s", addr.IP.String()), false)
 	out, err := ncutils.RunCmd(fmt.Sprintf("ip route get %s", addr.IP.String()), false)
 	if err != nil || !strings.Contains(out, iface) {
 	if err != nil || !strings.Contains(out, iface) {

+ 9 - 0
netclient/local/routes_windows.go

@@ -7,6 +7,15 @@ import (
 	"github.com/gravitl/netmaker/netclient/ncutils"
 	"github.com/gravitl/netmaker/netclient/ncutils"
 )
 )
 
 
+// GetDefaultRoute - Gets the default route (ip and interface) on a linux machine
+func GetDefaultRoute() (string, string, error) {
+	var ipaddr string
+	var iface string
+	var err error
+
+	return ipaddr, iface, fmt.Errorf("not written yet on windows")
+}
+
 func setRoute(iface string, addr *net.IPNet, address string) error {
 func setRoute(iface string, addr *net.IPNet, address string) error {
 	var err error
 	var err error
 	_, err = ncutils.RunCmd("route ADD "+addr.String()+" "+address, false)
 	_, err = ncutils.RunCmd("route ADD "+addr.String()+" "+address, false)

+ 4 - 0
netclient/ncutils/iface.go

@@ -90,3 +90,7 @@ func IfaceExists(ifacename string) bool {
 	}
 	}
 	return false
 	return false
 }
 }
+
+func IpIsPrivate(ipnet net.IP) bool {
+	return ipnet.IsPrivate() || ipnet.IsLoopback()
+}