brunch

You can make anything
by writing

C.S.Lewis

by Master Seo Sep 25. 2023

37탄-10. AWS 보안 아키텍처 labs : 300

<1>   [실습] Level 300: Multilayered API Security with Cognito and WAF  = api gw 변경된 암호 적용  


<2> Level 300: Autonomous Monitoring Of Cryptographic Activity With KMS : ECS 기반 App이 KMS 사용 활동 감사


<3> Level 300: Autonomous Patching With EC2 Image Builder And Systems Manager : 블루/그린 배포 방식 AMI 자동 업데이트  


<4> Level 300: IAM Permission Boundaries Delegating Role Creation : AWS Account 2개 필요, IAM 권한 경계 활용


<5> Level 300: IAM Tag Based Access Control for EC2 : AWS Account 2개 필요, Tag 리소스 대상 관리 설정


<6> Level 300: Incident Response Playbook with Jupyter - AWS IAM : 사고 발생 시 분석 실습, 주피터 사용


<7> Level 300: Lambda Cross Account Using Bucket Policy : AWS Account 2개 필요, 2개 계정 간 IAM Role과 IAM 정책 실습


<8> Level 300: Lambda Cross Account IAM Role Assumption : AWS Account 2개 필요, 2개 계정 간 IAM Role 실습


<9> Level 300: VPC Flow Logs Analysis Dashboard : AWS Account 2개 필요, VPC Flows 로그를 분석 Athena 및 시각화        





시작  


<1>   [실습] Level 300: Multilayered API Security with Cognito and WAF  = api gw 변경된 암호 적용  


다음 구성을 단계적으로 적용하는 것이다.

단계적으로 적용하며 보안 강화가 된다.

WAF적용 , 코그니토 적용   


1

실습 환경 배포 시간이 소요되니, 미리 배포해둘 것 : 버지니아 북부리전

CW 알람 내용 : kms 오류 이벤트 발생 시


2

람다에서 사용할수있는 데이터 필요.  s3버킷이 필요.

S3 버킷 생성 및 Lambda deployment packages 업로드 해두기


# S3 버킷 생성

NICKNAME=topasvga

aws s3 mb s3://$NICKNAME-walab --region us-east-1


# Lambda deployment packages 다운로드

wget https://d3h9zoi3eqyz7s.cloudfront.net/Security/300_multilayer_api_security_with_congnito_and_waf/rds-create-table.zip


wget https://d3h9zoi3eqyz7s.cloudfront.net/Security/300_multilayer_api_security_with_congnito_and_waf/rds-query.zip


wget https://d3h9zoi3eqyz7s.cloudfront.net/Security/300_multilayer_api_security_with_congnito_and_waf/python-requests-lambda-layer.zip 



# S3 버킷에 업로드

aws s3 cp rds-create-table.zip s3://$NICKNAME-walab

aws s3 cp rds-query.zip s3://$NICKNAME-walab

aws s3 cp python-requests-lambda-layer.zip s3://$NICKNAME-walab


# 확인

aws s3 ls s3://$NICKNAME-walab --human-readable --summarize   



3

AWS CloudFormation 템플릿 파일 다운로드 : section1-base.yaml

wget https://wellarchitectedlabs.com/Security/300_Multilayered_API_Security_with_Cognito_and_WAF/Code/templates/section1/section1-base.yaml  


4

AWS CloudFormation Stack 배포 : Name(walab-api) → 10분 정도 소요

S3BucketName 에 만든 S3버킷이름 입력 필요!   


5

배포 후 output 에 Cloud9URL 클릭 후 테스트 환경 진입  


6

cd walab-scripts 후 bash install_package.sh 실행(boto3, requests 설치)


#

aws sts get-caller-identity

Admin권한을 가지고 있다.  

aws s3 ls


# 버전 확인

python3 -V

pip3 --version

#

cd walab-scripts

cat install_package.sh

bash install_package.sh

pip3 list   



7

Confirm Successful Application Deployment 확인 : CF Output에 APIGatewayURL 복사(메모, 자주 사용 예정)

Output 에서 APIGatewayURL  확인해주세요~

# In Cloud9, execute the script called sendRequest.py with the argument of your APIGatewayURL.

APIGatewayURL='https://p9pxds4mke.execute-api.us-east-1.amazonaws.com/Dev/?id=1'

python sendRequest.py $APIGatewayURL   



8

혹은 웹 브라우저에서 위 주소 접속 확인 , 뒤에 id=2 , id=3 변경해서 확인해보자   



9

Api gw서비스가자.

 apigw와 람다가 통합되어 있다.

API GW → walab-api(Edge) 선택 ⇒ 리소스 선택 : GET 통합 요청 확인 (Lambda) , 그외 접속 URL도 확인  



10

API GW → wa-lab-rds-api(Regional) 선택 ⇒ 정보 확인, 접속 URL 확인 ← 위, APIGatewayURL 주소



11

Lambda 확인 : 2개 - RDSCreateTable , RDSTest(Test Lambda function to access a RDS Database and read sample data)

RDSTest : 트리거 API GW 2개 확인, 권한 확인, RDS 접속을 위한 환경 변수, VPC내 배치

동작?

 apigw - 람다- rds 구성

 RDS  에서 데이터를 가져 온다.  

람다는 rds와  통신해야 해서,  VPC 내에서 동작하게 설정된 부분 확인하자.  



12

람다의 환경변수에 DB에 접근해야하는 정보가 있다.

람다 > 환경 변수 가서 확인  



13

USE SECRETS SECURELY - 링크 ←암호 자동 교체를 위한 Lambda 배포에 5분 소요 : 제대로 동작하지 않아서 Skip 

DB 암호 실습은 하지 마라!!

잘 안된다.

디비 암호를 특정 주기마다 자동 교체 하는      



14

코그니토 , WAF 적용해보자!!!

REVENT REQUESTS FROM ACCESSING API DIRECTLY - 링크 ← 배포에 4분 정도 소요하니 미리 배포 하자  

https://wellarchitectedlabs.com/security/300_labs/300_multilayered_api_security_with_cognito_and_waf/3_prevent_requests_from_accessing_api_directly/



15

Cloudformation

wget https://wellarchitectedlabs.com/Security/300_Multilayered_API_Security_with_Cognito_and_WAF/Code/templates/section3/section3-enhance_security.yaml  


AWS CloudFormation Stack 배포 : Name(walab-cdn-waf-cognito), APIGatewayURL과 S3버킷명 기입 → 4분 정도 소요

S3 버킷명

Topasvga-bucket    



16

배포 확인(CF output): CloudFront(WAF, Origin-API_GW), WAF(2개, 1개는 API GW에 연동), Secret Manager(OriginVerifyHeader + 자동 교체 Lambda)  


구조?

Cloudfront 붙인다.

WAF 붙인다.  



동작은 ?

API Gateway 받을떄  사용자 지정 해더가 맞을떄만  람다로 전달한다.

외부에서 apigw로 직접은 못들어온다.

외부에서 내부로 들어오는 환경을  제어한다.

Cloudfront 는 APIGW를 본다.  

WAF 2개임

CloudFront에도 붙어 있고, APIGW 에도 붙어 있다.   



17

이제부터 APIGatewayURL로 접속 불가!, 아래 설정 필요


Add custom HTTP headers to the requests : 요청에 사용자 HTTP 헤더를 추가

스택 배포가 완료되면 이제 CloudFront의 요청에 사용자 지정 헤더를 추가할 수 있습니다. 앞서 설명한 대로 이렇게 하면 사용자가 CloudFront를 우회하여 API에 직접 액세스하는 것을 방지할 수 있습니다  


CF Output : OriginVerifyHeaderName 이 X-Origin-Verify 로 설정되어 있는지 확인하세요

이제 OriginVerifyHeader 값을 클릭하면 다음과 같이 AWS Secrets Manager로 진입  


AWS Secrets Manager에서 OriginVerifyHeader 비밀을 클릭하여 X-Origin-Verify 헤더 값을 가져오기

비밀 값 대화 상자에서 비밀 값 검색을 클릭합니다 . HEADERVALUE의 비밀 값을 기록합니다.

이 값을 CloudFront의 오리진 헤더 값 으로 사용하겠습니다  


이제 Secrets Manager는 이 헤더 값을 자동으로 교체하여 이전 실습에서 암호 정보를 교체한 것과 동일한 방식으로 향후 손상 가능성을 방지.  



18

CloudFront → 원본 (편집) : 사용자 정의 헤더 추가 : X-Origin-Verify , 값은 위 Secret Manager값 붙여넣기 ⇒ 변경 사항 저장(3~5분 반영 시간 소요)

// 이 해더가 있어야 APIGW가 처리하는 것으로 되었다.  



19

WAF(API-GW) → 정책 확인 : 헤더와 값 매칭 확인  



20

이제 최종 확인 :

CF Output에 CloudFrontEndpoint 클릭해서 접속 확인, APIGatewayURL도 다시 접속 확인

⇒ WebACL에서 Sample Request 확인  

Apigw 로  직접 못들어 온다.   



21

Cloud9 에서도 확인?  


# APIGatewayURL 시도  = 에러가 난다.

APIGatewayURL='https://p9pxds4mke.execute-api.us-east-1.amazonaws.com/Dev/?id=1'

python sendRequest.py $APIGatewayURL   


# CloudFrontEndpoint 시도 = 성공한다.   

CloudFrontEndpoint='https://d3ua9kogvj5qwi.cloudfront.net/?id=2'

python sendRequest.py $CloudFrontEndpoint    



22

APPLICATION LAYER DEFENCE - 링크

WAF 간단하게 사용해보는 것이다.


목표 : SQL 주입, 분산 서비스 거부(DDoS) 및 기타 일반적인 공격과 같은 취약성의 위험을 완화하기 위해 AWS WAF를 사용하여 보안을 더욱 강화

SQL Injection 공격 시도 : (TMI) Lab Authors - Jang Whan Han, Well-Architected Geo Solutions Architect.  



# SQL Injection 공격 시도 : 모든 값이 다 출력

python sendRequest.py 'https://d3ua9kogvj5qwi.cloudfront.net/?id=1 or 1=1'


Sending your request WITHOUT id token generated by Cognito.....

Response code: 200 , Response Data: ["My favorite player is Lionel Messi","My favorite player is Cristiano Ronaldo","My favorite player is Son Heung-min"]

디비에 있는 모든 값이 다 출력된다.  



23

아래 WAFWebACLG는 CloudFront에 연동된 WebACL 입니다.

# SQL Injection 공격 시도 >> 어떻게 될까요?

python sendRequest.py 'https://d3ua9kogvj5qwi.cloudfront.net/?id=1 or 1=1'

...   



24

보안강화 ??  

CONTROL ACCESS TO API - 링크 

코그니토 이다.  



목표 : 식별된 사용자만 API에 액세스 허용 ← Amazon Cognito

사용자는 우리가 생성한 사용자 풀에 로그인하고 자격 증명 또는 액세스 토큰을 얻은 다음 토큰 중 하나로 API 메서드를 호출할 수 있습니다.

이러한 토큰은 일반적으로 요청의 Authorization 헤더로 설정됩니다.

Sign up with Amazon Cognito user pools

이미 배포한 두 번째 CloudFormation 템플릿에는 Amazon Cognito 사용자 풀이 이미 포함되어 있습니다.


Cognito의 앱 클라이언트 암호를 얻는 것부터 시작하겠습니다 . 이 암호는 랩의 후반부에서 ID 토큰을 생성하는 데 사용할 것입니다.  

Take note of App client secret. Other required values such as user pool ID and App client ID are available in the Output section of the current cloudformation stack   



25

Create Cognito user pools as Authorizer in API Gateway Console

API GW → wa-lab-rds-api 선택 : 리소스 → 메서드 요청 정보 확인 : 권한 부여 NONE

왼쪽 메뉴 ‘권한 부여자’ → ‘권한 부여자 생성’ : 이름(walab-authorizer), 유형(cognito), Cognito 사용자 풀, 토큰 소스(Authorization)    



26

리소스 → GET → 메서드 요청 편집 : (새창) 권한 부여(walab-authorizer) → 저장  



27

상단 API 배포 → 스테이지(Dev), 설명(WA Lab) ⇒ 배포   



28

배포 완료 후 리소스에서 GET 하단에 권한 부여 부분 확인  



29

Add Authorization header in CloudFront

설명 : 기본적으로 CloudFront는 엣지 로케이션에서 객체를 캐싱할 때 헤더를 고려하지 않습니다. 이제 API에 액세스하려면 요청에 유효한 ID 토큰이 있는 Authorization 헤더가 있어야 합니다. 따라서 헤더를 API 게이트웨이로 전달하도록 CloudFront를 구성합니다

CloudFront → 동작(편집) : 헤더 추가(다음 헤더 추가 - Authorization 선택) → 변경 사항 저장   



30

CloudFront → 무효화 : /*'   



31

Cognito 사용자 Sign up : CF output에 CognitoSignupURL 클릭 → 아래 Sign up 클릭 ⇒ 기입한 이메일로 확인



32

Cognito 에 사용자 추가 확인  



33

Generate an ID Token and send a request with ID Token

Cloud9 에서 먼저 그냥 요청 시도

# CloudFrontEndpoint 시도

CloudFrontEndpoint='https://d3ua9kogvj5qwi.cloudfront.net/?id=1'

python sendRequest.py $CloudFrontEndpoint   



34

용자 이름과 비밀번호, Cognito 사용자 풀 ID, 앱 클라이언트 ID 및 앱 비밀번호를 사용하여 ID 토큰을 생성해 보겠습니다.  

Cognito에 가입할 때 앱 클라이언트 비밀번호를 기록해 두었습니다 . 사용자 풀 ID, 앱 클라이언트 ID 등 기타 필수 값은 현재 cloudformation 스택의 출력 섹션 에서 확인할 수 있습니다.  

app_client_secret 확인 : Cognito → 선택 → 앱 통합 : 하단 ‘앱 클라이언트 이름’ 선택  



35

클라이언트 보안키 표시 클릭 후 아래 출력 내용 복사 후 사용  



36

# ID 토큰 생성

# python getIDtoken.py <username> <user_password> <user_pool_id> <app_client_id> <app_client_secret>

python getIDtoken.py gasida.seo@gmail.com 'P@ssw0rd' us-east-1_Vllj1OLBs 2crjkv50dm3j9d08r4vj3p90u8 1nl44osm5q6rom9ivcfj3jee1aed5nn9nfbig716i9n8lq0n5j05

Getting your ID token that will be expired in 60 minutes...

 Current time: 16/09/2023 20:20:19

/usr/local/lib/python3.6/site-packages/boto3/compat.py:88: PythonDeprecationWarning: Boto3 will no longer support Python 3.6 starting May 30, 2022. To continue receiving service updates, bug fixes, and security updates please upgrade to Python 3.7 or later. More information can be found here: https://aws.amazon.com/blogs/developer/python-support-policy-updates-for-aws-sdks-and-tools/

  warnings.warn(warning, PythonDeprecationWarning)

 ID token: NJ2UqKKtmoTkUCiTnYG3atKIzJv42enQiUasfNvbN0l3Y79MkaRQxAX8xYRICtDxfprVYrnG16jhaUa2HOIHlZQk22QanbzfB7fPmTideu3w'    



37

위에서 생성한 ID 토큰으로 요청 보내서 확인 → CloudFront를 통해서 API에 액세스하려면 ID 토큰을 Authorization 헤더로 제공해야 합니다.  



38

python sendRequest.py $CloudFrontEndpoint $IDT    



39

삭제?

TEAR DOWN - 링크  

walab-cdn-waf-cognito 스택 삭제

aws-cloud9-walab-api-Cloud9-IDE… 스택 삭제

→ 위 2개 스택 삭제 완료 시 walab-api 스택 삭제

⇒ 30분이 지나도 삭제가 안될 경우 아래 잔여 리소스 수동 삭제



RDS 인스턴스 삭제 → RDS 서브넷 그룹 삭제


VPC에 NATGW 삭제 → VPC 람다 보안 그룹 삭제


CloudWatch 로그 그룹 삭제


S3 버킷 삭제


실습용 IAM User 삭제    




<2> Level 300: Autonomous Monitoring Of Cryptographic Activity With KMS : ECS 기반 App이 KMS 사용 활동 감사


시드니 리전




<3> Level 300: Autonomous Patching With EC2 Image Builder And Systems Manager : 블루/그린 배포 방식 AMI 자동 업데이트


시드니 리전  



<4> Level 300: IAM Permission Boundaries Delegating Role Creation : AWS Account 2개 필요, IAM 권한 경계 활용  



<5> Level 300: IAM Tag Based Access Control for EC2 : AWS Account 2개 필요, Tag 리소스 대상 관리 설정  



<6> Level 300: Incident Response Playbook with Jupyter - AWS IAM : 사고 발생 시 분석 실습, 주피터 사용  



<7> Level 300: Lambda Cross Account Using Bucket Policy : AWS Account 2개 필요, 2개 계정 간 IAM Role과 IAM 정책 실습  



<8> Level 300: Lambda Cross Account IAM Role Assumption : AWS Account 2개 필요, 2개 계정 간 IAM Role 실습  



<9> Level 300: VPC Flow Logs Analysis Dashboard : AWS Account 2개 필요, VPC Flows 로그를 분석 Athena 및 시각화  





다음은 AWS 침투 테스트


https://brunch.co.kr/@topasvga/3451



주말 CloudNet  스터디 내용 참고하여  정리한 부분입니다.

https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863  

https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863  



감사합니다.

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari