Skip to main content

Renforcer la sécurité d’Amazon EKS avec RBAC, un IMDS sécurisé et la journalisation d’audit

Écrit par
Headshot of Kamil Potrec

Kamil Potrec

blog feature amazon eks security

7 juillet 2021

0 minutes de lecture

Les erreurs de configuration dans l’infrastructure en tant que code (IaC) peuvent être tout aussi dangereuses que les vulnérabilités dans le code. De petites erreurs de configuration peuvent rendre des données sensibles accessibles sur Internet, ou permettre à des utilisateurs anonymes d’accéder à des points de terminaison privés et à des tableaux de bord, puis de s’en servir comme point de départ d’une compromission. De récentes recherches sur la sécurité révèlent une hausse des logiciels malveillants ciblant la plateforme Kubernetes, ce qui souligne la nécessité de configurations sécurisées.

Dans cette série d’articles, nous examinerons les paramètres par défaut utilisés dans les déploiements d’Amazon Elastic Kubernetes Service (EKS). Nous montrerons ensuite comment de petites erreurs de configuration ou des effets secondaires indésirables peuvent exposer nos clusters à des problèmes de sécurité EKS.

Qu’est-ce qu’Amazon Elastic Kubernetes Service ?

Amazon Elastic Kubernetes Service est un service Kubernetes géré. AWS prend en charge la gestion des composants du plan de contrôle du cluster, tandis que le client est responsable de la gestion des nœuds de travail et des ressources du cluster.

Outre la haute disponibilité et l’évolutivité du plan de contrôle, Amazon EKS s’intègre à Identity Access Management pour gérer les contrôles d’accès basés sur les rôles, associer des comptes de service Kubernetes à des rôles IAM, et fournit des groupes de nœuds gérés pour ajuster automatiquement la capacité des nœuds de travail en fonction de la demande, ainsi qu’une journalisation centralisée et bien plus encore. Pour consulter la liste complète des fonctionnalités, reportez-vous à la documentation officielle d’Amazon EKS.

Outre les coûts supplémentaires, les inconvénients d’un service géré incluent la perte de contrôle granulaire des paramètres du plan de contrôle et le fait que les données stockées dans la base de données du plan de contrôle doivent résider sur des comptes appartenant à AWS.

Déploiement rapide d’EKS

Amazon EKS peut être déployé de différentes façons : via une console Web, l’outil en ligne de commande Amazon EKS dédié ou des outils IaC tels que CloudFormation ou Terraform.

Nous allons utiliser Terraform pour déployer un cluster avec les valeurs par défaut. Vous trouverez les fichiers de configuration Terraform de cette démonstration dans ce dépôt. Nous utiliserons Terraform Cloud pour exécuter les commandes Terraform et conserver les modifications d’état.

Le cluster EKS doit s’exécuter dans un VPC. Vous pouvez déployer un VPC avec Terraform à l’aide de ce module.

module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = local.cluster_name
  cidr = var.vpc_cidr

  azs             = var.vpc_azs
  private_subnets = var.private_subnet_cidrs
  public_subnets  = var.public_subnet_cidrs

  enable_nat_gateway     = var.enable_nat_gateway
  single_nat_gateway     = var.single_nat_gateway
  one_nat_gateway_per_az = var.one_nat_gateway_per_az
}

Pour notre environnement de démonstration, nous allons déployer 3 sous-réseaux privés et 3 sous-réseaux publics. Les sous-réseaux privés ne disposent pas de route par défaut vers la passerelle Internet. Une passerelle NAT fournira un accès à Internet aux sous-réseaux privés. Remarque : nous déployons une seule passerelle NAT à des fins de démonstration. L’architecture réseau générale de notre environnement de démonstration est représentée ci-dessous.

Schéma de VPC AWS montrant une passerelle Internet, trois zones de disponibilité, des sous-réseaux publics et privés, ainsi que du trafic acheminé vers un sous-réseau public.

Le cluster EKS nécessite l’identifiant d’un VPC existant ainsi que les identifiants des sous-réseaux utilisés pour communiquer avec les pools de nœuds et provisionner des équilibreurs de charge pour les services et les contrôleurs d’entrée. Dans le cadre de notre environnement de démonstration, nous allons déployer un groupe de nœuds autogéré de 3 instances.

module "cluster" {
  source          = "terraform-aws-modules/eks/aws"
  cluster_name    = local.cluster_name
  cluster_version = var.cluster_version
  subnets         = module.vpc.private_subnets
  vpc_id          = module.vpc.vpc_id

  worker_groups = [
    {
      instance_type = var.wg_instance_type
      asg_max_size  = var.wg_asg_max_size
    }
  ]
}

Terraform Cloud vous permet d’exécuter des plans depuis son interface ou via des opérations à distance. Pour déclencher des actions depuis l’interface, vous devez valider le code dans le système de contrôle de version. Les opérations à distance permettent d’obtenir rapidement des commentaires sur l’état des fichiers de configuration locaux. En coulisses, Terraform téléverse une archive des fichiers de configuration locaux vers un serveur distant, exécute la commande à distance et transmet les résultats en continu à votre terminal. Pour utiliser un fichier d’état géré par Terraform Cloud, nous devons ajouter une configuration backend avec l’espace de travail et l’organisation appropriés.

terraform {
  backend "remote" {
    hostname = "app.terraform.io"
    # TODO: update with your own organization
    organization = "your-unique-organization-name"

    workspaces {
      name = "eks-demo-deployments"
    }
  }
}

Cela nécessite également un accès à Terraform Cloud via son API. Pour savoir comment le configurer, consultez la documentation officielle de Terraform Cloud.

Le plan initial indique que nos fichiers de configuration créeront 44 nouvelles ressources.

dev@pwnbox:adversarialengineering/eks-demo-deployments/terraform/default$ terraform plan
Running plan in the remote backend. Output will stream here. Pressing Ctrl-C
will stop streaming the logs, but will not stop the plan running remotely.

Preparing the remote plan...

The remote workspace is configured to work with configuration at
terraform/default/ relative to the target repository.
<OMITTED>
     + tags                             = {
          + "Name" = "eks-threat-modelling-5FZtd82l"
        }
      + tags_all                         = {
          + "Name" = "eks-threat-modelling-5FZtd82l"
        }
    }

Plan: 44 to add, 0 to change, 0 to destroy.

Nous pouvons maintenant utiliser l’interface de Terraform Cloud pour déployer l’environnement. Une fois le déploiement terminé, nous devrions pouvoir consulter les informations de notre nouveau cluster sur la page de présentation.

Exécution Terraform Cloud affichant une configuration EKS appliquée, avec les sorties de l’endpoint du cluster, de son nom, de l’ID du groupe de sécurité et de la configuration Kubernetes.

Une fois l’environnement déployé, nous pouvons suivre la documentation officielle d’AWS pour accéder au cluster de démonstration.

dev@pwnbox:~$ aws eks --region eu-west-1 update-kubeconfig --name eks-threat-modelling-5FZtd82l
Added new context arn:aws:eks:eu-west-1:123456789012:cluster/eks-threat-modelling-5FZtd82l to /home/dev/.kube/config
dev@pwnbox:~$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   172.20.0.1   <none>        443/TCP   15m
dev@pwnbox:~$

« Ce cluster nous servira de référence pour l’évaluation. Commençons par constater à quel point nous avons facilement réussi à nous connecter au cluster.

Restreindre l’accès à l’API Kubernetes

Le service EKS donne accès à l’API Kubernetes via des points de terminaison de service. Par défaut, le point de terminaison du cluster est accessible publiquement. Cela signifie que n’importe qui sur Internet peut tenter d’y accéder. Par défaut, l’API Kubernetes accepte les requêtes anonymes. Toutefois, les autorisateurs ABAC et RBAC exigent tous deux une autorisation explicite pour les utilisateurs anonymes/non authentifiés. Les clusters EKS ont RBAC activé par défaut, ce que nous pouvons vérifier en examinant les indicateurs du serveur API.

FLAG: --authentication-token-webhook-cache-ttl="7m0s"
FLAG: --authentication-token-webhook-config-file="/etc/kubernetes/authenticator/apiserver-webhook-kubeconfig.yaml"
FLAG: --authentication-token-webhook-version="v1beta1"
FLAG: --authorization-mode="[Node,RBAC]"
FLAG: --authorization-policy-file=""
FLAG: --authorization-webhook-cache-authorized-ttl="5m0s"
FLAG: --authorization-webhook-cache-unauthorized-ttl="30s"
FLAG: --authorization-webhook-config-file=""
FLAG: --authorization-webhook-version="v1beta1"

Les journaux montrent également qu’EKS implémente une méthode d’authentification par jeton webhook. Cela signifie que les utilisateurs Kubernetes doivent obtenir leur jeton d’authentification auprès de l’API AWS, qui est distincte du point de terminaison de l’API Kubernetes du cluster. Amazon EKS n’influe pas sur les décisions d’autorisation prises par le cluster.

Pour en avoir la certitude, nous pouvons tenter de nous connecter au cluster sans identifiants d’authentification. Pour simuler des utilisateurs anonymes, nous devons envoyer une requête à l’API sans en-tête d’autorisation. kubectl dispose d’une option de débogage très pratique qui affiche toutes les requêtes sous forme de commandes CURL que nous pouvons réutiliser.

dev@pwnbox:$ kubectl get pod -v 9
<OMITTED>
I0620 13:50:56.340980      19 round_trippers.go:425] curl -k -v -XGET  -H "Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json" -H "User-Agent: kubectl/v1.20.1 (linux/amd64) kubernetes/c4d7527" 'https://DC83F13246D9B2E468D2CAAD692EAF22.yl4.eu-west-1.eks.amazonaws.com/api/v1/namespaces/default/pods?limit=500'
I0620 13:50:56.435282      19 round_trippers.go:445] GET https://DC83F13246D9B2E468D2CAAD692EAF22.yl4.eu-west-1.eks.amazonaws.com/api/v1/namespaces/default/pods?limit=500 200 OK in 94 milliseconds
I0620 13:50:56.435317      19 round_trippers.go:451] Response Headers:
I0620 13:50:56.435326      19 round_trippers.go:454]     Audit-Id: 4814a650-c35b-4c98-bc0c-ba22fb3d58ce
I0620 13:50:56.435334      19 round_trippers.go:454]     Cache-Control: no-cache, private
I0620 13:50:56.435342      19 round_trippers.go:454]     Content-Type: application/json
I0620 13:50:56.435349      19 round_trippers.go:454]     Content-Length: 2926
I0620 13:50:56.435356      19 round_trippers.go:454]     Date: Sun, 20 Jun 2021 13:50:56 GMT
I0620 13:50:56.436467      19 request.go:1107] Response Body: {"kind":"Table","apiVersion":"meta.k8s.io/v1","metadata":{"selfLink":"/api/v1/namespaces/default/pods","resourceVersion":"12794"},"columnDefinitions"

Si nous envoyons la même requête sans l’en-tête d’autorisation approprié, nous constatons qu’elle n’a pas été autorisée.

dev@pwnbox:$ curl -k -v -XGET  https://DC83F13246D9B2E468D2CAAD692EAF22.yl4.eu-west-1.eks.amazonaws.com/api/v1/namespaces/default/pods?limit=500'
<OMITTED>
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {

  },
  "status": "Failure",
  "message": "pods is forbidden: User \"system:anonymous\" cannot list resource \"pods\" in API group \"\" in the namespace \"default\"",
  "reason": "Forbidden",
  "details": {
    "kind": "pods"
  },
  "code": 403

Maintenant que nous avons vérifié que l’accès à nos ressources est relativement restreint par défaut, parlons de défense en profondeur. Ce concept consiste à superposer différents types de contrôles de sécurité afin d’éviter unpoint de défaillance unique dans notre système de sécurité. Dans notre déploiement actuel, les autorisations RBAC sont le seul contrôle qui empêche quiconque sur Internet d’accéder à notre cluster.

Ce fichier de configuration montre comment quelqu’un pourrait autoriser l’accès anonyme :

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-only
subjects:
- kind: User
  name: system:anonymous
roleRef:
  kind: ClusterRole
  name: view
  apiGroup: rbac.authorization.k8s.io

Une fois cette configuration appliquée, nous constatons que la requête anonyme aboutit :

dev@pwnbox:$ curl -k -v -XGET https://DC83F13246D9B2E468D2CAAD692EAF22.yl4.eu-west-1.eks.amazonaws.com/api/v1/namespaces/default/pods?limit=500'
<OMITTED>
{
  "kind": "PodList",
  "apiVersion": "v1",
  "metadata": {
    "selfLink": "/api/v1/namespaces/default/pods",
    "resourceVersion": "15018"
  },
  "items": []

Les développeurs de Kubernetes ont mis en place des mesures de sécurité pour que ce type de configuration soit explicitement défini. L’utilisateur system:anonymous et le groupe system:unauthenticated doivent être explicitement répertoriés dans l’attribut subjects. Les caractères génériques, tels que *, n’accordent pas l’accès à ces deux sujets. Vous pouvez le vérifier en remplaçant le name du sujet dans notre exemple par le caractère *.

L’accès public au serveur de l’API Kubernetes amplifie également l’impact de toute fuite d’identifiants. Si l’API est accessible publiquement, les identifiants divulgués peuvent potentiellement être utilisés depuis n’importe où dans le monde. La découverte d’une vulnérabilité zero-day dans le processus d’autorisation constitue une autre raison majeure de limiter les adresses IP autorisées à envoyer des paquets au serveur API. Des vulnérabilités de ce type ont déjà été signalées, notamment CVE-2019-11253 et CVE-2020-8559.

Nous pouvons réduire l’impact des points de terminaison publics en limitant l’accès à certaines adresses IP. Dans Terraform, il suffit d’ajouter l’attribut cluster_endpoint_public_access_cidrs à la définition du module.

La deuxième option consiste à désactiver complètement le point de terminaison public et à activer un point de terminaison privé du VPC. Dans le module Terraform, cela se configure à l’aide des attributs cluster_endpoint_private_access et cluster_endpoint_public_access. Ainsi, seuls les utilisateurs ayant accès au réseau VPC peuvent accéder au cluster.

Cependant, ces deux options ont une incidence considérable sur les coûts opérationnels. L’absence de point de terminaison public peut poser problème si vous utilisez un système de déploiement continu public comme Terraform Cloud. Dans notre environnement de démonstration, la désactivation du point de terminaison public a fait échouer le déploiement et généré l’erreur d’accès refusé suivante.

Erreur lors de l’application de Terraform : une requête de vérification de l’état du cluster EKS expire pendant la création et la mise à jour des ressources.

Cette erreur se produit parce qu’en interne, le module Terraform tente d’actualiser la carte de configuration aws-auth, une opération qui ne peut être effectuée que via l’API Kubernetes. Comme vous pouvez le constater, le nom de domaine complet du serveur API a été résolu en adresse IP privée et le fournisseur ne peut pas le joindre. Nous pouvons corriger cette erreur en désactivant la gestion de la carte de configuration dans notre module Terraform. Cela signifie qu’à partir de ce moment, nous devrons gérer la carte de configuration d’autorisation par une autre méthode.

Pour désactiver complètement le point de terminaison public, vous devez mettre en place un système de déploiement continu qui s’exécute depuis le VPC et peut accéder au point de terminaison privé, ou qui fait transiter la connexion par un proxy. Ce guide explique très bien comment procéder avec AWS CodePipeline, et ce module Terraform permet d’exécuter Atlantis dans le service AWS Fargate.

L’accès des développeurs peut également devenir plus complexe, car vous devrez mettre en place un bastion ou un service VPN afin de leur fournir un accès au point de terminaison privé.

Restreindre l’accès au service de métadonnées d’instance

EKS utilise les profils d’instance pour accorder des autorisations AWS à un kubelet exécuté sur un nœud. Le kubelet peut accéder à ces identifiants via le service de métadonnées d’instance (IMDS). IMDS est accessible par une requête HTTP envoyée à une adresse IP de liaison locale. Par défaut, tous les pods du nœud peuvent accéder à ce service de métadonnées. Nous pouvons le vérifier en exécutant un pod et en obtenant un jeton STS.

apiVersion: v1
kind: Pod
metadata:
  name: aws
  namespace: default
spec:
  containers:
  - name: aws
    image: amazon/aws-cli:latest
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always

dev@pwnbox:$ kubectl exec -it aws -- /bin/bash
bash-4.2# aws sts get-caller-identity
{
    "UserId": "AROAYREY3WYOLQYZ5IGZJ:i-0f52c37fc0a7a4a44",
    "Account": "123456789012",
    "Arn": "arn:aws:sts::123456789012:assumed-role/eks-threat-modelling-5FZtd82l20210620220209389400000009/i-0f52c37fc0a7a4a44"
}
bash-4.2#

Dans l’exemple ci-dessus, nous pouvons utiliser toutes les autorisations attribuées au nœud. Il s’agit clairement d’un problème de sécurité lié à une élévation de privilèges, car par défaut, les pods ne devraient pas avoir besoin d’accéder aux services AWS.

La seule façon d’atténuer ce problème consiste à limiter l’accès réseau des pods au service IMDS. IMDS existe en deux versions. La version 1 utilise un mécanisme de requête/réponse et peut être interrogée par tout processus capable d’envoyer des paquets à l’adresse de liaison locale. La version 2 utilise des sessions et permet de définir une durée de vie (TTL) arbitraire pour les messages de réponse. Selon la documentation AWS, IMDSv1 restera disponible en parallèle d’IMDSv2.

Pour limiter la portée de ce problème à l’aide de la configuration AWS native, nous devons désactiver complètement IMDSv1. Pour cela, définissez l’attribut metadata_http_tokens des nœuds de travail sur required. Ensuite, limitez la durée de vie (TTL) des paquets de réponse à 1, ce qui correspond en fait au comportement par défaut du service. Avec un TTL défini sur 1, la couche réseau de Kubernetes ne peut pas transférer le paquet vers l’espace de noms réseau du pod.

dev@pwnbox:$ kubectl exec -it aws -- aws sts get-caller-identity

Unable to locate credentials. You can configure credentials by running "aws configure".
command terminated with exit code 253

Le module Terraform pour Amazon EKS utilise des groupes Auto Scaling et des modèles de lancement pour créer les nœuds. Par conséquent, si vous modifiez les paramètres du service de métadonnées, les instances devront être actualisées.

Cette solution présente toutefois une limite : tout pod dont l’attribut hostNetworking est défini sur true pourra toujours obtenir les identifiants.

apiVersion: v1
kind: Pod
metadata:
  name: aws-node
  namespace: default
spec:
  hostNetwork: true
  containers:
  - name: aws-node
    image: amazon/aws-cli:latest
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always

dev@pwnbox:$ kubectl exec -it aws-node -- aws sts get-caller-identity
{
    "UserId": "AROAYREY3WYOLQYZ5IGZJ:i-0e0ecce7af113398b",
    "Account": "123456789012",
    "Arn": "arn:aws:sts::123456789012:assumed-role/eks-threat-modelling-5FZtd82l20210620220209389400000009/i-0e0ecce7af113398b"
}

Les stratégies réseau natives de Kubernetes peuvent également servir à restreindre l’accès aux adresses IP de liaison locale et ainsi empêcher l’accès à IMDS. La documentation AWS Calico explique comment installer le plug-in CNI Calico. La stratégie réseau suivante devrait empêcher l’accès à IMDS. Le plug-in Calico n’isole pas les pods dont l’attribut hostNetwork est défini sur true ; il présente donc la même limite que la solution native consistant à désactiver IMDSv1 et à définir le TTL maximal sur 1. Les stratégies réseau ne nécessitent toutefois pas de renouveler les nœuds et peuvent être appliquées à des pods spécifiques si IMDS est réellement nécessaire dans le pod.

apiVersion: crd.projectcalico.org/v1
kind: GlobalNetworkPolicy
metadata:
  name: block-metadata-egress-only
spec:
  selector: all()
  egress:
  - action: Deny
    protocol: TCP
    destination:
      nets:
      - 169.254.169.254/32
  - action: Allow
    destination:
      nets:
      - 0.0.0.0/0

dev@pwnbox:$ kubectl exec -it aws -- aws sts get-caller-identity
{
    "UserId": "AROAYREY3WYOLQYZ5IGZJ:i-06a05d6ddfff5b2bd",
    "Account": "123456789012",
    "Arn": "arn:aws:sts::123456789012:assumed-role/eks-threat-modelling-5FZtd82l20210620220209389400000009/i-06a05d6ddfff5b2bd"
}
dev@pwnbox:$ kubectl apply -f tests/disable-imds-network-access/network-policy.yaml
globalnetworkpolicy.crd.projectcalico.org/allow-all-egress-except-ec2-metadata created
dev@pwnbox:$ kubectl exec -it aws -- aws sts get-caller-identity

Unable to locate credentials. You can configure credentials by running "aws configure".
command terminated with exit code 253
dev@pwnbox:$

Activer la journalisation

Maintenant que nous avons vu certaines erreurs de configuration susceptibles d’exposer les clusters EKS à des menaces externes et internes, voyons s’il est possible d’auditer ces événements. Kubernetes fournit des journaux d’audit qui permettent aux administrateurs de surveiller les actions effectuées par les utilisateurs et les services du cluster. Malheureusement, ces journaux ne sont pas activés par défaut dans EKS, ni dans la configuration du module Terraform par défaut. Pour les activer, nous devons utiliser l’attribut cluster_enabled_log_types et spécifier les types de journaux requis.

EKS permet d’activer indépendamment plusieurs types de journaux. Du point de vue de la sécurité, ceux qui nous intéressent principalement sont les journaux audit et authenticator.

Les journaux d’audit nous permettent de surveiller les requêtes Kubernetes et de les attribuer à des entités. Notez que les journaux d’audit génèrent des événements pour chaque action effectuée sur le cluster et transmettent donc de grands volumes de données vers la destination configurée, qui est CloudWatch par défaut. En limitant les journaux à audit et authenticator, nous pouvons réduire le volume.

Par exemple, nous pouvons rechercher les modifications apportées à la map aws-config pour déterminer si quelqu’un l’a altérée. Nous pouvons utiliser le filtre suivant pour obtenir tous les événements de type patch concernant un objet nommé aws-auth.

{ ($.verb = "patch") && ($.objectRef.name = "aws-auth") }

Les événements d’audit contiennent des informations très utiles qui peuvent nous aider à déterminer qui a effectué la modification, d’où cette personne s’est connectée, et bien plus encore.

{
    "kind": "Event",
    "apiVersion": "audit.k8s.io/v1",
    "level": "RequestResponse",
    "auditID": "844b26da-3ce9-4062-b7aa-3c0a869d9e45",
    "stage": "ResponseComplete",
    "requestURI": "/api/v1/namespaces/kube-system/configmaps/aws-auth?fieldManager=kubectl-edit",
    "verb": "patch",
    "user": {
        "username": "kubernetes-admin",
        "uid": "heptio-authenticator-aws:123456789012:AROAYREY3WYOBFHU7VIRM",
        "groups": [
            "system:masters",
            "system:authenticated"
        ],
        "extra": {
            "accessKeyId": [
                "ASIAYREY3WYOETXWXAOG"
            ]
        }
    },
    "sourceIPs": [
        "12.34.256.27"
    ],
    "userAgent": "kubectl/v1.20.1 (linux/amd64) kubernetes/c4d7527",
    "objectRef": {
        "resource": "configmaps",
        "namespace": "kube-system",
        "name": "aws-auth",
        "apiVersion": "v1"
    },
    "responseStatus": {
        "metadata": {},
        "code": 200
    },
    <OMITTED>

Ces journaux peuvent également être très utiles pour détecter les tentatives d’accès aux ressources par des utilisateurs non autorisés. La requête suivante permet de rechercher toutes les requêtes envoyées par un utilisateur anonyme :

{ ($.user.username = *anonymous) }

{
    "kind": "Event",
    "apiVersion": "audit.k8s.io/v1",
    "level": "Metadata",
    "auditID": "68f24024-080b-4ae7-a97b-fd5fd9792e31",
    "stage": "ResponseComplete",
    "requestURI": "/api/v1/namespaces/kube-system/configmaps/aws-auth",
    "verb": "get",
    "user": {
        "username": "system:anonymous",
        "groups": [
            "system:unauthenticated"
        ]
    },
    "sourceIPs": [
        "12.34.256.27"
    ],
    "userAgent": "kubectl/v1.20.1 (linux/amd64) kubernetes/c4d7527",
    "objectRef": {
        "resource": "configmaps",
        "namespace": "kube-system",
        "name": "aws-auth",
        "apiVersion": "v1"
    },
    "responseStatus": {
        "metadata": {},
        "status": "Failure",
        "reason": "Forbidden",
        "code": 403
    },
    "requestReceivedTimestamp": "2021-06-21T17:08:02.384514Z",
    "stageTimestamp": "2021-06-21T17:08:02.384693Z",
    "annotations": {
        "authorization.k8s.io/decision": "forbid",
        "authorization.k8s.io/reason": ""
    }
}

Les journaux d’authentification, quant à eux, peuvent nous aider à savoir qui tente de se connecter au cluster et à associer ces entités aux groupes et utilisateurs Kubernetes. Dans l’exemple précédent, nous savons que l’utilisateur associé à l’ID de clé AROAYREY3WYOBFHU7VIRM a modifié la configmap, mais nous ne savons pas à quelle entité AWS correspond cet ID de clé.

ime="2021-06-21T16:32:01Z" level=info msg="access granted" arn="arn:aws:iam::123456789012:role/ci" client="127.0.0.1:39092" groups="[system:masters]" method=POST path=/authenticate sts=sts.eu-west-1.amazonaws.com uid="heptio-authenticator-aws:123456789012:AROAYREY3WYOBFHU7VIRM" username=kubernetes-admin

À suivre : renforcer la sécurité avancée d’Amazon EKS

Dans cet article, nous avons donc examiné certains problèmes de sécurité susceptibles de survenir lors de l’utilisation d’Amazon Elastic Kubernetes Service, notamment en matière d’authentification et d’autorisation, ainsi que d’accès au service de métadonnées des instances. Nous avons également vu comment atténuer ces risques en production. Dans la prochaine partie de cette série, nous examinerons l’architecture multi-comptes, étape essentielle pour isoler les clusters Amazon EKS, l’importance d’utiliser des rôles IAM dédiés lors de la création de clusters Amazon EKS, ainsi que les moyens de mieux protéger les secrets stockés dans les plans de contrôle Amazon EKS. Consultez le prochain article ou suivez-nous sur Twitter à l’adresse @snkysec pour être averti de sa publication.

L’analyse Snyk Infrastructure as Code (Snyk IaC) peut également contribuer à atténuer les problèmes de sécurité liés à l’utilisation d’Amazon EKS avec Cloud Formation ou Terraform, en détectant les problèmes de sécurité dans votre code de déploiement avant sa mise en production. Créez un compte gratuit et lancez vos analyses !

Sécurisez votre infrastructure dès la source

Snyk automatise la sécurité et la conformité de l’IaC dans vos workflows, et détecte les ressources dont la configuration a dérivé ou qui sont manquantes.

Publié dans: