Site icon 지락문화예술공작단

AWS 클라우드 에서 지리적 IP(GeoIP) 차단 관리 방법

AWS 클라우드 에서 지리적 IP(GeoIP) 차단 관리 방법

글로벌 게임 서비스를 하다 보면, 여러 가지 이유로 특정 국가에 대한 IP를 차단하거나 허용해야 하는 요구 사항이 흔히 발생합니다. 대개 이를 위해서 별도의 상용 방화벽을 사용하여 지리적 IP 블록 기능을 활용하거나, 직접 방화벽을 구축하고 지리적 IP 데이터를 인터넷을 통해 찾아서 직접 관리하는 방법을 사용하기도 합니다.

이 글에서는 실제로 일어나는 서비스 시나리오에 기반해서 현재 AWS가 제공하는 기능을 최대한 활용하여 이러한 요구 사항을 충족하는 과정을 단계별로 살펴 보고자 합니다.

1. 요구 사항
A사는 전문 게임 퍼블리셔 회사이고, B 게임 개발사가 만든 X게임을 글로벌 서비스로 오픈하려고 합니다. 퍼블리싱 계약 상 중국과 일본에서 접근은 차단해야 하지만, 일부 IP는 관리 목적을 위해 접근을 허용해야 하게 되었습니다.

그 외에도 현실적인 몇 가지 요구 사항을 추가해 본다면,

  1. 게임 서비스는 로그인 서버와 게임 서버로 구분되어 있다.
  2. 로그인 서비스는 REST 방식의 HTTPS 서버이며, 게임 서버는 TCP 이다.
  3. 게임 서버는 특정 IP로 바로 접근해야 한다.
  4. 게임 클라이언트 변경은 어렵다. 운영 체제(OS) 에 대한 접근은 퍼블리싱 회사에 대해 엄격하게 제한된다. 따라서 가능한 인프라 아키텍처로 문제를 해결해야 한다.
  5. 가능하다면 장기적으로 DDoS방어력을 갖추기 바란다.

아마 인프라 보안 관련 기술 경험이 있는 분이라면 몇 가지 대안을 생각했을 것입니다. 예를 들어, 방화벽 레이어를 서버군 앞에 둔다던가 직접 HAProxy 같은 리버스 프록시를 설정하는 해 볼 수 있을 것입니다. 그렇다면, AWS 클라우드에서 이러한 지리적 IP를 쉽게 허용 및 차단하는 방법은 무엇이 있을까요?

이를 위해, AWS에서는 자체 클라우드 서비스와 파트너들이 제공하는 다양한 파트너 솔루션을 제공합니다.  이 중에서 어떤 것이 가장 간단한 것인지 찾기 위해 팀이 모였다면, 간단한 브레인스토밍을 진행할 수 있습니다.

2. 다양한 접근 방법
일반적인 해결 방법과 AWS 안에서 가능한 모든 방법을 테이블에 올려 놓는 다고 하면, 아래와 같은 방법을 고려해 볼 수 있습니다.

  1. 모바일 클라이언트 게임에서 지역을 알아내서 접근 자체를 막는 방법
  2. 상용 방화벽 레이어를 게임 서버와 로그인 서버에 구축하는 방법
  3. HA 프록시 등으로 프록시 서버 레이어를 구성해서 두는 방법
  4. 운영 체제 내 방화벽 기능을 이용하는 방법
  5. Amazon Route 53의 지리적 IP 라우팅 기능을 이용하는 방법
  6. Amazon CloudFront 및 WAF(Web Application Firewall)을 사용하는 방법

요구 사항 중 가장 큰 제약 조건은 바로 2번 요구 사항입니다. 게임 서버와 로그인 서버는 각기 다른 방식으로 서버와 통신하기 때문에, 가장 쉽게 인프라 아키텍처로 해결할 수 있는 방법은 위에서 2, 3번입니다.

그렇다면 2번과 3번은 각기 어떤 단점이 있을까요? 공통적으로 TCP 접근을 위해 외부에 공개(public) IP를 오픈하고, 게임 서버와 연결해 줄 수 있는 NAT 기능까지 지원하는지 살펴 봐야 합니다. 뿐만 아니라, 지리적 IP 차단 및 관리가 용이한지도 살펴봐야 할 것이다.

따른 문제점은 상당한 비용이 발생한다는 점입니다. 지리적 IP 정보를 인터넷에서 받아서 직접 리눅스 서버 등으로 방화벽 레이어를 구축하는 경우, 지리적 IP 정보는 지역 수준의 구분은 인터넷에서 무료로 구할 수 있습니다. 하지만, 이를 이용해서 iptable과 같은 기능을 이용해서 직접 구현해야 합니다. 이런 것을 직접 구성하고 관리하는 것은 어렵습니다.

위의 그림은 이러한 경우의 아키텍처입니다. 게임 서버를 위한 지리적 IP 차단 레이어는 상용이든 직접 구현하든 고정 IP를 지원해야 하고, 방화벽 규칙을 위한 레이어가 존재해야 합니다. 여기서는 서브넷으로 상호 영역을 구분하였습니다.

요구 사항 3번 조건이 너무 강하다면, 게임 서버 앞단에는 직접 구현된 NAT 레이어와 방화벽 레이어가 존재해야 합니다. 비용 최적화를 위해서는 가능한 두 NAT 레이어를 분리해야 하는데, 그 이유는 AWS에서 고정 IP를 인스턴스에 부여하는 갯수가 제한이 있기 때문입니다.

특히, 요구 사항 4번 조건처럼 게임 개발사인 B사가 인프라 관리 요건에 맞게 클라이언트의 코드를 수정하는 것이 어려운 경우가 많습니다. 모바일 게임 클라이언트 코드에서 해결하는 방안은 쉽지 않습니다. 만약 개발사가 동의 한다면, 로그인 전에 특정 지리적 IP 정보를 알려주는 서버를 만들어서 로그인 전에 체크를 하는 방법은 있습니다.

4번 해결 방안은 퍼블리셔와 개발사 간의 계약에 의해 결정되므로 경우에 따라 가능한 해결책일 수 있습니다. 하지만, 게임 서버 안에 직접 운영 체제 방화벽으로 방어를 하는 것으로 일괄 적으로 관리할 수 있는 방안을 찾아야 한다는 단점이 있습니다.

3. AWS 클라우드에서 해법 찾기
자 이제 AWS 서비스를 통한 해법을 보다 깊게 살펴보겠습니다. 먼저 지리적 IP 처리 기능으로 활용할 수 있는 서비스는 Amazon Route53의 지리적 라우팅 기능과 Amazon CloudFront에 존재하는 AWS WAF (웹 애플리케이션 방화벽) 기능입니다. 앞의 요구 사항에 적합한 구현을 위해서는 각 서비스 기능에 대해 좀 더 깊이 있게 이해를 해야 합니다.

Rout53의 지리적 라우팅 기능은 클라이언트가 접속한 IP로 부터 지리적 위치를 알아내고 이를 특정한 AWS서비스 리소스로 라우팅해 주는 기능입니다.

위의 그림은 Route 53에서 지리적 라우팅의 설정 모습입니다. A 레코드 셋 설정을 통해 지리적으로 들어오는 IP를 ELB, S3, CloudFront의 엔드포인트 등으로 연결해 주게 됩니다.

로그인 서버 앞에서 지리적 IP콘트롤을 가장 간단하게 구성할 수 있는 것은 Route53과 CloudFront를 이용한 지리적 IP 제어 아키텍처입니다.

Amazon WAF는 현재 지리적 IP 차단 기능을 제공하지 않습니다. 따라서, 요구 사항을 해결하기 위해서는 앞단에서 먼저 지리적 위치를 어떻게든 알아내는 것이 필요합니다.  위 그림에서는 CloudFront를 2개 배포하고, 막으려는 대상 지리적 위치를 1번 CloudFront로 보냅니다. WAF의 경우는 규칙(Rule)의 순서에 따라 우선순위가 정해지는데, 허용하려는 IP 영역을 1번에 두고, 막으려는 지역, 예를 들면 한국(KR), 일본(JP), 중국(CN) 등을 전체 차단을 2번 규칙에 두면 됩니다. 지리적 제어가 필요 없는 클라이언트 지역은 2번 CloudFront로 보내게 됩니다.

그런데 이 방법에는 한 가지 문제가 존재합니다. CloudFront를 Route53에서 A레코드로 등록하려면 CloudFront에 CNAME을 할당해야 합니다. 문제는 위의 구성에서 CNAME이 두 개가 된다는 점입니다.

CloudFront는 고객이 최초 요청한 대상에 대해 체크를 하게 되는데, 만약 다른 도메인으로 경유해서 들어오게 되면 “Bad Request”라는 메시지를 던지게 됩니다.

즉, 위의 경우 1번 CF의 CNAME이 a.com, 2번 CF의 CNAME이 b.com이라고 이라고 하고, 이를 묶기 위해 c.com을 두었다면, 고객은 c.com으로 요구를 요청하게 됩니다. 1번, 2번 CloudFront모두 요청한 도메인(c.com)이 자신의 CNAME과 다르기 때문에 오류를 내게 됩니다. 이를 해결하는 방법은 매우 간단합니다. 클라이언트에서 요청할 때 헤더의 origin 값을 1번, 2번 CNAME으로 바꾸어서 전달해 주면 됩니다.

하지만, 클라이언트가 각기 다른 CNAME 값 중에 어디로 요청할 수 있다는 말은 이미 지리 정보를 클라이언트가 알고 있어야 한다는 문제에 다시 봉착 합니다. 이는 별도 지리 정보 제공 서버가 있어야 하거나, 클라이언트가 자신의 위치를 알고 있어야 합니다.

이를 해결하기 위해서는 좀 더 서비스 내부 기능을 활용하는 방법을 고안해 내야 합니다. 그 해결책 중의 하나가 바로 CloudFront 샌드위치 아키텍처입니다.

먼저 이와 같은 아키텍처를 고안하게 된 배경을 설명해 보고자 합니다. WAF는 CIDR로 IP 조건을 검색할 수 있습니다. 단 /8, /16, /24, /32 로 8비트 단위 레인지 만을 지원합니다. 중국에 속한 IP는 CIDR로 대략 6천개 정도 되는데, 이를 위 단위로 전환하면 대략 6만건의 CIDR가 됩니다.

조건이 너무 많아지면 성능 저하가 발생할 수 있고, 만약 고객이 여러 지역에 대해 관리를 해야 한다면 CIDR 형태로 WAF상에서 관리하는 것은 무척 힘든일이 될 수 있습니다.

재미난 것은 CloudFront의 고급 기능 중에 확장 헤드를 추가해 주는 기능이 있습니다. cloudfront-viewer-country라는 확장 헤더는 요청이 어느 나라에서 이루어졌는지를 헤더값으로 추가해주게 됩니다.

이렇게 확장 헤더값을 추가하는 기능보다 WAF는 앞에 존재하기 때문에 가져 올 수가 없습니다. 따라서, 이 기능을 이용하려면 WAF를 한번 더 통과하게 해서, cloudfront-viewer-country 확장 헤더 값을 추가한 이후에, 두번째 WAF에서 이 값을 이용해서 차단 할 수 있습니다.

첫번째 CloudFront를 통과하게 되면, 요청 IP가 CloudFront의 값으로 변하게 되는데, 원래 고객의 IP값은 x-forwarded-for 값에 존재합니다. 따라서 이 때 WAF 규칙을 만들 수 있게 됩니다.

각각 문자열 조건을 만든 다음 아래와 같이 WAF 규칙을 만드는 것입니다.

물론 본 아키텍처의 단점은 CloudFront의 가격이 2배가 나온다는 점입니다. 그러나, 지역별 IP 차단이라는 요구 사항에 대해 관리 및 운영 편리성을 생각하면 매우 효율적이고 간단한 해결책입니다.

게임 서비스에서 지리적 IP 관리는 매우 일상적인 요구 사항입니다. AWS 클라우드 서비스 빌딩 블록을 이용하여, 간단한 아키텍처 재구성만으로 본 요구 사항을 구성하는 해법을 찾아 보았습니다. 이러한 요구 사항을 충족해 주는 AWS 서비스나 기능이 나올 때 까지 활용해 볼 수 있는 대안이 될 것입니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 박선용 솔루션즈 아키텍트께서 작성해주셨습니다.

Source: AWS 클라우드 에서 지리적 IP(GeoIP) 차단 관리 방법

Exit mobile version