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

Aws controls #1

Merged
merged 2 commits into from
Dec 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 15 additions & 1 deletion controls/eks-cis-2.1.1.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# encoding: UTF-8

control 'eks-cis-2.1.1' do
title 'draft'
title 'Enable audit logs'
desc "The audit logs are part of the EKS managed Kubernetes control plane
logs that are managed by Amazon EKS. Amazon EKS is integrated with AWS
CloudTrail, a service that provides a record of actions taken by a user, role,
Expand Down Expand Up @@ -63,5 +63,19 @@
tag cis_level: 1
tag cis_controls: ['6', 'Rev_7']
tag cis_rid: '2.1.1'

region = input('cluster-region')
name = input('cluster-name')

log_types_enabled = json({command: "aws eks describe-cluster --region #{region} --name #{name} --query cluster.logging.clusterLogging[?enabled].types"}).flatten

describe "All five logging types should be enabled" do
subject { log_types_enabled }
it { should include 'api' }
it { should include 'audit' }
it { should include 'authentication' }
it { should include 'controllerManager' }
it { should include 'scheduler' }
end
end

15 changes: 15 additions & 0 deletions controls/eks-cis-4.1.1.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,20 @@
tag cis_level: 1
tag cis_controls: ['5.1', 'Rev_6']
tag cis_rid: '4.1.1'

allowed_cluster_admin_principals = input('allowed_cluster_admin_principals')

options = {
assignment_regex: /^([^\s]*?)\s*([^\s]*?)$/
}

rolebindings = parse_config(command("kubectl get clusterrolebindings cluster-admin --no-headers -o=custom-columns='NAME:.metadata.name,SUBJECT:.subjects[*].name'").stdout, options)

rolebindings.params.each do |rb|
describe "Cluster role bindings should restrict access to cluster-admin role" do
subject { rb.last }
it { should be_in allowed_cluster_admin_principals }
end
end
end

21 changes: 21 additions & 0 deletions controls/eks-cis-4.1.6.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,26 @@
tag cis_level: 1
tag cis_controls: ['5.1', 'Rev_6']
tag cis_rid: '4.1.6'

pods = command("kubectl get pods --all-namespaces -o=custom-columns='NAME:.metadata.name,AUTOMOUNT:.spec.automountServiceAccountToken'")
service_accounts = command("kubectl get serviceaccounts --all-namespaces -o=custom-columns='NAME:.metadata.name,AUTOMOUNT:.spec.automountServiceAccountToken'")

options = {
assignment_regex: /^([^\s]*?)\s*([^\s]*?)$/
}

parse_config(pods.stdout, options).params.each do |pod|
describe "Pod #{pod[0]} automountServiceAccountToken" do
subject { pod[1] }
it { should cmp "false" }
end
end

parse_config(service_accounts.stdout, options).params.each do |service_account|
describe "Service account #{service_account[0]} automountServiceAccountToken" do
subject { service_account[1] }
it { should cmp "false" }
end
end
end

13 changes: 12 additions & 1 deletion controls/eks-cis-5.3.1.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# encoding: UTF-8

control 'eks-cis-5.3.1' do
title 'draft'
title 'Ensure Kubernetes Secrets are encrypted using Customer Master
Keys (CMKs) managed in AWS KMS'
desc "Encrypt Kubernetes secrets, stored in etcd, using secrets encryption
feature during Amazon EKS cluster creation."
desc 'rationale', "
Expand Down Expand Up @@ -48,5 +49,15 @@
tag cis_level: 1
tag cis_controls: ['14.8', 'Rev_7']
tag cis_rid: '5.3.1'

region = input('cluster-region')
name = input('cluster-name')

encryption_enabled = json({command: "aws eks describe-cluster --region #{region} --name #{name} --query cluster.logging.clusterLogging[?enabled].types"}).flatten

describe "Encryption configuration" do
subject { encryption_enabled }
it { should exist }
end
end

35 changes: 34 additions & 1 deletion controls/eks-cis-5.4.1.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# encoding: UTF-8

control 'eks-cis-5.4.1' do
title 'draft'
title 'Restrict Access to the Control Plane Endpoint'
desc "Enable Endpoint Private Access to restrict access to the cluster's
control plane to only an allowlist of authorized IPs."
desc 'rationale', "
Expand Down Expand Up @@ -125,5 +125,38 @@
tag cis_level: 1
tag cis_controls: ['14.6', 'Rev_7']
tag cis_rid: '5.4.1'

region = input('cluster-region')
name = input('cluster-name')

expected_allowlist = input('allowlist_cidr_blocks')

access_restrictions = json({command: "aws eks describe-cluster --region #{region} --name #{name} --query cluster.resourcesVpcConfig"})
actual_allowlist = access_restrictions['publicAccessCidrs']


describe "Private access should be enabled" do
subject { access_restrictions }
its('endpointPrivateAccess') { should be true }
end

describe.one do
describe "Public access should be disabled" do
subject { access_restrictions }
its('endpointPublicAccess') { should be false }
end
describe "Public access should be restricted to an allowlist of CIDR blocks" do
subject { allowlist }
it { should exist }
end
end
if actual_allowlist
actual_allowlist.each do |cidr|
describe "Cluster allowlist should match expected allowlist" do
subject { cidr }
it { should be_in expected_allowlist }
end
end
end
end

35 changes: 34 additions & 1 deletion controls/eks-cis-5.4.2.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# encoding: UTF-8

control 'eks-cis-5.4.2' do
title 'draft'
title 'Ensure clusters are created with Private Endpoint Enabled and
Public Access Disabled'
desc "Disable access to the Kubernetes API from outside the node network if
it is not required."
desc 'rationale', "
Expand Down Expand Up @@ -33,5 +34,37 @@
tag cis_level: 2
tag cis_controls: ['12', 'Rev_7']
tag cis_rid: '5.4.2'

region = input('cluster-region')
name = input('cluster-name')

expected_allowlist = input('allowlist_cidr_blocks')

access_restrictions = json({command: "aws eks describe-cluster --region #{region} --name #{name} --query cluster.resourcesVpcConfig"})
actual_allowlist = access_restrictions['publicAccessCidrs']

describe "Private access should be enabled" do
subject { access_restrictions }
its('endpointPrivateAccess') { should be true }
end

describe.one do
describe "Public access should be disabled" do
subject { access_restrictions }
its('endpointPublicAccess') { should be false }
end
describe "Public access should be restricted to an allowlist of CIDR blocks" do
subject { allowlist }
it { should exist }
end
end
if actual_allowlist
actual_allowlist.each do |cidr|
describe "Cluster allowlist should match expected allowlist" do
subject { cidr }
it { should be_in expected_allowlist }
end
end
end
end

11 changes: 10 additions & 1 deletion controls/eks-cis-5.4.3.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# encoding: UTF-8

control 'eks-cis-5.4.3' do
title 'draft'
title 'Ensure clusters are created with Private Nodes'
desc "Disable public IP addresses for cluster nodes, so that they only have
private IP addresses. Private Nodes are nodes with no public IP addresses."
desc 'rationale', "Disabling public IP addresses on cluster nodes restricts
Expand All @@ -21,5 +21,14 @@
tag cis_level: 1
tag cis_controls: ['12', 'Rev_7']
tag cis_rid: '5.4.3'

address_key = os.windows? ? '\"ExternalIP\"' : 'ExternalIP'

node_external_addresses = command("kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type==#{address_key})].address}'").stdout.strip

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this check refers to the presence of public ip in the EKS managed EC2 nodes not he K8S configs.

So the solution could be using aws cli to query list of EC2 managed nodes within the specified EKS cluster and using another aws cli command to check if they have public IP defined.

describe "The list of externally accessible IP addresses for nodes" do
subject { node_external_addresses }
it { should be_empty }
end
end

26 changes: 26 additions & 0 deletions inspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,29 @@ copyright_email: .
license: Apache-2.0
summary: InSpec Profile for AWS EKS CIS Benchmark v1.0.1
version: 0.1.0

inputs:
- name: cluster-name
description: "The name of the EKS cluster under test"
type: String
required: true
value: "eks-test"

- name: cluster-region
description: "The region hosting the EKS cluster under test"
type: String
required: true
value: "us-east-1"

# 4.1.1
- name: allowed_cluster_admin_principals
description: "Principal subjects allowed to hold the cluster-admin role"
type: Array
required: true
default: ["system:admin"]

- name: allowlist_cidr_blocks
description: "IPs from within these CIDR blocks should be the only ones allowed to access the cluster via k8s API from outside the VPC"
type: Array
required: true
default: ["0.0.0.0/0"]