Verbeter jouw security posture met OWASP voor Kubernetes hardening

Thomas Kooi

Platform Architect

Published: 3 January, 2022

Avisi Cloud draait Kubernetes-clusters sinds het begin van 2018. Sindsdien is er veel gebeurd. In deze blog kijken we naar een aantal praktische voorbeelden voor het hardenen van Kubernetes-clusters. We behandelen de praktische voorbeelden door gebruik te maken van de OWASP Security by design-principes.

Aan het einde van de blog eindigen we met tooling dat jou kan helpen om de benodigde security policies goed te laten verlopen.

Waarom is het belangrijk om de security posture van jouw Kubernetes-clusters te verbeteren? Ten eerste is Kubernetes erg complex. Het is makkelijk om fouten te maken zonder dat je dit door hebt. Dit willen we voorkomen, omdat dit een risico kan zijn op de beschikbaar- en vertrouwelijkheid van jouw applicaties. Indien jouw applicaties niet beschikbaar en betrouwbaar zijn, kan klantendata verloren gaan. Dit kan weer voor negatieve gevolgen zorgen, zoals imagoschade. Daarom is het goed om te kijken naar de inrichting van jouw Kubernetes-omgeving aan de hand van Security Principes. Deze Security Principes geven jou een handvat om te weten welke acties jij moet ondernemen om de Security Posture te verbeteren.

Veiligheidsrisico's, bedreigingen en principes

Voordat je een systeem kan beveiligen, is het belangrijk om bekend te zijn met de potentiële risico's en bedreigingen van dit systeem. Voor Kubernetes helpt Microsoft ons hiermee met behulp van hun Kubernetes threat matrix, zie hieronder.

k8s-matrix_hua4878c7204781a97e1b4d5f6e807311f_87982_900x0_resize_box_3

De threat matrix van Kubernetes is gebaseerd op de MITRE ATT&CK framework. Dit framework bestaat uit de volgende tactieken:
  • Initial access
  • Execution
  • Persistence
  • Privilege escalation
  • Defense evasion
  • Credential access
  • Discovery
  • Lateral movement
  • Impact

Om je cluster te beveiligen, is het nodig om mitigerende maatregelen te hebben voor elk van deze tactieken. De blogpost van Microsoft over de threat matrix is hiervoor een goed beginpunt.

Security by design

Het gebruikmaken van security principes kan helpen bij het bepalen welke maatregelen er geïmplementeerd dienen te worden om je cluster veilig te houden. Om hierbij te helpen kan je gebruikmaken van de OWASP Security by design-principes:

  • Minimize attack surface area
  • Establish secure defaults
  • Principle of Least privilege
  • Principe of Defense in depth
  • Fail securely
  • Don't trust services
  • Separation of duties
  • Avoid security by obscurity
  • Keep security simple
  • Fix security issues correctly

In deze blog gaan we door elk van deze principes en kijken we welke maatregelen wij hieruit kunnen halen die je kan toepassen op je Kubernetes-cluster. Let op dat je security vanuit meerdere perspectieven kan benaderen en het is altijd belangrijk om hier vanuit meerdere hoeken naar te kijken.

Veiligheid implementeren in Kubernetes

1. Minimize attack surface area

Een goede manier om risico's te minimaliseren is door de aanval oppervlakte te verkleinen. Binnen Kubernetes zijn er verschillende manier om dit te doen.

Gebruik minimale container images
Draai zo min mogelijk container images, het liefst zonder een shell. Een goede suggestie hiervoor zijn distroless container images. Er zijn ook minimale versies van container base images (Linux Distributies) beschikbaar óf je kan gebruikmaken van een alpine base image.

Een linux distributie is een verzameling van software packages rond een Linux kernel.  Dit is traditioneel voor virtual machines. Voor containers heb je deze smaken ook (minus de kernel die hierbij niet nodig is). Standaard zit er in een linux distributie veel meer software als wat je voor normaal gebruik nodig hebt. Een minimaal distributie heeft hier een groot deel van verwijderd, waardoor de grote van het image verkleint is. Dit heeft als gevolg dat het aanvalsoppervlak voor kwaadwillende ook kleiner is. 

Terwijl ongebruikte bestanden geen groot probleem zijn, zorgt het niet hebben van deze container images voor een paar voordelen:

  1. Het versnelt je deployments door de bandbreedte/opslaggebruik te verlagen.
  2. Als je applicatie gecomprimeerd is zijn er veel minder potentiële handige tools beschikbaar waar een kwaadwillende actor gebruik van kan maken.
  3. Wanneer gebruik wordt gemaakt van vulnerability scans krijg je niet zoveel valse positieven. Het resultaat hiervan is dat je een goed idee krijgt van welke kwetsbaarheden in de software packages in je image belangrijk zijn.

Inkomend verkeer

Publieke verkeer dat het cluster tegenkomt, op het interne netwerk, zal niet direct in contact moeten komen met de nodes binnen het cluster. Maak gebruik van een load balancer om met inkomend verkeer om te gaan.
  • Maak gebruik van een ingress controller of gateway (proxy) om met het inkomende verkeer op je cluster af te handelen. Dit soort componenten geven snel voordelen, zoals access logging of protocol validatie.
  • Configureer netwerkpolicies voor je inkomend verkeer controller en andere services die te maken hebben met inkomend verkeer (bijv. node parts en load balancers).

Binnen AME Kubernetes is de toegang naar cluster nodes beschermd door middel van een firewall. Op AWS vindt deze bescherming plaats door middel van security regels.

Een goede netwerk policy om te downloaden in elke namespace is een standaard deny all policy:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: default-deny-all
  namespace: examplenamespace
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
  ingress: []
  egress: []


Andere voorbeelden van goede netwerk policies zijn transparant in wat een container kan doen, in plaats van alle soorten verkeer toe te laten. Dit is een policy die DNS traffic toestaat naar de Kube-system namespace:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-util-traffic
  namespace: examplenamespace
spec:
  podSelector:
    matchLabels: {}
  policyTypes:
  - Egress
  egress:
  - ports:
    # Allow DNS
    - port: 53
      protocol: UDP
    - port: 53
      protocol: TCP
    to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system


Als je applicatie toegang tot het publieke internet nodig heeft, vermijdt dan egress verkeer met 0.0.0.0/0 en voeg except toe voor interne subnets (RFC1918).

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-egress-to-external
  namespace: examplenamespace
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: example
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
        except:
        # deny internal RFC1918 subnets
        - 10.0.0.0/8
        - 172.16.0.0/12
        - 192.168.0.0/16

Container registries

Sinds alles in Kubernetes draait op container images, kan het opstarten van een gecomprimeerde container image binnen je cluster ervoor zorgen dat je kwaadaardige software zoals crypto-miners binnen je cluster opstart. Andere scenario's kunnen zijn dat een aanvaller een remote shell weet te bemachtigen binnen je container of scripts daarop kan downloaden en uitvoeren.

Om te waarborgen dat je geen gecomprimeerde images opstart binnen je cluster, kan je het volgende doen:

  1. Draai alleen container images van bekende en gevalideerde bronnen. Als je organisatie
    groot genoeg is waardoor je de capaciteit hebt om het te onderhouden, is het verstandig om alleen container images van je eigen bronnen te gebruiken. Dit betekent echter wel dat je moet zorgen dat deze images up-to-date blijven.
  2. Draai container image vulnerability scans op elke container image binnen je cluster. Je kan dit voor elke container image doen die in je cluster draait met een admission webhook of begin met je eigen container images door image scanning in je CI pipelines en/of registry uit te voeren.

Als je jouw self hosted registry op Harbor draait, dan zijn er verschillende opties beschikbaar. Voor hosted solutions, check je provider's documentatie.

2. Establish secure defaults

De "Establish secure defaults"-principe zegt dat de standaard optie veilig moet zijn. Om extra privileges te kunnen verkrijgen, is het belangrijk dat er meerdere stappen uitgevoerd worden. Dit is zodat een verhoogd privilege niveau niet een configuratiefout kan zijn. Dit kan je waarborgen door gebruik te maken van veilige default instellingen voor je cluster.

Pod Security Policy of Pod-Security Standards gebruiken
Kubernetes heeft een eigen oplossing om de scope van bevoegdheden die een container heeft, wanneer deze in het cluster wordt uitgevoerd, te beperken. Het nu verouderde Pod Security Policy was de manier om dit te doen. Sinds Kubernetes v1.21 is dit deprecated en dient er gebruikgemaakt te worden van de nieuwe Pod Security Standards (PSS).

Voor nieuwe clusters is aangeraden om PSS in te zetten. PSS bevat drie policies: Privileged, Baseline en Restricted:

Profiel Beschrijving
Bevoorrecht Onbeperkt beleid met het breedst mogelijke niveau van machtigingen. Dit beleid staat bekende escalaties van bevoegdheden toe.
Basislijn Minimaal restrictief beleid dat bekende escalaties van bevoegdheden voorkomt. Staat de standaard (minimaal gespecificeerde) Pod-configuratie toe.
Beperkt Zwaar beperkt beleid, volgens de huidige best practices voor het verharden van pods.


Indien Pod Security Standards zijn ingeschakeld in je cluster (via een featureGate), kun je dit per namespace configureren.

apiVersion: v1
kind: Namespace
metadata:
  name: my-restricted-namespace
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: latest
    pod-security.kubernetes.io/warn: restricted
    pod-security.kubernetes.io/warn-version: latest

Admission controllers

Het cloud native-ecosysteem heeft een aantal goede projecten beschikbaar om ervoor te zorgen dat applicaties/containers met de juiste settings draaien. Ze kunnen helpen met het afdwingen van security defaults door automatisch PodSecurityContext te configureren voor nieuwe pods of door het installeren van NetworkPolicies binnen een cluster.

Kyverno

Kyverno is een policy management engine speciaal gebouwd voor het Kubernetes-ecosysteem. Het is heel eenvoudig om met Kyverno aan de slag te gaan.

Via Kyverno is het mogelijk om elk gewenst beleid binnen een Kubernetes-cluster af te dwingen. Zo kan je ervoor zorgen dat alle containers van de juiste registry komen, naamgeving correct is en er netwerk policies aanwezig zijn. Er zijn ook een goede set aan default policies beschikbaar (voorbeeld).

Een goed voorbeeld van secure defaults binnen een Kubernetes-cluster is het installeren van een default network policy dat al het netwerkverkeer weigert. Dit kan met Kyverno via de volgende policy: 

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-networkpolicy
  annotations:
    policies.kyverno.io/title: Add Network Policy
    policies.kyverno.io/category: Multi-Tenancy
    policies.kyverno.io/subject: NetworkPolicy
    policies.kyverno.io/description: >-
      By default, Kubernetes allows communications across all Pods within a cluster.
      The NetworkPolicy resource and a CNI plug-in that supports NetworkPolicy must be used to restrict
      communications. A default NetworkPolicy should be configured for each Namespace to
      default deny all ingress and egress traffic to the Pods in the Namespace. Application
      teams can then configure additional NetworkPolicy resources to allow desired traffic
      to application Pods from select sources. This policy will create a new NetworkPolicy resource
      named `default-deny` which will deny all traffic anytime a new Namespace is created.      
spec:
  rules:
  - name: default-deny
    match:
      resources:
        kinds:
        - Namespace
    generate:
      kind: NetworkPolicy
      name: default-deny
      namespace: ""
      synchronize: true
      data:
        spec:
          # select all pods in the namespace
          podSelector: {}
          # deny all traffic
          policyTypes:
          - Ingress
          - Egress


3. Principe van het minste privilege

Gebruik geen root binnen containers

De meeste standaard workloads hoeven niet onder de rootgebruiker te worden uitgevoerd. Ook in een container is het geen goed idee om root te gebruiken, omdat dit een grote mate van geprivilegieerde acties in Linux mogelijk maakt. Mogelijke risico's zijn onder meer het verkrijgen van toegang tot een Kubernetes-node (container-escape).

Zorg bij het maken van een nieuwe containerimage dat deze niet als rootgebruiker wordt uitgevoerd. Je kunt dit doen met de USER statement in je Dockerfile. Sysdig heeft een goede blogpost over de best practices voor een Dockerfile geschreven.

Een veelvoorkomende reden waarom images nog steeds root gebruiken, is om het gebruik van een poort onder 1024 toe te staan. Je moet in plaats daarvan ofwel een hogere poort voor je applicatie gebruiken,of linux-capabilities gebruiken om het gebruik van deze poort toe te staan ​​(CAP_NET_ADMIN). 

Let op: indien je de capability gebruikt moet je ervoor zorgen dat je deze ook toevoegt aan de container security context capabilities.

Gebruik RBAC

Role based access control (RBAC) is standaard ingeschakeld binnen Kubernetes. Zorg ervoor dat je bij het maken van een nieuw serviceaccount alleen de benodigde permissies geeft.

Je moet ook voorkomen dat het standaard serviceaccounttoken in een pod wordt gemount (automountServiceAccountToken: false). Indien je toch een service account token nodig hebt, maak dan een speciaal serviceaccount en geef hier zo min mogelijk permissies aan.

  • Dedicated Service Account voor elke deployment / statefulset.
  • Vermijd het mounten van een serviceaccounttoken, tenzij dat nodig is (bijvoorbeeld met service meshes, of als toegang tot de Kubernetes API nodig is)
  • Vermijd het gebruik van de cluster-admin clusterRoleBinding. Gebruik speciale RBAC-rollen voor elke serviceaccount en/of gebruiker. Een project dat hierbij kan helpen is RBAC manager van FairwindsOps .


Bescherm cloud credentials

De inloggegevens van cloudproviders zijn vaak zeer gevoelige credentials, omdat ze toegang bieden tot infrastructuur zoals EC2-instanties, control plane-VM's of back-ups. Binnen een Kubernetes-context zijn er in ieder geval twee plaatsen die inloggegevens voor cloudproviders kunnen hebben:

  1. Cloudintegraties, zoals de cloud controller manager. Deze worden bijvoorbeeld gebruikt om load balancers te provisionen, automatisch te schalen (autoscaling) of persistente volumes (PVC) te beheren.
  2. Instance metadata, een API of document dat is opgeslagen op de VM waarmee je toegang krijgt tot de API van de cloudprovider.

Door het principe van least privilege te gebruiken, zorg je ervoor dat voor alle inloggegevens het minimaal benodigde aantal permissies is ingesteld. Mocht er iets misgaan, dan zal de impact beperkt zijn.

Ten tweede, zorg ervoor dat elke namespace goed geconfigureerde network policies heeft. Dit verhindert toegang tot de instantie metadata-API (bijvoorbeeld 169.254.169.254 op AWS ). Zet bijvoorbeeld al het uitgaande netwerkverkeer standaard dicht.

Zorg ervoor dat alle workloads die Kubernetes secrets met cloud-provider credentials gebruiken worden uitgevoerd op nodes die losstaan ​​van normale applicatieworkloads. Als een aanvaller erin slaagt om uit een container te komen en toegang te krijgen tot het hostsysteem, kan die alle Kubernetes secrets op die node achterhalen of opvragen. Indien je workloads met de cloud-provider credentials op andere hosts draaien, is de impact van een node comprise veel minder.

Zorg ervoor dat de NodeRestriction admission controller is ingeschakeld. Dit zou bij de meeste providers het geval moeten zijn.

Kubeconfig file

Het kubeconfig file is een manier om met de Kubernetes API-server te communiceren. Het bevat de credentials en het endpoint van de Kubernetes API. Als een aanvaller toegang krijgt tot een kubeconfig-file, dan kan die acties uitvoeren terwijl die zich voordoet als de gebruiker of het systeem waartoe de kubeconfig behoort.

Credentials die in een kubeconfig-file worden gebruikt moeten gemakkelijk kunnen worden ingetrokken. Hiervoor dien je gebruik te maken van een authenticatiemechanisme zoals bijvoorbeeld OpenID Connect voor je cluster. De meeste enterprise ready Kubernetes service providers hebben hiervoor een oplossing.

Gebruik geen authenticatie voor je API-server via client certificates. Indien dit de enigste optie is, deel dit dan niet met andere gebruikers. Momenteel is er geen mechanisme om de client certificaten in te trekken binnen Kubernetes (kubernetes/kubernetes#60917).

Als OIDC niet beschikbaar is, overweeg dan gebruik te maken van statische bearer tokens of gebruik certificaten met een zeer korte levensduur (<24h).

4. Principe of defense in depth

"Defense in depth" vertelt ons om ervoor te zorgen dat als één maatregel faalt, er op een lager niveau een andere maatregel moet zijn dat misbruik voorkomt.

Toegang tot API-server

Hoewel het toepassen van het principe of least privilage bij RBAC een goede maatregel is, is het verstandig om de toegang tot de API-server alsnog te beperken.

  • Zorg ervoor dat de toegang tot de Kubernetes API-server is beveiligd via een firewall of IP-restricties.
  • Installeer network policies binnen elke namespace en ontzeg toegang tot externe services (inclusief de Kubernetes API-service). Wees expliciet in het toegang geven van specifieke pods tot de Kubernetes API-server.


Pod Security context

Bij het principe van least privilage hebben we het gehad over het niet draaien van containers/pods als root user. Dit beperkt al veel toegang tot de linux kernel. Aanvullend is het belangrijk om de Linux capabilities te beperken en een pod security context in te stellen. Hiermee zorg je ervoor dat de container met een specifieke Linux user ID draait.

Configureer de podSecurityContext:

   securityContext:
        runAsNonRoot: true
        runAsGroup: 65532
        runAsUser: 65532
        fsGroup: 65532

Configureer de container security context door alle Linux capabilities uit te zetten en een readOnly root filesystem aan te zetten:

   securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
            drop: [ 'ALL' ]

Gebruik seccomp

Hoewel de meeste Linux-functionaliteiten niet beschikbaar zijn wanneer de juiste pod- en container security context configureert zijn, zegt het "defense in depth"-principe om dit op meerdere lagen dicht te zetten. Met seccomp kunt je de Linux-functionaliteiten waartoe je container toegang heeft beperken. Het beperkt de beschikbare system calls vanuit de container naar de kernel.

Seccomp kan eenvoudig worden geconfigureerd voor bijna alle toepassingen. Dit kan op twee manieren. Voor de versies voorafgaand aan Kubernetes v1.19 kan je de volgende annotatie op een pod gebruiken:

 seccomp.security.alpha.kubernetes.io/pod: runtime/default

Sinds Kubernetes v1.19 kan je dit configureren via de pod Security context:

 securityContext:
    seccompProfile:
      type: RuntimeDefault

5. Fail securily

Webhooks (admission controllers)

Admission Controllers/Policy management engines zoals Kyverno gebruiken admission webhooks om resources te valideren tijdens admission tot de Kubernetes API-server. Zorg ervoor dat wanneer je een voor dit doel geïnstalleerde webhook gebruikt, de validatie-webhook zo geconfigureert is dat een admission wordt geweigerd als de service die het moet bereiken niet beschikbaar is. Dit geldt voor de standaardinstallatie van de webhook voor Kyverno of OPA Gatekeeper. Dit zorgt ervoor dat er geen resources worden geïnstalleerd die niet voldoen aan het beleid, mocht de admission controller niet beschikbaar zijn.

Het weigeren van admissions die niet voldoen kan gedaan worden door de failurePolicy voor een webhook te configureren:

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
...
webhooks:
- name: my-webhook.example.com
  failurePolicy: Fail
  ...

Let op: zorg ervoor dat de admission controller wordt uitgerold voor hoge beschikbaarheid (bijvoorbeeld: >2 replicas) om te voorkomen dat de API-server geen nieuwe resources kan verwerken als een node binnen het cluster uitvalt waarop de admission controller draait. De service voor de admission controller mag nooit onbeschikbaar zijn, anders is je cluster op dat moment niet bruikbaar. Zie ook: documentatie.

6. Don’t trust services

Gebruik mTLS voor communicatie

Zorg ervoor dat alle componenten die binnen Kubernetes worden uitgerold zijn geconfigureerd om mTLS te gebruiken voor communicatie. Door gebruik te maken van mTLS ontstaan je twee voordelen:

  1. Hiermee kunnen zowel de client als de server hun identiteit bewijzen.
  2. Het zorgt voor authenticatie voordat er enige communicatie plaatsvindt tussen systemen.

Het kan ook gewenst zijn om mTLS te gebruiken tussen de workloads die binnen het cluster zijn uitgerold. Dit kan handmatig worden ingeregeld met behulp van cert-manager en self-signed certificaten of door het gebruik van een service-mesh zoals linkerd.

Beide methoden zorgen voor een zero trust-security (nooit vertrouwen, altijd verifiëren) implementatie door de bewezen identiteit van een workload. Zorg ervoor dat je dit combineert met een sterke identiteits- en authenticatieoplossing op de applicatielaag (zoals OIDC).

Extern opslaan van cluster events log files

Een tactiek die wordt gebruikt bij het ontwijken van detectie is het verwijderen van Kubernetes events of het wissen van de container logs. Zorg ervoor dat de events en logging door wordt gestuurd naar een externe service, met extra toegangscontrole, los van Kubernetes.

Cluster Events

Kubernetes-cluster events moeten extern worden opgeslagen. Dit kan worden bereikt door de eventstream te volgen met een custom component binnen het cluster en deze in stdout te loggen, zodat een log collection agent deze naar een ander systeem kan transporteren of door iets als een event-router te gebruiken om de events rechtstreeks door te sturen. Enkele projecten hiervoor zijn:

Log Collectie

Hoewel kubectl logshet prima is om logging in realtime te bekijken, is het verstandig om alle log events van alle systemen die op het cluster worden uitgevoerd op te slaan in een extern systeem. Dit kan ELK, Loki of een andere logging systeem zijn.

  • De meeste Kubernetes-providers hebben een standaardoplossing voor logbeheer (in ieder geval de grote public cloud-providers). Dit is een makkelijk te starten optie.
  • Je kunt ook een eigen ELK-stack of Loki implementatie opstarten en een logging daemon binnen het cluster installeren om de log events door te sturen. Houd er rekening mee dat je deze componenten bij voorkeur niet binnen hetzelfde cluster installeert, omdat een aanvaller dan de optie heeft om deze data te verwijderen.
AME Kubernetes wordt standaard geleverd met een Loki-installatie. Alle loggegevens worden geëxporteerd naar een Loki-instantie buiten het cluster, die wordt beheerd en beveiligd door Avisi Cloud.


7. Separation of duties

Traditioneel wordt voor het principe seperation of duties vaak gesproken over het gebruik van afzonderlijke gebruikers voor verschillende domeinen. Binnen Kubernetes vertaalt dit zich naar het gebruik van externe gebruikers versus serviceaccounts, maar ook de rollen van nodes binnen een cluster.

Serviceaccounts en gebruikers

  • Gebruik geen serviceaccounts/tokens om menselijke gebruikers te verifiëren. Elke gebruiker dient een persoonlijk account te gebruiken.
  • Deel geen serviceaccounts tussen deployments/statefulsets. Elke resource dient zijn eigen serviceaccount te hebben.
  • Serviceaccounts mogen alleen worden gebruikt door systeemcomponenten, plug-ins die toegang vereisen tot de Kubernetes API-server (ingress controller en, operators) of externe diensten die integreren met Kubernetes (zorg ervoor dat je het principe van least privilage toepast).

Aparte node-pools gebruiken

Zorg ervoor dat er afzonderlijke node-pools worden gebruikt voor het uitvoeren of draaien van gevoelige systemen, zoals databases, of secret management software zoals Hashicorp Vault. Dit geldt ook voor het draaien van systeemcomponenten binnen het cluster, zoals een cloud controller manager (moet worden uitgevoerd op control plane-node).

Hoewel je veel toegang kunt beperken door network policies en pod-security contexts te gebruiken, als iemand erin slaagt uit een container te breken en toegang te krijgen tot een node, dan heeft deze toegang tot elk secret en/of proces dat op dat node wordt uitgevoerd.

8. Avoid security by obscurity

Het "Avoid security by obscurity"-principe vertelt ons dat we ervoor moeten zorgen dat er voldoende beveiligingscontroles zijn waarop kan worden vertrouwd. Vertaald naar Kubernetes betekent dit:

  • Vertrouw er niet op dat een service niet wordt ontdekt voor beveiliging (bijvoorbeeld een willekeurige naamruimte en poorten die in gebruik zijn). Het is namelijk mogelijk om alle endpoints via DNS op te vragen.
  • Zorg ervoor dat je niet afhankelijk bent van een willekeurige node-poort om inkomend verkeer naar een applicatie te beperken. Zorg er in plaats daarvan voor dat er een network policy en authenticatie/autorisatie ingeregeld is.


9. Keep security simple

Kubernetes en het cloud native-ecosysteem kunnen erg complex zijn. Wanneer je een cluster beheert, moet je de ingeregelde beveiligingsmaatregelen ervan begrijpen. Het principe van "Keep Security simple" vertelt ons dat we ervoor moeten zorgen dat er geen grote complexiteit voor mensen wordt toegevoegd wanneer er nieuwe security controls worden ingeregeld.

Zorg ervoor dat je de automatiseringsopties gebruikt die beschikbaar zijn binnen Kubernetes om aan de slag te gaan met beveiliging. Het gebruik van een admission controller (Kyverno) om deployments te valideren aan een standaard security policy of hulpmiddelen om ontwikkelaars te helpen met beveiliging, is een must om dingen simpel en werkbaar te houden. Hierdoor wordt voorkomen dat er nieuwe risico's door menselijke fouten ontstaan.

Zichtbaarheid

Je kan ervoor zorgen dat security simpel blijft door goed inzicht te hebben in alle aanwezige security controls en hoe deze in productie zijn toegepast. Sommige admission controllers komen met een gebruikersinterface die voor dit doel kan worden gebruikt.

Verder is het mogelijk om via Prometheus metrics over security controls op te halen - bijna elk project heeft wel een export mogelijkheid hiervoor. In combinatie met Grafana is hier veel zichtbaarheid in te creëren.

10. Fix security issues correctly

Kwetsbaarheid van applicatie

Het hebben van een kwetsbaarheid in je applicatie kan leiden tot toegang tot resources binnen een cluster. Voorbeelden hiervan zijn: een nieuwe shell kunnen starten en toegang krijgen tot gegevens van een ander intern eindpunt (SSRF).

De volgende tactieken verdedigen hiertegen:
  • Network Policies configureren. Dit beperkt de blootstelling als een aanvaller erin slaagt voet aan de grond te krijgen binnen een applicatie.
  • Gebruik minimale images, bij voorkeur zonder shell. Een goede suggestie hiervoor zijn distroless images.

Wanneer een kwetsbaarheid in een applicatie is geïdentificeerd, zorg er dan voor dat het risico wordt geminimaliseerd door middel van de bovenstaande items én zorg ervoor dat je het snel kunt patchen. Hiervoor hebt je een geautomatiseerde deployment pipeline nodig.

CVE's patchen

Gebruik een vulnerability scanner om CVE's in je container images te identificeren. Eenmaal geïdentificeerd, patch ze naar een nieuwe versie. Gebruik de vulnerability scanner om ervoor te zorgen dat de CVE's niet langer aanwezig zijn in je container image. Een goede scanner hiervoor is Trivy (https://github.com/aquasecurity/trivy).

Idealiter vindt dit proces plaats binnen de CI pipelines / builtstraat, met additionele scans binnen het cluster.

Tooling

Het beheren van Kubernetes kan een uitdaging zijn; ervoor zorgen dat je beveiligingsniveau voldoende is, dat je gebruikmaakt van best practices en meer. Gelukkig zijn er tal van tools en producten beschikbaar om je te helpen bij dit proces. Enkele van onze favoriete tools zijn:

  • Kube-jager - Kubernetes-beveiligingszwakte-jager
  • Kube bench - CIS Kubernetes Benchmark validatie
  • Polaris - Kubernetes Best practices-scanner
  • Clusterlint - Een best practices-checker voor Kubernetes-clusters


Conclusie

Wanneer je gebruikmaakt van Avisi Managed Environments, helpt Avisi Cloud je met het implementeren van best practices zodat je zekerheid hebt over hoe je beveiligingsniveau is. Avisi Cloud doet dit via de Customer onboarding. Met behulp van onze production hardening guide helpen onze engineers jou om het meeste uit een AME Kubernetes-cluster te halen.

Door de State-mindset van Cloud Provider Hosts kost het developers veel tijd en handwerk om softwarereleases te doen. Wij van Avisi Cloud vinden dat het uitrollen van software geautomatiseerd moet worden en dat vanuit de Change-mindset gehandeld moet worden. Daarom hebben wij Avisi Managed Environments gecreëerd, waarmee jij 20% extra ontwikkelcapaciteit kan behalen. Wil jij ook 20% extra ontwikkelcapaciteit? Neem dan contact met ons op.

 

Related blogs

Did you enjoy reading?

Share this blog with your audience!