저작권 안내: 저작권자표시 Yes 상업적이용 No 컨텐츠변경 No

스프링5 입문

JSP 2.3

JPA 입문

DDD Start

인프런 객체 지향 입문 강의

'madvirus'에 해당되는 글 1건

  1. 2013.06.24 IP 필터 만들기 1, 아이디어

몇 년 전, 이전 직장에서 웹 게임의 CBT를 진행하는데, 갑자기 외부에서의 연결이 급격하게 느려지는 증상이 발생했다. 얼른 웹 서버와 DB에 들어가 봤으나 CPU/네트워크 관련 수치 모두 문제가 없었다. 내부에서의 연결은 문제 없이 잘 들어가졌다. 유관 팀과 함께 조사를 진행하다가 원인을 찾았다. 원인은 "방화벽의 차단 IP 목록"이었다.


방화벽에 등록된 차단 IP에 중국 IP 및 IP 대역들이 등록되어 있었는데, 그 개수가 많아서 트래픽 증가와 함께 방화벽의 CPU 사용률이 높아졌고 이로 인해 방화벽이 느려지는 문제가 발생했다. 웹 게임 서버로 들어오는 웹 요청을 방화벽이 빠르게 처리하지 못하자, 외부 게이머들의 불만이 폭주하기 시작했다. 일단, 방화벽의 IP 차단 목록의 개수를 줄여서 (정확하게는 화이트 리스트의 순위를 위로 올려서) 상황을 벗어났다. 그 당시 차단 IP 개수가 많아져도 성능이 저하되지 않는 IP 차단 모듈을 만들어봐야지라는 생각을 했고, 거의 3년이 지난 요즈음 IP 차단 기능을 제공하는 ip-filter 모듈 제작을 시작해서 0.1 버전을 만들었다.


아이디어


방화벽의 내부 구현을 알 순 없었지만, 검사할 IP 규칙 목록의 개수가 많았을 때 방화벽의 CPU 점유률이 높아지고 검사할 규칙 목록의 개수가 적었을 때 CPU 점유률이 낮아진 것으로 보아, 클라이언트의 IP에 해당하는 검사 규칙이 나타날 때 까지 순차적으로 각 규칙을 확인하는 것 같았다. 방화벽 설정에는 (중국 IP 대역 목록을 포함한) 매우 많은 차단 규칙이 앞쪽에 위치해 있었기 때문에, 클라이언트의 연결 요청이 들어오면 이 많은 차단 규칙을 다 확인한 뒤에 방화벽을 통과할 수 있는 것으로 추정되었다. IP가 규칙에 맞는지 여부를 확인하는 것은 순전히 CPU를 잡아 먹는 연산이기 때문에 동접자수가 증가할수록 CPU 점유률이 높아졌을 거라 생각된다.


그래서, 생각해본 것이 규칙 목록들을 트리 구조로 구성하는 것이었다. 예를 들어, 아래의 규칙에 해당하는 IP를 차단하고 싶다고 하자.

  • 1.2.3.4 (정확한 일치 IP)
  • 1.2.3.128/25 (1.2.3.128 ~ 1.2.3.255 대역)
  • 1.12.13.14 (정확한 일치 IP)
  • 10.20.* (10.20.0.0 ~ 10.20.255.255 대역)
  • 10.30.40.51 (정확한 일치 IP)
  • 10.30.40.52 (정확한 일치 IP)

이 검사 대상 IP 목록을 아래 그림과 같은 트리 형식으로 보관하는 것이다.



이렇게 트리 형식으로 검사할 규칙의 개수에 상관없이 항상 5 레벨 이하의 트리 탐색으로 특정 IP가 검사 규칙에 일치하는지 여부를 알아낼 수 있다. 예를 들어, IP 주소가 "1.12.13.5"라고 하자. 이 경우, 트리 상의 루트->1->12->13 까지는 일치하나 마지막 5레벨에서 IP 주소의 마지막 "5"와 일치하는 노드가 존재하지 않는다. 따라서, "1.12.13.5"는 매칭되는 규칙이 존재하지 않는다. 반면에 IP 주소가 "10.30.40.51"인 경우, 트리 상의 루트->10->30->40->51 에 정확하게 일치하므로, "10.30.40.51"은 매칭되는 규칙이 존재한다.


검사해야 할 규칙 목록이 백 개이든, 천 개이든, 만 개이든 상관없이 항상 5 레벨 이하의 트리 탐색으로 특정 IP가 검사 규칙에 걸리는지 확인할 수 있다. 따라서, 규칙 개수가 증가하더라도 앞서 순차적 검사와 달리 더 적은 CPU 시간을 사용할 거라 예상된다. 예를 들어, 규칙이 만 개이고 클라이언트 IP가 어떤 규칙에도 일치하지 않는다면, 만 번의 루프를 돈 뒤에야 비로서 클라이언트 IP가 규칙에 적용되지 않음을 알게 된다. 반면 위 트리 구조는 최대 5 레벨의 트리 탐색으로 클라이언트 IP가 규칙에 적용되는지 여부를 알 수 있다.


결과물


어떤 식으로 구현했는지 공유하기에 앞서 실제 만들어 본 0.1 버전을 github에 올려 보았다. 아래 github 사이트에서 ip-filter의 사용법과 소스를 확인해 볼 수 있다.

다음에는


다음에 정리해 볼 내용은 아래와 같은 것들이 있다.



Posted by 최범균 madvirus

댓글을 달아 주세요