Skip to content

Commit 8ae4547

Browse files
authored
feat: Convert policies to v1 (#2467)
[draft for easier reviewing at #2466] - fixed many issues of duplicate rows. Each resources tested must have a single line in the output (but if our SELECT query joins with subtables, each resource may have many rows... ). - removed endpoint_api_serve_on_secure_port.. The check tested that the k8s-api was served on port 6443 or 443. But obviously the port number has very little to do with security. NSA-Cisa [page 18], of course, doesn't specify that these must be the port numbers. e.g. minikube uses port 8443 instead of 6443. The check also tested the port 'name', but that of course also doesn't necesarrily indicate the actual protocol used... - fixed `default_deny_ingress` and `default_deny_egress` policies to actually work (they always returned fail until now). Also deleted `default_dont_allow_ingress` and `default_dont_deny_egress`, since they seem to be duplicates of the `deny` policy? https://media.defense.gov/2022/Aug/29/2003066362/-1/-1/0/CTR_KUBERNETES_HARDENING_GUIDANCE_1.2_20220829.PDF <!-- 🎉 Thank you for making CloudQuery awesome by submitting a PR 🎉 --> #### Summary <!-- Explain what problem this PR addresses --> <!-- Use the following steps to ensure your PR is ready to be reviewed - [ ] Read the [contribution guidelines](../blob/main/CONTRIBUTING.md) 🧑‍🎓 - [ ] Test locally on your own infrastructure - [ ] Run `go fmt` to format your code 🖊 - [ ] Lint your changes via `golangci-lint run` 🚨 (install golangci-lint [here](https://golangci-lint.run/usage/install/#local-installation)) - [ ] Update or add tests 🧪 - [ ] Ensure the status checks below are successful ✅ --->
1 parent 9cd9dab commit 8ae4547

File tree

67 files changed

+1625
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+1625
-0
lines changed

plugins/source/k8s/policies/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Deprecation Notice
2+
3+
These are the policy files for CloudQuery **v0.x.x**. Please use the [policies_v1/](../policies_v1/) directory for CloudQuery v1.x.x policies.
4+
15
# CloudQuery Policies
26

37
CloudQuery SQL Policies for Kubernetes
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# CloudQuery Policies
2+
3+
CloudQuery SQL Policies for Kubernetes
4+
5+
## Policies and Compliance Frameworks Available
6+
7+
- [Kubernetes NSA CISA v1](./nsa_cisa_v1/policy.sql)
8+
9+
## Running
10+
11+
You can execute policies with `psql`. For example:
12+
13+
```bash
14+
# Set DSN to your PostgreSQL populated by CloudQuery
15+
export DSN=postgres://postgres:pass@localhost:5432/postgres
16+
# Execute the NSA CISA Policy
17+
psql ${DSN} -f ./nsa_cisa_v1/policy.sql
18+
```
19+
20+
This will create all the results in `k8s_policy_results` table which you can query directly, connect to any BI system (Grafana, Preset, AWS QuickSight, PowerBI, …).
21+
22+
You can also output it into CSV or HTML with the following built-in `psql` commands:
23+
24+
```bash
25+
# Set DSN to your PostgreSQL populated by CloudQuery
26+
export DSN=postgres://postgres:pass@localhost:5432/postgres
27+
# default tabular output
28+
psql ${DSN} -c "select * from k8s_policy_results"
29+
# CSV output
30+
psql ${DSN} -c "select * from k8s_policy_results" --csv
31+
# HTML output
32+
psql ${DSN} -c "select * from k8s_policy_results" --html
33+
```
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
create table if not exists k8s_policy_results
2+
(
3+
execution_time timestamp with time zone,
4+
framework varchar(255),
5+
check_id varchar(255),
6+
title text,
7+
context text,
8+
namespace text,
9+
resource_id varchar(1024),
10+
resource_name text,
11+
status varchar(16)
12+
)

plugins/source/k8s/policies_v1/nsa_cisa_v1/README.md

Whitespace-only changes.
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
\echo "Executing K8S Network Hardening NSA CISA v1"
2+
3+
\echo "Enforce CPU resource limits"
4+
5+
\echo "Deamonsets enforce cpu limit"
6+
\set check_id "daemonset_cpu_limit"
7+
\ir ../queries/network_hardening/daemonset_cpu_limit.sql
8+
9+
\echo "Deployments enforce cpu limit"
10+
\set check_id "deployment_cpu_limit"
11+
\ir ../queries/network_hardening/deployment_cpu_limit.sql
12+
13+
\echo "Jobs enforce cpu limit"
14+
\set check_id "job_cpu_limit"
15+
\ir ../queries/network_hardening/job_cpu_limit.sql
16+
17+
18+
\echo "Namespaces CPU limit range default"
19+
\set check_id "namespace_limit_range_default_cpu_limit"
20+
\ir ../queries/network_hardening/namespace_limit_range_default_cpu_limit.sql
21+
22+
23+
\echo "Namespaces CPU limit resource quota"
24+
\set check_id "namespace_resource_quota_cpu_limit"
25+
\ir ../queries/network_hardening/namespace_resource_quota_cpu_limit.sql
26+
27+
28+
\echo "ReplciaSets enforce cpu limit"
29+
\set check_id "replicaset_cpu_limit"
30+
\ir ../queries/network_hardening/replicaset_cpu_limit.sql
31+
32+
33+
\echo "Enforce CPU request"
34+
35+
\echo "Deamonsets enforce cpu request"
36+
\set check_id "daemonset_cpu_request"
37+
\ir ../queries/network_hardening/daemonset_cpu_request.sql
38+
39+
\echo "Deployments enforce cpu request"
40+
\set check_id "deployment_cpu_request"
41+
\ir ../queries/network_hardening/deployment_cpu_request.sql
42+
43+
\echo "Jobs enforce cpu request"
44+
\set check_id "job_cpu_limit"
45+
\ir ../queries/network_hardening/job_cpu_limit.sql
46+
47+
48+
\echo "Namespaces CPU request range default"
49+
\set check_id "namespace_limit_range_default_cpu_request"
50+
\ir ../queries/network_hardening/namespace_limit_range_default_cpu_request.sql
51+
52+
53+
\echo "Namespaces CPU request resource quota"
54+
\set check_id "namespace_resource_quota_cpu_request"
55+
\ir ../queries/network_hardening/namespace_resource_quota_cpu_request.sql
56+
57+
58+
\echo "ReplciaSets enforce cpu request"
59+
\set check_id "replicaset_cpu_request"
60+
\ir ../queries/network_hardening/replicaset_cpu_request.sql
61+
62+
\echo "Ensure memory limits set"
63+
64+
\echo "Deamonsets enforce memory limit"
65+
\set check_id "daemonset_memory_limit"
66+
\ir ../queries/network_hardening/daemonset_memory_limit.sql
67+
68+
\echo "Deployments enforce memory limit"
69+
\set check_id "deployment_memory_limit"
70+
\ir ../queries/network_hardening/deployment_memory_limit.sql
71+
72+
\echo "Jobs enforce memory limit"
73+
\set check_id "job_memory_limit"
74+
\ir ../queries/network_hardening/job_memory_limit.sql
75+
76+
77+
\echo "Namespaces CPU memory range default"
78+
\set check_id "namespace_limit_range_default_memory_limit"
79+
\ir ../queries/network_hardening/namespace_limit_range_default_memory_limit.sql
80+
81+
82+
\echo "Namespaces CPU memory resource quota"
83+
\set check_id "namespace_resource_quota_memory_limit"
84+
\ir ../queries/network_hardening/namespace_resource_quota_memory_limit.sql
85+
86+
87+
\echo "ReplciaSets enforce memory limit"
88+
\set check_id "replicaset_memory_limit"
89+
\ir ../queries/network_hardening/replicaset_memory_limit.sql
90+
91+
92+
\echo "Enforce Memory request"
93+
94+
\echo "Deamonsets enforce memory request"
95+
\set check_id "daemonset_memory_request"
96+
\ir ../queries/network_hardening/daemonset_memory_request.sql
97+
98+
\echo "Deployments enforce memory request"
99+
\set check_id "deployment_memory_request"
100+
\ir ../queries/network_hardening/deployment_memory_request.sql
101+
102+
\echo "Jobs enforce memory request"
103+
\set check_id "job_memory_request"
104+
\ir ../queries/network_hardening/job_memory_request.sql
105+
106+
107+
\echo "Namespaces Memory request range default"
108+
\set check_id "namespace_limit_range_default_memory_request"
109+
\ir ../queries/network_hardening/namespace_limit_range_default_memory_request.sql
110+
111+
112+
\echo "Namespaces Memory request resource quota"
113+
\set check_id "namespace_resource_quota_memory_request"
114+
\ir ../queries/network_hardening/namespace_resource_quota_memory_request.sql
115+
116+
117+
\echo "ReplciaSets enforce cpu request"
118+
\set check_id "replicaset_memory_request"
119+
\ir ../queries/network_hardening/replicaset_memory_request.sql
120+
121+
122+
\echo "Enforce default deny network policy"
123+
124+
\echo "Network policy default deny egress"
125+
\set check_id "network_policy_default_deny_egress"
126+
\ir ../queries/network_hardening/network_policy_default_deny_egress.sql
127+
128+
129+
\echo "Network policy default deny ingress"
130+
\set check_id "network_policy_default_deny_ingress"
131+
\ir ../queries/network_hardening/network_policy_default_deny_ingress.sql
132+
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
\echo "Executing K8S Pod Security NSA CISA v1"
2+
3+
\set check_id "container_disallow_host_path"
4+
\echo "Disallow host path access"
5+
\ir ../queries/pod_security/pod_volume_host_path.sql
6+
7+
\echo "Verify containers have privileged access disabled"
8+
9+
\echo "Deamonset privileges disabled"
10+
\set check_id "daemonset_container_privilege_disabled"
11+
\ir ../queries/pod_security/daemonset_container_privilege_disabled.sql
12+
13+
\echo "Deployment containers privileged access disabled"
14+
\set check_id "deployment_container_privilege_disabled"
15+
\ir ../queries/pod_security/deployment_container_privilege_disabled.sql
16+
17+
\echo "Jobs container privileged access disabled"
18+
\set check_id "job_container_privilege_disabled"
19+
\ir ../queries/pod_security/job_container_privilege_disabled.sql
20+
21+
\echo "Pod container privileged access disabled"
22+
\set check_id "pod_container_privilege_disabled"
23+
\ir ../queries/pod_security/pod_container_privilege_disabled.sql
24+
25+
\echo "ReplicaSet container privileged access disabled"
26+
\set check_id "replicaset_container_privilege_disabled"
27+
\ir ../queries/pod_security/replicaset_container_privilege_disabled.sql
28+
29+
\echo "Container privileged escalation disabled"
30+
31+
\echo "DaemonSet container privileged escalation disabled"
32+
\set check_id "daemonset_container_privilege_escalation_disabled"
33+
\ir ../queries/pod_security/daemonset_container_privilege_escalation_disabled.sql
34+
35+
\echo "Deployment container privileged escalation disabled"
36+
\set check_id "deployment_container_privilege_escalation_disabled"
37+
\ir ../queries/pod_security/deployment_container_privilege_escalation_disabled.sql
38+
39+
\echo "Job container privileged escalation disabled"
40+
\set check_id "job_container_privilege_escalation_disabled"
41+
\ir ../queries/pod_security/job_container_privilege_escalation_disabled.sql
42+
43+
\echo "Pod container privileged escalation disabled"
44+
\set check_id "pod_container_privilege_escalation_disabled"
45+
\ir ../queries/pod_security/pod_container_privilege_escalation_disabled.sql
46+
47+
\echo "ReplicaSet container privileged escalation disabled"
48+
\set check_id "replicaset_container_privilege_escalation_disabled"
49+
\ir ../queries/pod_security/replicaset_container_privilege_escalation_disabled.sql
50+
51+
52+
\echo "Host network access disabled"
53+
54+
\echo "DaemonSet container hostNetwork disabled"
55+
\set check_id "daemonset_host_network_access_disabled"
56+
\ir ../queries/pod_security/daemonset_host_network_access_disabled.sql
57+
58+
\echo "Deployment container hostNetwork disabled"
59+
\set check_id "deployment_host_network_access_disabled"
60+
\ir ../queries/pod_security/deployment_host_network_access_disabled.sql
61+
62+
\echo "Job container hostNetwork disabled"
63+
\set check_id "job_host_network_access_disabled"
64+
\ir ../queries/pod_security/job_host_network_access_disabled.sql
65+
66+
\echo "Pod container hostNetwork disabled"
67+
\set check_id "pod_container_privilege_escalation_disabled"
68+
\ir ../queries/pod_security/pod_host_network_access_disabled.sql
69+
70+
\echo "ReplicaSet container hostNetwork disabled"
71+
\set check_id "replicaset_container_privilege_escalation_disabled"
72+
\ir ../queries/pod_security/replicaset_host_network_access_disabled.sql
73+
74+
75+
\echo "HostPID and HostIPC sharing disabled"
76+
77+
\echo "DeamonSet containers HostPID and HostIPC sharing disabled"
78+
\set check_id "daemonset_hostpid_hostipc_sharing_disabled"
79+
\ir ../queries/pod_security/daemonset_hostpid_hostipc_sharing_disabled.sql
80+
81+
\echo "Deployment containers HostPID and HostIPC sharing disabled"
82+
\set check_id "deployment_hostpid_hostipc_sharing_disabled"
83+
\ir ../queries/pod_security/deployment_hostpid_hostipc_sharing_disabled.sql
84+
85+
\echo "Job containers HostPID and HostIPC sharing disabled"
86+
\set check_id "job_hostpid_hostipc_sharing_disabled"
87+
\ir ../queries/pod_security/job_hostpid_hostipc_sharing_disabled.sql
88+
89+
\echo "Pod containers HostPID and HostIPC sharing disabled"
90+
\set check_id "pod_hostpid_hostipc_sharing_disabled"
91+
\ir ../queries/pod_security/pod_hostpid_hostipc_sharing_disabled.sql
92+
93+
\echo "ReplicaSet containers HostPID and HostIPC sharing disabled"
94+
\set check_id "replicaset_hostpid_hostipc_sharing_disabled"
95+
\ir ../queries/pod_security/replicaset_hostpid_hostipc_sharing_disabled.sql
96+
97+
\echo "Containers root file system is read-only"
98+
99+
\echo "DeamonSet containers root file system is read-only"
100+
\set check_id "daemonset_immutable_container_filesystem"
101+
\ir ../queries/pod_security/daemonset_immutable_container_filesystem.sql
102+
103+
\echo "Deployment containers root file system is read-only"
104+
\set check_id "deployment_immutable_container_filesystem"
105+
\ir ../queries/pod_security/deployment_immutable_container_filesystem.sql
106+
107+
\echo "Job containers root file system is read-only"
108+
\set check_id "job_immutable_container_filesystem"
109+
\ir ../queries/pod_security/job_immutable_container_filesystem.sql
110+
111+
\echo "Pod containers root file system is read-only"
112+
\set check_id "pod_immutable_container_filesystem"
113+
\ir ../queries/pod_security/pod_immutable_container_filesystem.sql
114+
115+
\echo "ReplicaSet containers root file system is read-only"
116+
\set check_id "replicaset_immutable_container_filesystem"
117+
\ir ../queries/pod_security/replicaset_immutable_container_filesystem.sql
118+
119+
120+
\echo "Enforce containers to run as non-root"
121+
122+
\echo "DeamonSet containers to run as non-root"
123+
\set check_id "daemonset_non_root_container"
124+
\ir ../queries/pod_security/daemonset_non_root_container.sql
125+
126+
\echo "Deployment containers to run as non-root"
127+
\set check_id "deployment_non_root_container"
128+
\ir ../queries/pod_security/deployment_non_root_container.sql
129+
130+
\echo "Job containers to run as non-root"
131+
\set check_id "job_non_root_container"
132+
\ir ../queries/pod_security/job_non_root_container.sql
133+
134+
\echo "Pod containers to run as non-root"
135+
\set check_id "pod_non_root_container"
136+
\ir ../queries/pod_security/pod_non_root_container.sql
137+
138+
\echo "ReplicaSet containers to run as non-root"
139+
\set check_id "replicaset_non_root_container"
140+
\ir ../queries/pod_security/replicaset_non_root_container.sql
141+
142+
143+
\echo "Automatic mapping of the service account tokens disabled"
144+
145+
\echo "Pod service account tokens disabled"
146+
\set check_id "pod_service_account_token_disabled"
147+
\ir ../queries/pod_security/pod_service_account_token_disabled.sql
148+
149+
\echo "Service account tokens disabled"
150+
\set check_id "service_account_token_disabled"
151+
\ir ../queries/pod_security/service_account_token_disabled.sql
152+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
\set ON_ERROR_STOP on
2+
SET TIME ZONE 'UTC';
3+
-- neat trick to set execution_time if not already set
4+
-- https://stackoverflow.com/questions/32582600/only-set-variable-in-psql-script-if-not-specified-on-the-command-line
5+
\set execution_time :execution_time
6+
SELECT CASE
7+
WHEN :'execution_time' = ':execution_time' THEN to_char(now(), 'YYYY-MM-dd HH24:MI:SS.US')
8+
ELSE :'execution_time'
9+
END AS "execution_time" \gset
10+
11+
\set framework 'cis_v1.2.0'
12+
13+
\ir ../create_k8s_policy_results.sql
14+
\ir ./network_hardening.sql
15+
\ir ./pod_security.sql
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
\set ON_ERROR_STOP on
2+
SET TIME ZONE 'UTC';
3+
-- neat trick to set execution_time if not already set
4+
-- https://stackoverflow.com/questions/32582600/only-set-variable-in-psql-script-if-not-specified-on-the-command-line
5+
\set execution_time :execution_time
6+
SELECT CASE
7+
WHEN :'execution_time' = ':execution_time' THEN to_char(now(), 'YYYY-MM-dd HH24:MI:SS.US')
8+
ELSE :'execution_time'
9+
END AS "execution_time" \gset
10+
11+
\ir nsa_cisa_v1/policy.sql
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
-- Join every row in the daemonset table with its json array of containers.
2+
WITH daemonset_containers AS (SELECT uid, value AS container
3+
FROM k8s_apps_daemon_sets
4+
CROSS JOIN jsonb_array_elements(spec_template->'spec'->'containers') AS value)
5+
6+
INSERT INTO k8s_policy_results (resource_id, execution_time, framework, check_id, title, context, namespace,
7+
resource_name, status)
8+
select uid AS resource_id,
9+
:'execution_time'::timestamp AS execution_time,
10+
:'framework' AS framework,
11+
:'check_id' AS check_id,
12+
'Daemonset enforces cpu limits' AS title,
13+
context AS context,
14+
namespace AS namespace,
15+
name AS resource_name,
16+
CASE
17+
WHEN
18+
-- Every container needs to have a CPU limit for the check to pass
19+
(SELECT COUNT(*) FROM daemonset_containers WHERE daemonset_containers.uid = k8s_apps_daemon_sets.uid AND
20+
daemonset_containers.container->'resources'->'limits'->>'cpu' IS NULL) > 0
21+
THEN 'fail'
22+
ELSE 'pass'
23+
END AS status
24+
FROM k8s_apps_daemon_sets
25+

0 commit comments

Comments
 (0)