Comprendete il rischio delle policy. Ponete domande sulle policy in linguaggio naturale. Richiedi una demo →

Published:

Il modo eccessivamente complesso in cui CloudTrail e CloudWatch Events lavorano insieme

by FireMon

Uno dei problemi più fastidiosi del mio percorso nel cloud è stato capire come CloudTrail e CloudWatch Events lavorino insieme. Per qualche motivo mi ci sono voluti anni (e moltissimi test) per comprendere davvero come funziona questa connessione; e soprattutto come funziona con il concetto di trail multi-region e di AWS Organization. Poi, una volta capito tutto, ho dato per scontato che lo sapessero già tutti, ma conversazioni recenti hanno reso evidente che questa confusione è piuttosto diffusa. Ecco quindi il mio miglior tentativo di semplificare le cose.

Innanzitutto, il problema che vogliamo risolvere: creare CloudWatch Rules basate su CloudTrail Events e utilizzarle per inviare notifiche o attivare funzioni Lambda.

Tutto qui: voglio inviare una notifica per qualcosa di semplice come la chiamata API che apre una nuova regola di security group (AuthorizeSecurityGroupIngress, nel caso ve lo steste chiedendo).

Perché funzioni occorrono i seguenti elementi:

  • CloudTrail abilitato nella region in cui viene effettuata la chiamata API.
  • CloudTrail che invia i dati in streaming a CloudWatch.
  • Una CloudWatch Rule nella region della chiamata API che cerchi quella specifica chiamata API, o tutte le chiamate API di CloudTrail.

E ora la confusione:

  • Quando si crea un CloudTrail multi-region o un trail di Organization, dietro le quinte AWS sta in realtà configurando trail in ogni singola region (e in ogni account, nel caso di un trail di Organization). Sono tutti trail separati, ma ciascuno è configurato per inviare i propri risultati a un bucket S3 condiviso, ed è possibile gestirli solo nell'account e nella region di origine.
  • Tuttavia gli eventi CloudWatch relativi alle chiamate API vengono creati solo nella region della chiamata API.
  • Quindi, se si crea un trail multi-region, i dati vengono raccolti centralmente, ma gli eventi compaiono solo a livello locale. Una CloudWatch Rule nella region del trail principale si attiverà solo per le chiamate API effettuate in quella region (principale). Perciò, se si crea un allarme per le modifiche ai security group, questo funzionerà solo nella region principale, non nelle altre region, anche se CloudTrail è attivo.
  • Il CloudWatch Log Group/Stream comparirà nella region primaria, non nelle altre region, ma ogni Event viene creato nella region che lo ha generato.
  • Se si vogliono raccogliere tutti gli eventi relativi alle chiamate API occorre utilizzare una definizione di evento non documentata (che ho riportato di seguito).
  • Se si legge la documentazione di Amazon… nulla di tutto ciò viene spiegato chiaramente. Almeno non sono riuscito a trovarlo. Anzi, una volta ero in una chiamata di supporto in cui avevo capito come fare, e il rappresentante AWS continuava a mormorare: "Non credo che funzioni così" mentre i miei eventi iniziavano ad arrivare. Stava passando una serataccia.

Per qualche motivo questo per me era davvero poco intuitivo. Avevo dato per scontato che, centralizzando il trail, si potesse centralizzare anche la CloudWatch Rule per attivarsi in base agli eventi delle chiamate API. Purtroppo era del tutto errato: anche centralizzando il trail, occorre comunque creare la Rule in ogni region di interesse. Anche utilizzando Event Bus per raccogliere eventi da più account, occorre comunque creare una CloudWatch Rule in ogni region di ogni account per inviare l'evento al Bus, e poi occorre creare Rules in ogni region dell'Event Bus per attivare la notifica/azione desiderata.

Ecco come consiglio di affrontare la questione se si desiderano funzionalità di alerting quasi in tempo reale o di auto-remediation/azioni supportate dalle CloudWatch Rules:

  • Attivare un trail multi-region. È sufficiente farlo una sola volta, e un trail di Organization è sufficiente.
  • In questo modo vengono creati tutti i trail regionali necessari. Sembra un unico trail centrale, ma in realtà è un insieme di trail regionali che inviano i propri dati a un ricevitore centrale.
  • Opzione 1: creare una CloudWatch Rule in ogni region per cui si desidera l'alerting quasi in tempo reale. CloudFormation e Terraform sono validi alleati in questo caso.
  • Opzione 2: centralizzare tutti gli eventi. In ciascuna region creare una Rule che invii tutti gli eventi CloudTrail a una funzione Lambda o a un topic SNS, che poi li inoltra alla destinazione desiderata. Noi stessi utilizziamo questa tecnica; l'invio avviene tramite un endpoint API personalizzato, ma è possibile inviare i dati in streaming a Kinesis o a quasi qualsiasi altro servizio.

Per iniziare, ecco due esempi di codice.

Il filter pattern segreto per la CloudWatch Rule che raccoglie tutti gli eventi da CloudTrail:

{

"detail-type": [

"AWS API Call via CloudTrail"

] }

Ed ecco un esempio di codice Lambda per inoltrare gli eventi, in questo caso a Kinesis:

import json

import boto3

def lambda_handler(event, context):

kinesis = boto3.client('kinesis', region_name='us-west-2')

data = json.dumps(event)

print(data)

response = kinesis.put_record(

StreamName='cloudsec_prod_stream_alert_kinesis',

Data=data,

PartitionKey='test-client-id'

)

print(response)

return {

'statusCode': 200,

'body': json.dumps('Record added')

}

Come CloudTrail e CloudWatch lavorano insieme | FireMon