Skip to content

Commit 061d984

Browse files
committed
Add Node Admission restriction for Azure node Manager
1 parent 913d6d9 commit 061d984

File tree

5 files changed

+40
-3
lines changed

5 files changed

+40
-3
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apiVersion: admissionregistration.k8s.io/v1
2+
kind: ValidatingAdmissionPolicyBinding
3+
metadata:
4+
name: openshift-cloud-controller-manager-cloud-provider-azure-node-admission
5+
spec:
6+
policyName: openshift-cloud-controller-manager-cloud-provider-azure-node-admission
7+
validationActions: ["Deny"]
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
apiVersion: admissionregistration.k8s.io/v1beta1
2+
kind: ValidatingAdmissionPolicy
3+
metadata:
4+
name: openshift-cloud-controller-manager-cloud-provider-azure-node-admission
5+
spec:
6+
failurePolicy: Fail
7+
matchConstraints:
8+
resourceRules:
9+
- apiGroups: [""]
10+
apiVersions: ["v1"]
11+
operations: ["UPDATE"]
12+
resources: ["nodes"]
13+
validations:
14+
# all requests should have a node-name claim, this prevents impersonation of the SA.
15+
- expression: "has(request.userInfo.extra) && ('authentication.kubernetes.io/node-name' in request.userInfo.extra)"
16+
message: "this user must have a \"authentication.kubernetes.io/node-name\" claim"
17+
# all requests should originate from the MCN owner's node
18+
- expression: "object.metadata.name == request.userInfo.extra[\"authentication.kubernetes.io/node-name\"][0]"
19+
messageExpression: "'updates to Node ' + string(object.metadata.name) + ' may only be effected from the cloud node manager running on the same node'"
20+
matchConditions:
21+
# Only check requests from Azure Cloud Node Manager SA, this allows all other SAs with the correct RBAC to modify Nodes.
22+
- name: "check-only-machine-config-daemon-requests"
23+
expression: "request.userInfo.username == 'system:serviceaccount:openshift-cloud-controller-manager:cloud-node-manager'"

pkg/cloud/azure/azure.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/asaskevich/govalidator"
1111
configv1 "github.com/openshift/api/config/v1"
12+
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
1213
appsv1 "k8s.io/api/apps/v1"
1314
rbacv1 "k8s.io/api/rbac/v1"
1415
"k8s.io/apimachinery/pkg/util/validation/field"
@@ -31,6 +32,8 @@ var (
3132
{ReferenceObject: &appsv1.DaemonSet{}, EmbedFsPath: "assets/cloud-node-manager-daemonset.yaml"},
3233
{ReferenceObject: &rbacv1.ClusterRole{}, EmbedFsPath: "assets/azure-cloud-controller-manager-clusterrole.yaml"},
3334
{ReferenceObject: &rbacv1.ClusterRoleBinding{}, EmbedFsPath: "assets/azure-cloud-controller-manager-clusterrolebinding.yaml"},
35+
{ReferenceObject: &admissionregistrationv1.ValidatingAdmissionPolicy{}, EmbedFsPath: "assets/validating-admission-policy.yaml"},
36+
{ReferenceObject: &admissionregistrationv1.ValidatingAdmissionPolicyBinding{}, EmbedFsPath: "assets/validating-admission-policy-binding.yaml"},
3437
}
3538
)
3639

pkg/cloud/azure/azure_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func TestResourcesRenderingSmoke(t *testing.T) {
9090
}
9191

9292
resources := assets.GetRenderedResources()
93-
assert.Len(t, resources, 4)
93+
assert.Len(t, resources, 6)
9494
})
9595
}
9696
}

pkg/cloud/cloud_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,24 +149,28 @@ func TestGetResources(t *testing.T) {
149149
}, {
150150
name: "Azure resources returned as expected",
151151
testPlatform: platformsMap[string(configv1.AzurePlatformType)],
152-
expectedResourceCount: 5,
152+
expectedResourceCount: 7,
153153
expectedResourcesKindName: []string{
154154
"Deployment/azure-cloud-controller-manager",
155155
"DaemonSet/azure-cloud-node-manager",
156156
"ClusterRole/azure-cloud-controller-manager",
157157
"ClusterRoleBinding/cloud-controller-manager:azure-cloud-controller-manager",
158+
"ValidatingAdmissionPolicy/openshift-cloud-controller-manager-cloud-provider-azure-node-admission",
159+
"ValidatingAdmissionPolicyBinding/openshift-cloud-controller-manager-cloud-provider-azure-node-admission",
158160
"PodDisruptionBudget/azure-cloud-controller-manager",
159161
},
160162
}, {
161163
name: "Azure resources returned as expected with single node cluster",
162164
testPlatform: platformsMap[string(configv1.AzurePlatformType)],
163-
expectedResourceCount: 4,
165+
expectedResourceCount: 6,
164166
singleReplica: true,
165167
expectedResourcesKindName: []string{
166168
"Deployment/azure-cloud-controller-manager",
167169
"DaemonSet/azure-cloud-node-manager",
168170
"ClusterRole/azure-cloud-controller-manager",
169171
"ClusterRoleBinding/cloud-controller-manager:azure-cloud-controller-manager",
172+
"ValidatingAdmissionPolicy/openshift-cloud-controller-manager-cloud-provider-azure-node-admission",
173+
"ValidatingAdmissionPolicyBinding/openshift-cloud-controller-manager-cloud-provider-azure-node-admission",
170174
},
171175
}, {
172176
name: "Azure Stack resources returned as expected",

0 commit comments

Comments
 (0)