2025년 11월 18일 20:20(KST), Cloudflare 네트워크에서 핵심 네트워크 트래픽 처리에 심각한 실패가 발생하기 시작했습니다. 이로 인해 인터넷 사용자들이 저희 고객의 사이트에 접속하려 할 때 Cloudflare 네트워크 내부 오류를 알리는 에러 페이지가 표시되었습니다.

결론부터 말씀드리면, 이번 문제는 사이버 공격이나 어떠한 악의적인 활동으로 인해 발생한 것이 아닙니다.
대신, 데이터베이스 시스템 중 하나의 권한을 변경하는 과정에서 문제가 촉발되었습니다. 이 변경으로 인해 봇 관리(Bot Management) 시스템이 사용하는 "기능 파일(feature file)"에 중복된 항목이 다수 출력되었고, 결과적으로 파일 크기가 두 배로 늘어났습니다. 이렇게 예상보다 커진 파일은 네트워크를 구성하는 모든 머신으로 전파되었습니다.
네트워크 트래픽을 라우팅하는 머신들의 소프트웨어는 끊임없이 변화하는 위협에 대응하기 위해 이 파일을 읽어 봇 관리 시스템을 업데이트합니다. 하지만 해당 소프트웨어에는 기능 파일 크기에 대한 제한이 있었고, 두 배로 커진 파일은 이 제한을 초과했습니다. 이로 인해 소프트웨어에 오류가 발생했습니다.
초기에는 이를 초대형 DDoS 공격으로 잘못 의심하기도 했으나, 곧 핵심 원인을 정확히 파악했습니다. 우리는 잘못된 대형 파일의 전파를 중단하고 이전 버전의 파일로 교체했습니다. 23:30경부터 핵심 트래픽은 대부분 정상적으로 흐르기 시작했습니다. 이후 몇 시간 동안 트래픽이 급격히 복구되면서 발생한 네트워크 부하를 관리했고, 익일 02:06 기준으로 모든 시스템이 정상화되었습니다.
고객 여러분과 인터넷 생태계 전반에 끼친 영향에 대해 진심으로 사과드립니다. Cloudflare가 인터넷 생태계에서 차지하는 중요성을 고려할 때, 시스템 중단은 용납될 수 없는 일입니다. 우리 네트워크가 트래픽을 라우팅하지 못한 시간은 팀원 모두에게 매우 고통스러운 일이었습니다. 오늘 저희가 여러분께 실망을 드렸음을 잘 알고 있습니다.
이 글은 정확히 무슨 일이 일어났는지, 어떤 시스템과 프로세스가 실패했는지에 대한 심층적인 기록입니다. 또한, 다시는 이런 일이 발생하지 않도록 하기 위한 계획의 시작점입니다.
장애 발생 현황
아래 차트는 Cloudflare 네트워크에서 제공된 5xx HTTP 상태 코드(서버 오류)의 양을 보여줍니다. 평소에는 매우 낮게 유지되어야 하지만, 장애 시작과 동시에 급증했습니다.

20:20 이전의 평탄한 라인은 정상적인 상태를 의미하며, 이후 급격한 스파이크와 변동은 잘못된 기능 파일 로드로 인한 시스템 실패를 보여줍니다.
주목할 점은 시스템이 오류를 뿜어내다가도 일시적으로 회복되는 모습을 보였다는 것입니다. 이는 내부 오류치고는 매우 이례적인 동작이었습니다.
원인은 ClickHouse 데이터베이스 클러스터에서 5분마다 실행되는 쿼리가 설정 파일을 생성하고 있었기 때문입니다. 권한 관리를 개선하기 위해 클러스터가 점진적으로 업데이트되고 있었는데, 업데이트된 부분에서 쿼리가 실행될 때만 잘못된 데이터가 생성되었습니다. 결과적으로 5분마다 정상 파일 혹은 잘못된 파일이 번갈아 생성되어 네트워크 전체로 빠르게 전파되었습니다.
이러한 변동성 때문에, 때로는 정상 설정 파일이, 때로는 잘못된 파일이 배포되면서 시스템이 회복과 실패를 반복했습니다. 이로 인해 초기에는 이를 공격으로 오인하게 만들었습니다. 결국 모든 ClickHouse 노드가 잘못된 설정 파일을 생성하게 되면서 변동이 멈추고 오류 상태로 고착화되었습니다.
영향받은 서비스
핵심 CDN 및 보안 서비스: HTTP 5xx 오류 발생
Turnstile: 로드 실패
Workers KV: 코어 프록시 실패로 인한 '프론트엔드' 게이트웨이 요청 실패 (5xx 오류 증가)
Dashboard: 대부분의 사용자가 Turnstile 오류로 인해 로그인 불가
Email Security / Access: 일부 기능 및 인증 실패
Cloudflare의 요청 처리 방식과 문제점
Cloudflare로 들어오는 모든 요청은 잘 정의된 경로를 따릅니다.
요청은 HTTP 및 TLS 계층에서 종료된 후, **FL(Frontline)**이라 불리는 코어 프록시 시스템으로 유입되고, 마지막으로 Pingora를 통해 캐시를 조회하거나 원본 서버(Origin)에서 데이터를 가져옵니다.

코어 프록시(FL) 내부에는 WAF, DDoS 방어, 봇 관리 등 다양한 모듈이 존재합니다. 이번 장애의 원인은 바로 봇 관리(Bot Management) 모듈이었습니다.
봇 관리 시스템은 머신러닝 모델을 사용하여 모든 요청에 봇 점수를 매깁니다. 이 모델은 "기능(feature) 설정 파일"을 입력으로 받는데, 이 파일은 봇인지 아닌지를 예측하는 데 사용되는 개별 특성들의 모음입니다. 이 파일은 새로운 위협에 대응하기 위해 몇 분마다 갱신되어 전체 네트워크에 배포됩니다.
하지만 기본 ClickHouse 쿼리 동작의 변경으로 인해 이 파일에 수많은 중복 행이 포함되었고, 고정된 크기 제한을 넘어서면서 봇 모듈에 오류를 일으켰습니다. 봇 모듈에 의존하는 모든 트래픽 처리가 실패하면서 5xx 오류가 반환된 것입니다.
혼란을 가중시킨 상황들: 공격인가?
우리를 더욱 헷갈리게 만들고 공격이라고 의심하게 만든 또 다른 증상이 있었습니다. 바로 Cloudflare의 상태 페이지(Status Page)가 다운된 것입니다. 상태 페이지는 Cloudflare 인프라와 완전히 분리되어 호스팅되지만, 우연의 일치로 문제가 발생하여 공격자가 우리 시스템과 상태 페이지를 동시에 공격하고 있다고 의심하게 만들었습니다.

내부 사고 대응 챗룸에서도 최근 발생했던 대규모 Aisuru DDoS 공격의 연장선이 아닌지 우려하는 목소리가 있었습니다.

Matthew Prince(CEO): "이게 그 거대 봇넷이 힘자랑하는 건가 걱정되네요."
근본 원인: 쿼리 동작 변경
앞서 언급했듯, 근본적인 문제는 봇 관리용 기능 파일을 생성하는 ClickHouse 쿼리에서 발생했습니다.
우리는 분산 쿼리의 보안과 신뢰성을 높이기 위해, 쿼리가 시스템 계정이 아닌 초기 사용자 계정 권한으로 실행되도록 변경하고 있었습니다. 20:05에 사용자에게 기본 테이블에 대한 명시적 접근 권한을 부여하는 변경 사항을 적용했습니다.
문제는 기존 쿼리가 데이터베이스 이름을 필터링하지 않고 system.columns를 조회하고 있었다는 점입니다.
SELECT name, type
FROM system.columns
WHERE table = 'http_requests_features'
ORDER BY name;
권한 변경 전에는 default 데이터베이스의 컬럼만 반환했지만, 변경 후에는 실제 데이터가 저장된 r0 데이터베이스의 메타데이터까지 접근 가능해지면서 동일한 컬럼이 중복되어 반환되기 시작했습니다.

메모리 할당 문제와 패닉(Panic)
성능 최적화를 위해 프록시 서비스의 모듈들은 메모리를 미리 할당(preallocate)하며, 제한을 둡니다. 봇 관리 시스템은 런타임에 사용할 수 있는 기능(feature)의 수를 200개로 제한하고 있었습니다(실제 사용은 약 60개).
하지만 중복 데이터로 인해 200개가 넘는 기능이 포함된 파일이 전파되자, 이 제한을 초과하게 되었고 Rust 코드는 패닉(Panic)을 일으켰습니다.
에러 처리가 되지 않은 unwrap() 호출로 인해 시스템이 패닉 상태에 빠짐

이 코드는 다음과 같은 패닉 메시지를 남기고 5xx 오류를 발생시켰습니다. thread fl2_worker_thread panicked: called Result::unwrap() on an Err value
기타 영향 및 복구
대시보드 로그인에 사용되는 Turnstile 서비스도 영향을 받아, 많은 고객이 로그인할 수 없었습니다.

타임라인 (Timeline)
시간 (KST) | 상태 | 설명 |
|---|---|---|
20:05 | 정상 | 데이터베이스 접근 제어 변경 사항 배포. |
20:28 | 영향 시작 | 배포가 고객 환경에 도달, 고객 HTTP 트래픽에서 첫 오류 관측. |
20:32-22:05 | 조사 진행 | 팀이 Workers KV 서비스의 트래픽 증가 및 오류 조사 착수. 초기 증상은 Workers KV 응답률 저하로 보였으며, 이로 인한 다운스트림 영향으로 파악됨. 트래픽 조작 및 계정 제한 등의 완화 조치 시도. 20:31에 첫 자동화 테스트에서 문제 감지, 20:32 수동 조사 시작, 20:35 사고 대응 콜 생성. |
22:05 | 영향 감소 | Workers KV 및 Cloudflare Access 우회 적용. 조사 과정에서 Workers KV와 Access가 이전 버전의 코어 프록시를 사용하도록 내부 시스템 우회 적용. 문제가 완전히 해결된 것은 아니었으나 영향은 감소함. |
22:37 | 복구 작업 | 봇 관리 설정 파일 롤백에 집중. 봇 관리 설정 파일이 원인임을 확신하고, 이전 정상 버전(Last-known-good)으로 복원하는 것을 최우선으로 진행. |
23:24 | 조치 완료 | 새로운 봇 관리 설정 파일 생성 및 전파 중단. 봇 관리 모듈이 500 오류의 원인이며 잘못된 설정 파일 때문임을 확인. 자동 배포 중단. |
23:24 | 테스트 완료 | 새 파일(복구용 파일) 테스트 완료. 이전 버전 설정 파일을 사용하여 성공적으로 복구됨을 확인하고 전역 배포 가속화. |
23:30 | 주요 영향 해소 | 주요 영향 해결. 올바른 봇 관리 설정 파일이 전역으로 배포되었으며, 대부분의 서비스가 정상 작동 시작. 다운스트림 서비스들의 오류 감소 관측. |
익일 02:06 | 종료 | 모든 서비스 정상화. 영향 종료. 모든 다운스트림 서비스가 재시작되었으며 운영 완전 복구. |
마무리 및 후속 조치
시스템은 현재 모두 정상화되었습니다. 우리는 이번과 같은 실패를 방지하기 위해 다음과 같은 조치를 취하고 있습니다.
Cloudflare가 생성한 설정 파일도 사용자 입력처럼 엄격하게 검증하도록 강화
기능에 대한 글로벌 킬 스위치(Kill switch) 확대 적용
코어 덤프나 오류 보고가 시스템 리소스를 압도하지 않도록 제한
모든 코어 프록시 모듈의 오류 실패 모드 재검토
from https://blog.cloudflare.com/18-november-2025-outage/
댓글을 남기려면 로그인이 필요합니다.
로그인 후 이 페이지로 돌아와 바로 댓글을 남길 수 있습니다.
