서버 IP 숨기기 & 디도스 방어: AWS CloudFront로 방패막이 세우기

1주 전

AWS CloudFront 설정 시작하기

“오라클 클라우드 프리티어로 서버 잘 만들었는데, 누가 내 IP로 직접 공격(DDoS)하면 어떡하지?”

서버 운영하면서 가장 무서운 건 내 서버의 실제 IP(Origin IP)가 털리는 것이다. IP가 노출되면 해커들의 직접적인 타겟이 되고, 디도스 공격 한 방에 서버가 뻗어버릴 수 있다.

그래서 우리는 AWS CloudFront를 ‘방패’로 세워야 한다. CloudFront를 앞단에 두면, 외부에서는 AWS의 IP만 보이고 내 오라클 서버의 진짜 IP는 감춰진다. 해커가 때려도 맷집 좋은 AWS가 대신 맞아주는 셈이다.

이 설정의 진짜 목적:

  1. Origin IP 은폐: nslookup을 해봐도 AWS IP만 나온다.
  2. DDoS 방어: AWS Shield Standard가 기본적으로 적용되어 네트워크 공격을 막아준다.
  3. 글로벌 가속: 전 세계에 있는 CDN으 속도 향상은 덤이다.

여기서 드는 합리적인 의문. “CDN이면 무료 플랜이 강력한 Cloudflare를 쓰면 되는 거 아닌가?”

이 질문에 대한 답변은 내가 지난번에 작성한 “셀프호스팅의 완성, AWS CloudFront 신규 요금제로 속도와 디도스 방어 종결” 글에 자세히 답변되어 있다.

속도와 보안, 그리고 관리의 편의성까지 잡는 CloudFront 설정을 시작해보자.

CloudFront 콘솔 접속하기

AWS Management Console에 로그인한다.

  1. 상단 검색창에 CloudFront를 입력한다.
  2. 서비스 목록에 뜨는 CloudFront를 클릭해서 들어간다.
AWS 콘솔 상단 검색창에 CloudFront를 검색하고 선택하는 화면

배포 생성 시작 (Create Distribution)

CloudFront 대시보드에서 방패 생성 작업을 시작한다.

요금제 선택

  1. 우측 상단에 보이는 주황색 버튼, [배포 생성(Create distribution)] 을 클릭한다.
  2. 요금제를 선택하여야 한다. 지난 번에 포스트한 글에서 설명한듯이 Free 요금제를 선택하면 된다.
Choose a plan

배포 이름(Distribution name) 설정

  1. 앞으로 화면에 보일 배포 이름을 만들어주자.
  2. Domain은 AWS Route53에서 관리 중인 도메인을 연결한다면 입력해주자. 다만, optional으로 되어 있는 것은 나중에 입력해도 되는 것이니 그냥 넘어가는 편이 낫다.
Get Started

원본 도메인(Origin) 설정 – 여기가 우리가 숨길 곳!

여기에 입력하는 정보가 바로 외부로부터 철저히 숨겨야 할 내 진짜 서버 정보다.

원본 도메인(Custom origin) 입력칸에 오라클 클라우드(Nginx) 서버의 도메인 주소를 입력한다.

  • 누구도 예측할 수 없게끔 어려운 서브도메인으로 지정해주자. (예: VSM0ptlx.domain.com)
  • 주의! Public IP 주소는 입력이 불가능하다 (예: 123.45.67.89)
Origin type

나는 오라클 클라우드에서 제공하고 있으므로 Origin typeOther를, Custome origin에는 오라클 클라우드 공인IP를 바라보고 있는 아무도 모를 서브도메인을 설정해준다.

서브도메인 설정, 이 부분이 왜 필요한지 부연 설명이 조금 더 필요할 것 같다. 자, 설정이 완료되면 앞으로의 접속 흐름은 이렇게 작동한다.

blog.domain.com 요청 → AWS가 원본인 sub.domain.com(서버의 공인IP)에 정보를 요청 → 서버 응답 → AWS가 받은 내용을 blog.domain.com에 반환

이 과정에서 sub.domain.com은 AWS와 나만 알고 있는 비밀스러운 URL이 되는 것이다. 따라서 sub.domain.com이 내 서버를 제대로 찾아갈 수 있도록, DNS 관리 콘솔에서 실제 서버의 공인 IP와 연결해주는 작업을 잊지 말아야 한다.

나는 Cloudflare에서 DNS를 관리하고 있으므로 다음과 같이 설정했다. 서브도메인(Origin)은 항상 서버의 공인 IP를 가리키고 있어야 한다는 사실을 명심하자.

서버 IP 숨기기 & 디도스 방어: AWS CloudFront로 방패막이 세우기

나머지 설정은 기본 설정으로 하면 된다. 다만, cache 설정은 새로운 만드는 블로그가 안정될 때까지는 cache를 사용하지 않는 것이 나을 것 같아서, 나는 cache를 사용하지 않는 설정(CachingDisabled)으로 했다.

또한, 원본 요청 정책에서 AllViewer을 반드시 설정해주자. 여러 경로를 오가는 사이에 최초의 도메인 주소(Host Header)를 유지해주기 위함이다.

서버 IP 숨기기 & 디도스 방어: AWS CloudFront로 방패막이 세우기

배포 생성

나머지는 나중에도 바꿀 수 있으니 기본값으로 설정하자. 그렇게 설정을 완료하면 배포가 시작된다.

서버 IP 숨기기 & 디도스 방어: AWS CloudFront로 방패막이 세우기

배포 완료 및 접근 확인 배포가 끝나면 dya3z3...cloudfront.net 형태의 배포 도메인이 생성된다. 이제 외부에서는 오라클 서버로 직접 들어오는 대신, 이 CloudFront 주소를 통해서만 데이터에 접근하게 된다.

참고로 캡처 화면에 보이는 ‘대체 도메인(Alternate Domain Name)’ 설정은 매우 중요하다. CloudFront는 여기에 등록되지 않은 도메인(Host Header)으로 요청이 들어오면 접속을 거부한다. 즉, 아무 도메인이나 CNAME만 건다고 연결되는 것이 아니라, 여기서 허용해준 도메인만 정식으로 처리한다는 뜻이다.

진짜 내 IP가 숨겨졌는지 확인해보자

IP 은폐 확인: 배포 도메인을 통해 서버의 공인IP는 숨겨졌다. 진짜인지 확인하려면 DNS 검사 도구를 활용해서 배포 도메인이 가르키는 IP를 확인해보자. 공인IP가 당연히 나오지 않을 것이다.

글로벌 가속 확인: 게다가 배포 도메인의 DNS를 요청하는 리전을 확인하여 가장 가까운 엣지 서버(Edge Server) 의 IP를 선별해서 알려준다. 즉, 미국에서 배포 도메인에 접근하면 미국의 엣지 서버 IP를 제공하여 빠른 응답 속도를 제공해 준다.

내 도메인 연결하기 (Alternate Domain Name)

내 도메인(예: blog.example.com)을 CloudFront에 연결하려면 대체 도메인(Alternate domain name) 설정을 해야 한다.

AWS Certificate Manager 접속

우선 내 도메인에 대한 인증서를 발급받아서 https로 접근할 수 있도록 설정하여야 한다. Cloudfront 화면에서도 인증서를 받을 수 있지만, 루트 도메인과 와일드카드 서드 도메인에 대한 인증서를 동시에 받기 위해서는 ACM에서 직접 발급받는 것이 낫다.

  • 대체도메인 아래의 Add domain를 눌러서 아래 내용을 진행해보자
    • Configure domains 단계에서 도메인을 입력하고 다음 단계로 진행하자
    • 다음 단계인 Get TLS certificate 화면 아래에 Create certificate in ACM 를 클릭하여 바로 넘어 갈수 있다.

인증서 요청과 DNS 검증

서버 IP 숨기기 & 디도스 방어: AWS CloudFront로 방패막이 세우기

도메인 추가와 DNS 검증 ACM 설정 화면에서 다음 두 가지 도메인을 모두 입력해준다.

  1. 루트 도메인: domain.com
  2. 와일드카드: *.domain.com (모든 서브도메인 포괄)

검증 방법은 DNS 검증을 선택한다. 이는 ACM이 제공하는 CNAME 이름(Name)값(Value)을 복사하여, 내가 이용 중인 DNS 관리 서비스에 레코드로 등록하는 방식이다. 이 CNAME 값이 확인되는 즉시 인증서가 발급된다.

대체 도메인 설정

이제 인증서가 발급되었다. 다시 Add domain를 클릭하여 유저가 접속할 도메인을 추가해주자. 이번에는 이미 만들어진 인증서가 불러와 질 것이다.

대체 도메인의 DNS 설정

이제 모든 준비는 끝났다. 내 도메인과 AWS가 만들어준 배포 도메인을 이어주는 마지막 다리를 놓을 차례다.

DNS 관리 서비스(Cloudflare, Route53 등)에 접속하여 아래와 같이 CNAME 레코드를 추가해주자.

  • Type: CNAME
  • Name (Host): 사용할 서브도메인 (예: blog 또는 www)
  • Target (Value): 아까 복사해둔 CloudFront 배포 도메인 (예: dya3z3...cloudfront.net)
  • TTL: 자동(Auto) 또는 기본값
서버 IP 숨기기 & 디도스 방어: AWS CloudFront로 방패막이 세우기

이렇게 설정하고 저장하면, 이제 도메인으로 접속하는 모든 트래픽은 AWS CloudFront라는 튼튼한 방패를 거쳐 내 서버로 안전하게 들어오게 된다.

루트 도메인 사용 시 주의사항: CNAME Flattening과 속도 저하

일반적으로 goodbyte.me와 같은 루트 도메인(Root Domain)은 CNAME 레코드로 설정할 수 없다. 이를 해결하기 위해 Cloudflare 같은 DNS 서비스는 CNAME Flattening이라는 기술을 사용한다. 이는 DNS 서버가 CNAME 뒤에 연결된 IP를 대신 조회하여 사용자에게 A 레코드(IP)처럼 반환해주는 방식이다.

편리한 기술이지만, AWS CloudFront와 함께 사용할 때는 심각한 속도 저하를 유발할 수 있다. 이유는 다음과 같다.

1. 엣지 서버 배정의 원리 CloudFront는 DNS 쿼리를 요청한 클라이언트의 위치를 파악하여 가장 가까운 엣지 서버(Edge Server)를 배정한다.

2. Flattening의 부작용 (위치 왜곡) 루트 도메인을 사용하여 CNAME Flattening이 작동하면, 실제 사용자가 아닌 DNS 서비스 제공자(Cloudflare 등)의 서버가 AWS에 IP를 요청하게 된다. 만약 DNS 서버가 해외(예: 미국)에 있다면, AWS는 요청자가 미국에 있다고 판단하여 미국 엣지 서버의 IP를 반환한다.

3. 결과: 해외 원정 트래픽 발생 결국 한국에 있는 사용자는 바로 옆의 서울 리전(ICN)을 놔두고, 태평양 건너 미국 서버와 통신하게 된다. 이는 불필요한 레이턴시(지연) 증가로 이어진다.

✅ 해결책: www 서브도메인 활용 이 문제를 피하는 가장 정석적인 방법은 루트 도메인 대신 www.goodbyte.me와 같은 서브도메인을 메인으로 사용하는 것이다.

서브도메인은 표준 CNAME 방식이 적용되므로, 사용자의 PC가 직접 CloudFront 주소를 해석(Resolve)한다. 덕분에 AWS는 사용자의 실제 위치(한국)를 정확히 인식하고 서울 엣지 서버 IP를 제공할 수 있다.

참고: 굳이 루트 도메인을 고집하고 싶다면, 스크립트를 짜서 주기적으로 서울 엣지 IP를 찾아 DNS에 하드코딩하는 방법도 있다. 하지만 정신 건강을 위해 ‘www 사용’을 강력히 추천한다.”

관련 글