Incident Library

IL-0340 Cloudflare · 2023-10-04networking

Cloudflare 1.1.1.1 리졸버가 4시간 동안 일부 유효한 DNS 질의에 SERVFAIL 을 냈다

루트 존은 모든 최상위 도메인으로 가는 길을 알려 주는 DNS 존이고, DNSSEC 로 서명돼 있다. Cloudflare 의 재귀 DNS 인프라는 루트 서버에 닿지 못할 때를 대비하고 해석을 빠르게 하려고 루트 존 사본을 받아 둔다. 새 루트 존은 보통 하루 두 번 나오고, 1.1.1.1 에서는 주 DNS 로직 위에서 도는 WebAssembly 앱 static_zone 이 새 판을 받아 내준다. static_zone 은 새 판을 파싱하는 데 성공해야 옛 판을 버린다.

2023년 9월 21일, 미리 알려진 루트 존 관리 변경으로 루트 존에 ZONEMD 레코드가 처음 들어왔다. ZONEMD 는 루트 존 내용의 체크섬이다. Cloudflare 는 루트 존을 바이너리 형식이 아닌 표현 형식으로 내부에 배포해 왔고, 에지에서 루트 존을 파싱하는 라이브러리는 모르는 레코드 형식을 만나면 파서 오류를 냈다. 존은 통째로 읽혀야 하므로 새 루트 존은 쓰이지 못했다. 메모리에 옛 판이 없는 서버는 요청마다 루트 서버에 직접 질의했지만, 옛 판이 있는 서버는 9월 21일 06:30 UTC 에 마지막으로 받은 판을 계속 썼다.

10월 4일 07:00 UTC 에 그 판의 DNSSEC 서명이 만료되자 일부 리졸버가 서명을 검증하지 못하고 SERVFAIL 을 냈다. 07:57 에 외부 신고가 들어왔고 08:03 에 내부 장애가 선언됐다. 08:50 의 override 규칙은 다른 노드로 넘긴 질의에 태그가 실리지 않아 효과가 없었다. 10:30 에 1.1.1.1 이 루트 존 파일을 미리 읽지 않게 하자 10:32 에 응답이 정상으로 돌아왔고, 11:02 에 장애를 닫았다. Cloudflare 는 공격이 아니라 내부 소프트웨어 오류였다고 밝혔다.

심각도
–
영향 범위
DNS resolution through 1.1.1.1 and products built on it, including WARP, Zero Trust and third-party DNS resolvers that use 1.1.1.1; SERVFAIL peaked at 15% of all queries
영향 사용자
some users of 1.1.1.1
지역
mainly larger data centers such as Ashburn, Virginia; Frankfurt, Germany; and Singapore
감지까지
1h 3m
복구까지
3h 32m

증상

2023년 10월 4일 07:00 UTC 부터 1.1.1.1 을 직접 쓰거나 WARP, Zero Trust, 또는 1.1.1.1 을 쓰는 다른 회사의 DNS 리졸버를 거치는 일부 사용자가 유효한 질의에 SERVFAIL DNS 응답을 받았다. 07:57 에 예상하지 못한 SERVFAIL 을 알리는 외부 신고가 처음 들어왔다.

평소에도 전체 질의의 3% 쯤은 DNSSEC 체인 문제, 권한 서버 연결 실패, 권한 서버의 느린 응답 같은 정당한 이유로 SERVFAIL 이 난다. 장애 중 SERVFAIL 은 전체 질의의 15% 까지 올랐고, Cloudflare 리졸버가 내는 SERVFAIL 의 비율은 12% 늘었다.

영향은 고르지 않았다. 주로 버지니아주 애시번, 독일 프랑크푸르트, 싱가포르처럼 큰 데이터 센터에 몰렸다. 9월 21일 이후 1.1.1.1 서비스를 재시작한 리졸버 서버는 루트 서버에 직접 질의했으므로 영향이 없었다. 큰 데이터 센터에는 그동안 재시작하지 않은 서버가 많았다. 리졸버가 TTL 이 지난 인기 레코드도 캐시에서 계속 내주는 serve stale 을 써서 전면 장애로 번지지는 않았다.

08:50 에 오래된 루트 존으로 응답하지 않게 하려고 override 규칙 phase = pre-cache set-tag rec_disable_static 을 배포했지만 SERVFAIL 은 그치지 않았다. 캐시 성능을 위해 다른 노드로 넘기는 질의에는 rec_disable_static 태그가 실리지 않았고, 그 노드의 static_zone 앱은 계속 오래된 정보로 답했다.

증상 DNS 조회 실패오류율 상승

원인

촉발
9월 21일 루트 존에 ZONEMD 라는 새 리소스 레코드 형식이 처음 들어왔고, 1.1.1.1 리졸버가 이 레코드를 파싱하지 못해 새 루트 존을 쓰지 못했다. 10월 4일 07:00 UTC 에 계속 쓰던 9월 21일 판 루트 존의 DNSSEC 서명이 만료됐다.

감지

07:57 UTC 에 예상하지 못한 SERVFAIL 을 알리는 외부 신고가 처음 들어왔고, 08:03 에 Cloudflare 내부 장애가 선언됐다. static_zone 이 오래된 루트 존을 내주는 상황을 알리는 알림은 없었다.

조치

후속 조치

교훈

Cloudflare 는 무엇이든 바뀌지 않으리라고 가정하지 말라는 것을 이 사고의 분명한 교훈으로 꼽았다. 최종 실행 파일에 들어가는 긴 라이브러리 사슬 어디에든 버그가 있거나, 입력이 바뀔 때 제대로 동작할 만큼 일찍 갱신되지 않은 것이 있을 수 있다고 했다. 회귀를 잡아내는 테스트와 입력이 바뀌어도 부드럽게 실패하는 시스템이 중요하다고 했다. DNS 와 BGP 처럼 인터넷에서 가장 중요한 시스템의 형식 변경은 영향을 줄 것이라고 늘 가정해야 한다고 했다. 오래된 루트 존을 내주는 것을 더 잘 감시했다면, 이미 있는 캐시 덕분에 영향이 없었을 것이라고 했다.

출처

참고 문서

관련 사례

내 클러스터에도 있는지 확인하기

kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이 사례와 같은 상태를 점검합니다. 이 사례의 구성 요소: 재귀 DNS 리졸버 서비스. 점검 항목의 근거는 이 사례 같은 공개 보고서입니다.

AI 도구와 스크립트용

API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.