Comment configurer des e-mails de notification personnalisés pour les résultats de Security Hub en utilisant EventBridge avec une rubrique Amazon SNS ?

Date de la dernière mise à jour : 11/01/2022

Je veux configurer une notification par e-mail personnalisée pour les résultats du Security Hub en utilisant Amazon EventBridge et une rubrique Amazon Simple Notification Service (Amazon SNS).

Brève description

La solution suivante vous montre comment configurer EventBridge avec SNS pour recevoir des notifications Security Hub. Selon la règle EventBridge, Amazon SNS envoie une notification à l'adresse ou aux adresses e-mail abonnées à la rubrique lorsque votre évènement se produit. Le message généré peut être difficile à lire en raison de sa mise en forme. Toutefois, l'inclusion d'une fonction AWS Lambda permet de créer un message d'alerte personnalisé avec une mise en forme améliorée avant de l'envoyer aux abonnés SNS.

Pour créer une notification par e-mail personnalisée, procédez comme suit :

1.    Créez les cibles de règles EventBridge suivantes :
Une rubrique SNS et des abonnements par e-mail.
Une fonction Lambda.

2.    Créez une règle EventBridge.

3.    Recevez une notification personnalisée.

Important : la solution suivante utilise les évènements AWS Security Hub et une fonction Lambda pour la personnalisation. Pour plus d'informations sur les coûts associés, consultez Tarification AWS Security Hub et Tarification AWS Lambda.

Solution

Créer une rubrique SNS et un abonnement

1.    Ouvrez la console Amazon SNS.

2.    Sur le volet de navigation, choisissez Rubriques.

3.    Choisissez Create topic (Créer une rubrique).

4.    Dans la section Détails, sélectionnez Standard pour Type.

5.    Pour Nom, saisissez le nom de votre rubrique.

6.    Choisissez Create topic (Créer une rubrique).

7.    Dans la rubrique créée, choisissez Create subscription (Créer un abonnement).

8.    Pour Topic ARN (ARN de rubrique), sélectionnez l'Amazon Resource Name (ARN) de la rubrique que vous avez créée s'il n'est pas automatiquement renseigné.

9.    Pour Protocol (Protocole), saisissez Email (E-mail).

10.    Pour Endpoint (Point de terminaison), saisissez l'adresse e-mail à laquelle vous souhaitez recevoir les notifications SNS.

11.    Choisissez Create subscription(Créer un abonnement).

Important : vous devez confirmer l'abonnement dans l'e-mail de confirmation envoyé à l'abonné pour que l'abonnement passe du statut PendingConfirmation à Confirmed.

Remarque : (Facultatif) vous pouvez également créer un abonnement authentifié qui empêche l'action de désabonnement sur votre rubrique.

Créer une fonction Lambda

Créez une fonction Lambda qui extrait les informations souhaitées du contenu JSON et publie un message personnalisé sur Amazon SNS.

1.    Ouvrez la console Lambda.

2.    Dans le panneau de navigation, sélectionnez Fonctions.

3.    Choisissez Create function (Créer une fonction).

4.    Choisissez Créer à partir de zéro.

5.    Pour Nom de la fonction, saisissez un nom pour votre fonction.

6.    Choisissez Runtime (Environnement d'exécution), puis Python 3.9.

7.    Pour Architecture, sélectionnez x86_64.

8.    Développez Change default execution role (Modifier le rôle d'exécution par défaut).

9.    Pour Execution role (Rôle d'exécution), sélectionnez Create a new role from AWS policy templates (Créer un nouveau rôle à partir de modèles de politique AWS).

10.    Dans Role name (Nom du rôle), entrez un nom pour le rôle.

11.    Pour Policy template (Modèle de politique), choisissez Amazon SNS publish policy (Politique de publication Amazon SNS).

12.    Choisissez Create function (Créer une fonction).

13.    Une fois la fonction créée, collez le code suivant dans la section Code source (Source du code). 

import json
import boto3

sns = boto3.client('sns')

def lambda_handler(event, context):
    
    #Extract details from JSON event
    detailType= event["detail-type"]
    region = event["region"]
    accountId = event["account"] 
    
    #Security Hub Insight Results
    if (detailType == "Security Hub Insight Results"):
        
        action = event["detail"]["actionDescription"]
        
        message = "Alert: %s in %s for account: %s\n Action description: %s" % (detailType, region,accountId,action)
    
    elif  ("Security Hub Findings" in detailType):
        
        finding = event["detail"]["findings"][0] 
        findingTime = finding["FirstObservedAt"]
        findingType = finding["Types"][0]
        findingDescription = finding["Description"]
        remediation = finding["Remediation"]["Recommendation"]["Text"]
        
        #Security Hub Findings - Custom finding
        if(detailType == "Security Hub Findings - Custom"):
            complianceStatus = finding["Compliance"]["Status"]
            severity = finding["Severity"]["Label"]
            remediationUrl = finding["Remediation"]["Recommendation"]["Url"]
            
            message = "Alert: %s in %s for account: %s\n\nFinding regarding: [%s] %s\n Severity: %s\nDescription: %s\nFirst observed at: %s\n%s: %s" % (detailType, region, accountId, complianceStatus, findingType, 
            severity, findingDescription, findingTime, remediation, remediationUrl)
        
        #Security Hub Findings - Imported finding
        else:
            message = "Alert: %s in %s for account: %s\n\nFinding regarding: %s\nFirst observed at: %s\nRemediation recommendation: %s" % (detailType, region, accountId, findingDescription,findingTime, remediation)
    
    #AWS API Call via CloudTrail finding
    elif (detailType == "AWS API Call via CloudTrail"):
        
        time = event["detail"]["eventTime"]
        eventName = event["detail"]["eventName"]
        requestParameters = event["detail"]["requestParameters"]
        
        message = "Alert: %s in %s for account: %s at time: %s\n\n Event: %s \n Request parameters: %s" % (detailType, region, accountId, time, eventName, requestParameters)
        
        
    #If the event doesn't match any of the above, return the event    
    else:
        message = str(event)
    
    response = sns.publish(
            TopicArn = "arn:aws:sns:eu-west-x:xxxxxxxxxxxx:test",
            Message = message
            )
    
    return {
      'statusCode': 200,
      'body': json.dumps('Success!')
}

Remarque : le code précédent personnalise et reformate tous les messages d'alerte Security Hub. Remplacez TopicArn("arn:aws:sns:REGION:ACCOUNT_ID:SecurityHubFindings") par l'ARN de votre rubrique. Remplacez eu-west-x:xxxxxxxxxxxx par votre identifiant de compte. 

14.    Pour enregistrer le code de fonction, choisissez Deploy (Déployer).

Cette fonction prend les événements Security Hub par défaut et les reformate dans un format plus lisible. Voici des exemples de messages :

Exemple 1 : Résultat du Security Hub Insight

Par défaut :

{"version": "0", "id": "ac844908-d14e-05b1-4b7b-836d85110e26", "detail-type": "Security Hub Insight Results", "source": "aws.securityhub", "account": "123456789012", "time": "2019-04-11T21:31:57Z", "region": "us-east-1", "resources": ["arn:aws:securityhub:us-east-1:123456789012:action/custom/slackMessaging"], "detail": {"actionName": "SendToSlack", "actionDescription": "Send Findings to Slack", "insightName": "5. AWS users with the most suspicious activity", "insightArn": "arn:aws:securityhub:::insight/securityhub/default/9", "resultType": "ResourceAwsIamAccessKeyUserName", "insightResults": [{"Admin": 7}, {"DenySlr_UI_User": 1}]}}

Personnalisé :

Alert: Security Hub Insight Results in us-east-1 for account: 123456789012
Action description: Send Findings to Slack

Exemple 2 : Découvertes du Security Hub – Action personnalisée

Par défaut :

{ "version": "0", "id": "e215f5c7-a866-e0cd-6d11-fc7ecf97e381", "detail-type": "Security Hub Findings - Custom Action", "source": "aws.securityhub", "account": "123456789012", "time": "2019-04-11T22:06:13Z", "region": "us-east-1", "resources": ["arn:aws:securityhub:us-east-1:123456789012:action/custom/slackMessaging"], "detail": { "actionName": "SendToSlack", "actionDescription": "Send Findings to Slack", "findings": [{ "SchemaVersion": "2018-10-08", "Id": "arn:aws:securityhub:us-east-1:123456789012:subscription/cis-aws-foundations-benchmark/v/1.2.0/1.12/finding/17932c44-6d58-4b3c", "ProductArn": "arn:aws:securityhub:us-east-1::product/aws/securityhub", "GeneratorId": "arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.2.0/rule/1.12", "AwsAccountId": "123456789012", "Types": ["Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"], "FirstObservedAt": "2018-12-02T05:06:34.874Z", "LastObservedAt": "2019-04-11T18:07:10.995Z", "CreatedAt": "2018-12-02T05:06:34.874Z", "UpdatedAt": "2019-04-11T18:26:20.631Z", "Severity": { "Product": 0, "Normalized": 0 }, "Title": "1.12 Ensure no root account access key exists", "Description": "The root account is the most privileged user in an AWS account...", "Remediation": { "Recommendation": { "Text": "For directions on how to fix this issue, please consult the AWS Security Hub CIS documentation.", "Url": "https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-standards.html#securityhub-standards-checks-1.12" } }, "ProductFields": { "StandardsGuideArn": "arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.2.0", "StandardsGuideSubscriptionArn": "arn:aws:securityhub:us-east-1:123456789012:subscription/cis-aws-foundations-benchmark/v/1.2.0", "RuleId": "1.12", "RecommendationUrl": "https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-standards.html#securityhub-standards-checks-1.12", "RecordState": "ACTIVE", "aws/securityhub/FindingId": "arn:aws:securityhub:us-east-1::product/aws/securityhub/arn:aws:securityhub:us-east-1:123456789012:subscription/cis-aws-foundations-benchmark/v/1.2.0/1.12/finding/17932c44-6d58-4b3c", "aws/securityhub/SeverityLabel": "INFORMATIONAL", "aws/securityhub/ProductName": "Security Hub", "aws/securityhub/CompanyName": "AWS" }, "Resources": [{ "Type": "AwsAccount", "Id": "AWS::::Account:123456789012", "Partition": "aws", "Region": "us-east-1" }], "Compliance": { "Status": "PASSED" }, "RecordState": "ACTIVE", "WorkflowState": "NEW" }, { "SchemaVersion": "2018-10-08", "Id": "arn:aws:securityhub:us-east-1:123456789012:subscription/cis-aws-foundations-benchmark/v/1.2.0/2.8/finding/5d6b42d8-122b-4cdf-8498-e045752e170c", "ProductArn": "arn:aws:securityhub:us-east-1::product/aws/securityhub", "GeneratorId": "arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.2.0/rule/2.8", "AwsAccountId": "123456789012", "Types": ["Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark"], "FirstObservedAt": "2019-01-05T05:21:44.990Z", "LastObservedAt": "2019-04-11T18:26:12.510Z", "CreatedAt": "2019-01-05T05:21:44.990Z", "UpdatedAt": "2019-04-11T18:26:12.510Z", "Severity": { "Product": 0, "Normalized": 0 }, "Title": "2.8 Ensure rotation for customer created CMKs is enabled", "Description": "AWS Key Management Service (KMS) allows customers to rotate the backing key...", "Remediation": { "Recommendation": { "Text": "For directions on how to fix this issue, please consult the AWS Security Hub CIS documentation.", "Url": "https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-standards.html#securityhub-standards-checks-2.8" } }, "ProductFields": { "StandardsGuideArn": "arn:aws:securityhub:::ruleset/cis-aws-foundations-benchmark/v/1.2.0", "StandardsGuideSubscriptionArn": "arn:aws:securityhub:us-east-1:123456789012:subscription/cis-aws-foundations-benchmark/v/1.2.0", "RuleId": "2.8", "RecommendationUrl": "https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-standards.html#securityhub-standards-checks-2.8", "RecordState": "ACTIVE", "aws/securityhub/FindingId": "arn:aws:securityhub:us-east-1::product/aws/securityhub/arn:aws:securityhub:us-east-1:123456789012:subscription/cis-aws-foundations-benchmark/v/1.2.0/2.8/finding/5d6b42d8-122b-4cdf-8498-e045752e170c", "aws/securityhub/SeverityLabel": "INFORMATIONAL", "aws/securityhub/ProductName": "Security Hub", "aws/securityhub/CompanyName": "AWS" }, "Resources": [{ "Type": "AwsAccount", "Id": "AWS::::Account:123456789012", "Partition": "aws", "Region": "us-east-1" }], "Compliance": { "Status": "PASSED" }, "RecordState": "ACTIVE", "WorkflowState": "NEW" }] } }

Personnalisé :

Alert: Security Hub Findings - Custom Action in us-east-1 for account: 123456789012

Finding regarding: The root account is the most privileged user in an AWS account...
First observed at: 2018-12-02T05:06:34.874Z
Remediation recommendation: For directions on how to fix this issue, please consult the AWS Security Hub CIS documentation.

Exemple 3 : Découvertes du Security Hub – importées

Par défaut :

{ "version": "0", "id": "8e5622f9-d81c-4d81-612a-9319e7ee2506", "detail-type": "Security Hub Findings - Imported", "source": "aws.securityhub", "account": "123456789012", "time": "2019-04-11T21:52:17Z", "region": "us-west-2", "resources": ["arn:aws:securityhub:us-west-2::product/aws/macie/arn:aws:macie:us-west-2:123456789012:integtest/trigger/6294d71b927c41cbab915159a8f326a3/alert/f2893b211841"], "detail": { "findings": [{ "SchemaVersion": "2018-10-08", "Id": "arn:aws:macie:us-west-2:123456789012:integtest/trigger/6214d71b927c41cbab015159a8f316a3/alert/f2893b211841467198cc1201e9031ee4", "ProductArn": "arn:aws:securityhub:us-west-2::product/aws/macie", "GeneratorId": "arn:aws:macie:us-west-2:123456789012:integtest/trigger/6214d71b927c41cbab015159a8f316a3", "AwsAccountId": "123456789012", "Types": ["Sensitive Data Identifications/Passwords/Google Suite Two-factor backup codes in S3"], "FirstObservedAt": "2019-04-11T21:52:15.900Z", "LastObservedAt": "2019-04-11T21:52:15.900Z", "CreatedAt": "2019-04-11T21:52:15.900Z", "UpdatedAt": "2019-04-11T21:52:15.900Z", "Severity": { "Product": 6, "Normalized": 15 }, "Confidence": 5, "Title": "Google Suite Two-Factor Backup Codes uploaded to S3", "Description": "Google Suite two-factor backup codes uploaded to S3....", "Remediation": { "Recommendation": { "Text": "v2 Release" } }, "ProductFields": { "rule-arn": "arn:aws:macie:us-west-2:123456789012:trigger/6214d71b927c41cbab015159a8f316a3", "tags:0": "DATA_COMPLIANCE", "tags:1": "BASIC_ALERT", "themes:0/theme": "google_two_factor_backup", "themes:0/count": "1", "dlpRisk:0/risk": "8", "dlpRisk:0/count": "1", "owner:0/name": "vchin", "owner:0/count": "1", "aws/securityhub/FindingId": "arn:aws:securityhub:us-west-2::product/aws/macie/arn:aws:macie:us-west-2:123456789012:integtest/trigger/6214d71b927c41cbab015159a8f316a3/alert/f2893b211841467198cc1201e9031ee4", "aws/securityhub/SeverityLabel": "LOW", "aws/securityhub/ProductName": "Macie", "aws/securityhub/CompanyName": "Amazon" }, "Resources": [{ "Type": "AwsS3Bucket", "Id": "arn:aws:s3:::test-bucket-12", "Partition": "aws", "Region": "us-west-2" }], "RecordState": "ACTIVE", "WorkflowState": "NEW" }] } }

Personnalisé :

Alert: Security Hub Findings - Imported in us-west-2 for account: 123456789012

Finding regarding: Google Suite two-factor backup codes uploaded to S3....
First observed at: 2019-04-11T21:52:15.900Z
Remediation recommendation: v2 Release

Exemple 4 : Appel d'API AWS via CloudTrail

Par défaut :

{"version": "0", "id": "b34c4525-95f0-8dd1-cd9e-9fc5be10039e", "detail-type": "AWS API Call via CloudTrail", "source": "aws.securityhub", "account": "123456789012", "time": "2021-12-10T10:47:54Z", "region": "eu-west-1", "resources": [], "detail": {"eventVersion": "1.08", "userIdentity": {"type": "AssumedRole", "principalId": "AROATGMYP4FKHTE5RKJC3", "arn": "arn:aws:sts::123456789012", "accountId": "123456789012", "accessKeyId": "ASIATGMYXXFKNHWOYQF7", "sessionContext": {"sessionIssuer": {"type": "Role", "principalId": "AROATGMYP4FKHX5RKJC3", "arn": "arn:aws:iam::123456789012:role/Admin", "accountId": "123456789012", "userName": "Admin"}, "webIdFederationData": {}, "attributes": {"creationDate": "2021-12-10T10:08:16Z", "mfaAuthenticated": "false"}}}, "eventTime": "2021-12-10T10:47:54Z", "eventSource": "securityhub.amazonaws.com", "eventName": "BatchUpdateFindings", "awsRegion": "eu-west-1", "sourceIPAddress": "54.240.197.20", "userAgent": "aws-internal/3 aws-sdk-java/1.12.112 Linux/5.4.156-94.273.amzn2int.x86_64 OpenJDK_64-Bit_Server_VM/25.312-b07 java/1.8.0_312 vendor/Oracle_Corporation cfg/retry-mode/standard", "requestParameters": {"Workflow": {"Status": "NEW"}, "FindingIdentifiers": [{"Id": "arn:aws:securityhub:eu-west-1:123456789012:subscription/cis-aws-foundations-benchmark/v/1.2.0/2.5/finding/2fd7f0dd-1088-44c5-bbe1-9c8a0ddce035", "ProductArn": "arn:aws:securityhub:eu-west-1::product/aws/securityhub"}]}, "responseElements": {"UnprocessedFindings": [], "ProcessedFindings": [{"Id": "arn:aws:securityhub:eu-west-1:123456789012:subscription/cis-aws-foundations-benchmark/v/1.2.0/2.5/finding/2fd7f0dd-1088-44c5-bbe1-9c8a0ddce035", "ProductArn": "arn:aws:securityhub:eu-west-1::product/aws/securityhub"}]}, "requestID": "fd52e76e-282f-47c7-a7bc-b9a1e1ca2cdd", "eventID": "433b8e9c-cf08-4909-adf7-ea0c548459ad", "readOnly": "False", "eventType": "AwsApiCall", "managementEvent": "True", "recipientAccountId": "123456789012", "eventCategory": "Management"}}

Personnalisé :

Alert: AWS API Call via CloudTrail in eu-west-1 for account: 123456789012 at time: 2021-12-10T10:47:32Z

Event: BatchUpdateFindings
Request parameters: {'Workflow': {'Status': 'NOTIFIED'}, 'FindingIdentifiers': [{'Id': 'arn:aws:securityhub:eu-west-x:xxxxxxxxxxxx:subscription/cis-aws-foundations-benchmark/v/1.2.0/2.5/finding/2fd7f0dd-1088-44c5-bbe1-9c8a0ddce035', 'ProductArn': 'arn:aws:securityhub:eu-west-1::product/aws/securityhub'}]}

Remarque : vous pouvez modifier le message pour chaque type de découverte du Security afin de le rendre plus adapté à votre cas d'utilisation.

Créer et configurer la règle EventBridge

1.    Ouvrez la console EventBridge.

2.    Sélectionnez Create rule (Créer une règle).

3.    Saisissez un nom pour votre règle. Vous pouvez éventuellement saisir une description.

4.    Dans Define pattern (Définir le modèle), sélectionnez Event pattern (Modèle d'événement).

5.    Pour Event matching pattern (Modèle de correspondance d'événement), sélectionnez Pre-defined pattern by service (Modèle prédéfini par service).

6.    Pour Service provider (Fournisseur de services), sélectionnez AWS.

7.    Pour Service name (Nom du service), sélectionnez Security hub.

8.    Pour Event type (Type d'événement), sélectionnez All Events (Tous les événements).

Remarque : vous pouvez également configurer des alertes pour des événements spécifiques plutôt que pour tous les événements. La fonction Lambda est configurée pour reformater tous les événements dans un format plus lisible.

9.    Dans la section Select event bus (Sélectionner un bus d'événements), choisissez AWS default event bus (Bus d'événements AWS par défaut).

10.    Dans Select targets (Sélectionner des cibles), choisissez Lambda target (Cible Lambda) dans le menu Target (Cible).

11.    Sélectionnez la fonction Lambda créée précédemment.

Recevoir une notification personnalisée

Lorsque l'un des événements configurés se produit, vous recevez une notification personnalisée par e-mail de la part de no-reply@sns.amazonaws.com.