AWS/Monitoring

AWS Monitoring[Certificate Manager] - AWS ACM 인증서 만료일자 체크 Slack 알람

TTwY 2021. 9. 28. 09:27
728x90
반응형

AWS Certificate Manager는 AWS 서비스 및 연결된 내부 리소스에 사용할 공인 및 사설 SSL/TLS(Secure Sockets Layer/전송 계층 보안) 인증서를 손쉽게 프로비저닝, 관리 및 배포할 수 있도록 지원하는 서비스입니다.

https://docs.aws.amazon.com/ko_kr/acm/latest/userguide/acm-overview.html

 

란 무엇입니까?AWSCertificate Manager - AWS Certificate Manager

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com


ACM(AWS Certificate Manager)의 인증서를 이용하여 https 통신 설정시 SSL Certificate 값으로 설정합니다.
ACM은 인증서에 대한 관리 갱신 기능을 제공합니다. ACM이 인증서를 자동으로 갱신(DNS 유효성 검사를 사용하는 경우)하며, 만료가 다가오면 전자 메일 알림을 보냅니다.
가져오기 등으로 ACM 인증서를 등록한 경우는 자동으로 갱신되지 않으며, 마찬가지로 만료가 다가오면 전자 메일 알림을 보냅니다.

하지만 보통 IAM으로 콘솔이나 코드를 통한 AWS Resource를 관리하고 있기 때문에 메일을 확인하지 못하는 경우가 생각보다 많습니다. 인증서 유효기간을 놓쳐 인증서가 만료되면 https 통신에 장애가 발생하기 때문에 제공하고 있는 서비스에 영향을 미치는 장애가 발생하게 됩니다.
이런 장애를 방지하고자 AWS ACM 인증서에 대해서 만료일자를 체크하여 Slack으로 Message 발생시키는 방법에 대해서 글을 작성해보았습니다. 

 

구성진행 순서

1. IAM Role 생성

2. Lambda Function 만들기
3. CloudWatch > Events > Rules
4. Lambda Code 수정
5. 테스트

 

1. IAM Role 생성

Lambda Funtion에 사용 할 IAM Role을 생성하도록 하겠습니다.

Lambda Function을 생성하면 만들어지는 기본 IAM Role(역할)을 사용할 수도 있지만 IAM Role(역할) 생성하여 권한 설정을 통해서 구성을 해보도록 하겠습니다.

아래와 같이 Lambda 를 선택한 후 다음:권한을 클릭합니다.

아래와 같이 4개의 권한을 선택합니다.

역할 이름을 작성하고, 역할 만들기를 클릭합니다.

위와 같은 화면이 보이면 IAM Role(역할) 생성이 완료 되었습니다.

 

2. Lambda Funtion 만들기

Slack Message를 받기 위한 Lambda Function 생성 및 Slack 기본 설정은 아래의 글에 자세하게 설명되어 있으니 상세 설정 부분에 대해서 아래 글을 보고 초반부 세팅을 하고 다시 본글로 오시면 됩니다.

https://longtermsad.tistory.com/49

 

AWS Monitering[CloudWatch] - 1. CloudWatch Alarm을 Slack 연동하기

AWS에서는 Amazon CloudWatch Alarm(경보)를 사용하여 모니터링 할 수 있으며 Alarm(경보)를 설정하고 해당 내용에 대해서 알람을 받을 수 있습니다. https://docs.aws.amazon.com/ko_kr/AmazonC..

longtermsad.tistory.com

Lambda Function 생성 설정을 아래와 같이 설정 후 함수 생성을 클릭합니다.

Lambda 함수 생성 후 구성 > 기본 설정 > 편집 버튼을 클릭하여 제한 시간을 1분으로 늘려줍니다.

구성 > 환경 변수를 클릭하여 Slack 에 대한 환경 변수를 입력합니다.

3. CloudWatch > Events > Rules

Rules를 생성하여 Lambda Function에 Trigger를 설정하도록 하겠습니다.

Create Rule 버튼을 클릭하여 Rules을 생성하겠습니다.

Event Source에서 Schedule로 선택 후 Cron expression에 0 0 * * ? * 을 입력합니다. 아래에 예정된 10개의 Trigger Date가 표시되게 됩니다. 간략하게 설명 드리자면 매일 00시 00분 00초(GMT 시간)에 이 Event가 발생하게 하겠다 라고 설정을 하는 것입니다. 한국 시간으로 계산을 하려면 +09:00 를 해야 하기 떄문에 한국시간으로는 매일 오전 9시에 이 이벤트 Rules가 발생하게 하는 것을 설정한 것입니다.

Targets은 위에서 만들어 주었던 Lambda function을 선택합니다.

필수값인 Name을 작서애 주고 Create rule를 선택해 rule을 생성합니다.

위와 같이 생성되었으면 이상없이 rule을 설정하였습니다.

 

4. Lambda Code 수정

Lmabda funtion의 Trigger도 설정해주었기 때문에 Trigger 발생 시 Slack의 메시지를 발송하는 Lambda Code를 작성해보도록 하겠습니다.

 

import boto3
import json
import logging
import os
import datetime

from boto3.session import Session
from base64 import b64decode
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError

HOOK_URL = os.environ['HOOK_URL']
SLACK_CHANNEL = os.environ['slackChannel']

logger = logging.getLogger()
logger.setLevel(logging.INFO)


def lambda_handler(event, context):
   
    s_req = Session()
    
    regions = s_req.get_available_regions('acm')
    state ='인증서만료'
    
    for region in regions :
        try :
            client = boto3.client('acm',region_name=region)
            certificates=client.list_certificates(MaxItems=1000)
            certs = certificates.get('CertificateSummaryList')
            for c in certs :
                
                rep=client.describe_certificate(CertificateArn=c.get('CertificateArn'))
                cert=rep.get('Certificate')
                if (( cert.get('NotAfter')-datetime.datetime.now(datetime.timezone.utc)).days < 700 ) :
                    arn = cert.get('CertificateArn')
                    adomain = cert.get('SubjectAlternativeNames')
                    f_adomain = str(adomain)[1:-1]
                    domain = cert.get('DomainName')
                    notafter = cert.get('NotAfter').strftime('%Y-%m-%d')
                    renewable = cert.get('RenewalEligibility')
                    if renewable == "INELIGIBLE":
                        renewable = "사용 불가능"
                    elif renewable == "ELIGIBLE":
                        renewable = "사용 가능"
                    else:
                        renewable = "알 수 없음"
                    
                    slack_message ={
                    "channel": SLACK_CHANNEL,
                    "text": "*[인증서 만료 알림]* %s "% (arn),
                    "attachments": [
                        {   
                            "color" : "danger",
                		    "text": "도메인 : %s \n 추가도메인 : %s \n 만료일자 : %s \n 갱신자격 : %s" %(domain, f_adomain, notafter, renewable)
                        }
                    ]
                        
                    }
                    req = Request(HOOK_URL, json.dumps(slack_message).encode('utf-8'))
                    try:
                        response = urlopen(req)
                        response.read()
                        logger.info("Message posted to %s", slack_message['channel'])
                    except HTTPError as e:
                        logger.error("Request failed: %d %s", e.code, e.reason)
                    except URLError as e:
                        logger.error("Server connection failed: %s", e.reason)
                
                    
        except Exception as e : 
            ec2_client = boto3.client('ec2')
            r=ec2_client.describe_regions(RegionNames=[region])
            if(r.get('Regions')[0].get('OptInStatus')=='not-opted-in') :
                continue
            else :
                logger.error("failed to get certificate information")

 

Lambda Code를 저장(Deploy) 하면 Lambda Code 수정이 끝납니다.

 

5. 테스트

Lmabda Code를 작성하는 곳에서 저장(Deploy) 버튼 옆에 Test 버튼을 확인 할 수 있습니다.

Test 버튼을 클릭하고 아래와 같이 제목만 설정한 후 Save를 클릭합니다. Lambda로 전달해 줄 인자값이 없으므로 특별한 값을 입력하지 않아도 됩니다.

Save 후 Test 버튼을 클릭하면 테스트가 진행됩니다.

Test 전에 수정해야 할 부분이 한 곳 있습니다. 모든 Region의 인증서에 대해서 조회 후 처리하기 때문에 runtime 시간이 조금 길게 나옵니다. 그렇기 떄문에 Lambda의 Runtime의 시간을 늘려주도록 하겠습니다.

구성(Configuration) > 일반 구성(General configuration)을 클릭하여 제한 시간(timeout)을 1분으로 늘려줍니다.

변경 후 Test 버튼을 클릭합니다.

우와 같이 Lmabda function이 정상적으로 수행되었으며, 아래와 같은 Slack Message를 받게 됩니다.

Test를 위해 Lambda Code 상에서 인증서 만료 일자 계산을 > 700 으로 해두었습니다. 본인이 Slack Message를 받고 싶은 일자로 변경하여 사용하시면 됩니다.

 

질문 사항이나 제가 전달한 내용이 잘못되었거나, 다른 부분이 있으면 댓글로 남겨 주시면 답변 드리도록 하겠습니다.

 

감사합니다.

728x90
반응형