2025년 11월 18일 아침, Cloudflare의 엔지니어들은 한동안 자신들이 공격받고 있다고 확신했다.
증상이 들어맞았다. 인터넷의 거대한 구획으로 가는 트래픽이 5xx 에러를 뿜었고, 실패가 파도처럼 왔다 갔다 했다 — 나빴다가, 괜찮았다가, 다시 나빴다 — 이건 크고 적응적인 서비스 거부 공격이 보이는 모습 그대로다. 게다가 Cloudflare 자신의 장애에도 살아남도록 일부러 자사 인프라 바깥에 호스팅해둔 공개 상태 페이지가 하필 비슷한 시각에 내려갔다. 그 사고 채널에 있었다면, 모든 신호가 적을 가리켰다.
적은 없었다. Cloudflare가 자기 자신을 공격하고 있었고, 그걸 확신하기까지 몇 시간이 걸렸다. 실패가 요동친 데에는 아무도 설계하지 않았고 바깥에서는 보이지 않는 이유가 있었기 때문이다.
세 번의 Cloudflare 장애를 짚어보고 싶다. Cloudflare는 이 규모의 회사 중 거의 아무도 하지 않는 일을 하기 때문이다: 길고, 기술적이고, 진짜로 정직한 포스트모템을 공개하고, 그걸 나란히 놓고 읽게 해준다. 그리고 나란히 놓고 읽으면, 놀라운 건 이렇게 잘하는 회사가 장애를 겪는다는 사실이 아니다. 장애들이 계속 같은 이야기를 한다는 것이다.
2019년: 정규식
2019년 7월 2일에서 시작하자. Cloudflare는 WAF — 트래픽에서 공격을 검사하는 관리형 규칙 — 에 새 규칙을 밀어넣었다. 규칙 하나에 정규식이 들어 있었고, 그 정규식은 파국적 백트래킹(catastrophic backtracking)을 했다: 특정 입력에서 빠르게 매치되거나 실패하는 대신, 지수적으로 많은 경우의 수를 헤매며 CPU 코어 하나를 고민으로 붙잡았다.
Cloudflare는 그 WAF를 HTTP 트래픽을 서빙하는 모든 머신에서 돌린다. 그래서 규칙이 나가자, 전 세계 네트워크의 CPU 사용률이 HTTP·HTTPS를 처리하는 모든 코어에서 사실상 100%까지 올랐다. 27분 동안 Cloudflare 뒤에 있던 인터넷의 큰 덩어리가 그냥 사라졌다 — 느려진 게 아니라 사라졌다 — 모든 서버가 요청에 답하는 대신 정규식을 백트래킹하느라 바빴기 때문이다.
포스트모템에는 정규식 자체보다 더 중요한 디테일이 있다. 단일 정규식 평가에 쓰는 CPU를 상한 씌우는 보호 장치가 존재했었다. 그게 앞선 WAF 리팩터링 과정에서 제거됐다. 바로 이 종류의 실수를 잡아야 했던 가드가 더는 거기 없었고, 규칙은 도중에 걸러줄 단계적 롤아웃 없이 한 번에 지구 전체로 나갔다.
2025년 6월: 의존성
2025년 6월 12일로 건너뛰자. 이건 표면적으로는 완전히 달라 보인다. 나쁜 정규식도, CPU 고갈도 없다. 대신 Cloudflare의 키-값 저장소인 Workers KV가 2시간 28분 동안 백엔드 스토리지 접근을 잃었다.
KV가 그토록 중요했던 이유는, 놀랄 만큼 많은 다른 Cloudflare 제품이 그것에 기대고 있어서다. Access, Gateway, WARP, Images, Stream, Turnstile — 이들 모두가 Workers KV에서 설정과 상태를 읽고, KV의 백엔드 저장소 일부는 서드파티 클라우드에 있었다. 그 클라우드에 IAM 문제가 생겼다: 신원 서비스 롤아웃이 어긋나 토큰 발급이 멈췄고, 저장소로의 읽기·쓰기가 타임아웃됐다. KV가 내려갔고, KV 위에 서 있던 모든 것이 함께 내려갔다.
다른 실패, 같은 형태. 거대한 폭발 반경이 조용히 의존하던 단일 컴포넌트가, 아무도 하중을 견디는 부품이라 예상 못 한 변경에 무너졌다.
2025년 11월: 피처 파일
그래서 모두가 공격받는다고 생각한 그날로 돌아온다.
Bot Management — 요청이 사람인지 봇인지 점수 매기는 Cloudflare의 시스템 — 은 “피처 파일”로 돌아간다. ClickHouse 데이터베이스 쿼리로 생성되어 몇 분마다 엣지로 배포되는 설정 덩어리다. 11월 18일, 누군가 그 데이터베이스에 권한 변경을 했다. 그 변경은 그것만 떼어놓고 보면 합리적이었다. 부작용은, 피처 파일을 채우는 쿼리가 중복 행을 반환하기 시작해 파일 크기가 약 두 배로 불어난 것이었다.
새 프록시 엔진에는 하드 리밋이 있었다: 최대 200개의 피처를 받아들인다. 정상 운영에서 파일은 60개 정도를 담았으니, 아무도 그 천장을 생각하지 않았다. 두 배가 된 파일이 200을 넘겼다. 그리고 리밋에 부딪힌 Rust 코드가, 나쁜 설정을 전 세계 장애로 바꾸는 바로 그 짓을 했다: 에러 경로에서 unwrap()을 호출한 것이다. Rust에서 에러에 대한 unwrap()은 스레드를 패닉시킨다. HTTP 트래픽을 서빙하던 프로세스가 쓰러졌고, 그게 사용자에게는 5xx 에러가 됐다.
이제 요동침이 이해된다. 그 피처 파일은 몇 분마다 재생성됐고, 처음에는 데이터베이스 노드 일부에만 권한 변경이 적용돼 있었다. 그래서 파이프라인은 좋은 파일과 나쁜 파일을 번갈아 생성했다. 좋은 파일: 복구된다. 나쁜 파일: 전부 패닉. 복구, 패닉, 복구, 패닉 — 실패의 심장박동이었고, 안에서 보기엔 공격자가 약점을 탐색하는 모습과 똑같았다.
세 번, 같은 장애
나란히 놓아보자.
2019년: 변경(WAF 규칙)이 한 번에 전 세계로 나갔고, 잠복한 문제(제거된 CPU 가드)를 만났으며, 폭발 반경 차단이 없었다(전역 푸시, 스테이징 없음).
2025년 6월: 변경(의존하는 클라우드의 IAM 롤아웃)이 잠복한 문제(Cloudflare 절반이 하나의 키-값 저장소 위에 조용히 서 있던 것)를 만났고, 폭발 반경 차단이 없었다(KV가 모두에게 한꺼번에 실패).
2025년 11월: 변경(데이터베이스 권한 수정)이 잠복한 문제(200개 피처 리밋과 fail-closed로 죽는 unwrap())를 만났고, 폭발 반경 차단이 없었다(피처 파일이 몇 분마다 전역 푸시).
세 번의 장애, 세 개의 완전히 다른 근접 원인 — 정규식, 클라우드 제공업체, 데이터베이스 권한 — 그리고 그 밑에는 매번 하나의 구조. 변경이 빠르게 전 세계로 전파된다. 그것을 촉발하는 바로 그 입력이 나타나기 전까지 보이지 않던 잠복 취약성을 만난다. 그리고 그 중간의 무엇도 실패를 작게 만들도록 지어지지 않았다: 카나리도, 단일 불량 아티팩트가 함대를 얼마나 무너뜨릴 수 있는지에 대한 상한도, 죽는 대신 성능을 낮춰 버티는 에러 경로도 없다.
그 마지막 부분이 셋 모두의 조용한 흉수다. 2019년의 가드는 제거됐다. 2025년의 unwrap()은 폴백 대신 패닉을 택했다. 에러 처리가 fail-closed일 때 — “뭔가 잘못됐다”가 “마지막으로 알려진 정상 버전을 서빙한다”가 아니라 “서빙을 멈춘다”를 뜻할 때 — 모든 잠복 버그는 로그 한 줄이 아니라 장애가 된다.
고치기 어려운 이유, 그리고 사실 Cloudflare만의 문제가 아닌 이유
반사적인 대응은 “단계적 롤아웃을 넣고 전역 푸시를 멈춰라”다. Cloudflare도 안다; 그렇게 말했고, 11월 이후 작게 실패한다는 뜻을 이름에 담은 내부 노력을 발표했다. 하지만 이 패턴이 끈질긴 데에는 이유가 있고, 그건 CDN이 애초에 위험을 집중시키는 이유와 같다: 글로벌 엣지의 가치 제안 전체가 변경이 몇 초 만에 어디에나 닿는다는 것이다. 즉시 전파되는 설정은 기능이다. 지구 전역에서 거의 실시간으로 갱신되는 봇 점수는 기능이다. 그 속도와 균일함이 당신이 값을 치르고 사는 것이다.
단계적 롤아웃은 그 마찰을 제거한 것이 셀링 포인트인 시스템에 마찰을 일부러 되집어넣는 것이다. 추가하는 카나리 하나하나가 “이 머신엔 새 규칙이 있고 저 머신엔 없다”는 몇 분이고, 그 자체가 또 다른 버그와 운영 세금의 원천이다. 플랫폼을 빠르게 만든 그 본능이, 아무도 반응하기 전에 불량 아티팩트를 전역으로 만드는 바로 그 본능이다.
그래서 나는 이 포스트모템들을 “Cloudflare가 계속 실수한다”로 읽지 않는다. 업계 전체가 내린 설계 선택 — 중앙화하고, 빠르게 전파하고, 아티팩트를 믿는다 — 에 대해 되풀이해 날아오는 청구서로 읽는다. 대부분 아직 갚지 않은. 정직한 교훈은 체크리스트가 아니다. 당신 플랫폼의 초능력이 전 세계에 한 번에 한 가지를 하는 것이라면, 당신의 결정적 위험은 영원히 전 세계에 한 번에 잘못된 것을 하는 일이라는 것이다. 모든 포스트모템은 근접 원인만 새로 갈아 끼운 그 같은 문장이다.
다음 것은 이미 쓰이고 있다. 어떤 변경이 그것만 떼어놓고 보면 합리적으로 보일지 아직 모를 뿐이다.