mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-14 09:29:07 +02:00
Restrict rule authorization to accept rules, the destination side for SSH, and the marker protocol's own port
This commit is contained in:
@@ -81,14 +81,18 @@ func MergeWildcardUsers(dst map[string]map[string]struct{}, users map[string]str
|
||||
|
||||
// NormalizePolicyRuleProtocol is the real-typed sibling of the twin helper in
|
||||
// shared types: it maps the NetBird virtual protocols to the wire protocol and
|
||||
// scopes a portless netbird-vnc rule to the embedded VNC port.
|
||||
// scopes a portless marker-protocol rule to the port that protocol implies.
|
||||
func NormalizePolicyRuleProtocol(rule *PolicyRule) (*PolicyRule, PolicyRuleProtocolType) {
|
||||
protocol := sharedtypes.WirePolicyRuleProtocol(rule.Protocol)
|
||||
if rule.Protocol != PolicyRuleProtocolNetbirdVNC || len(rule.Ports) > 0 || len(rule.PortRanges) > 0 {
|
||||
if len(rule.Ports) > 0 || len(rule.PortRanges) > 0 {
|
||||
return rule, protocol
|
||||
}
|
||||
ports, ok := sharedtypes.MarkerScopedPorts(rule.Protocol)
|
||||
if !ok {
|
||||
return rule, protocol
|
||||
}
|
||||
scoped := *rule
|
||||
scoped.Ports = sharedtypes.VNCScopedPorts()
|
||||
scoped.Ports = ports
|
||||
return &scoped, protocol
|
||||
}
|
||||
|
||||
|
||||
@@ -1412,3 +1412,38 @@ func TestPeerSSHEnabledFromPolicies_MatchesMap_Sweep(t *testing.T) {
|
||||
assertSSHEquivalence(t, account, peerID, validatedPeers)
|
||||
}
|
||||
}
|
||||
|
||||
// The bidirectional shape is the one the three SSH deciders can disagree on:
|
||||
// Calculate walks ApplyResolvedRuleToState, the components sync path walks
|
||||
// ruleEnablesSSHForPeer, and the login/register path walks
|
||||
// PeerSSHEnabledFromPolicies. Every other case in this file sets
|
||||
// Bidirectional:false or omits it, so none of them exercise the source side.
|
||||
func TestPeerSSHEnabledFromPolicies_MatchesMap_BidirectionalNetbirdSSH(t *testing.T) {
|
||||
account, validatedPeers := scalableTestAccountWithoutDefaultPolicy(20, 2)
|
||||
account.Groups["ssh-users"] = &types.Group{ID: "ssh-users", Name: "SSH Users", Peers: []string{}}
|
||||
account.Policies = append(account.Policies, &types.Policy{
|
||||
ID: "policy-ssh-bidi", Name: "SSH Access", Enabled: true, AccountID: "test-account",
|
||||
Rules: []*types.PolicyRule{{
|
||||
ID: "rule-ssh-bidi", Name: "Allow SSH", Enabled: true,
|
||||
Action: types.PolicyTrafficActionAccept, Protocol: types.PolicyRuleProtocolNetbirdSSH,
|
||||
Bidirectional: true,
|
||||
Sources: []string{"group-0"}, Destinations: []string{"group-1"},
|
||||
AuthorizedGroups: map[string][]string{"ssh-users": {"root"}},
|
||||
}},
|
||||
})
|
||||
|
||||
// peer-0 is source-only, peer-10 is destination-only.
|
||||
assertSSHEquivalence(t, account, "peer-0", validatedPeers)
|
||||
assertSSHEquivalence(t, account, "peer-10", validatedPeers)
|
||||
|
||||
sourceOnly := componentsNetworkMap(account, "peer-0", validatedPeers)
|
||||
require.NotNil(t, sourceOnly)
|
||||
assert.False(t, sourceOnly.EnableSSH,
|
||||
"a bidirectional netbird-ssh rule must not enable SSH on its source-side peer")
|
||||
assert.Empty(t, sourceOnly.AuthorizedUsers,
|
||||
"a source-side peer must carry no authorized users")
|
||||
|
||||
destination := componentsNetworkMap(account, "peer-10", validatedPeers)
|
||||
require.NotNil(t, destination)
|
||||
assert.True(t, destination.EnableSSH, "the destination-side peer must have SSH enabled")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user