Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate network maps for routed network #2068

Merged
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
574dc50
extends route with access control groups
bcmmbaga May 21, 2024
d6ab64c
add support for creating and updating routes with access control groups
bcmmbaga May 21, 2024
00fd7d3
Add access control groups to routes API request and response
bcmmbaga May 21, 2024
cda9c7e
fix tests
bcmmbaga May 22, 2024
17f6984
fix tests
bcmmbaga May 22, 2024
79fcb04
Add network map processing for routed networks
bcmmbaga May 28, 2024
10ebf1c
Refactor FirewallRule message and add RouteFirewallRule
bcmmbaga May 30, 2024
a9cb906
Refactor enum and field names in management proto files
bcmmbaga May 30, 2024
8e60f79
Refactor firewall rules and add route firewall rules
bcmmbaga May 30, 2024
564482e
Add firewall rules for routed networks
bcmmbaga May 30, 2024
69df319
Refactor enums and remove redundant code
bcmmbaga May 30, 2024
bf67e73
fix lint errors
bcmmbaga May 31, 2024
35248ea
Move getAllRoutePoliciesFromGroups function to route.go
bcmmbaga Jun 2, 2024
58e99d7
Add tests for account peers routes firewall
bcmmbaga Jun 2, 2024
dc94586
Add support for port range in policy rules
bcmmbaga Jun 3, 2024
7498e93
Implement port range support in firewall rules
bcmmbaga Jun 3, 2024
c97ae04
fix tests
bcmmbaga Jun 3, 2024
b771f80
Fix sonarcloud
bcmmbaga Jun 6, 2024
655c967
Merge branch 'refs/heads/feature/network-route-access-control' into r…
bcmmbaga Jun 6, 2024
a53242f
Refactor
bcmmbaga Jun 6, 2024
ea89187
Replace PeerIP with SourceRange in RouteFirewallRule.
bcmmbaga Jun 10, 2024
a6c70ea
Add CIDR notation to source range
bcmmbaga Jun 10, 2024
8a9ab88
fix sonarlint
bcmmbaga Jun 10, 2024
9e6ef96
Merge branch 'refs/heads/feature/network-route-access-control' into r…
bcmmbaga Jun 20, 2024
37dcf73
Fix merge
bcmmbaga Jun 20, 2024
3053425
Add dynamic routing capabilities and allow all traffic for routes wit…
bcmmbaga Jun 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,153 changes: 775 additions & 378 deletions management/proto/management.pb.go

Large diffs are not rendered by default.

90 changes: 71 additions & 19 deletions management/proto/management.proto
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,12 @@ message NetworkMap {

// firewallRulesIsEmpty indicates whether FirewallRule array is empty or not to bypass protobuf null and empty array equality.
bool firewallRulesIsEmpty = 9;

// RoutesFirewallRules represents a list of routes firewall rules to be applied to peer
repeated RouteFirewallRule routesFirewallRules = 10;

// RoutesFirewallRulesIsEmpty indicates whether RouteFirewallRule array is empty or not to bypass protobuf null and empty array equality.
bool routesFirewallRulesIsEmpty = 11;
}

// RemotePeerConfig represents a configuration of a remote peer.
Expand Down Expand Up @@ -342,32 +348,78 @@ message NameServer {
int64 Port = 3;
}

enum RuleProtocol {
UNKNOWN = 0;
ALL = 1;
TCP = 2;
UDP = 3;
ICMP = 4;
}

enum RuleDirection {
IN = 0;
OUT = 1;
}

enum RuleAction {
ACCEPT = 0;
DROP = 1;
}


// FirewallRule represents a firewall rule
message FirewallRule {
string PeerIP = 1;
direction Direction = 2;
action Action = 3;
protocol Protocol = 4;
RuleDirection Direction = 2;
RuleAction Action = 3;
RuleProtocol Protocol = 4;
string Port = 5;

enum direction {
IN = 0;
OUT = 1;
}
enum action {
ACCEPT = 0;
DROP = 1;
}
enum protocol {
UNKNOWN = 0;
ALL = 1;
TCP = 2;
UDP = 3;
ICMP = 4;
}
}

message NetworkAddress {
string netIP = 1;
string mac = 2;
}


message PortInfo {
oneof portSelection {
uint32 port = 1;
Range range = 2;
}

message Range {
uint32 start = 1;
uint32 end = 2;
}
}

// RouteFirewallRule signifies a firewall rule applicable for a routed network.
message RouteFirewallRule {
// PeerIP IP address of the routing peer.
string peerIP = 1;
bcmmbaga marked this conversation as resolved.
Show resolved Hide resolved

// Direction of the firewall.
RuleDirection direction = 2;

// Action to be taken by the firewall when the rule is applicable.
RuleAction action = 3;

// NetworkType of the routed network.
NetworkType networkType = 4;

// Network prefix for the routed network.
string destination = 5;

// Protocol of the routed network.
RuleProtocol protocol = 6;
lixmal marked this conversation as resolved.
Show resolved Hide resolved

// Details about the port.
PortInfo portInfo = 7;

enum NetworkType {
IPV4 = 0;
IPV6 = 1;
}
}

16 changes: 9 additions & 7 deletions management/server/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ type AccountManager interface {
DeletePolicy(accountID, policyID, userID string) error
ListPolicies(accountID, userID string) ([]*Policy, error)
GetRoute(accountID string, routeID route.ID, userID string) (*route.Route, error)
CreateRoute(accountID, prefix, peerID string, peerGroupIDs []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error)
CreateRoute(accountID, prefix, peerID string, peerGroupIDs []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, accessControlGroupIDs []string, enabled bool, userID string) (*route.Route, error)
SaveRoute(accountID, userID string, route *route.Route) error
DeleteRoute(accountID string, routeID route.ID, userID string) error
ListRoutes(accountID, userID string) ([]*route.Route, error)
Expand Down Expand Up @@ -415,6 +415,7 @@ func (a *Account) GetPeerNetworkMap(peerID, dnsDomain string, validatedPeersMap
}

routesUpdate := a.getRoutesToSync(peerID, peersToConnect)
routesFirewallRules := a.getPeerRoutesFirewallRules(peerID, validatedPeersMap)

dnsManagementStatus := a.getPeerDNSManagementStatus(peerID)
dnsUpdate := nbdns.Config{
Expand All @@ -432,12 +433,13 @@ func (a *Account) GetPeerNetworkMap(peerID, dnsDomain string, validatedPeersMap
}

return &NetworkMap{
Peers: peersToConnect,
Network: a.Network.Copy(),
Routes: routesUpdate,
DNSConfig: dnsUpdate,
OfflinePeers: expiredPeers,
FirewallRules: firewallRules,
Peers: peersToConnect,
Network: a.Network.Copy(),
Routes: routesUpdate,
DNSConfig: dnsUpdate,
OfflinePeers: expiredPeers,
FirewallRules: firewallRules,
RoutesFirewallRules: routesFirewallRules,
}
}

Expand Down
7 changes: 4 additions & 3 deletions management/server/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1576,9 +1576,10 @@ func TestAccount_Copy(t *testing.T) {
},
Routes: map[route.ID]*route.Route{
"route1": {
ID: "route1",
PeerGroups: []string{},
Groups: []string{"group1"},
ID: "route1",
PeerGroups: []string{},
Groups: []string{"group1"},
AccessControlGroups: []string{},
},
},
NameServerGroups: map[string]*nbdns.NameServerGroup{
Expand Down
22 changes: 13 additions & 9 deletions management/server/grpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,21 +492,25 @@ func toSyncResponse(config *Config, peer *nbpeer.Peer, turnCredentials *TURNCred

firewallRules := toProtocolFirewallRules(networkMap.FirewallRules)

routesFirewallRules := toProtocolRoutesFirewallRules(networkMap.RoutesFirewallRules)

return &proto.SyncResponse{
WiretrusteeConfig: wtConfig,
PeerConfig: pConfig,
RemotePeers: remotePeers,
RemotePeersIsEmpty: len(remotePeers) == 0,
NetworkMap: &proto.NetworkMap{
Serial: networkMap.Network.CurrentSerial(),
PeerConfig: pConfig,
RemotePeers: remotePeers,
OfflinePeers: offlinePeers,
RemotePeersIsEmpty: len(remotePeers) == 0,
Routes: routesUpdate,
DNSConfig: dnsUpdate,
FirewallRules: firewallRules,
FirewallRulesIsEmpty: len(firewallRules) == 0,
Serial: networkMap.Network.CurrentSerial(),
PeerConfig: pConfig,
RemotePeers: remotePeers,
OfflinePeers: offlinePeers,
RemotePeersIsEmpty: len(remotePeers) == 0,
Routes: routesUpdate,
DNSConfig: dnsUpdate,
FirewallRules: firewallRules,
FirewallRulesIsEmpty: len(firewallRules) == 0,
RoutesFirewallRules: routesFirewallRules,
RoutesFirewallRulesIsEmpty: len(routesFirewallRules) == 0,
},
}
}
Expand Down
6 changes: 6 additions & 0 deletions management/server/http/api/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,12 @@ components:
items:
type: string
example: "chacdk86lnnboviihd70"
access_control_groups:
description: Access control group identifier associated with route.
type: array
items:
type: string
example: "chacbco6lnnbn6cg5s91"
required:
- id
- description
Expand Down
6 changes: 6 additions & 0 deletions management/server/http/api/types.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 14 additions & 2 deletions management/server/http/routes_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,16 @@ func (h *RoutesHandler) CreateRoute(w http.ResponseWriter, r *http.Request) {
peerId = *req.Peer
}

peerGroupIds := []string{}
var peerGroupIds []string
if req.PeerGroups != nil {
peerGroupIds = *req.PeerGroups
}

var accessControlGroupIds []string
if req.AccessControlGroups != nil {
accessControlGroupIds = *req.AccessControlGroups
}

if (peerId != "" && len(peerGroupIds) > 0) || (peerId == "" && len(peerGroupIds) == 0) {
util.WriteError(status.Errorf(status.InvalidArgument, "only one peer or peer_groups should be provided"), w)
return
Expand All @@ -107,7 +112,7 @@ func (h *RoutesHandler) CreateRoute(w http.ResponseWriter, r *http.Request) {

newRoute, err := h.accountManager.CreateRoute(
account.Id, newPrefix.String(), peerId, peerGroupIds,
req.Description, route.NetID(req.NetworkId), req.Masquerade, req.Metric, req.Groups, req.Enabled, user.Id,
req.Description, route.NetID(req.NetworkId), req.Masquerade, req.Metric, req.Groups, accessControlGroupIds, req.Enabled, user.Id,
)
if err != nil {
util.WriteError(err, w)
Expand Down Expand Up @@ -204,6 +209,10 @@ func (h *RoutesHandler) UpdateRoute(w http.ResponseWriter, r *http.Request) {
newRoute.PeerGroups = *req.PeerGroups
}

if req.AccessControlGroups != nil {
newRoute.AccessControlGroups = *req.AccessControlGroups
}

err = h.accountManager.SaveRoute(account.Id, user.Id, newRoute)
if err != nil {
util.WriteError(err, w)
Expand Down Expand Up @@ -280,5 +289,8 @@ func toRouteResponse(serverRoute *route.Route) *api.Route {
if len(serverRoute.PeerGroups) > 0 {
route.PeerGroups = &serverRoute.PeerGroups
}
if len(serverRoute.AccessControlGroups) > 0 {
route.AccessControlGroups = &serverRoute.AccessControlGroups
}
return route
}
64 changes: 53 additions & 11 deletions management/server/http/routes_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func initRoutesTestData() *RoutesHandler {
}
return nil, status.Errorf(status.NotFound, "route with ID %s not found", routeID)
},
CreateRouteFunc: func(accountID, network, peerID string, peerGroups []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, enabled bool, _ string) (*route.Route, error) {
CreateRouteFunc: func(accountID, network, peerID string, peerGroups []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, accessControlGroups []string, enabled bool, _ string) (*route.Route, error) {
if peerID == notFoundPeerID {
return nil, status.Errorf(status.InvalidArgument, "peer with ID %s not found", peerID)
}
Expand All @@ -102,16 +102,17 @@ func initRoutesTestData() *RoutesHandler {
}
networkType, p, _ := route.ParseNetwork(network)
return &route.Route{
ID: existingRouteID,
NetID: netID,
Peer: peerID,
PeerGroups: peerGroups,
Network: p,
NetworkType: networkType,
Description: description,
Masquerade: masquerade,
Enabled: enabled,
Groups: groups,
ID: existingRouteID,
NetID: netID,
Peer: peerID,
PeerGroups: peerGroups,
Network: p,
NetworkType: networkType,
Description: description,
Masquerade: masquerade,
Enabled: enabled,
Groups: groups,
AccessControlGroups: accessControlGroups,
}, nil
},
SaveRouteFunc: func(_, _ string, r *route.Route) error {
Expand Down Expand Up @@ -210,6 +211,27 @@ func TestRoutesHandlers(t *testing.T) {
Groups: []string{existingGroupID},
},
},
{
name: "POST OK With Access Control Groups",
requestType: http.MethodPost,
requestPath: "/api/routes",
requestBody: bytes.NewBuffer(
[]byte(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\",\"groups\":[\"%s\"],\"access_control_groups\":[\"%s\"]}", existingPeerID, existingGroupID, existingGroupID))),
expectedStatus: http.StatusOK,
expectedBody: true,
expectedRoute: &api.Route{
Id: existingRouteID,
Description: "Post",
NetworkId: "awesomeNet",
Network: "192.168.0.0/16",
Peer: &existingPeerID,
NetworkType: route.IPv4NetworkString,
Masquerade: false,
Enabled: false,
Groups: []string{existingGroupID},
AccessControlGroups: &[]string{existingGroupID},
},
},
{
name: "POST Non Linux Peer",
requestType: http.MethodPost,
Expand Down Expand Up @@ -279,6 +301,26 @@ func TestRoutesHandlers(t *testing.T) {
Groups: []string{existingGroupID},
},
},
{
name: "PUT OK With Access Control Groups",
requestType: http.MethodPut,
requestPath: "/api/routes/" + existingRouteID,
requestBody: bytes.NewBufferString(fmt.Sprintf("{\"Description\":\"Post\",\"Network\":\"192.168.0.0/16\",\"network_id\":\"awesomeNet\",\"Peer\":\"%s\",\"groups\":[\"%s\"],\"access_control_groups\":[\"%s\"]}}", existingPeerID, existingGroupID, existingGroupID)),
expectedStatus: http.StatusOK,
expectedBody: true,
expectedRoute: &api.Route{
Id: existingRouteID,
Description: "Post",
NetworkId: "awesomeNet",
Network: "192.168.0.0/16",
Peer: &existingPeerID,
NetworkType: route.IPv4NetworkString,
Masquerade: false,
Enabled: false,
Groups: []string{existingGroupID},
AccessControlGroups: &[]string{existingGroupID},
},
},
{
name: "PUT OK when peer_groups provided",
requestType: http.MethodPut,
Expand Down
6 changes: 3 additions & 3 deletions management/server/mock_server/account_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ type MockAccountManager struct {
UpdatePeerMetaFunc func(peerID string, meta nbpeer.PeerSystemMeta) error
UpdatePeerSSHKeyFunc func(peerID string, sshKey string) error
UpdatePeerFunc func(accountID, userID string, peer *nbpeer.Peer) (*nbpeer.Peer, error)
CreateRouteFunc func(accountID, prefix, peer string, peerGroups []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error)
CreateRouteFunc func(accountID, prefix, peer string, peerGroups []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, accessControlGroups []string, enabled bool, userID string) (*route.Route, error)
GetRouteFunc func(accountID string, routeID route.ID, userID string) (*route.Route, error)
SaveRouteFunc func(accountID string, userID string, route *route.Route) error
DeleteRouteFunc func(accountID string, routeID route.ID, userID string) error
Expand Down Expand Up @@ -412,9 +412,9 @@ func (am *MockAccountManager) UpdatePeer(accountID, userID string, peer *nbpeer.
}

// CreateRoute mock implementation of CreateRoute from server.AccountManager interface
func (am *MockAccountManager) CreateRoute(accountID, prefix, peerID string, peerGroupIDs []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, enabled bool, userID string) (*route.Route, error) {
func (am *MockAccountManager) CreateRoute(accountID, prefix, peerID string, peerGroupIDs []string, description string, netID route.NetID, masquerade bool, metric int, groups []string, accessControlGroups []string, enabled bool, userID string) (*route.Route, error) {
if am.CreateRouteFunc != nil {
return am.CreateRouteFunc(accountID, prefix, peerID, peerGroupIDs, description, netID, masquerade, metric, groups, enabled, userID)
return am.CreateRouteFunc(accountID, prefix, peerID, peerGroupIDs, description, netID, masquerade, metric, groups, accessControlGroups, enabled, userID)
}
return nil, status.Errorf(codes.Unimplemented, "method CreateRoute is not implemented")
}
Expand Down
Loading
Loading