당신이 AWS 계정을 만들고 가장 먼저 해야 할 일 들과 하지 말아야 할 일 들

이 글은 tmknom님이 Qiita에 올려주신 ‘AWS 계정을 만들고 나서 바로 해야 할 일들 정리(AWSアカウントを取得したら速攻でやっておくべき初期設定まとめ)‘에서 영감을 받아 작성되었습니다. 처음 AWS 계정을 만들고 나서 무엇을 해야 할 것인가도 중요하지만 하지 말아야 할 것을 아는 것도 중요하기 때문에 해야 할 것들과 하지말아야 할 것들에 대해서 정리해 보았습니다.


AWS 계정(루트 사용자) 보호

루트 사용자란?

AWS에 가입할때 맨 처음 만드는 e-mail어드레스와 패스워드로 인증하는 계정을 루트 사용자 라고 합니다. 이 루트 사용자는 그야말로 모든 권한을 지니고 있으며 권한에 대한 제약이 불가능하기 때문에 각별히 신경써서 다루어야 합니다. AWS의 모범사례에 의하면 AWS 루트 사용자를 만든 이후 가장 먼저 해야 할 일은 IAM 계정을 만들고 권한을 부여할 수 있는 IAM 관리자 계정을 만들고 이후 루트 사용자 대신 그 계정을 사용하는 것 입니다. 루트 사용자는 원칙적으로는 평상시엔 사용하지 않는 것이 좋습니다. 혹시 이 글을 읽으시는 분 중에 아직 루트 사용자를 이용하여 작업을 하시는 분이 계시다면 지금 즉시 관리자 권한을 지닌 IAM유저를 만들고 루트 사용자의 사용을 중지하시기 바랍니다.

AWS 계정에 대한 액세스 키를 만들지 말 것

AWS는 패스워드 인증 이외에 CLI나 SDK 사용을 위한 액세스 키 인증을 제공합니다. 하지만 루트 사용자에 대해서 액세스 키를 만들지는 마세요. 이미 있다면 삭제하시고 다른 IAM유저의 액세스 키를 사용해서 작업하시기 바랍니다.

루트 사용자 암호 변경

루트 사용자의 경우 강력한 암호를 사용하시기 바랍니다. 루트 사용자의 암호 변경 방법은 아래 링크에서 확인하실 수 있습니다.

루트 사용자에 대해 MFA 활성화

보안을 강화하기 위해 패스워드만 사용한 인증보다는 MFA(Multi-Factor Authentication)을 사용한 인증을 설정해 두세요. AWS에서는 Google Authenticator와 같은 개방형 TOPT 표준을 지원하는 애플리케이션을 MFA에 사용할 수 있습니다. 루트 사용자의 인증에 MFA를 설정하는 방법은 아래 링크를 참고하시기 바랍니다.

관리자용 IAM 그룹과 사용자의 작성

관리자용 IAM그룹을 만들고 IAM 사용자를 작성하여 관리자 그룹에 배치시킵니다. 구체적인 방법은 아래 링크를 참고하세요.

IAM유저 중에서도 관리자 권한과 같은 중요한 권한을 지닌 유저에 대해서는 MFA사용을 강제하는것이 좋습니다. 루트 사용자가 아닌 IAM유저에 대해서는 하드웨어 MFA나 가상 MFA이외에 휴대폰 문자 메세지(SMS)에 의한 MFA 사용도 가능합니다.

암호 정책 구성

관리자용 계정으로 로그인 한 후에 암호 정책을 설정하여 IAM 사용자의 암호에 대하여 복잡성 요건과 의무적인 교체주기를 지정할 수 있습니다.

보안 상태(Security Status)의 확인

여기까지 진행하셨다면 AWS를 안전하게 사용하기 위한 최소한의 조치가 완료되었습니다. IAM 서비스 페이지(https://console.aws.amazon.com/iam/home)로 이동하면 Security Status가 다음과 같이 모두 녹색이 되어 있는것을 확인합니다.

Security Status

청구정보 관련 설정

IAM에 대한 설정이 끝났다면 다음은 청구정보에 대한 설정을 진행해 봅시다.

IAM유저의 청구서 정보에 대한 액세스 허가

기본설정에서는 루트 사용자 이외에 유저가 청구정보에 접극하는것이 허가되어 있지 않습니다. 루트 사용자를 가급적 사용하지 않기 위해 IAM유저가 청구서 정보에 접근할 수 있도록 허가해 봅시다.

IAM유저에 대해 결제 정보 액세스를 허용했다면 이후 작업은 관리자 권한을 지닌 IAM유저를 사용해서 진행 할 수 있습니다.

청구정보와 비용 관리에 대한 설정

이메일로 청구서 받기

아래 링크의 지시에 따라 간단한 설정으로 이메일로 청구서를 받아볼 수 있습니다.

또한 프리티어 한고를 초과할 경우 메일이나 휴대폰 문자(SMS)를 통해 알려주는 결제 경보를 생성할 수도 있습니다.

그 밖의 설정들

이메일 설정

AWS로부터의 이메일을 설정합니다. 마케팅 메일을 받을지는 알아서들…

AWS Email Preferences

CloudTrail 유효화

AWS API호출에 대한 이력을 추적할 수 있는 CloudTrail이라는 서비스가 있습니다. 추적 내용은 S3 버킷에 저장됩니다.

git-secrets

git-secrets는 AWS가 만들어 공개하고 있는 툴로서 시크릿 액세스키와 같은 비밀 정보가 git에 커밋 되는 것을 막아줍니다.

GitHub에는 이렇게 잘못 올라온 비밀정보를 노리는 봇들이 수없이 동작하고 있어 실수로 정보가 공개되게 되면 악용되게 될 소지가 큽니다.

Lambda + CloudWatch Events + KMS를 사용하여 AWS 메니지먼트 콘솔에 대한 무단 액세스를 빠르게 감지하기

제목 그대로 입니다. 사실 내용이 초급자가 진행하기엔 만만치 않지만 도움이 되시는 분 도 있을것 같아 링크를 올려봅니다. 원문은 일본어 기사인데 조만간 번역해서 소개해 보기로 하고 일단은 구글번역 링크를 적어봅니다.

끝으로

이것으로 일단 가장 기본적인 설정이 끝났습니다.

추가적으로는 아래 IAM 모범 사례의 내용을 살펴보고 적용시킴으로서 더욱 강력한 보안을 확보 할 수 있습니다. 몇가지는 이 글과 겹치는 부분도 있지만 상세한 내용을 읽고 확인해 두는것도 좋을듯 합니다.

Amazon API Gateway + Lambda: 텔레그램 및 슬랙 전달 봇 만들기

안녕하세요! GS SHOP에서 IT Driven Open Communication 이라는 프로젝트를 하고 있는 김승연입니다.

저는 전부터 Labmda에 관심이 많았는데요. 아무리 t1.micro로 돌린다고 해도 Tokyo region 기준으로 한 달에 15달러가 나오는게 너무 아깝더라고요. 실제로 서버가 필요한(Web 서버가 요청을 받고 처리하고 응답해주는) 시간은 한 달에 많아도 7분(90ms * 4300 request) 내외였는데 한 달동안 언제든 요청을 받기 위해서 29일 23시간 53분을 기다리는 요금을 내는게 비효율적이라고 생각했어요.

하지만 Lambda는 EC2와는 달리 가입 후 12개월이 지나도 프리티어를 유지해주고 저 정도의 request면 무료로 이용이 가능했습니다!

Lambda-Free

Lambda-Bill

그래서 Lambda를 좋아하고, 이번에 회사에서 텔레그렘을 이용하는 팀과 슬랙을 이용하는 팀이 같이 소통해야될 일이 있어서 텔레그렘과 슬랙을 이어주는 봇을 만들어주면 어떨까? 하는 생각이 있어서 Lambda랑 API Gateway로 만들고 과정 일부를 공유하면 재밌겠다 싶어서 이 글을 쓰게 되었습니다 😀

Lambda 시작하기

먼저 Lambda console에 들어가봅시다! 좌측의 Create a Lambda function 클릭 여러 가지 형태의 lambda function을 만들 수 있는데 한 단계씩 올라갈 것이기 때문에 일단 Skip 하겠습니다! Name에는 TelegramToSlack, 그리고 저는 Python 2.7을 이용할게요. 코드는 Code entry type은 Edit code inline을 선택하고 내용은 간단하게 event를 그대로 return해볼게요.

def lambda_handler(event, context):
  return event

Nodejs version: https://gist.github.com/news700/6f1cbe80663a8965a0832ad277b4970e

Lambda function에는 eventcontext 두 개의 파라미터가 넘어오는데, event는 lambda function으로 넘어오는 파라미터들이 Dictionary 형태로 넘어오는 곳이고 context는 함수 이름, 버젼, arn, 메모리 제한, 남은 시간 등을 가져올 수 있는 객체에요..

넘어가서 handlerrole을 정해줘야하는데요. 기본으로 Handler에는 lambda_function.lambda_handler라는 값이 들어있어요. lambda_function이라는 모듈의 lambda_handler라 는 함수를 사용하겠다는 의미인데 inline으로 코드를 편집하게 되면 우리가 편집하는 코드의 파일명이 lambda_function.py이기 때문에 지금 우리가 짠 함수를 실행하겠다는 의미가 돼요. 나중에 프로젝트의 크기가 커지면 파일을 분리하게 되고 AWS Lambda가 실행해야할 함수를 찾아야될 때 이 값을 조정해서 사용하게 돼요.

Role은 이 함수가 어떤 권한을 가지고 실행될 것이냐를 결정해요. 최소한 lambda function을 실행할 수 있는 권한을 포함해야돼요. 그 외에 우리가 짜는 코드가 필요한 권한이 있다면(dynamodb에 데이터를 작성한다던가) 적절히 AWS IAM에서 Role을 생성하여 선택해주면 돼요. 일단 우리는 콤보박스에서 Create New Role 안의 Basic execution role을 이용할게요. lambda를 실행할 수만 있는 권한이에요. 일단 Role을 생성해준 뒤 해당 Role을 선택하여 사용할 수 있어요. Basic execution role을 클릭하면 새로운 창이 열려요(혹시 팝업이 차단돼서 안열릴 수 있으니 확인해보세요!)

IAM Management Console 창이 새로 떴는데 IAM Role에는 Create a new IAM Role을 선택해주시고 Role Name은 lambda_basic_execution으로 할게요. Allow 하고 돌아오면 Role에 lambda_basic_execution이 생성돼 있어요. 혹시 생성돼있지 않다면 새로고침을 해주세요! 다른 내용은 임시저장돼있어요 ㅎㅎ

여기까지 했다면 대략 이런 화면이 됐을거에요

Create-Lambda

Memory와 Timeout은 사용할 수 있는 memory와 최대 실행시간을 정하는건데요. 기본 값으로 두고 넘어갈게요. Next를 누르고 Create function을 누르면 Congratulations! Your Lambda function “TelegramToSlack” has been successfully created. 라는 메시지가 상단에 뜨네요!

그 위에 Test 버튼이 있어요. 이 함수를 웹상에서 테스트를 해볼 수 있는 기능이에요. JSON 형태로 파라미터를 지정할 수 있는데 이 파라미터들은 event변수에 dictionary 형태로 전달돼요. Hello World template 그대로 Save and test를 눌러봅시다. 그러면 아랫쪽에 Execution result: succeeded를 확인하실 수 있어요! 넘겼던 파라미터들이 잘 return된 모습을 확인할 수 있어요.

이렇게 Lambda의 기본 사용법을 알아봤습니다. 이제 API Gateway와의 연동을 진행해볼게요.

Lambda의 API Gateway 연동

이제 API Gateway Console로 들어가보죠. 파란색 Create API 버튼을 눌러주세요. API name에는 뭐 .. 음 .. Telegram으로 해볼게요. 이제 Create API를 눌러주세요.

이렇게 API Gateway에서 API를 생성해줬어요. Lambda와 연동해주기 위해 다시 Lambda console로 가서 TelegramToSlack을 선택해주세요. 화면에 보면 Code 탭 옆쪽에 API Endpoints 라는 탭이 있는 걸 확인할 수 있습니다.

API-Endpoints-Tab

누르고 들어가서 Add API endpoint를 클릭, API endpoint type에 API Gateway를 선택해주세요. API name을 클릭하면 Telegram이 보일거에요. Telegram을 선택해주시고 Resource name은 API path를 의미해요. /to-slack 정도로 해줄게요. Method는 POST로 설정해주세요. Telegram Bot이 POST요청을 보낼거에요. Deployment stage는 여러 단계의 stage를 두고 API 버젼을 따로 관리할 수 있는데 기본값 prod 그대로 두겠습니다. Security는 Open으로 설정해줘야 Telegram Bot이 들어올 수 있어요. 이제 Submit을 클릭합시다!

Add-Endpoint

이제 다시 API Gateway console로 가서 Telegram을 선택해보면 /to-slack 이 추가돼있는 것을 볼 수 있어요. 클릭해보면 Test를 해볼 수 있어요.

To-Slack-Added

Request body에 {“foo”: “bar”} 를 입력하고 Test를 눌러보면 response가 잘 오는 것을 확인할 수 있어요.

To-Slack-Test

Telegram Bot 세팅하기

Telegram Bot API에는 setWebHook이라는 API가 있는데요. 봇이 볼 수 있는 메시지를 설정한 https 주소로 보내주는 기능입니다. 먼저 Telegram에서 봇을 만들게요. https://core.telegram.org/bots 에 따라 텔레그렘에서 botfather 를 검색해 대화를 시작하면 Bot을 생성하고 API Key를 줍니다. 그 뒤에 텔레그램 Group에서 봇이 메시지를 받기 위해서는 privacy 모드를 해제해줘야돼요. botfather에게 /setprivacy 명령을 이용해 해제할 수 있어요.

Telegram

Lambda console의 API endpoints 탭에 가보면 API endpoint URL이 있습니다. Telegram bot의 web hook을 해당 URL로 걸어줄게요.

$ curl https://api.telegram.org/bot<API TOKEN>/setWebhook?url=<API endpoint URL>
{"ok":true,"result":true,"description":"Webhook was set"}

이제 해당 봇이 참여하는 대화의 메시지들은 우리가 만든 API Gateway로 가고 그 endpoint는 Lambda function을 실행시켜서 POST로 넘어온 값을 그대로 돌려줄겁니다!

Slack에 메시지 보내기

Slack의 Incoming WebHook을 이용해서 쉽게 한 채널에 메시지를 보낼 수 있습니다. Incoming WebHook은 https://slack.com/apps/build -> Make a Custom Integration -> Incoming WebHooks 에서 만들 수 있어요. 메시지를 보낼 채널을 선택하거나 만듭니다. 저는 telegram이라는 채널을 만들었어요. 초록색 Add Incoming WebHooks integration 버튼을 누르면 다음 페이지의 아랫쪽에 Webhook URL을 확인할 수 있어요.

이제 telegram에서 메시지가 올 때 마다 해당 URL에 “asdf”라는 메시지를 보내봅시다. Lambda console에 가서 코드를 다음과 같이 수정해주세요.

import httplib
import json
import urllib

def lambda_handler(event, context):
    conn = httplib.HTTPSConnection('hooks.slack.com')
    conn.request(
        'POST',
        '/services/T01234567/B0123456/abcdefghijklmnopqrstuvwxyz',  # slack에서 받은 webhook path
        urllib.urlencode({'payload': json.dumps({'text': 'asdf'})}),
        {'Content-Type': 'application/x-www-form-urlencoded'}
    )
    conn.getresponse()
    conn.close()

Nodejs version: https://gist.github.com/news700/37ab1ab1aa769c52e0361ee8a8ae0ed9

Save and test를 눌러 실행해보면 Slack telegram 채널에 asdf 라는 메시지가 온 것을 확인할 수 있어요! Telegram에서도 우리가 만든 봇 이름을 검색해서 메시지를 전송해보면 봇한테 메시지를 쓸 때 마다 Slack에 asdf가 오는 것을 확인할 수 있어요!

Slack

이제 Telegram에서 보내주는 포맷에 맞춰 전달받은 텍스트가 있으면 해당 텍스트를 슬랙에 넘겨주는 코드로 바꿔볼게요.

import httplib
import json
import urllib

def lambda_handler(event, context):
    if 'message' not in event:
        return
    if 'text' not in event['message']:
        return
    text = event['message']['text']
    conn = httplib.HTTPSConnection('hooks.slack.com')
    conn.request(
        'POST',
        '/services/T01234567/B0123456/abcdefghijklmnopqrstuvwxyz',  # slack에서 받은 webhook path
        urllib.urlencode({'payload': json.dumps({'text': text})}),
        {'Content-Type': 'application/x-www-form-urlencoded'}
    )
    conn.getresponse()
    conn.close()

Nodejs version: https://gist.github.com/news700/ce8154389f7e0bb7a8cb2b6812a73eb0

Final

이제 코드를 조금 고치면 새로운 방에 초대될 때마다 새로운 슬랙 채널을 만들 수도 있고 작성자도 표시해주거나 사진을 전송할 수도 있겠네요. 새로운 API를 추가해서 슬랙에서 쓴 메시지를 텔레그램에서도 받아볼 수 있겠네요. 여기서부터는 한 번 원하시는대로 직접 만들어보세요!

고맙습니다!