방어선 2-②: IP 평판·위협 인텔리전스의 쓸모와 한계

아프로·2026년 10월 30일

방어선 2-② IP 평판과 위협 인텔리전스 표지

"블랙리스트 IP는 진입점에서 바로 드롭한다." 원문의 문장입니다. 맞는 말이지만 반만 맞습니다. 실험실에서 IP 기준으로 "거부된 서로 다른 주문 3개"를 세게 했더니, 공격자보다 먼저 통신사 공유 IP 뒤의 정상 사용자 50명이 한 덩어리로 걸릴 뻔했습니다. IP는 사람이 아니라 주소입니다. 이번 글은 IP 평판을 어디까지 믿을지입니다.

IP 평판과 위협 인텔리전스

IP 평판(IP reputation)은 "이 주소가 최근 나쁜 짓에 쓰였나"를 점수나 목록으로 나타낸 것입니다. 위협 인텔리전스(TI, Threat Intelligence)는 그런 정보를 모아 나눠 주는 일 전체를 말합니다. 흔히 쓰는 출처는 이렇습니다.

  • 공동체 차단 목록. 여러 서버가 본 공격 IP를 모아 나눕니다. CrowdSec가 대표입니다.
  • 신고 기반 데이터베이스. 사용자가 신고한 악용 IP를 조회합니다. AbuseIPDB가 대표입니다.
  • 성격 목록. Tor 출구 노드, 공개 프록시, 클라우드 사업자 대역. 나쁘다기보다 "사람 집이 아닐 가능성이 높다"는 정보입니다.

CrowdSec의 구조

CrowdSec는 원문이 "Fail2ban의 현대적 대안"이라고 부른 도구입니다. 공식 문서 기준 구조는 이렇습니다.

  • Security Engine. 로그를 읽고 시나리오(행동 패턴, 예: 짧은 시간에 404가 많이 나는 IP)를 적용해 결정을 만듭니다.
  • Local API. 결정을 모아 두고 나눠 주는 곳입니다.
  • Remediation Component(예전 이름 bouncer). Nginx, 방화벽, 프록시 같은 곳에서 Local API의 결정을 읽어 실제로 막습니다.
  • Central API. 내 탐지를 공유하면 공동체 차단 목록을 받습니다.

결정에는 기간이 붙습니다. 기본 프로필은 IP를 4시간 차단하고, 반복되면 시간을 늘리는 식을 예시로 둡니다. 차단 대신 캡차를 걸 수도 있습니다. WAF 역할을 하는 AppSec 구성 요소도 있습니다. AppSec가 어떤 엔진 위에 만들어졌는지는 문서에서 확인하지 못했습니다(확인 필요).

AbuseIPDB를 요청마다 부르지 않는 이유

AbuseIPDB는 GET /api/v2/check에 IP를 보내면 악용 신뢰 점수(abuseConfidenceScore)를 돌려줍니다. API 키가 필요하고, 무료 등급은 하루 조회 1,000회입니다. 점수 범위를 문서가 명시하지는 않습니다(예시는 0, 52, 100. 0~100으로 보이나 확인 필요). 이 시리즈 실험실은 키가 필요한 외부 API를 부르지 않았습니다.

외부 평판 API를 요청 경로에서 매번 부르면 문제가 셋입니다.

  1. 지연. 요청마다 외부 왕복이 붙습니다.
  2. 한도. 하루 1,000회는 작은 서비스의 한 시간 트래픽도 안 됩니다.
  3. 개인정보. 사용자 IP를 제3자에게 계속 보내게 됩니다.

그래서 피드를 내려받아 캐싱합니다. 목록을 주기적으로 받아 Redis 집합이나 방화벽의 IP 집합에 넣고, 요청 경로에서는 로컬 조회만 합니다. 항목마다 만료를 둡니다. IP는 주인이 바뀌기 때문입니다.

한계: 주소는 사람이 아니다

CGNAT로 여러 사용자가 IP 하나를 나눠 쓰는 경우와 공격자가 주거 프록시로 IP를 계속 바꾸는 경우를 나란히 놓은 그림

여러 사람이 IP 하나를 쓴다

통신사 CGNAT, 회사·학교의 NAT, 공용 와이파이 뒤에서는 많은 사람이 공인 IP 하나를 나눠 씁니다. RFC 6269(IP 주소 공유의 문제)는 이렇게 적습니다. 주소를 나눠 쓰면 로그인을 여러 번 실패한 사용자 한 명이 다른 사용자들까지 막을 수 있고, 주소 공유가 널리 퍼지면 IP 기준 "벌칙 상자" 방식은 제대로 동작하지 않는다.

실험실 정상 사용자 중 50명은 CGNAT 주소 두 개(100.64.0.1, 100.64.0.2) 뒤에 있습니다. IP 기준 규칙의 기준값을 낮추면 이렇게 됩니다(2시간 분량 합성 트래픽).

IP 기준 규칙오탐 사용자그 IP를 함께 쓰는 정상 사용자
거부된 서로 다른 주문 3개 / 10분3명50명
거부된 서로 다른 주문 5개 / 1시간10명50명
서로 다른 주문 10개 / 10분51명60명
같은 규칙을 계정 기준으로0~5명해당 없음

가족이 보낸 주문 링크를 연 정상 사용자 몇 명이 같은 CGNAT 주소에서 합쳐져 기준을 넘었습니다. 그 IP를 막았다면 50명이 함께 막혔을 겁니다.

한 사람이 IP를 계속 바꾼다

반대로 공격자는 주거 프록시(일반 가정 회선을 빌려 쓰는 프록시 서비스)나 클라우드 인스턴스로 요청마다 IP를 바꿀 수 있습니다. 실험실의 "IP를 바꾸는 열거"는 요청마다 다른 IP를 썼고, IP 기준으로 세는 규칙은 어느 기준값에서도 이 공격을 잡지 못했습니다(미끼는 예외, 5편). 계정 기준 규칙은 5번째 요청에서 잡았습니다.

그 밖의 함정

  • IPv6. 가입자 하나가 보통 큰 대역(흔히 /64 이상)을 받습니다. 주소 하나 단위로 막으면 공격자는 옆 주소로 옮깁니다. /64로 묶어 다룹니다.
  • 낡은 항목. 어제 공격에 쓰인 IP가 오늘은 다른 가입자의 IP입니다. 만료 없는 목록은 시간이 갈수록 오탐 목록이 됩니다.
  • 정상 자동화. 결제사 웹훅, 모니터링, 제휴사 서버는 클라우드 대역에서 옵니다. "클라우드 IP면 차단"은 이들을 막습니다.

어디에 쓰면 좋은가

IP 평판은 결정이 아니라 점수의 재료로 쓸 때 가장 쓸모 있습니다.

  • 엣지에서 확실한 것만 떨어뜨리기. 여러 출처에서 동시에 최근 공격으로 보고된 IP, 알려진 스캐너.
  • 민감한 엔드포인트에서 문턱 높이기. 로그인, 비밀번호 재설정, 결제에서 평판 나쁜 IP는 챌린지를 한 번 더.
  • 다른 신호와 합치기. "계정 기준 거부 경보 + 평판 나쁜 IP"면 대응 단계를 하나 올립니다.
  • 차단에는 TTL. 수 시간 단위로 걸고 반복되면 늘립니다.

정리

  • IP 평판과 TI는 알려진 나쁜 주소를 싸고 빠르게 거르는 데 쓸모 있습니다. 피드는 받아서 캐싱하고, 요청마다 외부 API를 부르지 않습니다.
  • 하지만 IP는 사람이 아닙니다. CGNAT 뒤에서는 여러 사람이 한 IP를 쓰고(실험실에서 50명), 공격자는 요청마다 IP를 바꿉니다(실험실에서 IP 기준으로 세는 규칙은 하나도 못 잡음).
  • 신원 기준 신호를 먼저 쓰고, IP 평판은 점수의 재료와 문턱 조정에 쓰세요. 차단에는 반드시 만료를 둡니다.

출처와 확인 날짜

모든 링크는 2026-10-30에 확인했습니다.


이전 글 방어선 2-①: WAF와 OWASP CRS가 잡는 것, 못 잡는 것
다음 글 방어선 3: 실시간 파이프라인은 언제 필요한가
시리즈 전체 목록 해킹 시도를 몇 초 안에 잡는 서버 전체 목록

profile
고인물 개발자(OG)

0개의 댓글