waf를 만들기 위해서는 웹 acl을 생성해야한다.
Create web ACL을 클릭한다.
사용할 이름을 test-waf라고 지정한다.
사용할 리소스는 alb로 선택하고 리전은 꼭 사용할 alb가 있는 리전을 선택해야한다.
그리고 next를 누른다.
Add rules를 누르고 managed rule groups를 클릭한다.
AWS managed rule groups를 클릭하여
Anonymous IP list와 Admin protection 기능을 선택해준다.
그 외의 세부적인 기능은 사용할 서비스에 부합하게 선책해주면 된다.
우선 외부의 비정상 ip를 필터링하기 위해 Anonymous IP list와 Admin protection를
선택해 주었다.
그리고 add rules를 클릭한다.
next를 누른다.
규칙을 확인하고 다시 next를 누른다.
cloudwatch에 구성되는 항목을 선택을 확인한 다음 next를 누른다.
최종적으로 확인한 다음 생성 버튼을 클릭한다.
생성된 waf를 확인할 수 있다.
해당 waf는 eks를 사용하기위해 만든 alb에 들어오는 비정상 ip와 애플리케이션에 대한
악의적인 접근권한 취득을 막아준다.
waf에 들어오는 접속로그를 firehose로 받아 s3에 저장하고자 한다.
그 이유는 접속로그를 저장하여 추후 발생할 수 있는 보안사고가 발생했을 때
그동안 접속로그를 분석하여 예방할 수 있기 때문이다.
그리고 접속로그가 비정상적으로 증가하거나 비정상 로그가 발생했을 때 cloudwatch를 사용하여 경보를 발생시킨다.
특정 ip를 막아서 못들어오게 하기도 한다.
Delivery streams로 가서 Create delivery stream를 클릭한다.
이름은 반드시 "aws-waf-logs-"로 시작해야 한다.
안그러면 waf에서 로깅 enable을 할 때
리소스가 인식되지 않아 보이지 않는다.
소스(출발지)는 Direct Put을 선택하여 직접 넣기로 선택을 하고
데스티네이션(목적지)는 S3로 지정한다.
목적지 설정으로 가서 S3버킷을 기존에 만들어 놓은(만일 없다면 지금 만들고오자.)
S3버킷을 선택한다.
그리고 생성 버튼을 클릭한다.
Kinesis Data Firehose 대상을 사용하여 AWS WAF 로그를 활성화하는 계정에는 다음 권한이 있어야 한다.
출처:https://aws.amazon.com/ko/premiumsupport/knowledge-center/waf-turn-on-logging/
해당 권한들은 Step Function에서 지정하여
권한을 부여해줄 수 있다.
그래서 먼저 Step Function으로 간다음
상태머신을 클릭한다.
상태머신 생성을 클릭한다.
시각적으로 워크플로 설계를 선택하고
스트리밍 데이터에 유리한 Express 유형을 선택하고 다음을 클릭한다.
검색창에 순서대로 권한을 입력을 한 다음
하나하나 추가해준다.
최종적으로 다음과 같이 워크플로를 추가하고
다음버튼을 누른다.
선택사항을 검토 후 다음 버튼을 누른다.
이름은 MyStateMachine라고 하고
권한을 새 역할 생성으로 선택하고
로깅을 다음과 같이 생성한다.
최종 검토 후 상태 머신 생성을 클릭한다.
생성된것을 확인할 수 있다.
다시 WAF로 돌아와서 web ACLs를 클릭한다.
test-waf를 누른다.
Logging and metrics를 클릭한다.
enable
-> Kinesis Data Firehose stream->
-> Kinesis Data Firehose delivery stream상태바
-> aws-waf-logs-123을 선택한다.
save를 클릭한다.
그리고 시간이 좀 지난 뒤에(바로 안만들어 진다.)
s3로 가서 로그가 저장되는것을 확인할 수 있다.
S3 > 버킷 > 작업 > ACL을 사용하여 퍼블릭으로 설정
을 클릭한다.
퍼블릭으로 설정을 클릭한다.
그리고 다시 버킷 내부로 가서 로그파일을 하나를 클릭한다.
객체 URL을 클릭한다.
해당 파일을 텍스트 파일로 실행한다.
엄청난 양의 접속로그를 확인할 수 있다.
다음 시간에는 경보를 사용하여 에러 값이나 입력 바이트가
임계값보다 높아지면 경보를 올리게 설정하고
특정 ip만 접속하지 못하도록 설정할 것 이다.
WAF에서 ip set으로 가서 Create IP set을 클릭한다.
waf로 가서 eks를 내 핸드폰의 ip를 접속을 차단한다.
내 핸드폰의 ip는 waf로 가서 접속 로그를 확인하여 찾아내었다.
ip address에 추가를 한 다음에 Create IP set을 클릭한다.
다시 waf의 web ACLs로 가서 생성한 test-waf를 클릭한다.
Rules를 클릭한다.
Add rules을 클릭하여 my own rules를 클릭한다.
IP set을 선택하고 규칙의 이름을 my-phone으로 지정한다.
IP set에서 방금 만든 IP set을 지정한 다음
Block으로 선택한다.
선택 후 Add rules를 클릭한다.
그리고 save를 눌러서 완성한다.
이제 내 핸드폰으로 접속하면 403 오류가 발생하는 것을 확인할 수 있다.
waf에 들어오는 로그의 종류나 양에 따라서 경보가 발생하도록 설정할 계획이다.
cloudwatch로 가서 경보->모든 경보로 가서 경보 생성을 클릭한다.
지표 선택을 클릭한다.
WAFV2를 클릭하고 Region, Rule, WebACL를 클릭한다.
Rule은 ALL, 지표이름은 BlockedRequests라는 지표를 선택한다.
조건은 정적, 보다 큼 이라고 설정하고 임계값은 임의로 20이라고 잡는다.
임계값 20을 1분이라는 기간동안 계속 오게 되면 알람이 가도록 하기 위해서
기간을 1분으로 잡는다.
경보 트리거는 경보상태로 선택하고
새 주제 생성을 클릭한다.
새 주제의 이름은 WAF_BLOCK_ALRAM라고 한 다음
알람 메세지를 보낼 이메일을 적는다.
그리고 주제 생성을 클릭한다.
알림이 등록 되었으면 다음을 누른다.
경보의 이름은 Waf is under the attack by blocked ip
라고 하고 설명은 똑같이 해주고 다음 버튼을 누른다.
최종 검토를 진행한 다음 경보생성을 클릭한다.
알람을 받기 전에 이메일 인증을 해줘야 한다.
이메일로 온 컨펌메일을 받는다.
Confirm subscribe를 눌러준다.
구독 확인라는 창과 동시에
이제 알람 메세지가 해당 이메일로 전송된다.
DDOS -> waf로 대응,
shelid advance는 비싸기 때문에
waf를 사용하여 대응을 한다.
생성이 완료되었으면 내 핸드폰으로 접속을 계속 한다.
내 핸드폰의 ip가 block된 ip라고 가정한다.
테스트를 위해 Rulse에서 my-phone을 지워준다.
시나리오는
cloudwatch로 모니터링 하다가 allow ip의 접속로그가 비정상적으로 많을 시 경보가 발생하고, 해당 ip를 ip set으로 등록한다음 web ACLs로 block을 해준다.
라는 시나리오 이다.
그래서 내 핸드폰으로 해당 로드밸런서에 접속해서 새로고침을 계속 누른다.
그래서 AllowedRequests에 지속적으로 접속 로그가 증가하는것을 확인할 수 있다.
그래서 waf에서 해당 ip를 찾아낸다.
경보를 편집하여 지표 이름을 AllowedRequests로 바꿔준다.
이제 2분간 내 핸드폰에서 계속 새로고침을 누를것 이다.
경보상태가 되면서 내가 경보에서 지정한 이메일 주소로 알람 메세지가 갈 것 이다.
지정한 알람 명으로 알람 메세지가 오는것을 확인할 수 있다.
이제 해당 ip를 대상으로 ip set을 만들어 특정 아이피를 등록해준다.
waf에서 ip set으로 가서 Create IP set을 눌러준다.
이름을 my-phone라고 한다음 해당 ip를 IP address에 붙혀준다음
Create IP set을 눌러준다.
만들어 진것을 확인할 수 있다.
web ACLs로 다시 가서 test-waf를 눌러준다.
Rules를 눌러준다.
Add rules를 눌러준다음 Add my own rules and rule groups를 눌러준다.
IP set을 눌러준다음 이름을 my-phone이라고 지정한 다음
IP set을 my-phone로 지정해준다.
Action에서 Block을 선택 하여 해당 ip를 block해준다.
그리고 Add rule을 클릭한다.
save를 눌러준다.
다시 핸드폰으로 로드밸런서에 접속을 시도한다.
403 에러가 발생하는 것을 확인할 수 있다.
계속 접속을 시도했을때,
로그에서는 block이 된 로그가 cloudwatch에 출력되는 그래프를 확인할 수 있다.
사실 자동화를 하여서 임계값이 올라가면 EventBridge를 사용하여
cloudwatch를 연동시켜서 자동으로 ip를 차단시키는 방법을 찾고 싶었으나
guardduty와 pod polish 등 연결 시킬것들이 아직 많이 남아서 자동화까지는 못했다.