mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-26 01:53:42 +01:00
HA Network Routes: prevent routing directly-accessible networks through VPN interface (#612)
Prevent routing peer to add routes from the same HA group as client routes
This commit is contained in:
parent
0be46c083d
commit
1204bbd54a
@ -3,12 +3,13 @@ package routemanager
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/client/internal/peer"
|
"github.com/netbirdio/netbird/client/internal/peer"
|
||||||
"github.com/netbirdio/netbird/client/status"
|
"github.com/netbirdio/netbird/client/status"
|
||||||
"github.com/netbirdio/netbird/iface"
|
"github.com/netbirdio/netbird/iface"
|
||||||
"github.com/netbirdio/netbird/route"
|
"github.com/netbirdio/netbird/route"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"net/netip"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type routerPeerStatus struct {
|
type routerPeerStatus struct {
|
||||||
@ -52,7 +53,7 @@ func newClientNetworkWatcher(ctx context.Context, wgInterface *iface.WGIface, st
|
|||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
func getClientNetworkID(input *route.Route) string {
|
func getHANetworkID(input *route.Route) string {
|
||||||
return input.NetID + "-" + input.Network.String()
|
return input.NetID + "-" + input.Network.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,13 +3,14 @@ package routemanager
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/client/status"
|
"github.com/netbirdio/netbird/client/status"
|
||||||
"github.com/netbirdio/netbird/client/system"
|
"github.com/netbirdio/netbird/client/system"
|
||||||
"github.com/netbirdio/netbird/iface"
|
"github.com/netbirdio/netbird/iface"
|
||||||
"github.com/netbirdio/netbird/route"
|
"github.com/netbirdio/netbird/route"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"runtime"
|
|
||||||
"sync"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Manager is a route manager interface
|
// Manager is a route manager interface
|
||||||
@ -147,16 +148,24 @@ func (m *DefaultManager) UpdateRoutes(updateSerial uint64, newRoutes []*route.Ro
|
|||||||
|
|
||||||
newClientRoutesIDMap := make(map[string][]*route.Route)
|
newClientRoutesIDMap := make(map[string][]*route.Route)
|
||||||
newServerRoutesMap := make(map[string]*route.Route)
|
newServerRoutesMap := make(map[string]*route.Route)
|
||||||
|
ownNetworkIDs := make(map[string]bool)
|
||||||
|
|
||||||
for _, newRoute := range newRoutes {
|
for _, newRoute := range newRoutes {
|
||||||
// only linux is supported for now
|
networkID := getHANetworkID(newRoute)
|
||||||
if newRoute.Peer == m.pubKey {
|
if newRoute.Peer == m.pubKey {
|
||||||
|
ownNetworkIDs[networkID] = true
|
||||||
|
// only linux is supported for now
|
||||||
if runtime.GOOS != "linux" {
|
if runtime.GOOS != "linux" {
|
||||||
log.Warnf("received a route to manage, but agent doesn't support router mode on %s OS", runtime.GOOS)
|
log.Warnf("received a route to manage, but agent doesn't support router mode on %s OS", runtime.GOOS)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
newServerRoutesMap[newRoute.ID] = newRoute
|
newServerRoutesMap[newRoute.ID] = newRoute
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, newRoute := range newRoutes {
|
||||||
|
networkID := getHANetworkID(newRoute)
|
||||||
|
if !ownNetworkIDs[networkID] {
|
||||||
// if prefix is too small, lets assume is a possible default route which is not yet supported
|
// if prefix is too small, lets assume is a possible default route which is not yet supported
|
||||||
// we skip this route management
|
// we skip this route management
|
||||||
if newRoute.Network.Bits() < 7 {
|
if newRoute.Network.Bits() < 7 {
|
||||||
@ -164,8 +173,7 @@ func (m *DefaultManager) UpdateRoutes(updateSerial uint64, newRoutes []*route.Ro
|
|||||||
system.NetbirdVersion(), newRoute.Network)
|
system.NetbirdVersion(), newRoute.Network)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
clientNetworkID := getClientNetworkID(newRoute)
|
newClientRoutesIDMap[networkID] = append(newClientRoutesIDMap[networkID], newRoute)
|
||||||
newClientRoutesIDMap[clientNetworkID] = append(newClientRoutesIDMap[clientNetworkID], newRoute)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,13 +3,14 @@ package routemanager
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/netip"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/client/status"
|
"github.com/netbirdio/netbird/client/status"
|
||||||
"github.com/netbirdio/netbird/iface"
|
"github.com/netbirdio/netbird/iface"
|
||||||
"github.com/netbirdio/netbird/route"
|
"github.com/netbirdio/netbird/route"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"net/netip"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// send 5 routes, one for server and 4 for clients, one normal and 2 HA and one small
|
// send 5 routes, one for server and 4 for clients, one normal and 2 HA and one small
|
||||||
@ -336,6 +337,55 @@ func TestManagerUpdateRoutes(t *testing.T) {
|
|||||||
serverRoutesExpected: 0,
|
serverRoutesExpected: 0,
|
||||||
clientNetworkWatchersExpected: 0,
|
clientNetworkWatchersExpected: 0,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "HA server should not register routes from the same HA group",
|
||||||
|
inputRoutes: []*route.Route{
|
||||||
|
{
|
||||||
|
ID: "l1",
|
||||||
|
NetID: "routeA",
|
||||||
|
Peer: localPeerKey,
|
||||||
|
Network: netip.MustParsePrefix("100.64.251.250/30"),
|
||||||
|
NetworkType: route.IPv4Network,
|
||||||
|
Metric: 9999,
|
||||||
|
Masquerade: false,
|
||||||
|
Enabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "l2",
|
||||||
|
NetID: "routeA",
|
||||||
|
Peer: localPeerKey,
|
||||||
|
Network: netip.MustParsePrefix("8.8.9.8/32"),
|
||||||
|
NetworkType: route.IPv4Network,
|
||||||
|
Metric: 9999,
|
||||||
|
Masquerade: false,
|
||||||
|
Enabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "r1",
|
||||||
|
NetID: "routeA",
|
||||||
|
Peer: remotePeerKey1,
|
||||||
|
Network: netip.MustParsePrefix("100.64.251.250/30"),
|
||||||
|
NetworkType: route.IPv4Network,
|
||||||
|
Metric: 9999,
|
||||||
|
Masquerade: false,
|
||||||
|
Enabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "r2",
|
||||||
|
NetID: "routeC",
|
||||||
|
Peer: remotePeerKey1,
|
||||||
|
Network: netip.MustParsePrefix("8.8.9.9/32"),
|
||||||
|
NetworkType: route.IPv4Network,
|
||||||
|
Metric: 9999,
|
||||||
|
Masquerade: false,
|
||||||
|
Enabled: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
inputSerial: 1,
|
||||||
|
shouldCheckServerRoutes: runtime.GOOS == "linux",
|
||||||
|
serverRoutesExpected: 2,
|
||||||
|
clientNetworkWatchersExpected: 1,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for n, testCase := range testCases {
|
for n, testCase := range testCases {
|
||||||
|
Loading…
Reference in New Issue
Block a user