Skip to content

Commit ddc26ee

Browse files
authored
Merge pull request #2128 from elastx/nodeport-block-internet
🐛 Expose NodePorts on cluster network instead of 0.0.0.0/0
2 parents 91b7ccf + ea7bf33 commit ddc26ee

File tree

3 files changed

+77
-20
lines changed

3 files changed

+77
-20
lines changed

pkg/cloud/services/networking/securitygroups.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/attributestags"
2525
"github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/security/groups"
2626
"github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/security/rules"
27+
"k8s.io/utils/net"
2728

2829
infrav1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
2930
"sigs.k8s.io/cluster-api-provider-openstack/pkg/record"
@@ -200,7 +201,19 @@ func (s *Service) generateDesiredSecGroups(openStackCluster *infrav1.OpenStackCl
200201
workerRules := append([]resolvedSecurityGroupRuleSpec{}, defaultRules...)
201202

202203
controlPlaneRules = append(controlPlaneRules, getSGControlPlaneHTTPS()...)
203-
workerRules = append(workerRules, getSGWorkerNodePort()...)
204+
205+
// Fetch subnet to use for worker node port rules
206+
// In the future IPv6 support need to be added here
207+
if openStackCluster.Status.Network != nil {
208+
for _, subnet := range openStackCluster.Status.Network.Subnets {
209+
if net.IsIPv4CIDRString(subnet.CIDR) {
210+
workerRules = append(workerRules, getSGWorkerNodePortCIDR(subnet.CIDR)...)
211+
}
212+
}
213+
}
214+
215+
// Add rules allowing nodepors from all cluster nodes, this will take effect even if no subnetCIDR is found to ensure all nodes can commincate over nodeports at all time
216+
workerRules = append(workerRules, getSGWorkerNodePort(secWorkerGroupID, secControlPlaneGroupID)...)
204217

205218
// If we set additional ports to LB, we need create secgroup rules those ports, this apply to controlPlaneRules only
206219
if openStackCluster.Spec.APIServerLoadBalancer.IsEnabled() {

pkg/cloud/services/networking/securitygroups_rules.go

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -142,23 +142,67 @@ func getSGControlPlaneHTTPS() []resolvedSecurityGroupRuleSpec {
142142
}
143143

144144
// Allow all traffic, including from outside the cluster, to access node port services.
145-
func getSGWorkerNodePort() []resolvedSecurityGroupRuleSpec {
145+
func getSGWorkerNodePort(secWorkerGroupID string, secControlPlaneGroupID string) []resolvedSecurityGroupRuleSpec {
146146
return []resolvedSecurityGroupRuleSpec{
147147
{
148-
Description: "Node Port Services",
149-
Direction: "ingress",
150-
EtherType: "IPv4",
151-
PortRangeMin: 30000,
152-
PortRangeMax: 32767,
153-
Protocol: "tcp",
148+
Description: "Node Port Services",
149+
Direction: "ingress",
150+
EtherType: "IPv4",
151+
PortRangeMin: 30000,
152+
PortRangeMax: 32767,
153+
Protocol: "tcp",
154+
RemoteGroupID: secWorkerGroupID,
154155
},
155156
{
156-
Description: "Node Port Services",
157-
Direction: "ingress",
158-
EtherType: "IPv4",
159-
PortRangeMin: 30000,
160-
PortRangeMax: 32767,
161-
Protocol: "udp",
157+
Description: "Node Port Services",
158+
Direction: "ingress",
159+
EtherType: "IPv4",
160+
PortRangeMin: 30000,
161+
PortRangeMax: 32767,
162+
Protocol: "udp",
163+
RemoteGroupID: secWorkerGroupID,
164+
},
165+
{
166+
Description: "Node Port Services",
167+
Direction: "ingress",
168+
EtherType: "IPv4",
169+
PortRangeMin: 30000,
170+
PortRangeMax: 32767,
171+
Protocol: "tcp",
172+
RemoteGroupID: secControlPlaneGroupID,
173+
},
174+
{
175+
Description: "Node Port Services",
176+
Direction: "ingress",
177+
EtherType: "IPv4",
178+
PortRangeMin: 30000,
179+
PortRangeMax: 32767,
180+
Protocol: "udp",
181+
RemoteGroupID: secControlPlaneGroupID,
182+
},
183+
}
184+
}
185+
186+
// Allow all traffic from a specific CIDR to access node port services.
187+
func getSGWorkerNodePortCIDR(cidr string) []resolvedSecurityGroupRuleSpec {
188+
return []resolvedSecurityGroupRuleSpec{
189+
{
190+
Description: "Node Port Services",
191+
Direction: "ingress",
192+
EtherType: "IPv4",
193+
PortRangeMin: 30000,
194+
PortRangeMax: 32767,
195+
Protocol: "tcp",
196+
RemoteIPPrefix: cidr,
197+
},
198+
{
199+
Description: "Node Port Services",
200+
Direction: "ingress",
201+
EtherType: "IPv4",
202+
PortRangeMin: 30000,
203+
PortRangeMax: 32767,
204+
Protocol: "udp",
205+
RemoteIPPrefix: cidr,
162206
},
163207
}
164208
}

pkg/cloud/services/networking/securitygroups_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ func TestGenerateDesiredSecGroups(t *testing.T) {
323323
ManagedSecurityGroups: &infrav1.ManagedSecurityGroups{},
324324
},
325325
},
326-
expectedNumberSecurityGroupRules: 12,
326+
expectedNumberSecurityGroupRules: 14,
327327
wantErr: false,
328328
},
329329
{
@@ -342,7 +342,7 @@ func TestGenerateDesiredSecGroups(t *testing.T) {
342342
},
343343
},
344344
},
345-
expectedNumberSecurityGroupRules: 16,
345+
expectedNumberSecurityGroupRules: 18,
346346
wantErr: false,
347347
},
348348
{
@@ -570,13 +570,13 @@ func TestService_ReconcileSecurityGroups(t *testing.T) {
570570
Return([]groups.SecGroup{{ID: "1", Name: workerSGName}}, nil)
571571
m.ListSecGroup(groups.ListOpts{Name: bastionSGName}).Return(nil, nil)
572572

573-
// We expect a total of 12 rules to be created.
573+
// We expect a total of 14 rules to be created.
574574
// Nothing actually looks at the generated
575575
// rules, but we give them unique IDs anyway
576576
m.CreateSecGroupRule(gomock.Any()).DoAndReturn(func(opts rules.CreateOpts) (*rules.SecGroupRule, error) {
577577
log.Info("Created rule", "securityGroup", opts.SecGroupID, "description", opts.Description)
578578
return &rules.SecGroupRule{ID: uuid.NewString()}, nil
579-
}).Times(12)
579+
}).Times(14)
580580
},
581581
expectedClusterStatus: infrav1.OpenStackClusterStatus{
582582
ControlPlaneSecurityGroup: &infrav1.SecurityGroupStatus{
@@ -605,13 +605,13 @@ func TestService_ReconcileSecurityGroups(t *testing.T) {
605605
m.ListSecGroup(groups.ListOpts{Name: bastionSGName}).
606606
Return([]groups.SecGroup{{ID: "2", Name: bastionSGName}}, nil)
607607

608-
// We expect a total of 12 rules to be created.
608+
// We expect a total of 19 rules to be created.
609609
// Nothing actually looks at the generated
610610
// rules, but we give them unique IDs anyway
611611
m.CreateSecGroupRule(gomock.Any()).DoAndReturn(func(opts rules.CreateOpts) (*rules.SecGroupRule, error) {
612612
log.Info("Created rule", "securityGroup", opts.SecGroupID, "description", opts.Description)
613613
return &rules.SecGroupRule{ID: uuid.NewString()}, nil
614-
}).Times(17)
614+
}).Times(19)
615615
},
616616
expectedClusterStatus: infrav1.OpenStackClusterStatus{
617617
ControlPlaneSecurityGroup: &infrav1.SecurityGroupStatus{

0 commit comments

Comments
 (0)