요약

  • NXDOMAIN과 NODATA는 실패의 두 가지 표기가 아닙니다. NXDOMAIN은 실질 질의 이름이 존재하지 않는다고 말하고, NODATA는 이름이 존재하거나 존재할 수 있으나 요청한 종류의 레코드는 없다고 말합니다. 증거의 범위가 다르기 때문에 캐시 키도 달라집니다.
  • RFC 2308은 부정 응답을 이동 가능하면서도 수명이 있는 것으로 만들었습니다. 권위 있는 SOA는 영역 맥락과 SOA TTL 및MINIMUM중 작은 값에서 파생된 수명을 제공하며, 리졸버는 이 카운트다운이 0에 도달하면 부정을 더 이상 사용해서는 안 됩니다.
  • DNSSEC, NXDOMAIN 컷, 공격적 부정 캐싱은 이후 하나의 검증된 부정 응답이 더 넓은 질의 집합에 답하도록 했습니다. 그 효율은 잘못된 범위나 과도한 수명의 대가를 높이지만, DNS 증거를 법적 소유권이나 영구적 진실로 바꾸지는 않습니다.

응답 섹션은 비어 있지만 현실은 그렇지 않다

service.example의 A 레코드를 요청한다고 상상해 보십시오. A 레코드가 없는 응답이 도착합니다. 그 사실만으로는 거의 아무것도 증명되지 않습니다. 이름이 없을 수도 있습니다. 이름에 MX와 TXT 레코드는 있지만 A 레코드는 없을 수도 있습니다. 서버가 리졸버를 다른 곳으로 회선(referral)할 수도 있습니다. 서버에 접근할 수 없거나 잘못 설정되어 일시적으로SERVFAIL을 반환할 수도 있습니다.

잘못된 해석을 캐시하면 클라이언트가 보는 네임스페이스가 변합니다. 캐시가 A만 없는데도 이름 전체가 없다고 판단하면, 이후 MX 요청은 메일 데이터가 존재하더라도 권위 서버에 도달하지 못할 수 있습니다. 반대로 권위 있는 응답이 NXDOMAIN이었는데 A만 없다고 기억하면, 존재하지 않는 것으로 이미 알려진 이름에 대해 AAAA, TXT 등 모든 종류를 묻는 낭비가 생깁니다.

그래서 DNS에는 두 종류의 '없음'이 필요했습니다. NXDOMAIN은Name Error응답입니다. CNAME 체인을 모두 따라간 뒤 실질 질의 이름과 클래스에 적용됩니다. NODATA에는 자체 응답 코드가 없으며,NOERROR, 관련 응답의 부재, 부정 응답과 회선을 구분하는 권위 데이터를 통해 추론해야 합니다. NODATA는 실질 이름, 요청 종류, 클래스에 적용됩니다.

이 차이가RFC 2308이 정식화한 캐시 튜플을 설명합니다. NXDOMAIN은<QNAME, QCLASS>아래에, NODATA는<QNAME, QTYPE, QCLASS>아래에 저장됩니다. 키의 작은 차이가 겉보기 현실의 큰 변화를 막아 줍니다.

CNAME은 부정의 주체를 옮긴다

사용자가 입력한 레이블이 권위 서버가 부정한 레이블과 항상 같은 것은 아닙니다. 별칭은 존재하면서 하나 이상의 CNAME 레코드를 통해 존재하지 않는 정식 대상을 가리킬 수 있습니다. NXDOMAIN은 마지막 대상에 관한 것이지, CNAME을 성공적으로 제공한 별칭에 관한 것이 아닙니다.

이것이 RFC 2308이 QNAME을 신중하게 정의한 이유 중 하나였습니다. 부정을 편한 첫 레이블에 붙이는 캐시는 유효한 별칭을 사라지게 하거나 실제 주체 밖에서 증거를 재사용할 수 있습니다. 올바른 부정 캐싱은 식별에서 시작합니다. 권위 서버가 정확히 어떤 이름을 부정했는가?

NODATA에도 같은 주의가 필요합니다. 체인 끝의 빈 응답은 정식 대상에 요청한 종류의 레코드가 없음을 보여줄 수 있습니다. 그러나 별칭에 다른 종류의 레코드가 없다는 것을 증명하지 않으며, 체인의 모든 레이블이 존재하지 않는다는 것을 증명할 것은 더욱 없습니다.

선택적 기억에서 이동 가능한 진술로

RFC 1034는 1987년에 부정 캐싱을 기술했지만 선택 사항으로 다뤘습니다. 실패를 기억하면 검색 경로나 자동화 소프트웨어가 같은 실패 질의를 반복할 때 트래픽과 응답 시간을 줄일 수 있었습니다. 그러나 원래 설계에는 중요한 전파 취약점이 있었습니다. 서버는 자신이 캐시한 부정 응답을 다른 리졸버에 같은 유용한 증거와 남은 수명을 갖고 안전하게 전달할 수 없었습니다.

1998년 3월에 발표된 RFC 2308이 이 간극을 메우고, 무언가를 캐시하는 리졸버에 대해 부정 캐싱을 필수로 만들었습니다. NXDOMAIN이나 NODATA를 보고하는 권위 있는 서버는 포함 영역의 SOA 레코드를 권위 섹션에 넣어야 합니다. 이 레코드는 말하고 있는 영역을 식별하고, 진술을 재사용하는 데 필요한 시간 정보를 담습니다.

부정 수명은 SOA 레코드의 TTL과 SOAMINIMUM값 중 작은 쪽입니다. 리졸버는 부정 결과와 함께 SOA를 저장합니다. 캐시에서 결과를 반환할 때는 표시되는 TTL에 캐시에 머문 시간이 이미 빠져 있습니다. 0에 도달하면 그 부정을 다시 사용해서는 안 됩니다.

RFC 2308의 저자 표기는 Mark Andrews의 CSIRO 소속을 기록하고 있습니다. 이는 역사적 출처일 뿐, 본 글의 기관적 주제가 아닙니다. 공유 표준과 그 후속 개정은 IETF 문서화 절차를 통해 개발되었습니다.

왜 '없다'는 말에 시계가 함께 다녀야 하는가

DNS 네임스페이스는 트리이지만, 질의는 포워더의 그래프를 통해 이동할 수 있습니다. 잘못 설정된 서버들은 서로에게 포워딩할 수 있습니다. 부정 응답에 이동 가능한 카운트다운이 없으면, 각 서버가 그것을 받아 새로운 로컬 수명을 부여하고 되돌려 보낼 수 있습니다. 만료되어야 할 진술이 무한히 순환할 수 있습니다.

그래서 RFC 2308은 SOA가 없는 부정 응답은 캐시해서는 안 된다고 규정합니다. 한 서버의 짧은 수명은 다른 서버가 그것을 재시작하면 한계가 되지 않습니다. SOA는 장식적 메타데이터가 아니라, 독립적인 캐시들이 동일한 주장의 감쇠를 유지할 수 있게 합니다.

이 수리는 과적(overload)된 필드도 정리했습니다.RFC 1035는 SOAMINIMUM을 내보내는 TTL의 하한으로 기술했습니다. 구현체들은 그것을 최솟값, 기본값, 부정 캐시 타이머로 사용했습니다. RFC 2308은 사용되지 않는 보편적 하한 의미를 폐기하고, 영역 파일 기본값을$TTL로 분리하며,MINIMUM은 부정 수명의 입력으로 유지했습니다. 운영 소프트웨어가 드러낸 모호성을 후속 표준이 좁힌 것입니다.

문장이 자리 잡기 전에 배포가 구분을 찾았다

RFC 2308은 영웅적 발명가 서사가 아니라 회고적 구현 역사를 담고 있습니다. 1980년대 후반의 CHIVES 작업이 기록되어 있는데, 반복되는 검색 경로 실패와 값비싼 DNS 오류가 부정 캐싱을 운영적으로 유용하게 만들었습니다. 또한 1990년대 초반의 BIND 작업이 기록되어 있는데, 이름 오류와NOERROR_NODATA를 구분하고, 처음에는 고정된 짧은 수명을 사용하다가 나중에 캐시 결과와 함께 증거를 반환할 수 있도록 SOA를 유지했습니다.

이 기록들은RFC 2181의 RRset 정밀성과 RFC 2308의 튜플이 왜 중요했는지 보여줍니다. 구현자들은 단순히 더 빠른 캐시를 발견한 것이 아니라, '답이 없다'는 것이 형식화되고 범위가 지정된 주장으로 표현되어야 한다는 것을 발견했습니다.

역사적 부록은 배포 인구조사가 아닙니다. 특정 날짜에 인터넷의 어느 비율이 어떤 동작을 사용했는지 알려 주지는 못합니다. 다만 교정의 방향을 보여줍니다. 빈 응답에서, 기억된 상태로, 그리고 다른 리졸버가 주체·종류·수명을 검사할 수 있는 이동 가능한 결과로.

효율 속에 숨은 생성 지연

올바른 부정 응답은 영역이 바뀌면 틀릴 수 있습니다. 재귀 리졸버가 여전히 NXDOMAIN을 들고 있을 때 운영자가 이름을 만들면, 그 클라이언트들은 계속 이름이 없다고 봅니다. AAAA에 대한 NODATA가 캐시된 뒤 운영자가 AAAA 레코드를 추가하면, 이름은 보이지만 IPv6 도달 가능성은 권위 변경보다 뒤처질 수 있습니다.

따라서 TTL은 신뢰 점수가 아니라 트레이드오프입니다. 긴 부정 수명은 반복 질의와 권위 부하를 줄입니다. 그러나 생성이나 복구가 보이지 않는 구간을 연장합니다. RFC 2308은 리졸버가 공표된 값을 상한 처리할 수 있으며, 1~3시간 기본값이 실용적이라고 보면서 하루를 넘는 값이 문제를 일으켰다고 경고합니다.

전역 만료 순간은 없습니다. 리졸버들은 서로 다른 시각에 응답을 받고 서로 다른 상한을 적용할 수 있습니다. 영역이 지금 올바르더라도 클라이언트들은 유계(有界)된 더 오래된 부정을 계속 관찰할 수 있습니다. 롤아웃 계획은 변경 후 권위 서버가 무엇을 서비스하는지만이 아니라, 변경 전에 무엇이 캐시되었는지까지 고려해야 합니다.

실패는 주장 밖에 있어야 합니다. 타임아웃, 접근 불가 서버,SERVFAIL은 존재하지 않음이 아닙니다. RFC 2308은 일부 실패 조건에 별개의, 엄격히 제한된 선택적 캐싱 처리를 부여합니다. 임시적인 응답 불능을 NXDOMAIN으로 바꾸는 애플리케이션은 복구 가능한 장애를 메일 거부나 서비스 탐색 포기 같은 영구적 결정으로 바꿀 수 있습니다.

하나의 부정이 여러 질문에 답하기 시작할 때

DNSSEC는 부재에 대한 암호학적 증거를 추가했습니다.RFC 4034는 이름들을 정식 순서로 연결하고 소유자에 존재하는 레코드 종류를 나열하는 NSEC 레코드를 정의하며,RFC 4035는 검증자가 그 레코드로 NXDOMAIN이나 NODATA를 증명하는 방법을 정의합니다.

이 구분은 서명을 넘어서 유지됩니다. 소유자 이름 사이의 간격은 이름의 부재를 증명할 수 있습니다. 존재하는 소유자의 종류 비트맵은 요청한 종류의 부재를 증명할 수 있습니다. 암호학은 관련 DNS 진술을 인증할 뿐, 두 진술을 서로 바꿔 쓸 수 있게 하지는 않습니다.

RFC 5155는 해시된 소유자 이름과 Opt-Out을 포함하는 NSEC3를 도입했습니다. Opt-Out은 명시적 증거 한계입니다. 커버(cover)하는 NSEC3 레코드는 그 아래의 모든 가능한 이름이 없다는 것을 증명하지 않습니다.

RFC 8020은 이후 정의된 경계 내에서 노드의 NXDOMAIN이 그 아래 질의를 중단하도록 허용했습니다. 이 규칙은 트리를 따릅니다. 존재하지 않는 이름 아래에 후손이 존재할 수는 없습니다. NODATA에는 적용되지 않습니다. 한 종류의 레코드가 없는 이름은 여전히 다른 레코드와 후손을 가질 수 있기 때문입니다.

RFC 8198은 검증 리졸버가 캐시된 NSEC/NSEC3 증거를 공격적으로 사용하도록 합니다. 하나의 인증된 범위가 상위로 전송된 적 없는 질문에 대해 합성된 부정 응답을 뒷받침할 수 있습니다. 절약은 일반적인 정확 질의 캐싱보다 크고, 범위 안에 새 이름이 도입될 때 낡은 부정 증거의 결과도 그만큼 큽니다.

유계(有界)된 프로토콜 증거

부정 응답 체인은 권위와 실행을 분리합니다. 영역 운영자는 현재 내용과 타이밍 값을 선택합니다. 권위 있는 서버는 응답을 구성합니다. 재귀 리졸버는 그것을 분류하고, 튜플을 선택하고, 해당하면 검증하고, 로컬 한도를 적용하고, 결국 폐기합니다. 애플리케이션은 결과가 사용자나 트랜잭션에게 무엇을 의미하는지 결정합니다.

각 역할은 권한을 갖지만, 어느 것도 자기 층 밖의 현실을 소유하지 않습니다. DNSSEC 서명은 DNS 체인 하에서 출처와 무결성을 증명합니다. 이름에 대한 법적 권리, 조직의 존재하지 않음, 삭제의 현명함을 증명하지는 않습니다. 캐시는 유효한 부정을 증폭할 수 있지만, 그것을 영구히 만들 권위를 얻지는 못합니다.

역사적 성취는 정확하면서도 겸손했습니다. DNS는 부재를 이동할 수 있는 증거로 바꾸었습니다. 무엇이 빠져 있는지, 누가 관련 영역을 위해 말할 수 있는지, 독립적인 리졸버들이 그 진술을 얼마나 재사용할 수 있는지를 식별한 것입니다. NXDOMAIN과 NODATA의 구분은 그 효율이 여전히 존재하는 데이터를 지우지 않도록 지켰습니다.

출처와 한계

원래의 캐싱과 SOA 맥락은RFC 1034와RFC 1035에 문서화되어 있으며,RFC 2181이 RRset 명확화를 제공합니다. 부정 응답 정의, 튜플, SOA 수명, 포워딩 루프 경고, 구현 역사는RFC 2308에서 옵니다.

인증된 부정은RFC 4034,RFC 4035,RFC 5155로 유계(有界)됩니다. 이후의 NXDOMAIN 하위 트리 규칙은RFC 8020이고, 검증된 범위 합성은RFC 8198입니다. 후속 동작을 초기 리졸버에 투영하지 않으며, RFC 2308 부록은 완전한 측정 기록이 아니라 회고적 구현 증거로 다룹니다.