{"id":"IL-0250","org":"Slack","date":"2021-09-30","docs":[],"title":{"en":"slack.com stopped resolving on some DNSSEC-validating resolvers for about 24 hours after DNSSEC signing was turned on","ko":"slack.com 에 DNSSEC 를 켠 뒤 일부 재귀 리졸버에서 slack.com 이름이 풀리지 않아 일부 사용자가 24시간 동안 Slack 에 접속하지 못했다"},"domain":["networking","aws"],"impact":{"scope":"Resolution of slack.com names such as app.slack.com on some recursive resolvers, so affected Slack clients could not connect for about 24 hours","users":"Less than 1% of Slack's online users","region":"unknown"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"The DNSSEC rollout had been tested only on domains without a wildcard record, so the Route 53 wildcard NSEC bug first appeared on slack.com; Slack names not testing a wildcard domain first as an oversight. Removing the DS record at the registrar does not stop validation at once, because resolvers cache the DS record from the .com zone for up to 24 hours, and removing the DNSKEY while that record is still cached makes every validating resolver fail. Managing DNS through Terraform hid the console warning about disabling DNSSEC. Re-enabling signing would neither have helped nor hurt, because Route 53 generates a new ZSK each time signing is enabled.","ko":"Slack 은 와일드카드 레코드가 있는 도메인을 slack.com 보다 먼저 시험하지 않은 것을 실수로 꼽았다. .com 영역의 DS 레코드는 리졸버에 최대 24시간 캐시되므로, DS 레코드를 내린 뒤에도 그 시간 동안은 권한 영역에서 DNSKEY 를 지우면 안 된다. 영역에 서명을 다시 켜도 DS 레코드의 TTL 에는 영향이 없다. Terraform 으로 DNS 를 관리하면 Route53 콘솔이 서명을 끌 때 띄우는 경고를 보지 못한다. 리졸버마다 NSEC 응답을 다르게 해석해도 규격에 맞을 수 있으므로, 권한 이름 서버가 실제로 있는 레코드 타입을 NSEC 타입 비트맵에 정확히 담는 것만이 이 모호함을 피하는 길이다."},"related":[],"sources":[{"url":"https://slack.engineering/what-happened-during-slacks-dnssec-rollout/","kind":"blog","archived":"https://web.archive.org/web/20261105011225/https://slack.engineering/what-happened-during-slacks-dnssec-rollout/"}],"summary":{"en":"Slack uses Amazon Route 53 as the authoritative DNS server for its public domains and delegates some subzones to NS1. DNSSEC, which FedRAMP Moderate requires, can only be enabled for a whole domain, not per subdomain or subzone. Every other critical Slack domain had run with DNSSEC for at least a month, and 30 September 2021 was the third attempt on slack.com, after attempts on 7 and 8 September had been rolled back. The team validated each step with external DNS and DNSSEC monitoring from many resolvers, dnsviz.net and Verisign DNSSEC Debugger tests, dnschecker.org tests and dig, and all checks passed before and after the DS record was published.\n\nThe root cause was a bug in how Route 53 answered for wildcard records. slack.com has a *.slack.com wildcard record, which none of the domains rolled out before had. For a wildcard name and a record type that does not exist, Route 53 returned a signed NSEC record that did not list the types that do exist. When a client asked for the AAAA record of app.slack.com, which Slack does not publish, some resolvers, including Google Public DNS, cached that NSEC answer and concluded that no A record existed either, so they returned NODATA for the A lookup. The cached answer poisoned only one regional cache at a time, which is why only some users of an affected resolver saw failures. Slack's first attempts to reproduce the failure with a copy of the slack.com setup failed; after the NetLogs pointed to the wildcard and the Route 53 team linked it to the NSEC bug, a DNSSEC-enabled test zone reproduced it against Google Public DNS but not against Cloudflare Public DNS (1.1.1.1). Slack concluded that reusing a cached NSEC record this way is protocol compliant, as in the optional Aggressive NSEC (RFC 8198) that Google implements. Route 53 later rolled out a fix.\n\nDuring the incident the team removed the DS record from the registrar and then, when nothing improved, removed DNSSEC signing from the zones through Terraform, which also meant the team did not see the Route 53 console warning about disabling DNSSEC. Based on expert advice the team believed that DS records in the .com zone were not cached, but the .com zone asks resolvers to cache the slack.com DS record for 24 hours, a value the zone owner cannot change (Google's 8.8.8.8 caps it at 6 hours). Resolvers that still held the DS record could no longer validate the unsigned zone and returned SERVFAIL. Slack asked major ISPs and public resolver operators to flush their slack.com records and used the public flush pages of 8.8.8.8 and 1.1.1.1. Re-signing the zone was considered but not done; Route 53 later confirmed it would have generated a new zone signing key (ZSK), so validation would have kept failing. Client telemetry sent to slackb.com, a separate domain, kept working and showed the impact. Error rates returned to normal as caches were flushed and the 24-hour DS TTL expired.","ko":"Slack 은 FedRAMP Moderate 요건 때문에 넉 달 동안 모든 공개 도메인에 DNSSEC 서명을 켜 왔고, slack.com 을 뺀 도메인은 영향 없이 켰다. 공개 도메인의 권한 DNS 서버는 Amazon Route 53 이고 일부 하위 영역은 NS1 에 위임한다. slack.com 은 앞서 두 번 시도했다가 되돌렸다. 9월 7일에는 미국 대형 ISP 장애가 겹쳐 예방 차원에서 되돌렸다. 9월 8일에는 VPN 을 거쳐 접속하는 사용자 일부가 해석 문제를 겪었다. 권한 서버에서 서명이 켜지면 일부 리졸버가 RFC-2181 에 따라 zone apex 의 CNAME 을 거부했기 때문이었다. 팀은 하위 위임 영역을 ALIAS 레코드로 바꿨다.\n\n9월 30일 세 번째 시도에서 팀은 서명을 켜고 세 시간 동안 검증한 뒤 DS 레코드를 올렸다. 곧 일부 재귀 리졸버가 NODATA 를 내며 Slack 클라이언트에 ERR_NAME_NOT_RESOLVED 가 떴다. 팀은 DS 레코드를 내렸고, 한 시간 가까이 나아지지 않자 slack.com 영역의 서명까지 되돌렸다. 팀은 전문가 조언을 믿고 .com 영역의 DS 레코드가 캐시되지 않는다고 생각했다. 실제로는 .com 영역이 리졸버에게 DS 레코드를 기본 24시간 동안 캐시하게 하고, 영역 주인은 이 값을 바꿀 수 없다. 그래서 DS 레코드를 캐시한 DNSSEC 검증 리졸버가 서명이 사라진 slack.com 의 모든 조회에 SERVFAIL 을 냈다. 팀은 DNS 설정을 Terraform 으로 관리해서, Route53 콘솔이 서명을 끌 때 띄우는 경고도 보지 못했다. 팀은 주요 ISP 와 공개 리졸버 운영자에게 캐시를 비워 달라고 요청했고, 8.8.8.8 과 1.1.1.1 은 공개 사이트에서 직접 비웠다. 서명을 다시 켜는 방안은 확신이 없어 택하지 않았다. 되돌릴 때 지워진 ZSK 는 서명을 다시 켜면 새 키로 만들어진다고 나중에 Route53 팀이 확인했다. 그래서 서명을 다시 켰어도 검증은 계속 실패했을 것이다. 캐시가 비워지고 DS 레코드의 24시간 TTL 이 끝나면서 오류율이 정상으로 돌아왔다. 온라인 사용자의 1% 미만이 24시간 동안 영향을 받았다.\n\n근본 원인은 다른 도메인에는 없던 *.slack.com 와일드카드 레코드에 있었다. Route53 은 와일드카드 레코드에 없는 타입을 물으면 서명된 NSEC 응답을 내는데, 이 응답에 그 이름에 있는 레코드 타입을 담지 않았다. 그래서 클라이언트가 app.slack.com 의 AAAA 레코드를 물으면, Google Public DNS 를 비롯한 일부 리졸버가 그 응답을 A 레코드도 없다는 뜻으로 받아 캐시했다. 캐시는 지역별로 따로라서 같은 리졸버라도 오염된 지역 캐시를 쓰는 사용자만 실패했다. Google 은 선택 규격인 RFC 8198 Aggressive NSEC 을 구현하고 있었고, Slack 은 두 리졸버의 동작이 모두 규격에 맞다고 결론지었다. Route53 팀이 NSEC 타입 버그의 수정을 배포했다."},"trigger":{"en":"On 30 September 2021 the Traffic Engineering team enabled DNSSEC signing on the slack.com zone in Amazon Route 53 and on its sub-delegated zones in NS1, and after a three-hour soak published the slack.com DS record at the DNS registrar.","ko":"2021년 9월 30일 Traffic Engineering 팀이 세 번째 시도로 slack.com 의 Route53 영역과 NS1 하위 위임 영역에 DNSSEC 서명을 켜고, 세 시간 뒤 DNS 등록 기관에 slack.com 의 DS 레코드를 올렸다."},"severity":"unknown","symptoms":["dns-resolution-failures"],"timeline":{"detected_after":null,"resolved_after":"24h"},"date_kind":"incident","detection":{"en":"Customer Experience received user reports of \"ERR_NAME_NOT_RESOLVED\" errors in Slack clients, and customers sent NetLog captures through support cases. After signing was rolled back, Slack's external DNS and DNSSEC resolution probes alerted the Traffic team.","ko":"DS 레코드를 올린 직후 Customer Experience 팀이 ERR_NAME_NOT_RESOLVED 를 본다는 사용자 신고를 받았다. 이때 DNSSEC 프로브는 정상으로 나왔다. 서명을 되돌린 뒤에는 외부 DNS·DNSSEC 해석 프로브가 여러 리졸버의 해석 실패를 알려 Traffic 팀이 호출됐다."},"components":["dns-server","recursive-dns-resolver","terraform"],"root_cause":"software-bug","remediation":[{"text":{"en":"Removed the slack.com DS record from the DNS registrar","ko":"등록 기관에서 slack.com 의 DS 레코드를 내려 .com 영역에서 지웠다."}},{"text":{"en":"Rolled back DNSSEC signing on the slack.com authoritative and delegated zones, which made resolution worse","ko":"slack.com 권한 영역과 위임 영역의 DNSSEC 서명을 되돌려 마지막 정상 설정으로 돌렸다."}},{"text":{"en":"Asked major ISPs and public DNS resolver operators to flush their cached slack.com records","ko":"주요 ISP 와 공개 DNS 리졸버 운영자에게 연락해 slack.com 의 캐시 레코드를 모두 비워 달라고 요청했다."}},{"text":{"en":"Flushed the slack.com records on Google's 8.8.8.8 and Cloudflare's 1.1.1.1 through their public flush sites","ko":"Google 8.8.8.8 과 Cloudflare 1.1.1.1 처럼 캐시 비우기 사이트를 둔 리졸버는 팀이 직접 캐시를 비웠다."}}],"action_items":[],"contributing":["staging-not-representative","assumption-unverified","manual-action-worsened","revert-did-not-restore","limited-debug-access"],"recurrence_of":null,"symptoms_text":{"en":"Soon after Slack published the DS record for slack.com at its DNS registrar on 30 September 2021, the Customer Experience team started getting user reports of \"ERR_NAME_NOT_RESOLVED\" errors in Slack clients. Fewer than 1% of online users were affected, and most reports came from users of one private corporate recursive resolver and of Google Public DNS (8.8.8.8).\n\nThe error came from NODATA DNS responses returned by some recursive resolvers. NetLog captures that customers exported from the Chromium-based Slack clients showed slack.com resolving successfully and app.slack.com failing with ERR_NAME_NOT_RESOLVED a moment later. Slack's own DNSSEC probes had gone green after the DS record was published, and the impact looked far smaller than a real Google DNS problem would cause.\n\nThe team first removed the DS record from the registrar, but after nearly an hour the error rate had neither risen nor fallen. The team then rolled back DNSSEC signing on the slack.com zones, and the situation became much worse: the Traffic team was paged for slack.com resolution failures from many resolvers around the world, for example 9.9.9.9, and every DNSSEC-validating resolver that had recently cached the slack.com DS record returned SERVFAIL for all slack.com lookups.\n\nResolution recovered slowly as resolver operators flushed their caches. Some hours in, slack.com resolved correctly for the vast majority of customers, but users of smaller resolvers that had not flushed their slack.com records kept failing until the 24-hour TTL on the DS record in the .com zone ran out.","ko":"2021년 9월 30일 slack.com 의 DS 레코드를 DNS 등록 기관에 올린 직후 Customer Experience 팀에 사용자 신고가 들어왔다. Slack 클라이언트에 \"ERR_NAME_NOT_RESOLVED\" 오류가 뜬다는 신고였다. 그런데 DNSSEC 검증을 강제하는 이름 해석 모니터링과 DNSSEC 프로브는 모두 정상으로 나왔다.\n\n이 오류는 일부 재귀 리졸버가 낸 NODATA 응답 때문이었다. 신고는 대부분 기업 내부의 재귀 리졸버와 Google 공개 리졸버 8.8.8.8 에서 왔다. Google DNS 가 영향을 받았다면 모니터링과 고객 신고에 잡힌 것보다 피해가 훨씬 컸어야 했으므로, 팀은 이 점을 이상하게 여겼다.\n\n팀은 먼저 등록 기관에서 DS 레코드를 내렸다. 한 시간 가까이 지나도 오류율은 오르지도 내리지도 않고 그대로였다.\n\nDNSSEC 를 원인 후보에서 완전히 지우려고 slack.com 영역의 서명까지 되돌리자 상황이 훨씬 나빠졌다. 전 세계 여러 리졸버에서 slack.com 이 풀리지 않는다는 알림이 와서 Traffic 팀이 호출됐다. 9.9.9.9 리졸버의 해석 실패 알림도 그중 하나였다. 최근 slack.com 의 DS 레코드를 캐시한 DNSSEC 검증 리졸버는 모든 slack.com 조회에 SERVFAIL 을 냈다.\n\n공개 리졸버의 캐시를 비우자 내부 모니터링이 조금씩 나아졌다. 몇 시간 뒤에는 대부분의 고객에게 slack.com 이 정상으로 풀렸지만, slack.com 레코드를 비우지 않은 작은 리졸버를 쓰는 사용자들은 계속 접속하지 못했다.\n\n고객이 보내 준 NetLog 에서는 12:32:59.120 에 slack.com 이 정상으로 풀렸고, 1마이크로초 뒤 app.slack.com 이 'ERR_NAME_NOT_RESOLVED' 로 실패했다. slack.com 은 풀리는데 app.slack.com 만 풀리지 않았다.\n\nDNSSEC 를 켠 시험 영역으로 재현하자, 와일드카드 이름에 dig AAAA qqq.slackexperts.com @8.8.8.8 +dnssec 를 물으면 NSEC 레코드에 \"RRSIG NSEC\" 만 실린 응답이 왔다. 그 뒤 dig A qqq.slackexperts.com @8.8.8.8 +dnssec 는 status: NOERROR 에 ANSWER: 0 이었다. 실제로 있는 A 레코드가 응답에 빠져 있었다. 같은 재현이 Cloudflare 공개 DNS 1.1.1.1 에서는 일어나지 않았다."},"updated_at":"2026-11-14T12:33:49.845494Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0250","org_slug":"slack"}