쿠키 기본 설정 선택

당사는 사이트와 서비스를 제공하는 데 필요한 필수 쿠키 및 유사한 도구를 사용합니다. 고객이 사이트를 어떻게 사용하는지 파악하고 개선할 수 있도록 성능 쿠키를 사용해 익명의 통계를 수집합니다. 필수 쿠키는 비활성화할 수 없지만 '사용자 지정' 또는 ‘거부’를 클릭하여 성능 쿠키를 거부할 수 있습니다.

사용자가 동의하는 경우 AWS와 승인된 제3자도 쿠키를 사용하여 유용한 사이트 기능을 제공하고, 사용자의 기본 설정을 기억하고, 관련 광고를 비롯한 관련 콘텐츠를 표시합니다. 필수가 아닌 모든 쿠키를 수락하거나 거부하려면 ‘수락’ 또는 ‘거부’를 클릭하세요. 더 자세한 내용을 선택하려면 ‘사용자 정의’를 클릭하세요.

Lambda 함수를 사용하여 이벤트에 응답

포커스 모드
Lambda 함수를 사용하여 이벤트에 응답 - AWS 인증서 관리자

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

이 절차는 AWS Lambda 를 사용하여 Amazon 에서 수신 대기하고 EventBridge, Amazon Simple Notification Service(SNS)를 사용하여 알림을 생성하고 AWS Security Hub, 결과를 에 게시하여 관리자와 보안 팀에 가시성을 제공하는 방법을 보여줍니다.

Lambda 함수 및 IAM 역할을 설정하려면
  1. 먼저 AWS Identity and Access Management (IAM) 역할을 구성하고 Lambda 함수에 필요한 권한을 정의합니다. 이 보안 모범 사례를 통해 유연하게 함수를 호출할 권한이 있는 사용자를 지정하고 해당 사용자에게 부여된 권한을 제한할 수 있습니다. 대부분의 AWS 작업은 사용자 계정에서 직접 실행하는 것이 권장되지 않으며, 특히 관리자 계정에서는 실행하지 않는 것이 좋습니다.

    에서 IAM 콘솔을 엽니다https://console.aws.amazon.com/iam/.

  2. JSON 정책 편집기를 사용하여 아래 템플릿에 정의된 정책을 생성합니다. 고유한 리전 및 AWS 계정 세부 정보를 제공합니다. 자세한 내용은 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. IAM 역할을 생성하고 새 정책을 연결합니다. IAM 역할 생성 및 정책 연결에 대한 자세한 내용은 AWS 서비스에 대한 역할 생성(콘솔)을 참조하세요.

  4. 에서 AWS Lambda 콘솔을 엽니다https://console.aws.amazon.com/lambda/.

  5. Lambda 함수를 생성합니다. 자세한 내용은 콘솔로 Lambda 함수 생성을 참조하세요. 다음 단계를 완료합니다.

    1. [함수 생성(Create function)] 페이지에서 [새로 작성(Author from scratch)] 옵션을 선택하여 함수를 생성합니다.

    2. 함수 이름 필드에 “handle-expiring-certificates”와 같은 이름을 지정합니다.

    3. [런타임(Runtime)] 목록에서 Python 3.8을 선택합니다.

    4. [기본 실행 역할 변경(Change default execution role)]을 선택하고 [기존 역할 사용(Use an existing role)]을 선택합니다.

    5. [기존 역할(Existing role)] 목록에서 앞서 생성한 역할을 선택합니다.

    6. 함수 생성(Create function)을 선택합니다.

    7. [함수 코드(Function code)] 아래에 다음 코드를 삽입합니다.

      # 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. [환경 변수(Environment variables)]에서 [편집(Edit)]을 선택하고 선택적으로 다음 변수를 추가합니다.

      • (선택 사항) EXPIRY_DAYS

        인증서 만료 알림을 보내기 전의 리드 타임(일)을 지정합니다. 이 함수의 기본값은 45일이지만 사용자 지정 값을 지정할 수 있습니다.

      • (선택 사항) SNS_TOPIC_ARN

        Amazon 에 ARN 대한 를 지정합니다SNS. arn:aws:sns 형식으로 전체 ARN를 제공합니다.<region>:<account-number>:<topic-name>.

      • (선택 사항) SECURITY_HUB_REGION

        다른 리전 AWS Security Hub 에서 을 지정합니다. 이 값을 지정하지 않으면 실행 중인 Lambda 함수의 리전이 사용됩니다. 함수가 여러 리전에서 실행되는 경우 모든 인증서 메시지가 단일 리전의 Security Hub로 전송되도록 하는 것이 좋습니다.

    9. [기본 설정(Basic settings)]에서 [제한 시간(Timeout)]을 30초로 설정합니다.

    10. 페이지 상단에서 [배포(Deploy)]를 선택합니다.

다음 절차의 작업을 완료하여 이 솔루션의 사용을 시작합니다.

만료 이메일 알림을 자동화하려면

이 예제에서는 Amazon 를 통해 이벤트가 제기되는 시점에 만료되는 각 인증서에 대해 단일 이메일을 제공합니다 EventBridge. 기본적으로 는 만료 후 45일 이하의 인증서에 대해 매일 이벤트를 ACM 생성합니다. (이 기간은 ACM 의 PutAccountConfiguration 작업을 사용하여 사용자 지정할 수 있습니다API.) 이러한 각 이벤트는 다음과 같은 일련의 자동화된 작업을 트리거합니다.

ACM raises Amazon EventBridge event → >>>>>>> events Event matches Amazon EventBridge rule → Rule calls Lambda functionFunction sends SNS email and logs a Finding in Security Hub
  1. Lambda 함수를 생성하고 권한을 구성합니다. (이미 완료됨 - Lambda 함수 및 IAM 역할을 설정하려면 참조).

  2. 알림을 보내는 데 사용할 Lambda 함수의 표준 SNS 주제를 생성합니다. 자세한 내용은 Amazon SNS 주제 생성을 참조하세요.

  3. 관심 있는 사람이 새 SNS 주제를 구독합니다. 자세한 내용은 Amazon SNS 주제 구독을 참조하세요.

  4. Lambda 함수를 트리거하는 Amazon EventBridge 규칙을 생성합니다. 자세한 내용은 이벤트에 대응하는 Amazon EventBridge 규칙 생성을 참조하세요.

    의 Amazon EventBridge 콘솔에서 이벤트 > 규칙 페이지로 https://console.aws.amazon.com/events/이동하여 규칙 생성을 선택합니다. [서비스 이름(Service Name)], [이벤트 유형(Event Type)] 및 [Lambda 함수(Lambda function)]를 지정합니다. [이벤트 패턴 미리 보기(Event Pattern preview)] 편집기에서 다음 코드를 붙여 넣습니다.

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

    Lambda 수신과 같은 이벤트가 [샘플 이벤트 표시(Show sample event(s))] 아래에 표시됩니다.

    { "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" } }
정리하려면

구성 예 또는 다른 어떤 구성이 더 이상 필요하지 않은 경우, 보안 문제 및 예기치 않은 향후 요금 발생을 방지하기 위해 모든 트레이스를 제거하는 것이 좋습니다.

  • IAM 정책 및 역할

  • Lambda 함수

  • CloudWatch 이벤트 규칙

  • CloudWatch Lambda와 연결된 로그

  • SNS 주제

프라이버시사이트 이용 약관쿠키 기본 설정
© 2025, Amazon Web Services, Inc. 또는 계열사. All rights reserved.