구독해서 새 게시물에 대한 알림을 받으세요.

2025년 11월 18일 Cloudflare 서비스 중단

2025-11-18

12분 읽기

2025년 11월 18일 11시 20분 UTC(본 블로그의 모든 시간은 UTC 기준), Cloudflare 네트워크에서 핵심 네트워크 트래픽 전송에 심각한 오류가 발생하기 시작했습니다. 이로 인해 고객사의 사이트에 접속하려는 인터넷 사용자에게 Cloudflare 네트워크 오류를 나타내는 오류 페이지가 표시되었습니다.

HTTP error page displayed during the incident

이번 문제는 직간접적으로 사이버 공격이나 어떠한 종류의 악의적인 활동으로 인해 발생한 것이 아닙니다. 정확히는, 문제가 네트워크 자체에서 발생한 것이 아니라 데이터베이스 시스템 중 하나의 권한 변경 때문에 촉발되었습니다. 그 결과 데이터베이스가 Bot Management 시스템에서 사용하는 “피처 파일(feature file)”에 여러 항목을 잘못 출력하게 되었습니다. 결과적으로 해당 피처 파일의 크기가 두 배로 늘어났습니다. 예상보다 큰 피처 파일이 네트워크를 구성하는 모든 컴퓨터에 전파되었습니다.

Cloudflare 네트워크 전반의 트래픽을 라우팅하는 이 장비들의 소프트웨어는 지속적으로 변화하는 위협에 대응하기 위해 Bot Management 시스템을 최신 상태로 유지해야 합니다. 이 소프트웨어가 바로 그 목적을 위해 해당 피처 파일을 읽습니다. 이 소프트웨어는 피처 파일의 크기가 두 배 미만으로 제한되어 있었기 때문에 결국 소프트웨어에 오류가 발생했습니다.

처음에 나타난 증상 때문에 대규모 DDoS 공격으로 인한 것으로 잘못 판단했지만, 핵심 문제를 정확히 파악하여 예상보다 큰 피처 파일의 확산을 막고 이전 버전의 파일로 교체했습니다. 오후 2시 30분까지 핵심 트래픽은 대체로 정상적으로 흘렀습니다. 이후 몇 시간에 걸쳐 트래픽이 다시 온라인 상태로 돌아오면서 네트워크 여러 부분에서 증가된 부하를 완화하는 작업이 진행되었습니다. 17시 06분 현재 Cloudflare의 모든 시스템은 정상적으로 작동하고 있습니다.

고객과 인터넷에 피해를 끼쳐드려 진심으로 송구스럽게 생각합니다. 인터넷 생태계에서 Cloudflare의 중요성을 감안할 때, 당사 시스템의 모든 중단은 용납할 수 없습니다. 당사 네트워크가 트래픽을 라우팅할 수 없었던 기간이 발생했다는 사실은 모든 팀원에게 매우 고통스러운 일입니다. Cloudflare가 고객을 실망시켰다는 사실을 잘 알고 있습니다.

이 게시물은 정확히 무슨 일이 일어났고 어떤 시스템과 프로세스가 오류를 겪었는지에 대한 심층적인 이야기입니다. 또한, 이번과 같은 서비스 중단이 재발하지 않도록 하기 위한 노력의 시작이며, 결코 끝이 아닙니다.

서비스 중단

아래 차트는 Cloudflare 네트워크에서 발생한 5xx 오류 HTTP 상태 코드의 발생량을 보여줍니다. 일반적으로 이 값은 매우 낮아야 하며, 중단이 시작되기 직전까지는 낮았습니다.

Volume of HTTP 5xx requests served by the Cloudflare network

11:20 이전의 발생량은 Cloudflare 네트워크 전반에서 관찰된 예상되는 5xx 오류의 기준치를 나타냅니다. 급증과 그 이후의 변동은 잘못된 피처 파일을 로드하여 시스템 오류가 발생했음을 보여줍니다. 주목할 점은, 그 후 시스템이 일정 시간 동안 자체적으로 복구되는 현상을 보였다는 것입니다. 내부 오류 상황에서는 매우 이례적인 일이었습니다.

설명에 따르면, 해당 파일은 ClickHouse 데이터베이스 클러스터에서 실행되는 쿼리에 의해 5분마다 생성되고 있었으며, 이는 권한 관리를 개선하기 위해 점진적으로 업데이트되고 있던 과정이었습니다. 쿼리가 업데이트된 클러스터 부분에서 실행된 경우에만 잘못된 데이터가 생성되었습니다. 그 결과, 매 5분마다 올바른 구성 파일 또는 문제가 있는 구성 파일이 생성될 가능성이 있었고, 이 파일들이 네트워크 전반에 빠르게 전파되었습니다.

이러한 변동 때문에 상황이 명확하지 않았습니다. 시스템 전체가 회복되었다가 다시 실패하는 현상이 반복되었는데, 이는 네트워크에 때로는 올바른, 때로는 문제가 있는 구성 파일이 배포되었기 때문입니다. 처음에는 이 현상 때문에 공격이 원인인 것으로 판단했습니다. 결국 모든 ClickHouse 노드가 문제가 있는 구성 파일을 생성하게 되었고, 변동은 장애 상태로 안정화되었습니다.

오류는 근본 원인이 확인되고 해결되기 시작한 14:30까지 계속되었습니다. 문제 해결 방법은 잘못된 피처 파일의 생성과 전파를 중단하고, 확인된 정상 파일을 피처 파일 배포 큐에 수동으로 삽입한 뒤, 핵심 프록시를 강제로 재시작하는 것이었습니다.

위 차트에서 남아 있는 긴 꼬리 구간은 문제가 발생한 나머지 서비스들을 우리 팀이 재시작하는 과정을 보여주며, 5xx 오류 발생량은 17:06에 정상 수준으로 회복되었습니다.

다음 서비스에 영향이 있었습니다.

서비스/제품

영향 설명

핵심 CDN 및 보안 서비스

HTTP 5xx 상태 코드 이 게시물 상단의 스크린샷은 최종 사용자에게 전달되는 일반적인 오류 페이지입니다.

Turnstile

Turnstile 로드에 실패했습니다.

Workers KV

Workers KV는 핵심 프록시의 장애로 인해 KV “프론트엔드” 게이트웨이에 대한 요청이 실패하면서, HTTP 5xx 오류가 평소보다 크게 증가했습니다.

대시보드

대시보드는 대부분 작동했지만, 로그인 페이지에서 Turnstile을 사용할 수 없어 대부분의 사용자가 로그인할 수 없었습니다.

이메일 보안

이메일 처리 및 전송에는 영향이 없었지만, IP 평판 소스에 대한 일시적 접근 불가가 발생하여 스팸 탐지 정확도가 떨어지고 일부 신규 도메인 연령 감지가 작동하지 않았습니다. 다행히 고객에게 심각한 영향은 없었습니다. 또한 일부 자동 이동 작업에서 오류가 발생했습니다. 영향을 받은 모든 메시지는 검토 및 수정되었습니다.

Access

인증 실패는 대부분 사용자에게 광범위하게 발생했으며, 사고 시작 시점부터 13:05 롤백이 시작될 때까지 계속되었습니다. 기존의 Access 세션은 영향을 받지 않았습니다.

모든 인증 실패 시도는 오류 페이지로 이어졌기 때문에, 인증이 실패하는 동안 해당 사용자들은 목표 애플리케이션에 전혀 접속하지 못했습니다. 이 기간 동안의 성공적인 로그인은 이번 사고 중에도 정상적으로 기록되었습니다. 

당시 시도된 Access 구성 업데이트는 완전히 실패했거나, 전파가 매우 느리게 이루어졌을 가능성이 있습니다. 이제 모든 구성 업데이트가 복구되었습니다.

영향 기간 동안 HTTP 5xx 오류가 발생하는 것뿐만 아니라, CDN 응답 지연도 크게 증가했습니다. 이는 자동으로 잡히지 않은 오류에 추가 디버깅 정보를 붙이는 디버깅 및 관측 시스템이 많은 CPU를 사용했기 때문입니다.

Cloudflare가 요청을 처리하는 방식과 오늘 발생한 문제점

Cloudflare로 향하는 모든 요청은 명확하게 정의된 경로를 거칩니다. 이는 웹페이지를 로드하는 브라우저, API를 호출하는 모바일 애플리케이션, 혹은 다른 서비스에서 오는 자동화 트래픽일 수 있습니다. 이러한 요청은 먼저 HTTP 및 TLS 계층에서 종료되고, 이후 핵심 프록시 시스템("Frontline", 줄여서 FL)을 거쳐, 마지막으로 Pingora를 통해 캐시 조회를 수행하거나 필요 시 원본 서버에서 데이터를 가져옵니다.

핵심 프록시의 작동 방식에 대한 자세한 내용은 여기에서 확인할 수 있습니다. 

Diagram of our reverse proxy architecture

요청이 핵심 프록시를 통과하는 동안, 우리는 네트워크에서 제공되는 다양한 보안 및 성능 관련 제품을 실행합니다. 프록시는 각 고객의 고유한 구성과 설정을 적용하며, 여기에는 WAF 규칙 및 DDoS 방어 적용, 그리고 트래픽을 Developer Platform과 R2로 라우팅하는 작업이 포함됩니다. 이는 도메인별 모듈 세트를 통해 이루어지며, 이 모듈들이 핵심 프록시를 통과하는 트래픽에 고객 구성과 정책 규칙을 적용합니다.

해당 모듈 중 하나인 Bot Management 기능이 오늘 발생한 서비스 중단의 원인이었습니다. 

Cloudflare의 Bot Management 기능에는 네트워크를 통과하는 모든 요청을 대상으로 봇 점수를 생성하는 데 사용되는 머신 러닝 모델을 비롯한 다양한 시스템이 포함되어 있습니다. 고객은 봇 점수를 사용하여 어떤 봇이 사이트에 액세스하도록 허용할지 여부를 제어합니다.

이 모델은 “피처” 구성 파일을 입력으로 사용합니다. 여기서 피처란, 요청이 자동화된 것인지 여부를 예측하기 위해 머신러닝 모델이 사용하는 개별 특성을 의미합니다. 피처 구성 파일은 이러한 개별 피처들의 집합입니다.

이 피처 파일은 몇 분마다 갱신되어 네트워크 전체에 배포되며, 인터넷 전반의 트래픽 변화에 대응할 수 있게 해줍니다. 또한 새로운 유형의 봇과 봇 공격에 대응할 수 있도록 해주기 때문에 악성 행위자가 빠르게 전략을 바꾸는 상황에서 자주 그리고 신속하게 배포되는 것이 매우 중요합니다.

아래에서 설명할 ClickHouse 쿼리 동작의 변경으로 인해 이 파일이 중복된 “피처” 행을 많이 포함하게 되었습니다. 이로 인해 기존에 고정 크기였던 피처 구성 파일의 크기가 변경되었고, 그 결과 봇 모듈에서 오류가 발생했습니다.

그 결과, 봇 모듈에 의존하는 모든 트래픽에 대해, 고객 트래픽 처리를 담당하는 핵심 프록시 시스템에서 HTTP 5xx 오류 코드가 반환되었습니다. 이로 인해 핵심 프록시에 의존하는 Workers KV와 Access에도 영향이 미쳤습니다.

이번 사고와는 관련 없이, 우리는 고객 트래픽을 내부적으로 FL2라고 부르는 새로운 프록시 서비스 버전으로 이전하고 있습니다. 두 버전 모두 해당 문제의 영향을 받았지만, 관찰된 영향은 서로 달랐습니다.

새로운 FL2 프록시 엔진을 사용하는 고객은 HTTP 5xx 오류를 관찰했습니다. 기존 프록시 엔진인 FL을 사용하는 고객은 오류는 발생하지 않았지만, 봇 점수가 제대로 생성되지 않아 모든 트래픽에 봇 점수가 0으로 부여되었습니다. 봇 차단 규칙을 적용한 고객은 많은 수의 오탐(false positive)을 경험했을 것입니다. 규칙에서 봇 점수를 사용하지 않던 고객은 아무런 영향도 받지 않았습니다.

우리를 혼란스럽게 하고 이번 사건이 공격일 수 있다는 착각을 갖게 만든 또 다른 증상은 Cloudflare 상태 페이지가 다운된 것이었습니다. 상태 페이지는 Cloudflare 인프라와 전혀 연동되지 않고, Cloudflare에 의존하지 않는 별도의 환경에서 호스팅됩니다. 결국 이는 단순한 우연이었지만, 문제를 진단하던 일부 팀원들이 공격자가 우리 시스템과 상태 페이지를 동시에 노리고 있다고 오인하게 만들었습니다. 당시 상태 페이지를 방문한 이용자들은 다음과 같은 오류 메시지를 확인했습니다.

Error on the Cloudflare status page

내부 사고 대응 채팅방에서 우리는 이것이 최근에 빈번하게 발생한 대량의 Aisuru DDoS 공격의 연장선일 수 있다고 우려했습니다.

Internal chat screenshot

쿼리 동작의 변경

앞서 언급했듯이, 기본 쿼리 동작의 변경으로 인해 피처 파일에 중복된 행이 다수 포함되게 되었습니다. 해당 데이터베이스 시스템은 ClickHouse 소프트웨어를 사용합니다.

맥락을 이해하기 위해서는 ClickHouse의 분산 쿼리 동작 방식을 아는 것이 도움이 됩니다. ClickHouse 클러스터는 여러 샤드(shard)로 구성됩니다. 모든 샤드의 데이터를 쿼리하기 위해 우리는 default라고 하는 데이터베이스에서 분산 테이블(테이블 엔진 Distributed를 통해 구동)을 사용합니다. 이 Distributed 엔진은 데이터베이스 r0에서 기본 테이블을 쿼리합니다. 기본 테이블이 ClickHouse 클러스터의 각 샤드에서 데이터가 저장되는 위치입니다.

분산 테이블에 대한 쿼리는 공유 시스템 계정을 통해 실행됩니다. 분산 쿼리의 보안과 안정성을 개선하기 위한 노력의 일환으로, 앞으로는 초기 사용자 계정으로 실행되도록 변경 작업이 진행 중입니다.

오늘 이전까지, ClickHouse 사용자는 default 데이터베이스에 있는 테이블만 system.tables 또는 system.columns 같은 ClickHouse 시스템 테이블에서 테이블 메타데이터를 조회할 때 확인할 수 있었습니다.

사용자가 이미 r0의 기본 테이블에 대한 암묵적 접근 권한을 가지고 있기 때문에, 11:05에 이 접근 권한을 명시적으로 표시하도록 변경하여 사용자가 이 테이블들의 메타데이터도 확인할 수 있도록 했습니다. 모든 분산 서브쿼리가 초기 사용자 계정으로 실행되도록 보장함으로써, 쿼리 제한과 접근 권한을 더 세밀하게 평가할 수 있게 되었고, 한 사용자의 잘못된 서브쿼리가 다른 사용자에게 영향을 미치는 것을 방지할 수 있습니다.

위에서 설명한 변경으로 모든 사용자가 접근 가능한 테이블에 대한 정확한 메타데이터를 확인할 수 있게 되었습니다. 불행히도, 과거에는 다음과 같은 가정이 있었는데, 쿼리 결과에 반환되는 열 목록이 “default” 데이터베이스만 포함될 것이라는 가정이었습니다.

SELECT name, type FROM system.columns WHERE table = 'http_requests_features' order by name;

쿼리가 데이터베이스 이름을 필터링하지 않는다는 점에 주목하세요. 특정 ClickHouse 클러스터 사용자에게 명시적 권한을 점진적으로 배포하는 과정에서, 11:05 변경 이후 위 쿼리는 “중복” 열을 반환하기 시작했는데, 이는 r0 데이터베이스에 저장된 기본 테이블에 대한 열이 포함되었기 때문입니다.

안타깝게도, 이 쿼리가 바로 앞서 언급한 피처 파일의 각 입력 “피처”를 생성하기 위해 Bot Management에서 수행하는 로직에 사용되는 쿼리였습니다. 

위 쿼리는 다음과 같이 열 테이블을 반환했습니다(단순화된 예시).

Example of code block

그러나 사용자에게 추가 권한이 부여됨에 따라, 쿼리 응답에는 이제 r0 스키마의 모든 메타데이터가 포함되었고, 그 결과 응답의 행 수가 사실상 두 배 이상으로 증가하여 최종 파일 출력의 행 수(즉, 피처 수)에 영향을 미쳤습니다. 

메모리 사전 할당

당사 프록시 서비스에서 실행되는 각 모듈에는 무제한 메모리 사용을 방지하고, 성능 최적화를 위해 메모리를 사전 할당하기 위한 여러 제한이 설정되어 있습니다. 이번 사례에서는 Bot Management 시스템에 런타임에 사용할 수 있는 머신러닝 피처 수에 대한 제한이 있었습니다. 현재 이 제한은 200으로 설정되어 있으며, 이는 우리가 현재 사용하는 약 60개의 피처보다 훨씬 높은 수치입니다. 다시 말하지만, 이 제한은 성능상의 이유로 피처에 대한 메모리를 사전 할당하기 위해 존재합니다.

200개 이상의 피처를 가진 잘못된 파일이 서버로 전파되었을 때, 이 제한에 도달하여 시스템이 패닉 상태에 빠졌습니다. 아래는 FL2 Rust 코드로, 해당 검사를 수행하며 처리되지 않은 오류의 원인이 된 부분입니다.

code that generated the error

이로 인해 다음과 같은 패닉이 발생했으며, 이는 5XX 오류로 이어졌습니다.

thread fl2_worker_thread panicked: called Result::unwrap() on an Err value

사고 중 발생한 기타 영향

사고 중에 핵심 프록시를 사용하는 다른 시스템도 영향을 받았습니다. 여기에는 Workers KV와 Cloudflare Access가 포함되었습니다. 팀은 13:04에 Workers KV에 패치를 적용하여 핵심 프록시를 우회함으로써, 이 시스템들에 대한 영향을 줄일 수 있었습니다. 결과적으로 Workers KV에 의존하는 모든 다운스트림 시스템(Access 자체 등)에서 오류율 감소가 관찰되었습니다. 

Cloudflare 대시보드 역시 내부적으로 Workers KV가 사용되고 로그인 절차의 일부로 Cloudflare Turnstile이 배포되어 영향을 받았습니다.

Turnstile이 이번 중단 사태의 영향을 받았으며, 그 결과 활성 대시보드 세션이 없는 고객은 로그인할 수 없었습니다. 아래 그래프에서 볼 수 있듯이, 11:30~13:10 그리고 14:40~15:30의 두 기간 동안 가용성이 감소한 것으로 나타났습니다.

availability of Cloudflare internal APIs during the incident

첫 번째 구간인 11:30~13:10은 일부 제어판 및 대시보드 기능이 의존하는 Workers KV에 대한 영향 때문이었습니다. 이는 13:10에 Workers KV가 핵심 프록시 시스템을 우회하면서 복구되었습니다. 대시보드에 대한 두 번째 영향 구간은 피처 구성 데이터를 복원한 이후 발생했습니다. 로그인 시도 백로그가 대시보드를 압도하기 시작했습니다. 이 백로그는 재시도 시도와 결합되어 대기 시간을 높여 대시보드 가용성을 저하시켰습니다. 제어판 동시 처리를 확장함으로써, 대시보드 가용성은 약 15:30경에 회복되었습니다.

복원 및 후속 조치

시스템이 다시 정상적으로 온라인 상태를 회복함에 따라, 앞으로 이와 같은 장애에 대비해 시스템을 강화하는 작업이 이미 시작되었습니다. 특히 다음 작업에 착수 중입니다.

  • Cloudflare에서 생성된 구성 파일 수집 과정을, 사용자 생성 입력 처리 시와 동일한 방식으로 강화

  • 기능에 대한 더 많은 글로벌 킬 스위치 활성화

  • 핵심 덤프나 기타 오류 보고가 시스템 자원을 과도하게 점유하는 것을 방지

  • 모든 핵심 프록시 모듈에서 오류 조건에 대한 실패 모드 검토

오늘은 Cloudflare에 2019년 이후 최악의 장애가 발생했습니다. 가동이 중단되어 대시보드를 사용할 수 없게 되었습니다. 이로 인해 잠시 동안 새로운 기능들이 구동되지 않는 문제가 생기기도 했습니다. 하지만 지난 6년 넘게, 핵심 트래픽 대부분이 네트워크를 통해 흐르지 못하게 만드는 다른 중단은 없었습니다.

오늘과 같은 서비스 중단은 결코 용납할 수 없습니다. Cloudflare는 트래픽 흐름이 항상 유지되도록 하기 위해 장애 복원력이 뛰어난 시스템을 설계했습니다. 과거에 서비스 중단이 발생했을 때에도 항상 더 새롭고 복원력이 뛰어난 시스템을 구축해 왔습니다.

Cloudflare 팀 전체를 대표하여 오늘 인터넷에 불편을 끼쳐드린 점 진심으로 다시금 사과드립니다.

시간(UTC)

상태

설명

11:05

정상.

데이터베이스 접근 제어 변경 배포.

11:28

영향 시작.

배포가 고객 환경에 적용된 후, 고객 HTTP 트래픽에서 첫 번째 오류 발견.

11:32-13:05

팀이 Workers KV 서비스의 트래픽 증가 및 오류를 조사.

초기 증상으로 Workers KV 응답률 저하가 나타났으며, 이는 다른 Cloudflare 서비스에 다운스트림 영향을 미침.

Workers KV 서비스를 정상 운영 수준으로 복구하기 위해 트래픽 조작 및 계정 제한 등의 완화 조치 시도.

첫 번째 자동 테스트에서 11시 31분에 문제가 발견되었고, 11시 32분에 수동 조사를 시작. 11시 35분에 사고 대응 회의 소집.

13:05

Workers KV 및 Cloudflare Access 우회 구현 - 영향 감소.

조사 과정에서, Workers KV와 Cloudflare Access에 대한 내부 시스템 우회를 사용하여 이전 버전의 핵심 프록시로 복귀. 이번 문제는 이전 프록시 버전에서도 존재했지만, 아래에 설명된 것처럼 영향은 더 적었음.

13:37

작업은 Bot Management 구성 파일을 마지막으로 확인된 정상 버전으로 롤백하는 데 집중.

이번 사고의 원인은 명백히 Bot Management 구성 파일임. 팀은 여러 작업 흐름에서 서비스 복구 방법을 모색했으며, 가장 빠른 작업 흐름은 파일의 이전 버전 복원이었음.

14:24

새 Bot Management 구성 파일의 생성 및 전파 중단.

500 오류의 원인이 Bot Management 모듈에 있으며, 이는 잘못된 구성 파일로 인해 발생했음을 확인. 새 Bot Management 구성 파일의 자동 배포가 중단.

14:24

새 파일 테스트 완료.

이전 버전의 구성 파일을 사용하여 성공적으로 복구된 것을 확인한 후, 전역적으로 수정 사항을 신속하게 적용하는 데 집중.

14:30

주요 영향 해결. 다운스트림 영향 서비스에서 오류 감소가 관찰되기 시작.

올바른 Bot Management 구성 파일이 전역에 배포되었으며 대부분의 서비스가 올바르게 작동하기 시작.

17:06

모든 서비스 해결. 영향 종료.

모든 다운스트림 서비스가 재시작되었으며 모든 작동이 완전히 복원됨.

Cloudflare에서는 전체 기업 네트워크를 보호하고, 고객이 인터넷 규모의 애플리케이션을 효과적으로 구축하도록 지원하며, 웹 사이트와 인터넷 애플리케이션을 가속화하고, DDoS 공격을 막으며, 해커를 막고, Zero Trust로 향하는 고객의 여정을 지원합니다.

어떤 장치로든 1.1.1.1에 방문해 인터넷을 더 빠르고 안전하게 만들어 주는 Cloudflare의 무료 애플리케이션을 사용해 보세요.

더 나은 인터넷을 만들기 위한 Cloudflare의 사명을 자세히 알아보려면 여기에서 시작하세요. 새로운 커리어 경로를 찾고 있다면 채용 공고를 확인해 보세요.
중단사후봇 관리

X에서 팔로우하기

Matthew Prince|@eastdakota
Cloudflare|@cloudflare

관련 게시물