국가 IP User-Agent 기반 차단 규칙 만들기

클라우드플레어 국가 차단, IP 차단, User-Agent 차단은 Custom Rules에서 표현식 세 줄이면 끝납니다. 이 글에서는 ip.src.country, ip.src, http.user_agent 세 가지 필드를 이용해 실제로 동작하는 차단 규칙을 만드는 방법을 정리합니다.

3줄 요약

1. 국가 차단은 ip.src.country에 두 글자 국가 코드를 넣고 in 연산자로 묶습니다.

2. IP 차단은 단일 IP는 eq, 대역은 CIDR 표기, 여러 개는 중괄호 목록을 씁니다.

3. User-Agent 차단은 contains와 lower()를 함께 써야 대소문자 우회를 막습니다.

국가, IP, User-Agent 차단은 언제 쓰나요

세 가지 차단은 목적이 완전히 다릅니다. 무턱대고 다 켜면 진짜 방문자까지 막히니 아래 기준으로 골라 쓰세요.

  • 국가 차단: 서비스 대상 국가가 명확할 때. 한국 대상 쇼핑몰인데 특정 국가에서만 로그인 시도가 쏟아지는 경우
  • IP 차단: 공격 IP가 소수로 특정될 때. 로그에서 같은 IP가 수천 번 찍히는 경우
  • User-Agent 차단: 스크래퍼나 자동화 도구가 자기 이름을 그대로 노출할 때. python-requests, curl, scrapy 같은 문자열

국가 차단 규칙 만들기

국가는 ip.src.country 필드를 씁니다. 값은 ISO 3166-1 alpha-2 두 글자 대문자 코드입니다. 한국은 KR, 미국은 US, 중국은 CN, 러시아는 RU, 베트남은 VN입니다.

특정 국가만 막기

(ip.src.country in {"CN" "RU" "VN"})

조치는 Block으로 둡니다. 이 규칙은 해당 국가에서 오는 모든 요청을 즉시 차단합니다.

한국만 허용하고 나머지를 막기

(ip.src.country ne "KR")

화이트리스트 방식입니다. 강력하지만 위험합니다. 구글봇, 네이버봇, 결제 대행사 콜백 서버가 해외에서 들어오면 전부 막히기 때문입니다. 이 방식을 쓰려면 아래처럼 예외를 반드시 붙이세요.

(ip.src.country ne "KR"
 and not cf.client.bot
 and not starts_with(http.request.uri.path, "/api/callback"))

cf.client.bot은 클라우드플레어가 검증한 착한 봇(구글, 빙 등)을 뜻합니다. 이 조건을 넣어야 검색 노출이 죽지 않습니다.

특정 국가는 차단 대신 캡차

(ip.src.country in {"CN" "RU"} and http.request.uri.path contains "/login")

조치를 Managed Challenge로 두면 진짜 사람은 통과하고 자동화 도구만 걸립니다. 처음에는 Block보다 이쪽을 권합니다.

 

국가 차단, IP 차단, User-Agent 차단 적용 순서

IP 및 IP 대역 차단 규칙

IP는 ip.src 필드를 씁니다. 형태에 따라 문법이 조금씩 다릅니다.

단일 IP 하나 막기

(ip.src eq 203.0.113.45)

IP 값에는 따옴표를 붙이지 않습니다. 문자열이 아니라 IP 타입이기 때문입니다. 따옴표를 넣으면 저장할 때 문법 오류가 납니다.

여러 IP를 한 줄로 막기

(ip.src in {203.0.113.45 198.51.100.7 192.0.2.19})

중괄호 안에서는 쉼표가 아니라 공백으로 구분합니다. 클라우드플레어 표현식의 대표적인 함정입니다.

IP 대역 통째로 막기

(ip.src in {203.0.113.0/24 198.51.100.0/22})

CIDR 표기를 그대로 넣으면 됩니다. /24는 256개, /22는 1024개 주소를 한 번에 가리킵니다. 공격이 같은 대역에서 IP만 바꿔가며 들어올 때 유용합니다.

ASN 단위로 막기

(ip.geoip.asnum in {14061 16509})

특정 클라우드 사업자 전체에서 트래픽이 쏟아질 때 씁니다. 다만 ASN 차단은 범위가 대단히 넓으니 반드시 Managed Challenge부터 시작하세요.

User-Agent 차단 규칙

User-Agent는 http.user_agent 필드를 씁니다. 브라우저가 스스로 보내는 자기소개 문자열이라 얼마든지 위조할 수 있지만, 자동화 도구는 기본값을 그대로 쓰는 경우가 많아 여전히 효과가 있습니다.

기본 형태

(http.user_agent contains "python-requests")

대소문자 우회를 막는 형태

(lower(http.user_agent) contains "scrapy"
 or lower(http.user_agent) contains "curl"
 or lower(http.user_agent) contains "wget"
 or lower(http.user_agent) contains "python-requests"
 or lower(http.user_agent) contains "go-http-client")

lower() 없이 contains만 쓰면 Curl이나 CURL로 바꿔 보내는 순간 규칙이 무력해집니다. User-Agent 조건에는 습관처럼 lower()를 붙이세요.

User-Agent가 아예 비어 있는 요청 막기

(http.user_agent eq "")

정상 브라우저는 User-Agent를 반드시 보냅니다. 비어 있다면 대부분 조악한 스크립트입니다. 다만 사내 모니터링 스크립트나 헬스 체크가 걸릴 수 있으니 배포 전에 로그를 한 번 확인하세요.

 

필드별 문법과 주의점 정리표

세 가지를 섞은 실전 규칙

실제로는 하나만 쓰기보다 조건을 조합할 때 오탐이 확 줄어듭니다. 아래는 바로 복사해서 쓸 수 있는 예시입니다.

해외에서 들어오는 로그인 무차별 시도 차단

(http.request.uri.path contains "/login"
 and ip.src.country ne "KR"
 and http.request.method eq "POST")

조치는 Managed Challenge를 권합니다. 해외 출장 중인 실제 사용자도 캡차만 풀면 들어올 수 있습니다.

특정 국가에서 오는 스크래퍼만 정확히 차단

(ip.src.country in {"CN" "RU"}
 and lower(http.user_agent) contains "python")

국가 전체를 막는 대신 그 국가에서 오는 자동화 도구만 골라 막습니다. 일반 방문자는 전혀 영향을 받지 않습니다.

관리자 경로는 사무실 IP만 허용

(starts_with(http.request.uri.path, "/wp-admin")
 and not ip.src in {203.0.113.0/24 198.51.100.11})

not 하나로 화이트리스트가 됩니다. 다만 사무실 IP가 유동이면 본인이 잠기니, 적용 전에 IP가 고정인지 반드시 확인하세요.

이건 하지 마세요

  • 국가 코드를 소문자로 쓰기: "kr"은 매칭되지 않습니다. 반드시 대문자 KR입니다.
  • IP에 따옴표 붙이기: ip.src eq "203.0.113.45"는 문법 오류입니다. 따옴표를 빼세요.
  • 중괄호 안에 쉼표 넣기: {"CN", "RU"}가 아니라 {"CN" "RU"}입니다.
  • 구글봇 확인 없이 국가 화이트리스트 적용: 검색 크롤러가 막혀 색인에서 사라집니다. not cf.client.bot을 꼭 넣으세요.
  • 처음부터 Block으로 시작하기: 최소 하루는 Managed Challenge나 Log로 돌려 보고 이벤트 로그를 확인한 뒤 Block으로 올리세요.
  • 사용자 IP를 그대로 서버 로그에 남긴다고 믿기: 프록시를 켜면 원본 IP는 CF-Connecting-IP 헤더로 옵니다. 서버 설정을 함께 손봐야 합니다.

자주 묻는 질문

국가 차단을 켰는데 해당 국가에서 여전히 들어옵니다

VPN이나 프록시를 쓰면 출발지 국가가 바뀝니다. 국가 차단은 완벽한 방어가 아니라 소음을 줄이는 도구입니다. 더 확실하게 막으려면 Rate Limiting이나 봇 관리 기능을 함께 쓰세요.

규칙을 저장했는데 반영이 안 됩니다

먼저 해당 도메인 DNS 레코드의 프록시가 주황색 구름으로 켜져 있는지 확인하세요. 회색이면 트래픽이 클라우드플레어를 거치지 않아 어떤 규칙도 동작하지 않습니다.

차단된 방문자에게 어떤 화면이 보이나요

기본은 1020 오류 페이지입니다. Pro 요금제 이상이면 Custom Error Pages에서 안내 문구를 직접 만들 수 있습니다.

IP 하나만 막고 싶은데 Custom Rules 대신 더 쉬운 방법은 없나요

Security 메뉴의 IP Access Rules를 쓰면 IP, 대역, 국가, ASN을 목록 형태로 관리할 수 있습니다. 조건 조합이 필요 없다면 이쪽이 더 간단합니다.

규칙이 몇 개까지 가능한가요

무료 요금제는 Custom Rules 5개입니다. 그래서 조건마다 규칙을 새로 만들기보다 or로 묶어 한 규칙에 몰아넣는 편이 효율적입니다.

차단이 잘 되고 있는지 어떻게 확인하나요

Security 메뉴의 Events에서 규칙 이름으로 필터를 걸면 언제 어떤 요청이 걸렸는지 전부 보입니다. 규칙 이름을 알아보기 쉽게 지어 두는 것이 나중에 큰 도움이 됩니다.

마무리

국가, IP, User-Agent 차단은 각각 쓸 때보다 조합할 때 훨씬 정확합니다. 국가만 막으면 진짜 사용자가 걸리고, User-Agent만 막으면 위조로 뚫립니다. 오늘 소개한 표현식을 그대로 복사한 뒤 조치를 Managed Challenge로 하루만 돌려 보세요. Events 로그를 보면 어떤 조건이 실제로 유효한지 금방 감이 옵니다.

함께 보면 좋은 글