Merge pull request #2939 from paraglade/v2.5.4-security-cis

V2.5.4 release candidate updates for CIS 1.6 guides
This commit is contained in:
Nelson Roberts
2021-01-07 13:37:09 -07:00
committed by GitHub
15 changed files with 4153 additions and 31 deletions
+4
View File
@@ -7,3 +7,7 @@ package-lock.json
.DS_Store
.vscode/settings.json
/scripts/converters/output
/scripts/converters/results_to_markdown/*.json
/scripts/converters/results_to_markdown/.terraform
/scripts/converters/results_to_markdown/terraform.tfstate*
/scripts/converters/results_to_markdown/*.tfvars
@@ -1,6 +1,6 @@
---
title: CIS 1.5 Benchmark - Self-Assessment Guide - Rancher v2.5
weight: 204
weight: 201
---
### CIS v1.5 Kubernetes Benchmark - Rancher v2.5 with Kubernetes v1.15
@@ -1,6 +1,6 @@
---
title: Hardening Guide with CIS 1.5 Benchmark
weight: 99
weight: 200
---
This document provides prescriptive guidance for hardening a production installation of a RKE cluster to be used with Rancher v2.5. It outlines the configurations and controls required to address Kubernetes benchmark controls from the Center for Information Security (CIS).
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,538 @@
---
title: Hardening Guide with CIS 1.6 Benchmark
weight: 100
---
This document provides prescriptive guidance for hardening a production installation of a RKE cluster to be used with Rancher v2.5.4. It outlines the configurations and controls required to address Kubernetes benchmark controls from the Center for Information Security (CIS).
> This hardening guide describes how to secure the nodes in your cluster, and it is recommended to follow this guide before installing Kubernetes.
This hardening guide is intended to be used for RKE clusters and associated with specific versions of the CIS Kubernetes Benchmark, Kubernetes, and Rancher:
Rancher Version | CIS Benchmark Version | Kubernetes Version
----------------|-----------------------|------------------
Rancher v2.5.4 | Benchmark 1.6 | Kubernetes v1.18
[Click here to download a PDF version of this document](https://releases.rancher.com/documents/security/2.5/Rancher_Hardening_Guide_CIS_1.6.pdf)
### Overview
This document provides prescriptive guidance for hardening a RKE cluster to be used for installing Rancher v2.5.4 with Kubernetes v1.18 or provisioning a RKE cluster with Kubernetes v1.18 to be used within Rancher v2.5.4. It outlines the configurations required to address Kubernetes benchmark controls from the Center for Information Security (CIS).
For more detail about evaluating a hardened cluster against the official CIS benchmark, refer to the [CIS 1.6 Benchmark - Self-Assessment Guide - Rancher v2.5.4]({{< baseurl >}}/rancher/v2.x/en/security/rancher-2.5/1.6-benchmark-2.5/).
#### Known Issues
- Rancher **exec shell** and **view logs** for pods are **not** functional in a CIS 1.6 hardened setup when only public IP is provided when registering custom nodes. This functionality requires a private IP to be provided when registering the custom nodes.
- When setting the `default_pod_security_policy_template_id:` to `restricted` Rancher creates **RoleBindings** and **ClusterRoleBindings** on the default service accounts. The CIS 1.6 5.1.5 check requires the default service accounts have no roles or cluster roles bound to it apart from the defaults. In addition the default service accounts should be configured such that it does not provide a service account token and does not have any explicit rights assignments.
### Configure Kernel Runtime Parameters
The following `sysctl` configuration is recommended for all nodes type in the cluster. Set the following parameters in `/etc/sysctl.d/90-kubelet.conf`:
```ini
vm.overcommit_memory=1
vm.panic_on_oom=0
kernel.panic=10
kernel.panic_on_oops=1
kernel.keys.root_maxbytes=25000000
```
Run `sysctl -p /etc/sysctl.d/90-kubelet.conf` to enable the settings.
### Configure `etcd` user and group
A user account and group for the **etcd** service is required to be setup prior to installing RKE. The **uid** and **gid** for the **etcd** user will be used in the RKE **config.yml** to set the proper permissions for files and directories during installation time.
#### create `etcd` user and group
To create the **etcd** group run the following console commands.
The commands below use `52034` for **uid** and **gid** are for example purposes. Any valid unused **uid** or **gid** could also be used in lieu of `52034`.
```bash
groupadd --gid 52034 etcd
useradd --comment "etcd service account" --uid 52034 --gid 52034 etcd
```
Update the RKE **config.yml** with the **uid** and **gid** of the **etcd** user:
```yaml
services:
etcd:
gid: 52034
uid: 52034
```
#### Set `automountServiceAccountToken` to `false` for `default` service accounts
Kubernetes provides a default service account which is used by cluster workloads where no specific service account is assigned to the pod. Where access to the Kubernetes API from a pod is required, a specific service account should be created for that pod, and rights granted to that service account. The default service account should be configured such that it does not provide a service account token and does not have any explicit rights assignments.
For each namespace including **default** and **kube-system** on a standard RKE install the **default** service account must include this value:
```yaml
automountServiceAccountToken: false
```
Save the following yaml to a file called `account_update.yaml`
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
automountServiceAccountToken: false
```
Create a bash script file called `account_update.sh`. Be sure to `chmod +x account_update.sh` so the script has execute permissions.
```bash
#!/bin/bash -e
for namespace in $(kubectl get namespaces -A -o json | jq -r '.items[].metadata.name'); do
kubectl patch serviceaccount default -n ${namespace} -p "$(cat account_update.yaml)"
done
```
### Ensure that all Namespaces have Network Policies defined
Running different applications on the same Kubernetes cluster creates a risk of one
compromised application attacking a neighboring application. Network segmentation is
important to ensure that containers can communicate only with those they are supposed
to. A network policy is a specification of how selections of pods are allowed to
communicate with each other and other network endpoints.
Network Policies are namespace scoped. When a network policy is introduced to a given
namespace, all traffic not allowed by the policy is denied. However, if there are no network
policies in a namespace all traffic will be allowed into and out of the pods in that
namespace. To enforce network policies, a CNI (container network interface) plugin must be enabled.
This guide uses [canal](https://github.com/projectcalico/canal) to provide the policy enforcement.
Additional information about CNI providers can be found
[here](https://rancher.com/blog/2019/2019-03-21-comparing-kubernetes-cni-providers-flannel-calico-canal-and-weave/)
Once a CNI provider is enabled on a cluster a default network policy can be applied. For reference purposes a
**permissive** example is provide below. If you want to allow all traffic to all pods in a namespace
(even if policies are added that cause some pods to be treated as “isolated”),
you can create a policy that explicitly allows all traffic in that namespace. Save the following `yaml` as
`default-allow-all.yaml`. Additional [documentation](https://kubernetes.io/docs/concepts/services-networking/network-policies/)
about network policies can be found on the Kubernetes site.
> This `NetworkPolicy` is not recommended for production use
```yaml
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-allow-all
spec:
podSelector: {}
ingress:
- {}
egress:
- {}
policyTypes:
- Ingress
- Egress
```
Create a bash script file called `apply_networkPolicy_to_all_ns.sh`. Be sure to
`chmod +x apply_networkPolicy_to_all_ns.sh` so the script has execute permissions.
```bash
#!/bin/bash -e
for namespace in $(kubectl get namespaces -A -o json | jq -r '.items[].metadata.name'); do
kubectl apply -f default-allow-all.yaml -n ${namespace}
done
```
Execute this script to apply the `default-allow-all.yaml` the **permissive** `NetworkPolicy` to all namespaces.
### Reference Hardened RKE `cluster.yml` configuration
The reference `cluster.yml` is used by the RKE CLI that provides the configuration needed to achieve a hardened install
of Rancher Kubernetes Engine (RKE). Install [documentation](https://rancher.com/docs/rke/latest/en/installation/) is
provided with additional details about the configuration items. This reference `cluster.yml` does not include the required **nodes** directive which will vary depending on your environment. Documentation for node configuration can be found here: https://rancher.com/docs/rke/latest/en/config-options/nodes
```yaml
# If you intend to deploy Kubernetes in an air-gapped environment,
# please consult the documentation on how to configure custom RKE images.
# https://rancher.com/docs/rke/latest/en/installation/
# the nodes directive is required and will vary depending on your environment
# documentation for node configuration can be found here:
# https://rancher.com/docs/rke/latest/en/config-options/nodes
nodes: []
services:
etcd:
image: ""
extra_args: {}
extra_binds: []
extra_env: []
win_extra_args: {}
win_extra_binds: []
win_extra_env: []
external_urls: []
ca_cert: ""
cert: ""
key: ""
path: ""
uid: 52034
gid: 52034
snapshot: true
retention: ""
creation: ""
backup_config: null
kube-api:
image: ""
extra_args: {}
extra_binds: []
extra_env: []
win_extra_args: {}
win_extra_binds: []
win_extra_env: []
service_cluster_ip_range: ""
service_node_port_range: ""
pod_security_policy: true
always_pull_images: false
secrets_encryption_config:
enabled: true
custom_config: null
audit_log:
enabled: true
configuration: null
admission_configuration: null
event_rate_limit:
enabled: true
configuration: null
kube-controller:
image: ""
extra_args:
feature-gates: RotateKubeletServerCertificate=true
extra_binds: []
extra_env: []
win_extra_args: {}
win_extra_binds: []
win_extra_env: []
cluster_cidr: ""
service_cluster_ip_range: ""
scheduler:
image: ""
extra_args: {}
extra_binds: []
extra_env: []
win_extra_args: {}
win_extra_binds: []
win_extra_env: []
kubelet:
image: ""
extra_args:
feature-gates: RotateKubeletServerCertificate=true
protect-kernel-defaults: "true"
tls-cipher-suites: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256
extra_binds: []
extra_env: []
win_extra_args: {}
win_extra_binds: []
win_extra_env: []
cluster_domain: cluster.local
infra_container_image: ""
cluster_dns_server: ""
fail_swap_on: false
generate_serving_certificate: true
kubeproxy:
image: ""
extra_args: {}
extra_binds: []
extra_env: []
win_extra_args: {}
win_extra_binds: []
win_extra_env: []
network:
plugin: ""
options: {}
mtu: 0
node_selector: {}
update_strategy: null
authentication:
strategy: ""
sans: []
webhook: null
addons: |
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: restricted
spec:
requiredDropCapabilities:
- NET_RAW
privileged: false
allowPrivilegeEscalation: false
defaultAllowPrivilegeEscalation: false
fsGroup:
rule: RunAsAny
runAsUser:
rule: MustRunAsNonRoot
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- emptyDir
- secret
- persistentVolumeClaim
- downwardAPI
- configMap
- projected
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-allow-all
spec:
podSelector: {}
ingress:
- {}
egress:
- {}
policyTypes:
- Ingress
- Egress
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
automountServiceAccountToken: false
addons_include: []
system_images:
etcd: ""
alpine: ""
nginx_proxy: ""
cert_downloader: ""
kubernetes_services_sidecar: ""
kubedns: ""
dnsmasq: ""
kubedns_sidecar: ""
kubedns_autoscaler: ""
coredns: ""
coredns_autoscaler: ""
nodelocal: ""
kubernetes: ""
flannel: ""
flannel_cni: ""
calico_node: ""
calico_cni: ""
calico_controllers: ""
calico_ctl: ""
calico_flexvol: ""
canal_node: ""
canal_cni: ""
canal_controllers: ""
canal_flannel: ""
canal_flexvol: ""
weave_node: ""
weave_cni: ""
pod_infra_container: ""
ingress: ""
ingress_backend: ""
metrics_server: ""
windows_pod_infra_container: ""
ssh_key_path: ""
ssh_cert_path: ""
ssh_agent_auth: false
authorization:
mode: ""
options: {}
ignore_docker_version: false
kubernetes_version: v1.18.12-rancher1-1
private_registries: []
ingress:
provider: ""
options: {}
node_selector: {}
extra_args: {}
dns_policy: ""
extra_envs: []
extra_volumes: []
extra_volume_mounts: []
update_strategy: null
http_port: 0
https_port: 0
network_mode: ""
cluster_name:
cloud_provider:
name: ""
prefix_path: ""
win_prefix_path: ""
addon_job_timeout: 0
bastion_host:
address: ""
port: ""
user: ""
ssh_key: ""
ssh_key_path: ""
ssh_cert: ""
ssh_cert_path: ""
monitoring:
provider: ""
options: {}
node_selector: {}
update_strategy: null
replicas: null
restore:
restore: false
snapshot_name: ""
dns: null
upgrade_strategy:
max_unavailable_worker: ""
max_unavailable_controlplane: ""
drain: null
node_drain_input: null
```
### Reference Hardened RKE Template configuration
The reference RKE Template provides the configuration needed to achieve a hardened install of Kubenetes.
RKE Templates are used to provision Kubernetes and define Rancher settings. Follow the Rancher
[documentaion](https://rancher.com/docs/rancher/v2.x/en/installation) for additional installation and RKE Template details.
```yaml
#
# Cluster Config
#
default_pod_security_policy_template_id: restricted
docker_root_dir: /var/lib/docker
enable_cluster_alerting: false
enable_cluster_monitoring: false
enable_network_policy: true
#
# Rancher Config
#
rancher_kubernetes_engine_config:
addon_job_timeout: 45
ignore_docker_version: true
kubernetes_version: v1.18.12-rancher1-1
#
# If you are using calico on AWS
#
# network:
# plugin: calico
# calico_network_provider:
# cloud_provider: aws
#
# # To specify flannel interface
#
# network:
# plugin: flannel
# flannel_network_provider:
# iface: eth1
#
# # To specify flannel interface for canal plugin
#
# network:
# plugin: canal
# canal_network_provider:
# iface: eth1
#
network:
mtu: 0
plugin: canal
rotate_encryption_key: false
#
# services:
# kube-api:
# service_cluster_ip_range: 10.43.0.0/16
# kube-controller:
# cluster_cidr: 10.42.0.0/16
# service_cluster_ip_range: 10.43.0.0/16
# kubelet:
# cluster_domain: cluster.local
# cluster_dns_server: 10.43.0.10
#
services:
etcd:
backup_config:
enabled: false
interval_hours: 12
retention: 6
safe_timestamp: false
creation: 12h
extra_args:
election-timeout: '5000'
heartbeat-interval: '500'
gid: 52034
retention: 72h
snapshot: false
uid: 52034
kube_api:
always_pull_images: false
audit_log:
enabled: true
event_rate_limit:
enabled: true
pod_security_policy: true
secrets_encryption_config:
enabled: true
service_node_port_range: 30000-32767
kube_controller:
extra_args:
feature-gates: RotateKubeletServerCertificate=true
kubelet:
extra_args:
feature-gates: RotateKubeletServerCertificate=true
protect-kernel-defaults: 'true'
tls-cipher-suites: >-
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256
fail_swap_on: false
generate_serving_certificate: true
ssh_agent_auth: false
upgrade_strategy:
max_unavailable_controlplane: '1'
max_unavailable_worker: 10%
windows_prefered_cluster: false
```
### Hardened Reference Ubuntu 20.04 LTS **cloud-config**:
The reference **cloud-config** is generally used in cloud infrastructure environments to allow for
configuration management of compute instances. The reference config configures Ubuntu operating system level settings
needed before installing kubernetes.
```yaml
#cloud-config
apt:
sources:
docker.list:
source: deb [arch=amd64] http://download.docker.com/linux/ubuntu $RELEASE stable
keyid: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88
system_info:
default_user:
groups:
- docker
write_files:
- path: "/etc/apt/preferences.d/docker"
owner: root:root
permissions: '0600'
content: |
Package: docker-ce
Pin: version 5:19*
Pin-Priority: 800
- path: "/etc/sysctl.d/90-kubelet.conf"
owner: root:root
permissions: '0644'
content: |
vm.overcommit_memory=1
vm.panic_on_oom=0
kernel.panic=10
kernel.panic_on_oops=1
kernel.keys.root_maxbytes=25000000
package_update: true
packages:
- docker-ce
- docker-ce-cli
- containerd.io
runcmd:
- sysctl -p /etc/sysctl.d/90-kubelet.conf
- groupadd --gid 52034 etcd
- useradd --comment "etcd service account" --uid 52034 --gid 52034 etcd
```
@@ -22,6 +22,7 @@ These guides have been tested along with the Rancher v2.5 release. Each self-ass
Kubernetes Version | CIS Benchmark Version | Self Assessment Guide | Hardening Guides
---|---|---|---
Kubernetes v1.15+ | CIS v1.5 | [Link](./1.5-benchmark-2.5) | [Link](./1.5-hardening-2.5)
Kubernetes v1.18+ | CIS v1.6 | [Link](./1.6-benchmark-2.5) | [Link](./1.6-hardening-2.5)
### RKE2 Guides
@@ -0,0 +1 @@
0.14.3
@@ -0,0 +1,20 @@
locals {
results = jsondecode(file(var.results_file))
markdown = templatefile("${path.module}/templates/hardening.template.default.layout.md",
{
rancher_version = var.rancher_version
kubernetes_version = var.kubernetes_version
cis_version = var.cis_version
test_node = var.test_node
test_helper_path = var.test_helper_path
results = local.results
weight = var.index_weight
}
)
}
resource "local_file" "output" {
content = local.markdown
file_permission = "0644"
filename = var.output_file
}
@@ -0,0 +1,11 @@
/*
output "results" {
value = local.results
}
*/
/*
output "markdown" {
value = local.markdown
}
*/
@@ -0,0 +1,8 @@
rancher_version = "v2.5.4"
kubernetes_version = "v1.18"
cis_version = "1.6"
test_node = "cis-aio-0"
test_helper_path = "/home/myuser/repos/rancher-security-scan/package/helper_scripts"
results_file = "/home/myuser/tmp/tf_mk/csr.json"
index_weight = 101
output_file = "/home/myuser/repos/rancher-docs/content/rancher/v2.x/en/security/rancher-2.5/1.6-benchmark-2.5/_index.md"
@@ -0,0 +1 @@
This code is intended to replace the bash script to convert Rancer CIS scan results to markdown format suitable for publishing to the docs site.
@@ -0,0 +1,69 @@
---
title: CIS ${cis_version} Benchmark - Self-Assessment Guide - Rancher ${rancher_version}
weight: ${weight}
---
# CIS v1.6 Kubernetes Benchmark - Rancher v2.5 with Kubernetes v1.18
[Click here to download a PDF version of this document](https://releases.rancher.com/documents/security/2.5/Rancher_1.6_Benchmark_Assessment.pdf)
## Overview
This document is a companion to the Rancher v2.5 security hardening guide. The hardening guide provides prescriptive guidance for hardening a production installation of Rancher, and this benchmark guide is meant to help you evaluate the level of security of the hardened cluster against each control in the benchmark.
This guide corresponds to specific versions of the hardening guide, Rancher, CIS Benchmark, and Kubernetes:
Hardening Guide Version | Rancher Version | CIS Benchmark Version | Kubernetes Version
---------------------------|----------|---------|-------
Hardening Guide with CIS 1.5 Benchmark | Rancher v2.5 | CIS v1.5| Kubernetes v1.15
Because Rancher and RKE install Kubernetes services as Docker containers, many of the control verification checks in the CIS Kubernetes Benchmark don't apply and will have a result of `Not Applicable`. This guide will walk through the various controls and provide updated example commands to audit compliance in Rancher-created clusters.
This document is to be used by Rancher operators, security teams, auditors and decision makers.
For more detail about each audit, including rationales and remediations for failing tests, you can refer to the corresponding section of the CIS Kubernetes Benchmark v1.5. You can download the benchmark after logging in to [CISecurity.org]( https://www.cisecurity.org/benchmark/kubernetes/).
## Testing controls methodology
Rancher and RKE install Kubernetes services via Docker containers. Configuration is defined by arguments passed to the container at the time of initialization, not via configuration files.
Where control audits differ from the original CIS benchmark, the audit commands specific to Rancher Labs are provided for testing.
When performing the tests, you will need access to the Docker command line on the hosts of all three RKE roles. The commands also make use of the the [jq](https://stedolan.github.io/jq/) and [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) (with valid config) tools to and are required in the testing and evaluation of test results.
## Control Result Details
%{ for section in results ~}
### ${section.id} ${section.description}
%{ for check in section.checks ~}
#### ${check.id}: ${check.description}
Attribute | Details
--- | ---
**Result** | ${check.state}
**Remediation** | ${replace(replace(check.remediation,"|","\\|"),"\n","<br>")}
%{ if check.audit != "" ~}
**Audit** | <code style="color:#2c3d4f;font-weight:normal;background:content-box">${replace(check.audit,"|","\\|")}</code>
%{ endif ~}
%{ if check.expected_result != "" ~}
**Expected Result** | <code style="color:#2c3d4f;font-weight:normal;background:content-box">${check.expected_result}</code>
%{ endif ~}
%{ if check.actual_value_per_node[test_node] != "" ~}
{{% accordion label="Audit Output" %}}
```console
${check.actual_value_per_node[test_node]}
```
{{% /accordion %}}
%{ endif ~}
%{ if length(regexall("^\\w+(\\.sh)", "${check.audit}")) == 1 ~}
{{% accordion label="Audit Script" %}}
```bash
${file("${test_helper_path}/${regex("\\S+", check.audit)}") }
```
{{% /accordion %}}
%{ endif ~}
%{ endfor ~}
%{ endfor ~}
@@ -0,0 +1,73 @@
---
title: CIS ${cis_version} Benchmark - Self-Assessment Guide - Rancher ${rancher_version}
weight: ${weight}
---
### CIS ${cis_version} Kubernetes Benchmark - Rancher ${rancher_version} with Kubernetes ${kubernetes_version}
[Click here to download a PDF version of this document](https://releases.rancher.com/documents/security/2.5/Rancher_1.6_Benchmark_Assessment.pdf)
#### Overview
This document is a companion to the Rancher ${rancher_version} security hardening guide. The hardening guide provides prescriptive guidance for hardening a production installation of Rancher, and this benchmark guide is meant to help you evaluate the level of security of the hardened cluster against each control in the benchmark.
This guide corresponds to specific versions of the hardening guide, Rancher, CIS Benchmark, and Kubernetes:
Hardening Guide Version | Rancher Version | CIS Benchmark Version | Kubernetes Version
---------------------------|----------|---------|-------
Hardening Guide with CIS ${cis_version} Benchmark | Rancher ${rancher_version} | CIS ${cis_version}| Kubernetes ${kubernetes_version}
Because Rancher and RKE install Kubernetes services as Docker containers, many of the control verification checks in the CIS Kubernetes Benchmark don't apply and will have a result of `Not Applicable`. This guide will walk through the various controls and provide updated example commands to audit compliance in Rancher-created clusters.
This document is to be used by Rancher operators, security teams, auditors and decision makers.
For more detail about each audit, including rationales and remediations for failing tests, you can refer to the corresponding section of the CIS Kubernetes Benchmark ${cis_version}. You can download the benchmark after logging in to [CISecurity.org]( https://www.cisecurity.org/benchmark/kubernetes/).
#### Testing controls methodology
Rancher and RKE install Kubernetes services via Docker containers. Configuration is defined by arguments passed to the container at the time of initialization, not via configuration files.
Where control audits differ from the original CIS benchmark, the audit commands specific to Rancher Labs are provided for testing.
When performing the tests, you will need access to the Docker command line on the hosts of all three RKE roles. The commands also make use of the the [jq](https://stedolan.github.io/jq/) and [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) (with valid config) tools to and are required in the testing and evaluation of test results.
### Controls
%{ for section in results ~}
## ${section.id} ${section.description}
%{ for check in section.checks ~}
### ${check.id} ${check.description}
**Result:** ${check.state}
**Remediation:**
${check.remediation}
**Audit:**
```bash
${check.audit}
```
%{ if check.expected_result != "" ~}
**Expected Result**:
```console
${check.expected_result}
```
%{ endif ~}
%{ if length(regexall("^\\w+(\\.sh)", "${check.audit}")) == 1 ~}
**Audit Script:**
```bash
${file("${test_helper_path}/${regex("\\S+", check.audit)}") }
```
%{ endif ~}
%{ if check.actual_value_per_node[test_node] != "" ~}
**Returned Value**:
```console
${check.actual_value_per_node[test_node]}
```
%{ endif ~}
%{ endfor ~}
%{ endfor ~}
@@ -0,0 +1,32 @@
variable "rancher_version" {
type = string
}
variable "kubernetes_version" {
type = string
}
variable "cis_version" {
type = string
}
variable "test_node" {
type = string
}
variable "results_file" {
type = string
}
variable "test_helper_path" {
type = string
}
variable "index_weight" {
type = number
}
variable "output_file" {
type = string
}
+76 -29
View File
@@ -1,40 +1,84 @@
results_file="${1:-/source/results.json}"
test_helpers="${2:-/test_helpers}"
#!/bin/bash
#results_file="${1:-/source/results.json}"
results_file="${1:-/home/paraglade/brain/projects/cis_benchmark/clusters/cis/csr.json}"
#test_helpers="${2:-/test_helpers}"
test_helpers="${2:-/home/paraglade/brain/repos/rancher-security-scan/package/helper_scripts}"
header() {
cat <<EOF
---
title: CIS 1.6 Benchmark - Self-Assessment Guide - Rancher v2.5
weight: 101
---
### CIS v1.6 Kubernetes Benchmark - Rancher v2.5 with Kubernetes v1.18
[Click here to download a PDF version of this document](https://releases.rancher.com/documents/security/2.5/Rancher_1.6_Benchmark_Assessment.pdf)
#### Overview
This document is a companion to the Rancher v2.5 security hardening guide. The hardening guide provides prescriptive guidance for hardening a production installation of Rancher, and this benchmark guide is meant to help you evaluate the level of security of the hardened cluster against each control in the benchmark.
This guide corresponds to specific versions of the hardening guide, Rancher, CIS Benchmark, and Kubernetes:
Hardening Guide Version | Rancher Version | CIS Benchmark Version | Kubernetes Version
---------------------------|----------|---------|-------
Hardening Guide with CIS 1.5 Benchmark | Rancher v2.5 | CIS v1.5| Kubernetes v1.15
Because Rancher and RKE install Kubernetes services as Docker containers, many of the control verification checks in the CIS Kubernetes Benchmark don't apply and will have a result of \`Not Applicable\`. This guide will walk through the various controls and provide updated example commands to audit compliance in Rancher-created clusters.
This document is to be used by Rancher operators, security teams, auditors and decision makers.
For more detail about each audit, including rationales and remediations for failing tests, you can refer to the corresponding section of the CIS Kubernetes Benchmark v1.5. You can download the benchmark after logging in to [CISecurity.org]( https://www.cisecurity.org/benchmark/kubernetes/).
#### Testing controls methodology
Rancher and RKE install Kubernetes services via Docker containers. Configuration is defined by arguments passed to the container at the time of initialization, not via configuration files.
Where control audits differ from the original CIS benchmark, the audit commands specific to Rancher Labs are provided for testing.
When performing the tests, you will need access to the Docker command line on the hosts of all three RKE roles. The commands also make use of the the [jq](https://stedolan.github.io/jq/) and [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) (with valid config) tools to and are required in the testing and evaluation of test results.
> NOTE: only scored tests are covered in this guide.
### Controls
EOF
}
get_ids() {
jq -r .id ${results_file} | sort -n
jq -r .[].id ${results_file} | sort -n
}
get_id_text() {
id=${1}
jq -r --arg id "${id}" 'select(.id==$id) | .text' ${results_file}
jq -r --arg id "${id}" '.[] | select(.id==$id) | .description' ${results_file}
}
get_section_ids() {
id=${1}
jq -r --arg id "${id}" 'select(.id==$id) | .tests[].section' ${results_file}
jq -r --arg id "${id}" '.[] | select(.id==$id) | .checks[].id' ${results_file}
}
get_section_desc() {
id=${1}
section=${2}
jq -r --arg id "${id}" --arg section "${section}" 'select(.id==$id).tests[] | select(.section==$section).desc' ${results_file}
jq -r --arg id "${id}" --arg section "${section}" '.[] | select(.id==$id).checks[] | select(.id==$section).description' ${results_file}
}
get_tests() {
id=${1}
section=${2}
jq -r --arg id "${id}" --arg section "${section}" 'select(.id==$id).tests[] | select(.section==$section).results[].test_number' ${results_file}
jq -r --arg id "${id}" --arg section "${section}" '.[] | select(.id==$id).checks[] | select(.id==$section).id' ${results_file}
}
get_test() {
id=${1}
section=${2}
test_number=${3}
jq -r --arg id "${id}" --arg section "${section}" --arg test_number "${test_number}" 'select(.id==$id).tests[] | select(.section==$section).results[] | select(.test_number==$test_number)' ${results_file}
jq -r --arg id "${id}" --arg section "${section}" --arg test_number "${test_number}" '.[] | select(.id==$id).checks[] | select(.id==$test_number)' ${results_file}
}
cat headers/header-2.4.md
header
for id in $(get_ids); do
echo "## ${id} $(get_id_text ${id})"
@@ -43,15 +87,15 @@ for id in $(get_ids); do
echo
for test in $(get_tests ${id} ${section}); do
result=$(get_test ${id} ${section} ${test})
test_desc=$(echo ${result} | jq -r '.test_desc')
test_desc=$(echo ${result} | jq -r '.description')
audit=$(echo ${result} | jq -r '.audit')
audit_config=$(echo ${result} | jq -r '.AuditConfig')
actual_value=$(echo ${result} | jq -r '.actual_value')
type=$(echo ${result} | jq -r '.type')
status=$(echo ${result} | jq -r '.status')
audit_config=$(echo ${result} | jq -r '.audit_config')
actual_value=$(echo ${result} | jq -r '.actual_value_per_node."cis-aio-0"')
type=$(echo ${result} | jq -r '.test_type')
status=$(echo ${result} | jq -r '.state')
remediation=$(echo ${result} | jq -r '.remediation')
expected_result=$(echo ${result} | jq -r '.expected_result')
echo "#### ${test} ${test_desc}"
# echo "#### ${test} ${test_desc}"
echo
if [ "${type}" = "skip" ]; then
echo "**Result:** Not Applicable"
@@ -62,30 +106,31 @@ for id in $(get_ids); do
fi
if [ ! -z "${remediation}" ]; then
echo "**Remediation:**"
echo "${remediation}"
echo -e "${remediation//\\n/<br />}"
echo
fi
if [ ! -z "${audit}" ] && [ ${status} != "INFO" ]; then
if [[ ${audit} =~ "test_helpers" ]]; then
audit_script=$(basename ${audit})
if [ ! -z "${audit}" ] && [ "${status}" != "INFO" ] && [ "${type}" != "skip" ]; then
if [[ ${audit} =~ ".sh" ]]; then
audit_script=$(basename $(echo ${audit} | cut -d ' ' -f1))
test_helper="${test_helpers}/${audit_script}"
echo "**Audit Script:** ${audit_script}"
echo
echo '```'
cat "${test_helper}"
echo '```bash'
cat ${test_helper}
echo
echo '```'
echo
echo "**Audit Execution:**"
echo
echo '```'
echo '```bash'
echo "./${audit_script} $(echo ${audit} | awk '{print $2}')"
echo '```'
echo
else
echo "**Audit:**"
echo
echo '```'
echo "${audit}"
echo '```bash'
echo ${audit}
echo '```'
echo
fi
@@ -93,21 +138,23 @@ for id in $(get_ids); do
if [ ! -z "${audit_config}" ] && [ ${status} != "INFO" ]; then
echo "**Audit Config:**"
echo
echo '```'
echo "${audit_config}"
echo '```bash'
echo ${audit_config}
echo '```'
echo
fi
if [ ! -z "${actual_value}" ] && [ ${status} != "PASS" ]; then
if [ ! -z "${actual_value}" ] && [ "${status}" != "PASS" ] && [ "${type}" != "skip" ] && [ "${type}" != "manual" ]; then
echo "**Returned Value**:"
echo
echo "\`${actual_value}\`"
echo '```console'
echo ${actual_value}
echo '```'
echo
fi
if [ ! -z "${expected_result}" ]; then
echo "**Expected result**:"
echo
echo '```'
echo '```console'
echo ${expected_result}
echo '```'
echo