Skip to content

Commit 0177aaf

Browse files
committed
fix(config): harden kubernetes workload defaults
1 parent 2dfbaba commit 0177aaf

30 files changed

Lines changed: 1139 additions & 32 deletions

config/ingress/base/kustomization.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ kind: Kustomization
33
resources:
44
- traefik.yaml
55
- dynamic-config.yaml
6+
- networkpolicy.yaml
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
apiVersion: networking.k8s.io/v1
2+
kind: NetworkPolicy
3+
metadata:
4+
name: traefik-default-deny
5+
namespace: traefik
6+
spec:
7+
podSelector: {}
8+
policyTypes:
9+
- Ingress
10+
- Egress
11+
---
12+
apiVersion: networking.k8s.io/v1
13+
kind: NetworkPolicy
14+
metadata:
15+
name: traefik-allow-ingress
16+
namespace: traefik
17+
spec:
18+
podSelector:
19+
matchLabels:
20+
app: traefik
21+
policyTypes:
22+
- Ingress
23+
ingress:
24+
- ports:
25+
- protocol: TCP
26+
port: 8000
27+
- protocol: TCP
28+
port: 8443
29+
---
30+
apiVersion: networking.k8s.io/v1
31+
kind: NetworkPolicy
32+
metadata:
33+
name: traefik-allow-egress
34+
namespace: traefik
35+
spec:
36+
podSelector:
37+
matchLabels:
38+
app: traefik
39+
policyTypes:
40+
- Egress
41+
egress:
42+
- to:
43+
- namespaceSelector:
44+
matchLabels:
45+
kubernetes.io/metadata.name: kube-system
46+
podSelector:
47+
matchLabels:
48+
k8s-app: kube-dns
49+
ports:
50+
- protocol: UDP
51+
port: 53
52+
- protocol: TCP
53+
port: 53
54+
- to:
55+
- namespaceSelector:
56+
matchLabels:
57+
kubernetes.io/metadata.name: registry
58+
- namespaceSelector:
59+
matchLabels:
60+
kubernetes.io/metadata.name: mcp-sentinel
61+
- namespaceSelector:
62+
matchLabels:
63+
kubernetes.io/metadata.name: mcp-servers
64+
- namespaceSelector:
65+
matchLabels:
66+
kubernetes.io/metadata.name: mcp-servers-org
67+
- namespaceSelector:
68+
matchLabels:
69+
kubernetes.io/metadata.name: mcp-servers-public
70+
- namespaceSelector:
71+
matchLabels:
72+
platform.mcpruntime.org/managed: "true"
73+
ports:
74+
- protocol: TCP
75+
port: 80
76+
- protocol: TCP
77+
port: 3000
78+
- protocol: TCP
79+
port: 5000
80+
- protocol: TCP
81+
port: 8080
82+
- protocol: TCP
83+
port: 8081
84+
- protocol: TCP
85+
port: 8082
86+
# Traefik watches Ingress and TLS Secret objects through the Kubernetes API.
87+
- ports:
88+
- protocol: TCP
89+
port: 443

config/ingress/base/traefik.yaml

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,28 @@ apiVersion: v1
22
kind: Namespace
33
metadata:
44
name: traefik
5+
labels:
6+
pod-security.kubernetes.io/enforce: restricted
7+
pod-security.kubernetes.io/audit: restricted
8+
pod-security.kubernetes.io/warn: restricted
59
---
610
apiVersion: v1
711
kind: Namespace
812
metadata:
913
name: registry
14+
labels:
15+
pod-security.kubernetes.io/enforce: baseline
16+
pod-security.kubernetes.io/audit: restricted
17+
pod-security.kubernetes.io/warn: restricted
1018
---
1119
apiVersion: v1
1220
kind: Namespace
1321
metadata:
1422
name: mcp-sentinel
23+
labels:
24+
pod-security.kubernetes.io/enforce: baseline
25+
pod-security.kubernetes.io/audit: restricted
26+
pod-security.kubernetes.io/warn: restricted
1527
---
1628
apiVersion: v1
1729
kind: Namespace
@@ -214,11 +226,11 @@ spec:
214226
ports:
215227
- name: web
216228
port: 80
217-
targetPort: 80
229+
targetPort: 8000
218230
protocol: TCP
219231
- name: websecure
220232
port: 443
221-
targetPort: 443
233+
targetPort: 8443
222234
protocol: TCP
223235
selector:
224236
app: traefik
@@ -239,34 +251,39 @@ spec:
239251
app: traefik
240252
spec:
241253
serviceAccountName: traefik
254+
automountServiceAccountToken: true
255+
securityContext:
256+
runAsNonRoot: true
257+
runAsUser: 65534
258+
seccompProfile:
259+
type: RuntimeDefault
242260
containers:
243261
- name: traefik
244262
image: traefik:v2.10
245263
securityContext:
246264
allowPrivilegeEscalation: false
247-
readOnlyRootFilesystem: false
265+
readOnlyRootFilesystem: true
248266
runAsNonRoot: true
249267
runAsUser: 65534
250268
capabilities:
251269
drop:
252270
- ALL
253-
add:
254-
- NET_BIND_SERVICE
255271
args:
256272
- --providers.kubernetesingress=true
257273
- --providers.kubernetesingress.namespaces=registry,mcp-sentinel,mcp-servers,mcp-servers-org,mcp-servers-public
258-
- --entrypoints.web.address=:80
274+
- --entrypoints.web.address=:8000
259275
- --entrypoints.web.http.redirections.entryPoint.to=websecure
260276
- --entrypoints.web.http.redirections.entryPoint.scheme=https
261-
- --entrypoints.websecure.address=:443
277+
- --entrypoints.websecure.address=:8443
262278
- --entrypoints.websecure.http.tls=true
279+
- --ping=true
263280
- --providers.file.filename=/etc/traefik/dynamic/dynamic.yml
264281
- --providers.file.watch=true
265282
ports:
266283
- name: web
267-
containerPort: 80
284+
containerPort: 8000
268285
- name: websecure
269-
containerPort: 443
286+
containerPort: 8443
270287
- name: admin
271288
containerPort: 8080
272289
volumeMounts:
@@ -280,6 +297,18 @@ spec:
280297
limits:
281298
cpu: 500m
282299
memory: 256Mi
300+
livenessProbe:
301+
httpGet:
302+
path: /ping
303+
port: 8080
304+
initialDelaySeconds: 10
305+
periodSeconds: 20
306+
readinessProbe:
307+
httpGet:
308+
path: /ping
309+
port: 8080
310+
initialDelaySeconds: 5
311+
periodSeconds: 10
283312
volumes:
284313
- name: traefik-dynamic
285314
configMap:

config/ingress/overlays/http/deployment-args.patch.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- --providers.kubernetesingress.namespaces=registry,mcp-sentinel,mcp-servers,mcp-servers-org,mcp-servers-public
66
- --entrypoints.web.address=:8000
77
- --entrypoints.websecure.address=:8443
8+
- --ping=true
89
- --providers.file.filename=/etc/traefik/dynamic/dynamic.yml
910
- --providers.file.watch=true
1011
- op: replace

config/ingress/overlays/prod/traefik-no-redirect.yaml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# Traefik base enables HTTP to HTTPS on :80, which breaks HTTP-01 ACME challenges
2-
# (Let's Encrypt). Use plain HTTP on :80; HTTPS on :443 remains.
1+
# Traefik base enables HTTP to HTTPS, which breaks HTTP-01 ACME challenges
2+
# (Let's Encrypt). Use plain HTTP; HTTPS remains on the secure entrypoint.
33
apiVersion: apps/v1
44
kind: Deployment
55
metadata:
@@ -13,8 +13,9 @@ spec:
1313
args:
1414
- --providers.kubernetesingress=true
1515
- --providers.kubernetesingress.namespaces=registry,mcp-sentinel,mcp-servers,mcp-servers-org,mcp-servers-public
16-
- --entrypoints.web.address=:80
17-
- --entrypoints.websecure.address=:443
16+
- --entrypoints.web.address=:8000
17+
- --entrypoints.websecure.address=:8443
1818
- --entrypoints.websecure.http.tls=true
19+
- --ping=true
1920
- --providers.file.filename=/etc/traefik/dynamic/dynamic.yml
2021
- --providers.file.watch=true

config/manager/kustomization.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
resources:
22
- manager.yaml
3+
- networkpolicy.yaml
34
- pdb.yaml

config/manager/manager.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ apiVersion: v1
22
kind: Namespace
33
metadata:
44
name: mcp-runtime
5+
labels:
6+
pod-security.kubernetes.io/enforce: restricted
7+
pod-security.kubernetes.io/audit: restricted
8+
pod-security.kubernetes.io/warn: restricted
59
---
610
apiVersion: apps/v1
711
kind: Deployment
@@ -19,6 +23,7 @@ spec:
1923
control-plane: controller-manager
2024
spec:
2125
serviceAccountName: mcp-runtime-operator-controller-manager
26+
automountServiceAccountToken: true
2227
securityContext:
2328
runAsNonRoot: true
2429
seccompProfile:

config/manager/networkpolicy.yaml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
apiVersion: networking.k8s.io/v1
2+
kind: NetworkPolicy
3+
metadata:
4+
name: mcp-runtime-default-deny
5+
namespace: mcp-runtime
6+
spec:
7+
podSelector: {}
8+
policyTypes:
9+
- Ingress
10+
- Egress
11+
---
12+
apiVersion: networking.k8s.io/v1
13+
kind: NetworkPolicy
14+
metadata:
15+
name: mcp-runtime-allow-egress
16+
namespace: mcp-runtime
17+
spec:
18+
podSelector:
19+
matchLabels:
20+
control-plane: controller-manager
21+
policyTypes:
22+
- Egress
23+
egress:
24+
- to:
25+
- namespaceSelector:
26+
matchLabels:
27+
kubernetes.io/metadata.name: kube-system
28+
podSelector:
29+
matchLabels:
30+
k8s-app: kube-dns
31+
ports:
32+
- protocol: UDP
33+
port: 53
34+
- protocol: TCP
35+
port: 53
36+
# The operator reconciles cluster resources through the Kubernetes API.
37+
- ports:
38+
- protocol: TCP
39+
port: 443
40+
- to:
41+
- namespaceSelector:
42+
matchLabels:
43+
kubernetes.io/metadata.name: registry
44+
ports:
45+
- protocol: TCP
46+
port: 5000

config/registry/base/deployment.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ spec:
2020
runAsUser: 1000
2121
runAsGroup: 1000
2222
fsGroup: 1000
23+
seccompProfile:
24+
type: RuntimeDefault
2325
containers:
2426
- name: registry
2527
image: registry:2.8.3
@@ -30,7 +32,10 @@ spec:
3032
securityContext:
3133
allowPrivilegeEscalation: false
3234
runAsNonRoot: true
33-
readOnlyRootFilesystem: false
35+
readOnlyRootFilesystem: true
36+
capabilities:
37+
drop:
38+
- ALL
3439
env:
3540
- name: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY
3641
value: /var/lib/registry
@@ -39,6 +44,8 @@ spec:
3944
volumeMounts:
4045
- name: registry-storage
4146
mountPath: /var/lib/registry
47+
- name: tmp
48+
mountPath: /tmp
4249
resources:
4350
requests:
4451
cpu: 100m
@@ -62,3 +69,5 @@ spec:
6269
- name: registry-storage
6370
persistentVolumeClaim:
6471
claimName: registry-storage
72+
- name: tmp
73+
emptyDir: {}

config/registry/base/kustomization.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ resources:
66
- deployment.yaml
77
- service.yaml
88
- ingress.yaml
9+
- networkpolicy.yaml
910
- pdb.yaml

0 commit comments

Comments
 (0)