adding gateway routes for peers

This commit is contained in:
afeiszli 2022-08-22 16:44:04 -04:00
parent ec40ea78d3
commit 4d9a07bf00
7 changed files with 159 additions and 7 deletions

View file

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

View file

@ -12,6 +12,17 @@ import (
// SetPeerRoutes - sets/removes ip routes for each peer on a network
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
for _, peer := range newPeers {
for _, allowedIP := range peer.AllowedIPs {
@ -23,6 +34,13 @@ func SetPeerRoutes(iface string, oldPeers map[string]bool, newPeers []wgtypes.Pe
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
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
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 _, allowedIP := range peer.AllowedIPs {
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
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 _, allowedIP := range peer.AllowedIPs {
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)
}
}
}

View file

@ -9,6 +9,44 @@ import (
"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
// 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 {

View file

@ -8,6 +8,32 @@ import (
"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 {
var err error
_, _ = ncutils.RunCmd("route add -net "+addr.String()+" -interface "+iface, false)

View file

@ -12,6 +12,30 @@ import (
"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 {
out, err := ncutils.RunCmd(fmt.Sprintf("ip route get %s", addr.IP.String()), false)
if err != nil || !strings.Contains(out, iface) {

View file

@ -7,6 +7,15 @@ import (
"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 {
var err error
_, err = ncutils.RunCmd("route ADD "+addr.String()+" "+address, false)

View file

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