Menanggapi acara dengan fungsi Lambda - AWS Certificate Manager

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Menanggapi acara dengan fungsi Lambda

Prosedur ini menunjukkan cara menggunakan AWS Lambda untuk mendengarkan di Amazon EventBridge, membuat notifikasi dengan Amazon Simple Notification Service (SNS), dan mempublikasikan temuan ke AWS Security Hub, memberikan visibilitas kepada administrator dan tim keamanan.

Untuk mengatur fungsi Lambda dan peran IAM
  1. Pertama konfigurasikan peran AWS Identity and Access Management (IAM) dan tentukan izin yang diperlukan oleh fungsi Lambda. Praktik terbaik keamanan ini memberi Anda fleksibilitas dalam menentukan siapa yang memiliki otorisasi untuk memanggil fungsi, dan dalam membatasi izin yang diberikan kepada orang tersebut. Tidak disarankan untuk menjalankan sebagian besar AWS operasi langsung di bawah akun pengguna dan terutama tidak di bawah akun administrator.

    Buka konsol IAM di https://console.aws.amazon.com/iam/.

  2. Gunakan editor kebijakan JSON untuk membuat kebijakan yang ditentukan dalam templat di bawah ini. Berikan Wilayah dan detail AWS akun Anda sendiri. Untuk informasi selengkapnya, lihat Membuat kebijakan di tab JSON.

    { "Version":"2012-10-17", "Statement":[ { "Sid":"LambdaCertificateExpiryPolicy1", "Effect":"Allow", "Action":"logs:CreateLogGroup", "Resource":"arn:aws:logs:<region>:<AWS-ACCT-NUMBER>:*" }, { "Sid":"LambdaCertificateExpiryPolicy2", "Effect":"Allow", "Action":[ "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource":[ "arn:aws:logs:<region>:<AWS-ACCT-NUMBER>:log-group:/aws/lambda/handle-expiring-certificates:*" ] }, { "Sid":"LambdaCertificateExpiryPolicy3", "Effect":"Allow", "Action":[ "acm:DescribeCertificate", "acm:GetCertificate", "acm:ListCertificates", "acm:ListTagsForCertificate" ], "Resource":"*" }, { "Sid":"LambdaCertificateExpiryPolicy4", "Effect":"Allow", "Action":"SNS:Publish", "Resource":"*" }, { "Sid":"LambdaCertificateExpiryPolicy5", "Effect":"Allow", "Action":[ "SecurityHub:BatchImportFindings", "SecurityHub:BatchUpdateFindings", "SecurityHub:DescribeHub" ], "Resource":"*" }, { "Sid":"LambdaCertificateExpiryPolicy6", "Effect":"Allow", "Action":"cloudwatch:ListMetrics", "Resource":"*" } ] }
  3. Buat peran IAM dan lampirkan kebijakan baru padanya. Untuk informasi tentang membuat peran IAM dan melampirkan kebijakan, lihat Membuat peran untuk AWS layanan (konsol).

  4. Buka AWS Lambda konsol di https://console.aws.amazon.com/lambda/.

  5. Buat fungsi Lambda. Untuk informasi selengkapnya, lihat Membuat fungsi Lambda dengan konsol. Selesaikan langkah-langkah berikut:

    1. Pada halaman Create function, pilih opsi Author from scratch untuk membuat fungsi.

    2. Tentukan nama seperti "handle-expiring-certificates" di bidang Nama fungsi.

    3. Pilih Python 3.8 dari daftar Runtime.

    4. Perluas Ubah peran eksekusi default dan pilih Gunakan peran yang ada.

    5. Pilih peran yang sebelumnya Anda buat dari daftar peran yang ada.

    6. Pilih Buat fungsi.

    7. Di bawah kode Fungsi, masukkan kode berikut:

      # Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: MIT-0 # # Permission is hereby granted, free of charge, to any person obtaining a copy of this # software and associated documentation files (the "Software"), to deal in the Software # without restriction, including without limitation the rights to use, copy, modify, # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import json import boto3 import os from datetime import datetime, timedelta, timezone # ------------------------------------------- # setup global data # ------------------------------------------- utc = timezone.utc # make today timezone aware today = datetime.now().replace(tzinfo=utc) # set up time window for alert - default to 45 if its missing if os.environ.get('EXPIRY_DAYS') is None: expiry_days = 45 else: expiry_days = int(os.environ['EXPIRY_DAYS']) expiry_window = today + timedelta(days = expiry_days) def lambda_handler(event, context): # if this is coming from the ACM event, its for a single certificate if (event['detail-type'] == "ACM Certificate Approaching Expiration"): response = handle_single_cert(event, context.invoked_function_arn) return { 'statusCode': 200, 'body': response } def handle_single_cert(event, context_arn): cert_client = boto3.client('acm') cert_details = cert_client.describe_certificate(CertificateArn=event['resources'][0]) result = 'The following certificate is expiring within ' + str(expiry_days) + ' days: ' + cert_details['Certificate']['DomainName'] # check the expiry window before logging to Security Hub and sending an SNS if cert_details['Certificate']['NotAfter'] < expiry_window: # This call is the text going into the SNS notification result = result + ' (' + cert_details['Certificate']['CertificateArn'] + ') ' # this call is publishing to SH result = result + ' - ' + log_finding_to_sh(event, cert_details, context_arn) # if there's an SNS topic, publish a notification to it if os.environ.get('SNS_TOPIC_ARN') is None: response = result else: sns_client = boto3.client('sns') response = sns_client.publish(TopicArn=os.environ['SNS_TOPIC_ARN'], Message=result, Subject='Certificate Expiration Notification') return result def log_finding_to_sh(event, cert_details, context_arn): # setup for security hub sh_region = get_sh_region(event['region']) sh_hub_arn = "arn:aws:securityhub:{0}:{1}:hub/default".format(sh_region, event['account']) sh_product_arn = "arn:aws:securityhub:{0}:{1}:product/{1}/default".format(sh_region, event['account']) # check if security hub is enabled, and if the hub arn exists sh_client = boto3.client('securityhub', region_name = sh_region) try: sh_enabled = sh_client.describe_hub(HubArn = sh_hub_arn) # the previous command throws an error indicating the hub doesn't exist or lambda doesn't have rights to it so we'll stop attempting to use it except Exception as error: sh_enabled = None print ('Default Security Hub product doesn\'t exist') response = 'Security Hub disabled' # This is used to generate the URL to the cert in the Security Hub Findings to link directly to it cert_id = right(cert_details['Certificate']['CertificateArn'], 36) if sh_enabled: # set up a new findings list new_findings = [] # add expiring certificate to the new findings list new_findings.append({ "SchemaVersion": "2018-10-08", "Id": cert_id, "ProductArn": sh_product_arn, "GeneratorId": context_arn, "AwsAccountId": event['account'], "Types": [ "Software and Configuration Checks/AWS Config Analysis" ], "CreatedAt": event['time'], "UpdatedAt": event['time'], "Severity": { "Original": '89.0', "Label": 'HIGH' }, "Title": 'Certificate expiration', "Description": 'cert expiry', 'Remediation': { 'Recommendation': { 'Text': 'A new certificate for ' + cert_details['Certificate']['DomainName'] + ' should be imported to replace the existing imported certificate before expiration', 'Url': "https://console.aws.amazon.com/acm/home?region=" + event['region'] + "#/?id=" + cert_id } }, 'Resources': [ { 'Id': event['id'], 'Type': 'ACM Certificate', 'Partition': 'aws', 'Region': event['region'] } ], 'Compliance': {'Status': 'WARNING'} }) # push any new findings to security hub if new_findings: try: response = sh_client.batch_import_findings(Findings=new_findings) if response['FailedCount'] > 0: print("Failed to import {} findings".format(response['FailedCount'])) except Exception as error: print("Error: ", error) raise return json.dumps(response) # function to setup the sh region def get_sh_region(event_region): # security hub findings may need to go to a different region so set that here if os.environ.get('SECURITY_HUB_REGION') is None: sh_region_local = event_region else: sh_region_local = os.environ['SECURITY_HUB_REGION'] return sh_region_local # quick function to trim off right side of a string def right(value, count): # To get right part of string, use negative first index in slice. return value[-count:]
    8. Di bawah variabel Lingkungan, pilih Edit dan opsional tambahkan variabel berikut.

      • (Opsional) EXPIRY_DAYS

        Menentukan berapa banyak lead time, dalam beberapa hari, sebelum pemberitahuan kedaluwarsa sertifikat dikirim. Fungsi default ke 45 hari, tetapi Anda dapat menentukan nilai kustom.

      • (Opsional) SNS_TOPIC_ARN

        Menentukan ARN untuk Amazon SNS. <region><account-number><topic-name>Berikan ARN lengkap dalam format arn:aws:sns:::.

      • (Opsional) SECURITY_HUB_REGION

        Menentukan AWS Security Hub di Wilayah yang berbeda. Jika ini tidak ditentukan, Wilayah fungsi Lambda yang sedang berjalan digunakan. Jika fungsi dijalankan di beberapa Wilayah, mungkin diinginkan agar semua pesan sertifikat masuk ke Security Hub di satu Wilayah.

    9. Di bawah Pengaturan dasar, atur Timeout menjadi 30 detik.

    10. Di bagian atas halaman, pilih Deploy.

Selesaikan tugas dalam prosedur berikut untuk mulai menggunakan solusi ini.

Untuk mengotomatiskan pemberitahuan kedaluwarsa email

Dalam contoh ini, kami memberikan satu email untuk setiap sertifikat yang kedaluwarsa pada saat acara dimunculkan melalui Amazon EventBridge. Secara default, ACM memunculkan acara setiap hari untuk sertifikat yang 45 hari atau kurang dari kedaluwarsa. (Periode ini dapat disesuaikan menggunakan PutAccountConfigurationpengoperasian API ACM.) Masing-masing peristiwa ini memicu kaskade tindakan otomatis berikut:

ACM raises Amazon EventBridge event → >>>>>>> events Event matches Amazon EventBridge rule → Rule calls Lambda function → Function sends SNS email and logs a Finding in Security Hub
  1. Buat fungsi Lambda dan konfigurasikan izin. (Sudah selesai — lihatUntuk mengatur fungsi Lambda dan peran IAM).

  2. Buat topik SNS standar untuk fungsi Lambda yang akan digunakan untuk mengirim notifikasi. Untuk informasi selengkapnya, lihat Membuat topik Amazon SNS.

  3. Berlangganan pihak yang berkepentingan ke topik SNS baru. Untuk informasi selengkapnya, lihat Berlangganan topik Amazon SNS.

  4. Buat EventBridge aturan Amazon untuk memicu fungsi Lambda. Untuk informasi selengkapnya, lihat Membuat EventBridge aturan Amazon yang bereaksi terhadap peristiwa.

    Di EventBridge konsol Amazon di https://console.aws.amazon.com/events/, navigasikan ke halaman Events > Rules dan pilih Create rule. Tentukan Nama Layanan, Jenis Acara, dan fungsi Lambda. Di editor pratinjau Pola Acara, tempel kode berikut:

    { "source": [ "aws.acm" ], "detail-type": [ "ACM Certificate Approaching Expiration" ] }

    Peristiwa seperti yang diterima Lambda ditampilkan di bawah Tampilkan contoh acara:

    { "version": "0", "id": "9c95e8e4-96a4-ef3f-b739-b6aa5b193afb", "detail-type": "ACM Certificate Approaching Expiration", "source": "aws.acm", "account": "123456789012", "time": "2020-09-30T06:51:08Z", "region": "us-east-1", "resources": [ "arn:aws:acm:us-east-1:123456789012:certificate/61f50cd4-45b9-4259-b049-d0a53682fa4b" ], "detail": { "DaysToExpiry": 31, "CommonName": "My Awesome Service" } }
Untuk membersihkan

Setelah Anda tidak lagi memerlukan konfigurasi contoh, atau konfigurasi apa pun, itu adalah praktik terbaik untuk menghapus semua jejaknya untuk menghindari masalah keamanan dan biaya masa depan yang tidak terduga:

  • Kebijakan dan peran IAM

  • Fungsi Lambda

  • CloudWatch Aturan acara

  • CloudWatch Log yang terkait dengan Lambda

  • SNS Topik