-
Notifications
You must be signed in to change notification settings - Fork 16
Description
Summary
When using the Netbird Kubernetes operator's automatic policy creation feature (via allowAutomaticPolicyCreation: true and service annotations), all auto-generated policies are hardcoded to Bidirectional: true, ignoring any bidirectional settings from predefined policy bases in the Helm values.
Expected Behavior
When a predefined policy is configured with bidirectional: false in the Helm values, and a service references this policy via the netbird.io/policy annotation, the auto-generated policy should inherit the bidirectional setting from the predefined policy base.
Actual Behavior
The auto-generated policy always has Bidirectional: true, regardless of the predefined policy configuration.
Root Cause
In internal/controller/nbresource_controller.go, the handlePolicyCreate function hardcodes Bidirectional: true when creating auto-generated NBPolicy resources:
File: internal/controller/nbresource_controller.go
Lines: 145-158
func (r *NBResourceReconciler) handlePolicyCreate(ctx context.Context, nbResource *netbirdiov1.NBResource, req ctrl.Request, policy string, nbPolicy *netbirdiov1.NBPolicy, logger logr.Logger) error {
// ... validation code ...
*nbPolicy = netbirdiov1.NBPolicy{
ObjectMeta: v1.ObjectMeta{
Name: generatedName,
Annotations: map[string]string{"netbird.io/generated-by": req.NamespacedName.String()},
Finalizers: []string{"netbird.io/cleanup"},
Labels: r.DefaultLabels,
},
Spec: netbirdiov1.NBPolicySpec{
Name: name,
Description: "Generated by " + req.NamespacedName.String(),
SourceGroups: nbResource.Spec.PolicySourceGroups,
Bidirectional: true, // <-- HARDCODED TO TRUE
},
}
// ...
}Reproduction Steps
- Configure predefined policy in Helm values:
ingress:
enabled: true
allowAutomaticPolicyCreation: true
policies:
longhorn-ui:
name: 'Longhorn UI Access'
description: 'Team DevOps access to Longhorn UI'
sourceGroups: ['team-devops']
bidirectional: false # <-- This setting is ignored- Annotate a Kubernetes service:
service:
ui:
annotations:
netbird.io/expose: 'true'
netbird.io/groups: 'service-longhorn-ui'
netbird.io/policy: 'longhorn-ui'
netbird.io/policy-source-groups: 'team-devops'
netbird.io/policy-ports: '80'
netbird.io/policy-protocol: 'tcp'-
Apply the configuration
-
Check the created NBPolicy:
kubectl get nbpolicies.netbird.io longhorn-ui-longhorn-system-longhorn-frontend -o yamlResult:
The auto-generated policy shows bidirectional: true instead of inheriting bidirectional: false from the predefined policy.
Impact
This creates a security concern as it allows bidirectional traffic when only unidirectional access is desired (e.g., team-devops → service, but not service → team-devops).
In our use case, we want to expose internal services (like Longhorn UI) to DevOps teams via Netbird, but we don't want those services to be able to initiate connections back to team members' machines.
Observed Behavior
Two policies get created:
- Predefined policy
longhorn-ui: Hasbidirectional: false✅ - Auto-generated policy
longhorn-ui-longhorn-system-longhorn-frontend: Hasbidirectional: true❌
The NBResource status shows:
status:
policyName: longhorn-ui
policyNameMapping:
longhorn-ui: longhorn-ui-longhorn-system-longhorn-frontendThe service uses the auto-generated bidirectional policy, not the predefined unidirectional one.
Suggested Fix
- Look up the predefined policy configuration when creating auto-generated policies
- Inherit the
bidirectionalsetting from the predefined policy base - If no predefined policy exists, fall back to a configurable default (or keep current behavior of
true)
Example implementation approach:
bidirectional := true // default
if predefPolicy := r.lookupPredefinedPolicy(policy); predefPolicy != nil {
bidirectional = predefPolicy.Bidirectional
}
*nbPolicy = netbirdiov1.NBPolicy{
// ...
Spec: netbirdiov1.NBPolicySpec{
// ...
Bidirectional: bidirectional,
},
}Workaround
Disable allowAutomaticPolicyCreation and manually create NBPolicy resources with the correct bidirectional setting.
Environment
- Kubernetes Operator Version: v0.1.1 (latest)
- Kubernetes Version: 1.27
- Helm Chart: netbirdio/kubernetes-operator