Amazon EKS security best practices - Amazon EKS

Amazon EKS security best practices

This topic provides security best practices for your cluster.

Restricting access to the IMDS and Amazon EC2 instance profile credentials

By default, the Amazon EC2 instance metadata service (IMDS) provides the credentials assigned to the node IAM role to the instance, and any container running on the instance. When you use IAM roles for service accounts, it updates the credential chain of the pod to use the IAM roles for service accounts token. The pod, however, can still inherit the rights of the instance profile assigned to the node. We recommended that you block pod access to IMDS to minimize the permissions available to your containers if:

  • You’ve implemented IAM roles for service accounts and have assigned necessary permissions directly to all pods that require access to AWS services.

  • No pods in your cluster require access to IMDS for other reasons, such as retrieving the current Region.

For more information, see Retrieving Security Credentials from Instance Metadata. You can prevent access to IMDS from your instance and containers using one of the following options.

Important

If you use the AWS Load Balancer Controller in your cluster, you may need to change your load balancer configuration. For more information, see To deploy the AWS Load Balancer Controller to an Amazon EKS cluster.

  • Block access to IMDSv1 from the node and all containers and block access to IMDSv2 for all containers that don't use host networking – Your instance and pods that have hostNetwork: true in their pod spec use host networking. To implement this option, complete the steps in the row and column that apply to your situation.

    Deployment method New node group Existing node group
    Managed nodes without a custom launch template Not possible using any deployment method other than eksctl. If deploying with eksctl, use the --disable-pod-imds option with eksctl create nodegroup. eksctl can be used because it creates a launch template based on options you specify and deploys the node group using that launch template. We recommend creating a new node group with a custom launch template that includes the settings in the New node group column of the next row of this table.
    Managed nodes with a custom launch template Set the following settings in the launch template's Advanced details:
    • Metadata accessibleEnabled

    • Metadata versionV2 only (token required)

    • Metadata response hop limit1

    Update your launch template with the settings in the New column and then update your node group using the new launch template version.
    Self-managed
    • If creating the node group using the AWS Management Console

      1. Download the self-managed node group AWS CloudFormation template for your Region and operating system.

        • Linux – All Regions other than China (Beijing) and China (Ningxia)

          https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/amazon-eks-nodegroup.yaml
        • Linux – China (Beijing) and China (Ningxia)

          https://s3.cn-north-1.amazonaws.com.cn/amazon-eks/cloudformation/2020-10-29/amazon-eks-nodegroup.yaml
        • Windows – All Regions other than China (Beijing) and China (Ningxia)

          https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/amazon-eks-windows-nodegroup.yaml
        • Windows – China (Beijing) and China (Ningxia)

          https://s3.cn-north-1.amazonaws.com.cn/amazon-eks/cloudformation/2020-10-29/amazon-eks-windows-nodegroup.yaml
      2. Edit the file. Change the line that says HttpPutResponseHopLimit : 2 to HttpPutResponseHopLimit : 1 and save the file.

      3. Deploy the node group using the instructions in Launching self-managed Amazon Linux nodes or Launching self-managed Windows nodes. For the instruction about specifying an AWS CloudFormation template, instead of selecting Amazon S3 URL, select Upload a template file, then select Choose file, choose your edited file, and then continue on with the instructions. Set the value of DisableIMDSv1 to true too.

    • If creating the node group using eksctl, use the --disable-pod-imds option with eksctl create nodegroup.

    • If updating or migrating the node group using the AWS Management Console

      1. Download the self-managed node group AWS CloudFormation template for your Region and operating system.

        • Linux – All Regions other than China (Beijing) and China (Ningxia)

          https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/amazon-eks-nodegroup.yaml
        • Linux – China (Beijing) and China (Ningxia)

          https://s3.cn-north-1.amazonaws.com.cn/amazon-eks/cloudformation/2020-10-29/amazon-eks-nodegroup.yaml
        • Windows – All Regions other than China (Beijing) and China (Ningxia)

          https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/amazon-eks-windows-nodegroup.yaml
        • Windows – China (Beijing) and China (Ningxia)

          https://s3.cn-north-1.amazonaws.com.cn/amazon-eks/cloudformation/2020-10-29/amazon-eks-windows-nodegroup.yaml
      2. Edit the file. Change the line that says HttpPutResponseHopLimit : 2 to HttpPutResponseHopLimit : 1 and save the file.

      3. Update your self-managed node group using the instructions in Updating an existing self-managed node group. For the instruction about specifying an AWS CloudFormation template, instead of selecting Amazon S3 URL, select Upload a template file, then select Choose file, choose your edited file, and then continue on with the instructions. Set the value of DisableIMDSv1 to true too.

      Important

      Each time you update the node group, for any reason, such as a new AMI or Kubernetes version, you need to change the previous settings in the template again.

    • If migrating the node group using eksctl, then when you create the new node group, use the --disable-pod-imds option with eksctl create nodegroup.

      Important

      Each time you update the node group, for any reason, such as a new AMI or Kubernetes version, make sure to use this option when creating your new node group.

  • Block access to IMDSv1 and IMDSv2 for all containers that don't use host networking – Your instance and pods that have hostNetwork: true in their pod spec use host networking, but for legacy reasons still require access to IMDSv1. Run the following iptables commands on each of your Amazon Linux nodes (as root) or include them in your instance bootstrap user data script.

    yum install -y iptables-services iptables --insert FORWARD 1 --in-interface eni+ --destination 169.254.169.254/32 --jump DROP iptables-save | tee /etc/sysconfig/iptables systemctl enable --now iptables
    Important
    • The previous rule applies only to network interfaces within the node that have a name that starts with eni, which is all network interfaces that the CNI plugin creates for pods that don't use host networking. Traffic to the IMDS is not dropped for the node, or for pods that use host networking, such as kube-proxy and the CNI plugin.

    • If you implement network policy, using a tool such as Calico, the previous rule may be overridden. When implementing network policy, ensure that it doesn't override this rule, or that your policy includes this rule.

    • If you've applied security groups to pods and therefore, have branch network interfaces, in addition to the previous command, also run the following command.

      iptables -t mangle -A POSTROUTING -o vlan+ --destination 169.254.169.254/32 --jump DROP

      For more information about branch network interfaces, see Security groups for pods.