Skip to content

Commit bec7326

Browse files
Allow more permissive extensibility for securityRules
Signed-off-by: Danil-Grigorev <[email protected]>
1 parent 1c6a5d3 commit bec7326

File tree

3 files changed

+98
-22
lines changed

3 files changed

+98
-22
lines changed

api/v1beta1/types.go

+14
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,20 @@ func (s SubnetSpec) IsIPv6Enabled() bool {
893893
return false
894894
}
895895

896+
// GetSecurityRuleByDestination returns security group rule, which matches provided destination ports.
897+
func (s SubnetSpec) GetSecurityRuleByDestination(ports string) *SecurityRule {
898+
if s.SecurityGroup.SecurityRules == nil {
899+
return nil
900+
}
901+
902+
for _, rule := range s.SecurityGroup.SecurityRules {
903+
if rule.DestinationPorts != nil && *rule.DestinationPorts == ports {
904+
return &rule
905+
}
906+
}
907+
return nil
908+
}
909+
896910
// SecurityProfile specifies the Security profile settings for a
897911
// virtual machine or virtual machine scale set.
898912
type SecurityProfile struct {

azure/scope/cluster.go

+33-16
Original file line numberDiff line numberDiff line change
@@ -1020,9 +1020,18 @@ func (s *ClusterScope) SetControlPlaneSecurityRules() {
10201020
if !s.ControlPlaneEnabled() {
10211021
return
10221022
}
1023-
if s.ControlPlaneSubnet().SecurityGroup.SecurityRules == nil {
1023+
1024+
subnet := s.ControlPlaneSubnet()
1025+
1026+
if subnet.SecurityGroup.SecurityRules == nil {
1027+
subnet := s.ControlPlaneSubnet()
1028+
1029+
s.AzureCluster.Spec.NetworkSpec.UpdateControlPlaneSubnet(subnet)
1030+
}
1031+
1032+
if subnet.GetSecurityRuleByDestination("22") == nil {
10241033
subnet := s.ControlPlaneSubnet()
1025-
subnet.SecurityGroup.SecurityRules = infrav1.SecurityRules{
1034+
subnet.SecurityGroup.SecurityRules = append(s.ControlPlaneSubnet().SecurityGroup.SecurityRules,
10261035
infrav1.SecurityRule{
10271036
Name: "allow_ssh",
10281037
Description: "Allow SSH",
@@ -1034,22 +1043,30 @@ func (s *ClusterScope) SetControlPlaneSecurityRules() {
10341043
Destination: ptr.To("*"),
10351044
DestinationPorts: ptr.To("22"),
10361045
Action: infrav1.SecurityRuleActionAllow,
1037-
},
1038-
infrav1.SecurityRule{
1039-
Name: "allow_apiserver",
1040-
Description: "Allow K8s API Server",
1041-
Priority: 2201,
1042-
Protocol: infrav1.SecurityGroupProtocolTCP,
1043-
Direction: infrav1.SecurityRuleDirectionInbound,
1044-
Source: ptr.To("*"),
1045-
SourcePorts: ptr.To("*"),
1046-
Destination: ptr.To("*"),
1047-
DestinationPorts: ptr.To(strconv.Itoa(int(s.APIServerPort()))),
1048-
Action: infrav1.SecurityRuleActionAllow,
1049-
},
1050-
}
1046+
})
1047+
10511048
s.AzureCluster.Spec.NetworkSpec.UpdateControlPlaneSubnet(subnet)
10521049
}
1050+
1051+
port := strconv.Itoa(int(s.APIServerPort()))
1052+
if subnet.GetSecurityRuleByDestination(port) == nil {
1053+
subnet := s.ControlPlaneSubnet()
1054+
subnet.SecurityGroup.SecurityRules = append(s.ControlPlaneSubnet().SecurityGroup.SecurityRules, infrav1.SecurityRule{
1055+
Name: "allow_apiserver",
1056+
Description: "Allow K8s API Server",
1057+
Priority: 2201,
1058+
Protocol: infrav1.SecurityGroupProtocolTCP,
1059+
Direction: infrav1.SecurityRuleDirectionInbound,
1060+
Source: ptr.To("*"),
1061+
SourcePorts: ptr.To("*"),
1062+
Destination: ptr.To("*"),
1063+
DestinationPorts: ptr.To(port),
1064+
Action: infrav1.SecurityRuleActionAllow,
1065+
})
1066+
1067+
s.AzureCluster.Spec.NetworkSpec.UpdateControlPlaneSubnet(subnet)
1068+
}
1069+
10531070
}
10541071

10551072
// SetDNSName sets the API Server public IP DNS name.

docs/book/src/self-managed/custom-vnet.md

+51-6
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,13 @@ Security Rules were previously known as `ingressRule` in v1alpha3.
114114
</aside>
115115

116116
Security rules can also be customized as part of the subnet specification in a custom network spec.
117-
Note that ingress rules for the Kubernetes API Server port (default 6443) and SSH (22) are automatically added to the controlplane subnet only if security rules aren't specified.
118-
It is the responsibility of the user to supply those rules themselves if using custom rules.
117+
118+
Note that ingress rules for the Kubernetes API Server port (default 6443) and SSH (22) are automatically added to the controlplane subnet if these security rules aren't specified.
119+
It is the responsibility of the user to override those rules themselves when the default configuration does not match expected ruleset.
120+
121+
These rules are identified by `destinationPorts` value:
122+
- `<API_SERVER_PORT>` for the API server access. Default port is `6443`.
123+
- `22` for the SSH access.
119124

120125
Here is an illustrative example of customizing rules that builds on the one above by adding an egress rule to the control plane nodes:
121126

@@ -141,22 +146,22 @@ spec:
141146
name: my-subnet-cp-nsg
142147
securityRules:
143148
- name: "allow_ssh"
144-
description: "allow SSH"
149+
description: "Deny SSH"
145150
direction: "Inbound"
146151
priority: 2200
147152
protocol: "*"
148153
destination: "*"
149154
destinationPorts: "22"
150155
source: "*"
151156
sourcePorts: "*"
152-
action: "Allow"
157+
action: "Deny"
153158
- name: "allow_apiserver"
154-
description: "Allow K8s API Server"
159+
description: "Allow Custom K8s API Server"
155160
direction: "Inbound"
156161
priority: 2201
157162
protocol: "*"
158163
destination: "*"
159-
destinationPorts: "6443"
164+
destinationPorts: "1234" # Custom API server URL
160165
source: "*"
161166
sourcePorts: "*"
162167
action: "Allow"
@@ -177,6 +182,46 @@ spec:
177182
resourceGroup: cluster-example
178183
```
179184

185+
Alternatively, when default server `securityRules` apply, but the list needs to be extended, only required rules can be added, like so:
186+
187+
```yaml
188+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
189+
kind: AzureCluster
190+
metadata:
191+
name: cluster-example
192+
namespace: default
193+
spec:
194+
location: southcentralus
195+
networkSpec:
196+
vnet:
197+
name: my-vnet
198+
cidrBlocks:
199+
- 10.0.0.0/16
200+
subnets:
201+
- name: my-subnet-cp
202+
role: control-plane
203+
cidrBlocks:
204+
- 10.0.1.0/24
205+
securityGroup:
206+
name: my-subnet-cp-nsg
207+
securityRules:
208+
- name: "allow_port_9345"
209+
description: "RKE2 - allow node registration on port 9345"
210+
direction: "Inbound"
211+
priority: 2202
212+
protocol: "Tcp"
213+
destination: "*"
214+
destinationPorts: "9345"
215+
source: "*"
216+
sourcePorts: "*"
217+
action: "Allow"
218+
- name: my-subnet-node
219+
role: node
220+
cidrBlocks:
221+
- 10.0.2.0/24
222+
resourceGroup: cluster-example
223+
```
224+
180225
### Virtual Network service endpoints
181226

182227
Sometimes it's desirable to use [Virtual Network service endpoints](https://learn.microsoft.com/azure/virtual-network/virtual-network-service-endpoints-overview) to establish secure and direct connectivity to Azure services from your subnet(s). Service Endpoints are configured on a per-subnet basis. Vnets managed by either `AzureCluster` or `AzureManagedControlPlane` can have `serviceEndpoints` optionally set on each subnet.

0 commit comments

Comments
 (0)