서버 보안 정책 수립하기

정 승 연·2024년 6월 26일
1

AS-IS

  • 현재 모든 서버 요소들이 0.0.0.0/0 으로 열려있고 구조화되어있지 않다.

TO-BE

  • 서버에 들어오는 요청을 제한하여 DDos 와 같은 공격을 막는다.

기존 계획

  1. 현재 프론트는 S3 에 올려둔 정적 사이트를 원본으로하여 Cloud Front 에 연결해두었다. 그래서 그 페이지에서 오는 요청만 서버에 접속 할 수 있도록 제한한다.
  2. 이를 위해 aaa.aaa.ai 도메인을 alb 와 연결하고 alb 의 인바운드 규칙을 현재 사용하고 있는 Cloud Front 접두사 목록으로 제한한다.
    1. Cloud Front 접두사 목록이란. AWS 에서 관리하는 Cloud Front IP 주소 목록이며 Cloud Front IP 주소는 특정할 수 없고 주기적으로 바뀌기 때문에 AWS 에서 제공하는 접두사 목록(prefix) 를 사용한다.
    2. 이를 통해 ALB로 들어오는 요청을 프론트로 제한한다.

발생한 문제점

하지만 ALB의 보안그룹 인바운드 규칙을 cloud front 로 제한했을 때 계속 타임아웃이 나는 등 인바운드 규칙이 막혔다. 그래서 AWS Supports 에 사례를 생성해 여쭤봤다. 회신 받은 내용은 다음과 같다.

  1. S3+CF으로 배포 된 프론트에서 ALB 로 요청을 보낸다고 해도 이게 CF 에서 요청이 가는게 아니라 브라우저 (= 사용자가 접속한 ip) 에서 요청을 보내는거다. 따라서 보안그룹 인바운드 규칙을 CF 으로 제한하면 안되는게 당연하다. Cloud Front 를 거쳐서 오는게 아니니까!
  2. 이렇게 인바운드 규칙을 CF로 제한하고 싶다면 도메인과 ALB 사이에 CF를 둘 수 있다.
    1. 기존 [클라이언트 → 도메인 → ALB] 의 구성에서 [클라이언트 → 도메인 → CF → ALB] 으로 변경하는 것이다.
  3. 하지만 이렇게 도메인에 CF를 연동한다면 도메인을 알고있는 모든 사용자가 우리 서버에 접속 할 수 있게된다. 그렇다면 요청 송/수신 사이에 사용자 정의 헤더 검증을 추가해 요청을 제한할 수 있다. (요청하는 CF와 요청받는 ALB의 리스너 규칙에 사용자 정의 헤더를 추가하여)
    1. 그래서 프론트의 CF에 사용자 헤더를 추가하고 ALB의 리스너 규칙에 사용자 헤더 검증 로직을 추가했다. 이렇게 했더니 CORS 에러가 났다.

      1. 이렇게 하면 안된다! 먼저, 웹 페이지에서 aaa.aaa.ai 에 요청을 보냈을 때 preflight 로 보내는데 그것에 대해 403 이 뜬다. CF를 통해 전달된 요청이 아닌 이전처럼 사용자가 접속한 ip 에서 ALB 로 직접 요청된 것으로 ALB 에 보안 헤더가 존재하지 않는다.

      2. [프론트 CF + 도메인 + 백엔드 CF + alb] + 헤더 검증 을 해도 요청은 End User에서 오는 것이고 결국 프론트 cf 에 설정해둔 사용자 정의 헤더가 붙여지지 않는다. 그대로 End User이다. 그래서 헤더가 일치하지 않고, Origin 헤더가 없어 CORS 발생? 근데 또 이게 Cloud Front 에서 발생한 CORS 가 아니었기 때문에 확인할 수 없다.. 정말 이게 가능하게 하려면 …………… SAA의 조언이 필요하다는 AWS Supports 의 의견이 있었다. 구조적으로 옳지 않다는 의견을 2번이나 받았다 ..

      3. End User에 대한 이해가 부족했다 …. 브라우저의 동작 과정 !!!!!!!

      =================================
      [Summary]

      문의 사항 : CloudFront를 통해 Origin에 요청 전달시 CORS 에러 발생으로 이에 대한 분석

      분석 사항

      1. CORS Error는 CORS Preflight 요청시 Origin(ALB)에서 403 응답 전달
      2. CORS Preflight 요청은 CloudFront를 통해 전달된 요청이 아닌 End User -> ALB로 직접 요청이 전달된 건으로 ALB에 설정된 보안 헤더가 존재하지 않아 이에 대해 403 응답 수신

      안내 사항

      1. Origin(ALB)에서 403 Access Denied가 아닌 200 OK와 함께 적절한 CORS Preflight 응답 헤더가 포함되어 있어야 CORS 요청이 정상적으로 처리 될 수 있습니다
      2. 원하는 CORS 요청 시나리오가 "현재 구성된 아키텍쳐"에서 지원 할 수 없으므로 이에 대해 전문적인 도움 받을 수 있도록 담당 세일즈를 통해 SA의 도움 받으실것을 권고 드렸습니다.
      3. 따라서 ?????
  4. 그래서 CORS 처리로 막을 수 있을 것이라 생각했다. CORS는 브라우저에서 요청의 원본을 비교하기위해 서버에 preflight 를 날리는 것으로 브라우저에서 보내는 요청의 헤더값에 지정된 값을 넣어서 보낸다. 이러한 헤더값을 서버에서 검증해서 요청에 대한 응답을 보낸다.
    1. 기존에는 CORS를 뚫는것에 집중헀지 CORS를 활용할 생각을 못했다.
    2. 그래서 프론트가 배포한 CDN 주소만 서버에서 CORS를 허용하여 나머지 요청을 제한하려 했다.
      1. 하지만 브라우저에서 aaa.aaa.ai 를 그냥 접속 했을 때 요청이 허가됐다.

결론

  1. 결론적으로 CF + ALB 를 이용하여 서버에 오는 요청을 프론트로만 제한하기는 힘들다.
    1. 프론트에 띄워져있다 하더라도 End User 는 접속한 ip 이다?
    2. referer 헤더 검증을 통해 가능했을까?
    3. 그래서 네이버의 메인 페이지를 뜯어보았다. 개발자 모드를 이용해 네이버 api 도메인 주소를 알 수 있었고, 이것을 그냥 접속했을 때 요청 값을 볼 수 있었다. 따라서 다른 회사들도 api 도메인 주소에 그냥 접속할 수 있음을 알았다
      1. 근데 ip주소는 접속할 수 없었음. 방화벽으로 막아둔걸까?
  2. [프론트 → 도메인 → ALB] 의 요청 로직을 갖고 ALB 앞에 WAF를 붙인다.
    1. 국가 기반의 IP 차단, 속도 기반의 IP 차단 , Http Header 기반의 요청 차단 , DDoS 공격 형태의 Flooding 차단, PHP 애플리케이션 공격 차단 등 을 적용했다.
    2. AWS 에서 기본으로 제공하는 Rule 도 있고 Market space 에서 벤더 사의 솔루션을 사용할 수도 있다.
  3. CORS 처리를 통해서도 막을수는 없었다.
  4. 이에 따라 서버의 중요한 요소 (DB,EC2) 등을 private subnet에 배치해 보안을 강화하고 서버에 들어오는 요청을 제한한다.

회고

  1. End User에 대한 이해가 부족했다 ….
    1. 브라우저와 서버간의 요청 로직에 대한 이해가 부족했다. CF에 띄워두면 프론트의 요청이 CF에서 오는 줄 알았는데 CF는 S3를 원본으로 하여 CDN 을 띄워준 것이다. 전혀 관련이 없다. CF를 거쳐야 CF에서 오는 요청이 된다.
  2. WAF에 대해 더 일찍 찾아봤다면 일찍부터 적용했을텐데

WAF 관련 레퍼런스

https://velog.io/@woodonggyu/Getting-started-with-AWS-WAF
https://sh-t.tistory.com/98
https://omoknooni.tistory.com/57

0개의 댓글