Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix internet exposure rules #646

Merged
merged 10 commits into from
Jan 15, 2025
53 changes: 46 additions & 7 deletions rules/exposure-to-internet-via-gateway-api/raw.rego
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ deny[msga] {
not is_exposed_service(svc)

wl := input[_]
wl.metadata.namespace == svc.metadata.namespace
is_same_namespace(wl.metadata, svc.metadata)
spec_template_spec_patterns := {"Deployment", "ReplicaSet", "DaemonSet", "StatefulSet", "Pod", "Job", "CronJob"}
spec_template_spec_patterns[wl.kind]
wl_connected_to_service(wl, svc)
pod := get_pod_spec(wl)["spec"]
wl_connected_to_service(pod, svc)

result := svc_connected_to_httproute(svc, httproute)

Expand Down Expand Up @@ -56,18 +57,56 @@ is_exposed_service(svc) {
svc.spec.type == "LoadBalancer"
}

wl_connected_to_service(wl, svc) {
wl_connected_to_service(wl, svc) {


count({x | svc.spec.selector[x] == wl.metadata.labels[x]}) == count(svc.spec.selector)
}

wl_connected_to_service(wl, svc) {
wl.spec.selector.matchLabels == svc.spec.selector

is_same_namespace(metadata1, metadata2) {
metadata1.namespace == metadata2.namespace
}

wl_connected_to_service(wl, svc) {
count({x | svc.spec.selector[x] == wl.spec.template.metadata.labels[x]}) == count(svc.spec.selector)
is_same_namespace(metadata1, metadata2) {
not metadata1.namespace
not metadata2.namespace
}

is_same_namespace(metadata1, metadata2) {
not metadata2.namespace
metadata1.namespace == "default"
}

is_same_namespace(metadata1, metadata2) {
not metadata1.namespace
metadata2.namespace == "default"
}



# get_volume - get resource spec paths for {"Deployment","ReplicaSet","DaemonSet","StatefulSet","Job"}
get_pod_spec(resources) := result {
resources_kinds := {"Deployment","ReplicaSet","DaemonSet","StatefulSet","Job"}
resources_kinds[resources.kind]
result = {"spec": resources.spec.template, "start_of_path": "spec.template."}
}

# get_volume - get resource spec paths for "Pod"
get_pod_spec(resources) := result {
resources.kind == "Pod"
result = {"spec": resources, "start_of_path": ""}
}

# get_volume - get resource spec paths for "CronJob"
get_pod_spec(resources) := result {
resources.kind == "CronJob"
result = {"spec": resources.spec.jobTemplate.spec.template.spec, "start_of_path": "spec.jobTemplate.spec.template.spec."}
}




svc_connected_to_httproute(svc, httproute) = result {
rule := httproute.spec.rules[i]
ref := rule.backendRefs[j]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
[
{
"alertMessage": "workload 'httpbin' is exposed through httproute 'httpbin'",
"failedPaths": [],
"fixPaths": [],
"ruleStatus": "",
"packagename": "armo_builtins",
"alertScore": 7,
"alertObject": {
"k8sApiObjects": [
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "httpbin"
}
}
]
},
"relatedObjects": [
{
"object": {
"apiVersion": "gateway.networking.k8s.io/v1",
"kind": "HTTPRoute",
"metadata": {
"creationTimestamp": "2024-02-04T19:06:03Z",
"generation": 1,
"labels": {
"example": "httpbin-route"
},
"name": "httpbin",
"namespace": "httpbin",
"resourceVersion": "914",
"uid": "fd820080-801d-4fa7-934a-e23abe8bf746"
},
"spec": {
"hostnames": [
"www.example.com"
],
"parentRefs": [
{
"group": "gateway.networking.k8s.io",
"kind": "Gateway",
"name": "http",
"namespace": "gloo-system"
}
],
"rules": [
{
"backendRefs": [
{
"group": "",
"kind": "Service",
"name": "httpbin",
"port": 8000,
"weight": 1
}
],
"matches": [
{
"path": {
"type": "PathPrefix",
"value": "/"
}
}
]
}
]
},
"status": {
"parents": [
{
"conditions": [
{
"lastTransitionTime": "2024-02-04T19:06:03Z",
"message": "",
"observedGeneration": 1,
"reason": "Accepted",
"status": "True",
"type": "Accepted"
},
{
"lastTransitionTime": "2024-02-04T19:06:03Z",
"message": "",
"observedGeneration": 1,
"reason": "ResolvedRefs",
"status": "True",
"type": "ResolvedRefs"
}
],
"controllerName": "solo.io/gloo-gateway",
"parentRef": {
"group": "gateway.networking.k8s.io",
"kind": "Gateway",
"name": "http",
"namespace": "gloo-system"
}
}
]
}
},
"failedPaths": [
"spec.rules[0].backendRefs[0].name"
],
"reviewPaths": [
"spec.rules[0].backendRefs[0].name"
]
},
{
"object": {
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"creationTimestamp": "2024-02-04T19:05:12Z",
"labels": {
"app": "httpbin",
"service": "httpbin"
},
"name": "httpbin",
"namespace": "httpbin",
"resourceVersion": "811",
"uid": "c391feb7-54e5-41b2-869b-33166869f1b7"
},
"spec": {
"clusterIP": "10.96.162.234",
"clusterIPs": [
"10.96.162.234"
],
"internalTrafficPolicy": "Cluster",
"ipFamilies": [
"IPv4"
],
"ipFamilyPolicy": "SingleStack",
"ports": [
{
"name": "http",
"port": 8000,
"protocol": "TCP",
"targetPort": 8080
},
{
"name": "tcp",
"port": 9000,
"protocol": "TCP",
"targetPort": 9000
}
],
"selector": {
"app": "httpbin"
},
"sessionAffinity": "None",
"type": "ClusterIP"
},
"status": {
"loadBalancer": {}
}
}
}
]
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: "2024-02-04T19:05:12Z"
generation: 1
name: httpbin
namespace: httpbin
resourceVersion: "870"
uid: 7462bb4c-b5a2-413e-80ee-c1baaf34aade
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: httpbin
version: v1
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: httpbin
version: v1
spec:
containers:
- args:
- -port
- "8080"
- -max-duration
- 600s
command:
- go-httpbin
image: docker.io/mccutchen/go-httpbin:v2.6.0
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 8080
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
- command:
- tail
- -f
- /dev/null
image: curlimages/curl:7.83.1
imagePullPolicy: IfNotPresent
name: curl
resources:
limits:
cpu: 200m
requests:
cpu: 100m
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
- image: gcr.io/solo-public/docs/hey:0.1.4
imagePullPolicy: IfNotPresent
name: hey
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: httpbin
serviceAccountName: httpbin
terminationGracePeriodSeconds: 30
status:
availableReplicas: 1
conditions:
- lastTransitionTime: "2024-02-04T19:05:32Z"
lastUpdateTime: "2024-02-04T19:05:32Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
- lastTransitionTime: "2024-02-04T19:05:12Z"
lastUpdateTime: "2024-02-04T19:05:32Z"
message: ReplicaSet "httpbin-f46cc8b9b" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
observedGeneration: 1
readyReplicas: 1
replicas: 1
updatedReplicas: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
creationTimestamp: "2024-02-04T19:06:03Z"
generation: 1
labels:
example: httpbin-route
name: httpbin
namespace: httpbin
resourceVersion: "914"
uid: fd820080-801d-4fa7-934a-e23abe8bf746
spec:
hostnames:
- www.example.com
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: http
namespace: gloo-system
rules:
- backendRefs:
- group: ""
kind: Service
name: httpbin
port: 8000
weight: 1
matches:
- path:
type: PathPrefix
value: /
status:
parents:
- conditions:
- lastTransitionTime: "2024-02-04T19:06:03Z"
message: ""
observedGeneration: 1
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2024-02-04T19:06:03Z"
message: ""
observedGeneration: 1
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: solo.io/gloo-gateway
parentRef:
group: gateway.networking.k8s.io
kind: Gateway
name: http
namespace: gloo-system
Loading
Loading