From ab3881420cb2794badc9290dc5a5f6e57d918123 Mon Sep 17 00:00:00 2001 From: Borko Date: Mon, 16 Nov 2020 07:35:57 -0500 Subject: [PATCH] Created config and test files for Azure Kubernetes Service (AKS). (#733) * First draft of AKS configuration checks. * Updated Azure Configurations. Added more policy checks. * Finalized cfg components for AKS. * Fixed targets for aks-1.0 in common_test.go * Fixed yaml linting issues. * Fixed white space yaml linkting issues in policies.yaml * Fixed white space yaml linting issues in policies.yaml --- cfg/aks-1.0/config.yaml | 2 + cfg/aks-1.0/controlplane.yaml | 31 +++ cfg/aks-1.0/managedservices.yaml | 255 +++++++++++++++++ cfg/aks-1.0/master.yaml | 6 + cfg/aks-1.0/node.yaml | 452 +++++++++++++++++++++++++++++++ cfg/aks-1.0/policies.yaml | 256 +++++++++++++++++ cfg/config.yaml | 7 + cmd/common_test.go | 6 + 8 files changed, 1015 insertions(+) create mode 100644 cfg/aks-1.0/config.yaml create mode 100644 cfg/aks-1.0/controlplane.yaml create mode 100644 cfg/aks-1.0/managedservices.yaml create mode 100644 cfg/aks-1.0/master.yaml create mode 100644 cfg/aks-1.0/node.yaml create mode 100644 cfg/aks-1.0/policies.yaml diff --git a/cfg/aks-1.0/config.yaml b/cfg/aks-1.0/config.yaml new file mode 100644 index 0000000..b783945 --- /dev/null +++ b/cfg/aks-1.0/config.yaml @@ -0,0 +1,2 @@ +--- +## Version-specific settings that override the values in cfg/config.yaml diff --git a/cfg/aks-1.0/controlplane.yaml b/cfg/aks-1.0/controlplane.yaml new file mode 100644 index 0000000..e66ef26 --- /dev/null +++ b/cfg/aks-1.0/controlplane.yaml @@ -0,0 +1,31 @@ +--- +controls: +version: "aks-1.0" +id: 2 +text: "Control Plane Configuration" +type: "controlplane" +groups: + - id: 2.1 + text: "Authentication and Authorization" + checks: + - id: 2.1.1 + text: "Enable Azure Active Directory Integration" + type: "manual" + remediation: | + Use of OIDC should be implemented in place of client certificates. Cluster administrators can configure Kubernetes role-based access control (RBAC) based on a user's identity or directory group membership. Azure AD authentication is provided to AKS clusters with OpenID Connect. See https://docs.microsoft.com/en-us/azure/aks/managed-aad. + scored: false + - id: 2.1.2 + text: "Limit access to cluster configuration file" + type: "manual" + remediation: | + Use Azure role-based access control to define access to the Kubernetes configuration file in Azure Kubernetes Service (AKS). See https://docs.microsoft.com/en-us/azure/aks/control-kubeconfig-access + scored: false + + - id: 2.2 + text: "Logging" + checks: + - id: 2.2.1 + text: "Enable logging for the Kubernetes master components" + type: "manual" + remediation: "Enable log collection for the Kubernetes master components in the AKS cluster using Diagnostic settings." + scored: false diff --git a/cfg/aks-1.0/managedservices.yaml b/cfg/aks-1.0/managedservices.yaml new file mode 100644 index 0000000..1f748a6 --- /dev/null +++ b/cfg/aks-1.0/managedservices.yaml @@ -0,0 +1,255 @@ +--- +controls: +version: "aks-1.0" +id: 5 +text: "Managed Services" +type: "managedservices" +groups: + - id: 5.1 + text: "Image Registry and Image Scanning" + checks: + - id: 5.1.1 + text: "Ensure Image Vulnerability Scanning" + type: "manual" + remediation: | + Scan your container images for vulnerabilities, and only deploy images that have passed validation. Regularly update the base images and application runtime, then redeploy workloads in the AKS cluster. Deployment workflow should include a process to scan container images using tools such as Twistlock or Aqua, and then only allow verified images to be deployed. + scored: false + + - id: 5.1.2 + text: "Minimize user access to ACR" + type: "manual" + remediation: | + Use Azure AD and RBAC to minimize user access to ACR. For each Azure container registry, track whether the built-in admin account is enabled or disabled. Disable the account when not in use. See https://docs.microsoft.com/en-us/azure/container-registry/security-baseline#identity-and-access-control. + scored: false + + - id: 5.1.3 + text: "Minimize cluster access to read-only for ACR" + type: "manual" + remediation: | + Ensure identity assigned to AKS uses read-only role for accessing ACR. + scored: false + + - id: 5.1.4 + text: "Protect ACR using NSGs or Azure Firewall on your Virtual Network" + type: "manual" + remediation: | + Restrict access to an Azure container registry using an Azure virtual network or firewall rules. Configure rules to access an Azure container registry behind a firewall. See https://docs.microsoft.com/en-us/azure/container-registry/security-baseline#11-protect-resources-using-network-security-groups-or-azure-firewall-on-your-virtual-network + scored: false + + - id: 5.1.5 + text: "Record network packets and flow logs for ACR" + type: "manual" + remediation: | + Enable network security group (NSG) flow logs for the NSG attached to the subnet being used to protect your Azure container registry. See https://docs.microsoft.com/en-us/azure/container-registry/security-baseline#15-record-network-packets-and-flow-logs + scored: false + + - id: 5.1.6 + text: "Minimize complexity and administrative overhead of network security rules for ACR" + type: "manual" + remediation: | + For resources that need access to your container registry, use virtual network service tags (instead of specific IP addresses) for the Azure Container Registry service (service tag name "AzureContainerRegistry") to define network access controls on Network Security Groups or Azure Firewall. See https://docs.microsoft.com/en-us/azure/container-registry/security-baseline#18-minimize-complexity-and-administrative-overhead-of-network-security-rules + scored: false + + - id: 5.1.7 + text: "Configure central security log management for ACR" + type: "manual" + remediation: | + Ingest logs via Azure Monitor to aggregate security data generated by an Azure container registry. https://docs.microsoft.com/en-us/azure/container-registry/security-baseline#22-configure-central-security-log-management + scored: false + + - id: 5.1.8 + text: "Enable audit logging for ACR" + type: "manual" + remediation: | + Collect and consume this data to audit registry authentication events and provide a complete activity trail on registry artifacts such as pull and push events so you can diagnose security issues with your registry. See https://docs.microsoft.com/en-us/azure/container-registry/security-baseline#23-enable-audit-logging-for-azure-resources + scored: false + + - id: 5.1.9 + text: "Change default passwords for ACR where applicable" + type: "manual" + remediation: | + If the default admin account of an Azure container registry is enabled, complex passwords are automatically created and should be rotated. Disable the account when not in use. See https://docs.microsoft.com/en-us/azure/container-registry/security-baseline#32-change-default-passwords-where-applicable + scored: false + + - id: 5.1.10 + text: "Use dedicated administrative accounts" + type: "manual" + remediation: | + Create standard operating procedures around the use of dedicated administrative accounts. Use Azure Security Center Identity and Access Management to monitor the number of administrative accounts. See https://docs.microsoft.com/en-us/azure/container-registry/security-baseline#33-use-dedicated-administrative-accounts + scored: false + + - id: 5.1.11 + text: "Use single sign-on (SSO) with Azure Active Directory" + type: "manual" + remediation: | + Wherever possible, use Azure Active Directory SSO instead of configuring individual stand-alone credentials per-service. See https://docs.microsoft.com/en-us/azure/container-registry/security-baseline#34-use-single-sign-on-sso-with-azure-active-directory + scored: false + + - id: 5.1.12 + text: "Maintain an inventory of sensitive Information" + type: "manual" + remediation: | + Use resource tags to assist in tracking Azure container registries that store or process sensitive information. See https://docs.microsoft.com/en-us/azure/container-registry/security-baseline#41-maintain-an-inventory-of-sensitive-information + scored: false + + - id: 5.1.13 + text: "Isolate systems storing or processing sensitive information" + type: "manual" + remediation: | + Implement separate container registries, subscriptions, and/or management groups for development, test, and production. Resources storing or processing sensitive data should be sufficiently isolated. See https://docs.microsoft.com/en-us/azure/container-registry/security-baseline#42-isolate-systems-storing-or-processing-sensitive-information + scored: false + + - id: 5.1.14 + text: "Encrypt all sensitive information in transit to ACR" + type: "manual" + remediation: | + Ensure that any clients connecting to your Azure Container Registry are able to negotiate TLS 1.2 or greater. See https://docs.microsoft.com/en-us/azure/container-registry/security-baseline#44-encrypt-all-sensitive-information-in-transit + scored: false + + - id: 5.1.15 + text: "Use Azure RBAC to control access to resources in ACR" + type: "manual" + remediation: | + Use Azure role-based access control (Azure RBAC) to control access to data and resources in an Azure container registry. See https://docs.microsoft.com/en-us/azure/container-registry/security-baseline#46-use-azure-rbac-to-control-access-to-resources + scored: false + + - id: 5.1.16 + text: "Encrypt sensitive information at rest in ACR" + type: "manual" + remediation: | + Use encryption at rest on all Azure resources. By default, all data in an Azure container registry is encrypted at rest using Microsoft-managed keys. See https://docs.microsoft.com/en-us/azure/container-registry/security-baseline#48-encrypt-sensitive-information-at-rest + scored: false + + - id: 5.1.17 + text: "Ensure regular automated back ups for ACR" + type: "manual" + remediation: | + he data in your Microsoft Azure container registry is always automatically replicated to ensure durability and high availability. Optionally geo-replicate a container registry to maintain registry replicas in multiple Azure regions. See https://docs.microsoft.com/en-us/azure/container-registry/security-baseline#91-ensure-regular-automated-back-ups + scored: false + + - id: 5.2 + text: "Identity and Access Management (IAM)" + checks: + - id: 5.2.1 + text: "Use managed identities in Azure Kubernetes Service" + type: "manual" + remediation: | + Use SystemAssigned managed identity for AKS cluster. See https://docs.microsoft.com/en-us/azure/aks/use-managed-identity + scored: false + + - id: 5.2.2 + text: "Prefer using AAD Pod Identity" + type: "manual" + remediation: | + AAD Pod Identity enables Kubernetes applications to access cloud resources securely with Azure Active Directory (AAD). See https://github.com/Azure/aad-pod-identity + scored: false + + - id: 5.3 + text: "Cloud Key Management Service" + checks: + - id: 5.3.1 + text: "Ensure Kubernetes Secrets are stored and retrieved from Azure Key Vault." + type: "manual" + remediation: | + Use the Azure Key Vault with Secrets Store CSI Driver to retrieve secrets from Azure Key Vault and load it in the pod. See https://github.com/Azure/secrets-store-csi-driver-provider-azure. + scored: false + + - id: 5.4 + text: "Cluster Networking" + checks: + - id: 5.4.1 + text: "Enable NSG Flow Logs for AKS subnets." + type: "manual" + remediation: | + Enable network security group (NSG) flow logs for the NSG attached to the subnet being used for AKS cluster nodes. + scored: false + + - id: 5.4.2 + text: "Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled (Scored)" + type: "manual" + remediation: | + In a private cluster, the control plane or API server has internal IP address. See: https://docs.microsoft.com/en-us/azure/aks/private-clusters + scored: false + + - id: 5.4.3 + text: "Configure NSG on AKS worker node subnet" + type: "manual" + remediation: | + Configure NSG rules on AKS worker node subnet to allow only required network traffic. + scored: false + + - id: 5.4.4 + text: "Ensure Network Policy is Enabled and set as appropriate (Not Scored)" + type: "manual" + remediation: | + Enable Azure Network Policy or Calico Network policy on the AKS cluster. See https://docs.microsoft.com/en-us/azure/aks/use-network-policies. + scored: false + + - id: 5.5 + text: "Logging" + checks: + - id: 5.5.1 + text: "Enable Azure Monitor for container for kubelet logs" + type: "manual" + remediation: | + Enable Azure Monitor for containers via AKS diagnostics settings for collecting node and kubelet logs. See https://docs.microsoft.com/en-us/azure/azure-monitor/insights/container-insights-overview + scored: false + + - id: 5.6 + text: "Authentication and Authorization" + checks: + - id: 5.6.1 + text: "Use Azure RBAC for Kubernetes Authorization" + type: "manual" + remediation: | + Enabling Azure RBAC for Kubernetes Authorization will use a Kubernetes Authorization webhook server to enable you to manage permissions and assignments of Azure AD-integrated K8s cluster resources using Azure role definition and role assignments. See https://docs.microsoft.com/en-us/azure/aks/manage-azure-rbac + scored: false + + - id: 5.6.2 + text: "Use Kubernetes RBAC with Azure AD integration" + type: "manual" + remediation: | + Don't use fixed credentials within pods or container images, as they are at risk of exposure or abuse. Instead, use pod identities to automatically request access to other Azure resources using a central Azure AD identity solution. See https://docs.microsoft.com/en-us/azure/aks/operator-best-practices-identity#use-pod-identities + scored: false + + - id: 5.6.3 + text: "Use pod identities" + type: "manual" + remediation: | + Control access to cluster resources using role-based access control and Azure Active Directory identities in Azure Kubernetes Service. See https://docs.microsoft.com/en-us/azure/aks/azure-ad-rbac + scored: false + + - id: 5.7 + text: "Storage" + checks: + - id: 5.7.1 + text: "Enable host-based encryption" + type: "manual" + remediation: | + Enable host-based encryption on Azure Kubernetes Service (AKS). With host-based encryption, the data stored on the VM host of your AKS agent nodes' VMs is encrypted at rest and flows encrypted to the Storage service. This means the temp disks are encrypted at rest with platform-managed keys. The cache of OS and data disks is encrypted at rest with either platform-managed keys or customer-managed keys depending on the encryption type set on those disks. See https://docs.microsoft.com/en-us/azure/aks/enable-host-encryption. + scored: false + + - id: 5.7.2 + text: "Bring your own keys (BYOK) with Azure disks in Azure Kubernetes Service (AKS)" + type: "manual" + remediation: | + Azure Storage encrypts all data in a storage account at rest. By default, data is encrypted with Microsoft-managed keys. For additional control over encryption keys, you can supply customer-managed keys to use for encryption at rest for both the OS and data disks for your AKS clusters. See https://docs.microsoft.com/en-us/azure/aks/azure-disk-customer-managed-keys. + scored: false + + - id: 5.8 + text: "Other Cluster Configurations" + checks: + - id: 5.8.1 + text: "Ensure Kubernetes Web UI is Disabled (Scored)" + type: "manual" + remediation: | + The dashboard add-on is disabled by default for all new clusters created on Kubernetes 1.18 or greater. To disable dashboard on existing cluster use command line: + az aks disable-addons -g myRG -n myAKScluster -a kube-dashboard + scored: false + + - id: 5.8.2 + text: "Secure pods with Azure Policy as appropriate" + type: "manual" + remediation: | + Enable Azure Policy Add-on for AKS to control what functions pods are granted. See https://docs.microsoft.com/en-us/azure/aks/use-pod-security-on-azure-policy. + scored: false diff --git a/cfg/aks-1.0/master.yaml b/cfg/aks-1.0/master.yaml new file mode 100644 index 0000000..7ec9eae --- /dev/null +++ b/cfg/aks-1.0/master.yaml @@ -0,0 +1,6 @@ +--- +controls: +version: "aks-1.0" +id: 1 +text: "Control Plane Components" +type: "master" diff --git a/cfg/aks-1.0/node.yaml b/cfg/aks-1.0/node.yaml new file mode 100644 index 0000000..3a05a05 --- /dev/null +++ b/cfg/aks-1.0/node.yaml @@ -0,0 +1,452 @@ +--- +controls: +version: "aks-1.0" +id: 3 +text: "Worker Node Security Configuration" +type: "node" +groups: + - id: 3.1 + text: "Worker Node Configuration Files" + checks: + - id: 3.1.1 + text: "Ensure that the kubelet service file permissions are set to 644 or more restrictive (Automated)" + audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c permissions=%a $kubeletsvc; fi'' ' + tests: + test_items: + - flag: "permissions" + compare: + op: bitmask + value: "644" + remediation: | + Run the below command (based on the file location on your system) on the each worker node. + For example, + chmod 644 $kubeletsvc + scored: true + + - id: 3.1.2 + text: "Ensure that the kubelet service file ownership is set to root:root (Automated)" + audit: '/bin/sh -c ''if test -e $kubeletsvc; then stat -c %U:%G $kubeletsvc; fi'' ' + tests: + test_items: + - flag: root:root + remediation: | + Run the below command (based on the file location on your system) on the each worker node. + For example, + chown root:root $kubeletsvc + scored: true + + - id: 3.1.3 + text: "If proxy kubeconfig file exists ensure permissions are set to 644 or more restrictive (Manual)" + audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c permissions=%a $proxykubeconfig; fi'' ' + tests: + test_items: + - flag: "permissions" + compare: + op: bitmask + value: "644" + remediation: | + Run the below command (based on the file location on your system) on the each worker node. + For example, + chmod 644 $proxykubeconfig + scored: false + + - id: 3.1.4 + text: "Ensure that the proxy kubeconfig file ownership is set to root:root (Manual)" + audit: '/bin/sh -c ''if test -e $proxykubeconfig; then stat -c %U:%G $proxykubeconfig; fi'' ' + tests: + test_items: + - flag: root:root + remediation: | + Run the below command (based on the file location on your system) on the each worker node. + For example, chown root:root $proxykubeconfig + scored: false + + - id: 3.1.5 + text: "Ensure that the --kubeconfig kubelet.conf file permissions are set to 644 or more restrictive (Automated)" + audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c permissions=%a $kubeletkubeconfig; fi'' ' + tests: + test_items: + - flag: "permissions" + compare: + op: bitmask + value: "644" + remediation: | + Run the below command (based on the file location on your system) on the each worker node. + For example, + chmod 644 $kubeletkubeconfig + scored: true + + - id: 3.1.6 + text: "Ensure that the --kubeconfig kubelet.conf file ownership is set to root:root (Manual)" + audit: '/bin/sh -c ''if test -e $kubeletkubeconfig; then stat -c %U:%G $kubeletkubeconfig; fi'' ' + tests: + test_items: + - flag: root:root + remediation: | + Run the below command (based on the file location on your system) on the each worker node. + For example, + chown root:root $kubeletkubeconfig + scored: false + + - id: 3.1.7 + text: "Ensure that the certificate authorities file permissions are set to 644 or more restrictive (Manual)" + audit: | + CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}') + if test -z $CAFILE; then CAFILE=$kubeletcafile; fi + if test -e $CAFILE; then stat -c permissions=%a $CAFILE; fi + tests: + test_items: + - flag: "permissions" + compare: + op: bitmask + value: "644" + remediation: | + Run the following command to modify the file permissions of the + --client-ca-file chmod 644 + scored: false + + - id: 3.1.8 + text: "Ensure that the client certificate authorities file ownership is set to root:root (Manual)" + audit: | + CAFILE=$(ps -ef | grep kubelet | grep -v apiserver | grep -- --client-ca-file= | awk -F '--client-ca-file=' '{print $2}' | awk '{print $1}') + if test -z $CAFILE; then CAFILE=$kubeletcafile; fi + if test -e $CAFILE; then stat -c %U:%G $CAFILE; fi + tests: + test_items: + - flag: root:root + compare: + op: eq + value: root:root + remediation: | + Run the following command to modify the ownership of the --client-ca-file. + chown root:root + scored: false + + - id: 3.1.9 + text: "Ensure that the kubelet --config configuration file has permissions set to 644 or more restrictive (Automated)" + audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c permissions=%a $kubeletconf; fi'' ' + tests: + test_items: + - flag: "permissions" + compare: + op: bitmask + value: "644" + remediation: | + Run the following command (using the config file location identified in the Audit step) + chmod 644 $kubeletconf + scored: true + + - id: 3.1.10 + text: "Ensure that the kubelet --config configuration file ownership is set to root:root (Automated)" + audit: '/bin/sh -c ''if test -e $kubeletconf; then stat -c %U:%G $kubeletconf; fi'' ' + tests: + test_items: + - flag: root:root + remediation: | + Run the following command (using the config file location identified in the Audit step) + chown root:root $kubeletconf + scored: true + + - id: 3.2 + text: "Kubelet" + checks: + - id: 3.2.1 + text: "Ensure that the anonymous-auth argument is set to false (Automated)" + audit: "/bin/ps -fC $kubeletbin" + audit_config: "/bin/cat $kubeletconf" + tests: + test_items: + - flag: "--anonymous-auth" + path: '{.authentication.anonymous.enabled}' + compare: + op: eq + value: false + remediation: | + If using a Kubelet config file, edit the file to set authentication: anonymous: enabled to + false. + If using executable arguments, edit the kubelet service file + $kubeletsvc on each worker node and + set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable. + --anonymous-auth=false + Based on your system, restart the kubelet service. For example: + systemctl daemon-reload + systemctl restart kubelet.service + scored: true + + - id: 3.2.2 + text: "Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)" + audit: "/bin/ps -fC $kubeletbin" + audit_config: "/bin/cat $kubeletconf" + tests: + test_items: + - flag: --authorization-mode + path: '{.authorization.mode}' + compare: + op: nothave + value: AlwaysAllow + remediation: | + If using a Kubelet config file, edit the file to set authorization: mode to Webhook. If + using executable arguments, edit the kubelet service file + $kubeletsvc on each worker node and + set the below parameter in KUBELET_AUTHZ_ARGS variable. + --authorization-mode=Webhook + Based on your system, restart the kubelet service. For example: + systemctl daemon-reload + systemctl restart kubelet.service + scored: true + + - id: 3.2.3 + text: "Ensure that the --client-ca-file argument is set as appropriate (Automated)" + audit: "/bin/ps -fC $kubeletbin" + audit_config: "/bin/cat $kubeletconf" + tests: + test_items: + - flag: --client-ca-file + path: '{.authentication.x509.clientCAFile}' + remediation: | + If using a Kubelet config file, edit the file to set authentication: x509: clientCAFile to + the location of the client CA file. + If using command line arguments, edit the kubelet service file + $kubeletsvc on each worker node and + set the below parameter in KUBELET_AUTHZ_ARGS variable. + --client-ca-file= + Based on your system, restart the kubelet service. For example: + systemctl daemon-reload + systemctl restart kubelet.service + scored: true + + - id: 3.2.4 + text: "Ensure that the --read-only-port argument is set to 0 (Manual)" + audit: "/bin/ps -fC $kubeletbin" + audit_config: "/bin/cat $kubeletconf" + tests: + bin_op: or + test_items: + - flag: "--read-only-port" + path: '{.readOnlyPort}' + compare: + op: eq + value: 0 + - flag: "--read-only-port" + path: '{.readOnlyPort}' + set: false + remediation: | + If using a Kubelet config file, edit the file to set readOnlyPort to 0. + If using command line arguments, edit the kubelet service file + $kubeletsvc on each worker node and + set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable. + --read-only-port=0 + Based on your system, restart the kubelet service. For example: + systemctl daemon-reload + systemctl restart kubelet.service + scored: false + + - id: 3.2.5 + text: "Ensure that the --streaming-connection-idle-timeout argument is not set to 0 (Manual)" + audit: "/bin/ps -fC $kubeletbin" + audit_config: "/bin/cat $kubeletconf" + tests: + test_items: + - flag: --streaming-connection-idle-timeout + path: '{.streamingConnectionIdleTimeout}' + compare: + op: noteq + value: 0 + - flag: --streaming-connection-idle-timeout + path: '{.streamingConnectionIdleTimeout}' + set: false + bin_op: or + remediation: | + If using a Kubelet config file, edit the file to set streamingConnectionIdleTimeout to a + value other than 0. + If using command line arguments, edit the kubelet service file + $kubeletsvc on each worker node and + set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable. + --streaming-connection-idle-timeout=5m + Based on your system, restart the kubelet service. For example: + systemctl daemon-reload + systemctl restart kubelet.service + scored: false + + - id: 3.2.6 + text: "Ensure that the --protect-kernel-defaults argument is set to true (Automated)" + audit: "/bin/ps -fC $kubeletbin" + audit_config: "/bin/cat $kubeletconf" + tests: + test_items: + - flag: --protect-kernel-defaults + path: '{.protectKernelDefaults}' + compare: + op: eq + value: true + remediation: | + If using a Kubelet config file, edit the file to set protectKernelDefaults: true. + If using command line arguments, edit the kubelet service file + $kubeletsvc on each worker node and + set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable. + --protect-kernel-defaults=true + Based on your system, restart the kubelet service. For example: + systemctl daemon-reload + systemctl restart kubelet.service + scored: true + + - id: 3.2.7 + text: "Ensure that the --make-iptables-util-chains argument is set to true (Automated)" + audit: "/bin/ps -fC $kubeletbin" + audit_config: "/bin/cat $kubeletconf" + tests: + test_items: + - flag: --make-iptables-util-chains + path: '{.makeIPTablesUtilChains}' + compare: + op: eq + value: true + - flag: --make-iptables-util-chains + path: '{.makeIPTablesUtilChains}' + set: false + bin_op: or + remediation: | + If using a Kubelet config file, edit the file to set makeIPTablesUtilChains: true. + If using command line arguments, edit the kubelet service file + $kubeletsvc on each worker node and + remove the --make-iptables-util-chains argument from the + KUBELET_SYSTEM_PODS_ARGS variable. + Based on your system, restart the kubelet service. For example: + systemctl daemon-reload + systemctl restart kubelet.service + scored: true + + - id: 3.2.8 + text: "Ensure that the --hostname-override argument is not set (Manual)" + # This is one of those properties that can only be set as a command line argument. + # To check if the property is set as expected, we need to parse the kubelet command + # instead reading the Kubelet Configuration file. + audit: "/bin/ps -fC $kubeletbin " + tests: + test_items: + - flag: --hostname-override + set: false + remediation: | + Edit the kubelet service file $kubeletsvc + on each worker node and remove the --hostname-override argument from the + KUBELET_SYSTEM_PODS_ARGS variable. + Based on your system, restart the kubelet service. For example: + systemctl daemon-reload + systemctl restart kubelet.service + scored: false + + - id: 3.2.9 + text: "Ensure that the --event-qps argument is set to 0 or a level which ensures appropriate event capture (Manual)" + audit: "/bin/ps -fC $kubeletbin" + audit_config: "/bin/cat $kubeletconf" + tests: + test_items: + - flag: --event-qps + path: '{.eventRecordQPS}' + compare: + op: eq + value: 0 + remediation: | + If using a Kubelet config file, edit the file to set eventRecordQPS: to an appropriate level. + If using command line arguments, edit the kubelet service file + $kubeletsvc on each worker node and + set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable. + Based on your system, restart the kubelet service. For example: + systemctl daemon-reload + systemctl restart kubelet.service + scored: false + + - id: 3.2.10 + text: "Ensure that the --tls-cert-file and --tls-private-key-file arguments are set as appropriate (Manual)" + audit: "/bin/ps -fC $kubeletbin" + audit_config: "/bin/cat $kubeletconf" + tests: + test_items: + - flag: --tls-cert-file + path: '{.tlsCertFile}' + - flag: --tls-private-key-file + path: '{.tlsPrivateKeyFile}' + remediation: | + If using a Kubelet config file, edit the file to set tlsCertFile to the location + of the certificate file to use to identify this Kubelet, and tlsPrivateKeyFile + to the location of the corresponding private key file. + If using command line arguments, edit the kubelet service file + $kubeletsvc on each worker node and + set the below parameters in KUBELET_CERTIFICATE_ARGS variable. + --tls-cert-file= + --tls-private-key-file= + Based on your system, restart the kubelet service. For example: + systemctl daemon-reload + systemctl restart kubelet.service + scored: false + + - id: 3.2.11 + text: "Ensure that the --rotate-certificates argument is not set to false (Manual)" + audit: "/bin/ps -fC $kubeletbin" + audit_config: "/bin/cat $kubeletconf" + tests: + test_items: + - flag: --rotate-certificates + path: '{.rotateCertificates}' + compare: + op: eq + value: true + - flag: --rotate-certificates + path: '{.rotateCertificates}' + set: false + bin_op: or + remediation: | + If using a Kubelet config file, edit the file to add the line rotateCertificates: true or + remove it altogether to use the default value. + If using command line arguments, edit the kubelet service file + $kubeletsvc on each worker node and + remove --rotate-certificates=false argument from the KUBELET_CERTIFICATE_ARGS + variable. + Based on your system, restart the kubelet service. For example: + systemctl daemon-reload + systemctl restart kubelet.service + scored: false + + - id: 3.2.12 + text: "Verify that the RotateKubeletServerCertificate argument is set to true (Manual)" + audit: "/bin/ps -fC $kubeletbin" + audit_config: "/bin/cat $kubeletconf" + tests: + test_items: + - flag: RotateKubeletServerCertificate + path: '{.featureGates.RotateKubeletServerCertificate}' + compare: + op: eq + value: true + remediation: | + Edit the kubelet service file $kubeletsvc + on each worker node and set the below parameter in KUBELET_CERTIFICATE_ARGS variable. + --feature-gates=RotateKubeletServerCertificate=true + Based on your system, restart the kubelet service. For example: + systemctl daemon-reload + systemctl restart kubelet.service + scored: false + + - id: 3.2.13 + text: "Ensure that the Kubelet only makes use of Strong Cryptographic Ciphers (Manual)" + audit: "/bin/ps -fC $kubeletbin" + audit_config: "/bin/cat $kubeletconf" + tests: + test_items: + - flag: --tls-cipher-suites + path: '{range .tlsCipherSuites[:]}{}{'',''}{end}' + compare: + op: valid_elements + value: 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 + remediation: | + If using a Kubelet config file, edit the file to set TLSCipherSuites: to + 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 + or to a subset of these values. + If using executable arguments, edit the kubelet service file + $kubeletsvc on each worker node and + set the --tls-cipher-suites parameter as follows, or to a subset of these values. + --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 + Based on your system, restart the kubelet service. For example: + systemctl daemon-reload + systemctl restart kubelet.service + scored: false diff --git a/cfg/aks-1.0/policies.yaml b/cfg/aks-1.0/policies.yaml new file mode 100644 index 0000000..ec412ac --- /dev/null +++ b/cfg/aks-1.0/policies.yaml @@ -0,0 +1,256 @@ +--- +controls: +version: "aks-1.0" +id: 4 +text: "Kubernetes Policies" +type: "policies" +groups: + - id: 4.1 + text: "RBAC and Service Accounts" + checks: + - id: 4.1.1 + text: "Ensure that the cluster-admin role is only used where required (Not Scored)" + type: "manual" + remediation: | + Identify all clusterrolebindings to the cluster-admin role. Check if they are used and + if they need this role or if they could use a role with fewer privileges. + Where possible, first bind users to a lower privileged role and then remove the + clusterrolebinding to the cluster-admin role : + kubectl delete clusterrolebinding [name] + scored: false + + - id: 4.1.2 + text: "Minimize access to secrets (Not Scored)" + type: "manual" + remediation: | + Where possible, remove get, list and watch access to secret objects in the cluster. + scored: false + + - id: 4.1.3 + text: "Minimize wildcard use in Roles and ClusterRoles (Not Scored)" + type: "manual" + remediation: | + Where possible replace any use of wildcards in clusterroles and roles with specific + objects or actions. + scored: false + + - id: 4.1.4 + text: "Minimize access to create pods (Not Scored)" + type: "manual" + Remediation: | + Where possible, remove create access to pod objects in the cluster. + scored: false + + - id: 4.1.5 + text: "Ensure that default service accounts are not actively used. (Scored)" + type: "manual" + remediation: | + Create explicit service accounts wherever a Kubernetes workload requires specific access + to the Kubernetes API server. + Modify the configuration of each default service account to include this value + automountServiceAccountToken: false + scored: true + + - id: 4.1.6 + text: "Ensure that Service Account Tokens are only mounted where necessary (Not Scored)" + type: "manual" + remediation: | + Modify the definition of pods and service accounts which do not need to mount service + account tokens to disable it. + scored: false + + - id: 4.2 + text: "Pod Security Policies" + checks: + - id: 4.2.1 + text: "Minimize the admission of privileged containers (Not Scored)" + type: "manual" + remediation: | + Implement Azure Policy to disallow running of privileged containers. See https://docs.microsoft.com/en-us/azure/aks/use-pod-security-on-azure-policy#built-in-policy-initiatives + scored: false + + - id: 4.2.2 + text: "Disallow shared usage of host namespaces." + type: "manual" + remediation: | + Implement Azure Policy to disallow shared usage of host namespaces. See https://docs.microsoft.com/en-us/azure/aks/use-pod-security-on-azure-policy#built-in-policy-initiatives + scored: false + + - id: 4.2.3 + text: "Restrict all usage of host networking and ports" + type: "manual" + remediation: | + Implement Azure Policy to restrict all usage of host networking and ports. See https://docs.microsoft.com/en-us/azure/aks/use-pod-security-on-azure-policy#built-in-policy-initiatives + scored: false + + - id: 4.2.4 + text: "Restrict any usage of the host filesystem." + type: "manual" + remediation: | + Implement Azure Policy to restrict all usage of host networking and ports. See https://docs.microsoft.com/en-us/azure/aks/use-pod-security-on-azure-policy#built-in-policy-initiatives + scored: false + + - id: 4.2.5 + text: "Restrict Linux capabilities to the default set." + type: "manual" + remediation: | + Implement Azure Policy to restrict Linux capabilities to the default set. See https://docs.microsoft.com/en-us/azure/aks/use-pod-security-on-azure-policy#built-in-policy-initiatives + scored: false + + - id: 4.2.6 + text: "Restrict usage of defined volume types" + type: "manual" + remediation: | + Implement Azure Policy to restrict usage of defined volume types. See https://docs.microsoft.com/en-us/azure/aks/use-pod-security-on-azure-policy#built-in-policy-initiatives + scored: false + + - id: 4.2.7 + text: "Restrict the user and group IDs of the container" + type: "manual" + remediation: | + Implement Azure Policy to restrict the user and group IDs of the container. See https://docs.microsoft.com/en-us/azure/aks/use-pod-security-on-azure-policy#built-in-policy-initiatives + scored: false + + - id: 4.2.8 + text: "Restrict allocating an FSGroup that owns the pod's volumes" + type: "manual" + remediation: | + Implement Azure Policy to restrict allocating an FSGroup that owns the pod's volumes. See https://docs.microsoft.com/en-us/azure/aks/use-pod-security-on-azure-policy#built-in-policy-initiatives + scored: false + + - id: 4.2.9 + text: "Requires seccomp profile" + type: "manual" + remediation: | + Implement Azure Policy to requires seccomp profile. See https://docs.microsoft.com/en-us/azure/aks/use-pod-security-on-azure-policy#built-in-policy-initiatives. + scored: false + + - id: 4.2.10 + text: "Define the AppArmor profile used by containers" + type: "manual" + remediation: | + Implement Azure Policy to define the AppArmor profile used by containers. See https://docs.microsoft.com/en-us/azure/aks/use-pod-security-on-azure-policy#additional-optional-policies. + scored: false + + - id: 4.3 + text: "Network Policies and CNI" + checks: + - id: 4.3.1 + text: "Ensure that the CNI in use supports Network Policies (Not Scored)" + type: "manual" + remediation: | + To use a CNI plugin with Network Policy, enable Network Policy in AKS. See Recommendation 6.4.4. + scored: false + + - id: 4.3.2 + text: "Ensure that all Namespaces have Network Policies defined (Scored)" + type: "manual" + remediation: | + Follow the documentation and create NetworkPolicy objects as you need them. + scored: false + + - id: 4.4 + text: "Secrets Management" + checks: + - id: 4.4.1 + text: "Prefer using secrets as files over secrets as environment variables (Not Scored)" + type: "manual" + remediation: | + If possible, rewrite application code to read secrets from mounted secret files, rather than + from environment variables. + scored: false + + - id: 4.4.2 + text: "Consider external secret storage (Not Scored)" + type: "manual" + remediation: | + Use the Azure Key Vault with Secrets Store CSI Driver to retrieve secrets from Azure Key Vault and load it in the pod. See https://github.com/Azure/secrets-store-csi-driver-provider-azure. + scored: false + + - id: 4.5 + text: "Extensible Admission Control" + checks: + - id: 4.5.1 + text: "Configure Image Provenance using ImagePolicyWebhook admission controller (Not Scored)" + type: "manual" + remediation: | + Follow the Kubernetes documentation and setup image provenance. + scored: false + + - id: 4.6 + text: "General Policies" + checks: + - id: 4.6.1 + text: "Create administrative boundaries between resources using namespaces (Not Scored)" + type: "manual" + remediation: | + Follow the documentation and create namespaces for objects in your deployment as you need + them. + scored: false + + - id: 4.6.2 + text: "Ensure that the seccomp profile is set to docker/default in your pod definitions (Not Scored)" + type: "manual" + remediation: | + Seccomp is an alpha feature currently. By default, all alpha features are disabled. So, you + would need to enable alpha features in the apiserver by passing "--feature- + gates=AllAlpha=true" argument. + Edit the /etc/kubernetes/apiserver file on the master node and set the KUBE_API_ARGS + parameter to "--feature-gates=AllAlpha=true" + KUBE_API_ARGS="--feature-gates=AllAlpha=true" + Based on your system, restart the kube-apiserver service. For example: + systemctl restart kube-apiserver.service + Use annotations to enable the docker/default seccomp profile in your pod definitions. An + example is as below: + apiVersion: v1 + kind: Pod + metadata: + name: trustworthy-pod + annotations: + seccomp.security.alpha.kubernetes.io/pod: docker/default + spec: + containers: + - name: trustworthy-container + image: sotrustworthy:latest + scored: false + + - id: 4.6.3 + text: "Apply Security Context to Your Pods and Containers (Not Scored)" + type: "manual" + remediation: | + Follow the Kubernetes documentation and apply security contexts to your pods. For a + suggested list of security contexts, you may refer to the CIS Security Benchmark for Docker + Containers. + scored: false + + - id: 4.6.4 + text: "The default namespace should not be used (Scored)" + type: "manual" + remediation: | + Ensure that namespaces are created to allow for appropriate segregation of Kubernetes + resources and that all new resources are created in a specific namespace. + scored: false + + - id: 4.7 + text: "Azure Policy Controls for ACR" + checks: + - id: 4.7.1 + text: "Container Registry should use a virtual network service endpoint" + type: "manual" + remediation: | + Implement Azure Policy for Container Registry should use a virtual network service endpoint. See https://docs.microsoft.com/en-us/azure/container-registry/security-controls-policy#azure-security-benchmark + scored: false + + - id: 4.7.2 + text: "Container registries should not allow unrestricted network access" + type: "manual" + remediation: | + Implement Azure Policy for Container registries should not allow unrestricted network access. See https://docs.microsoft.com/en-us/azure/container-registry/container-registry-azure-policy#built-in-policy-definitions + scored: false + + - id: 4.7.3 + text: "Container registries should use private links" + type: "manual" + remediation: | + Implement Azure Policy for Container registries should use private links. See https://docs.microsoft.com/en-us/azure/container-registry/container-registry-azure-policy#built-in-policy-definitions + scored: false diff --git a/cfg/config.yaml b/cfg/config.yaml index c25c103..25a0199 100644 --- a/cfg/config.yaml +++ b/cfg/config.yaml @@ -212,6 +212,7 @@ version_mapping: "gke-1.0": "gke-1.0" "ocp-3.10": "rh-0.7" "ocp-3.11": "rh-0.7" + "aks-1.0": "aks-1.0" target_mapping: "cis-1.5": @@ -242,3 +243,9 @@ target_mapping: "rh-0.7": - "master" - "node" + "aks-1.0": + - "master" + - "node" + - "controlplane" + - "policies" + - "managedservices" diff --git a/cmd/common_test.go b/cmd/common_test.go index 4f04c28..725ae0b 100644 --- a/cmd/common_test.go +++ b/cmd/common_test.go @@ -417,6 +417,12 @@ func TestValidTargets(t *testing.T) { targets: []string{"master", "node", "controlplane", "etcd", "policies", "managedservices"}, expected: true, }, + { + name: "aks-1.0 valid", + benchmark: "aks-1.0", + targets: []string{"node", "policies", "controlplane", "managedservices"}, + expected: true, + }, { name: "eks-1.0 valid", benchmark: "eks-1.0",