DNS 조회와 캐시
100분 안팎
학습 목표
실습 전용 school.test 이름을 DNS에 등록하고 응답·TTL·NXDOMAIN을 확인합니다.
개념
이름 장애를 주소 장애와 분리합니다
학생이 school.test가 열리지 않는다고 신고했습니다. IP로 HTTP 요청은 되는데 이름으로 실패한다면 DNS 단계부터 확인할 근거가 있습니다. 하지만 IP 요청이 성공했다는 이유로 TLS까지 정상이라고 결론 내리지 않습니다. 이번에는 실습 전용 DNS에서 school.test와 web.school.test의 A 응답을 등록하고 TTL·상태 코드·권한 표시를 읽습니다. 조회 조건을 적어야 다른 담당자가 같은 답을 비교할 수 있으며 외부 인터넷의 이름 서버에는 실습 이름을 등록하지 않습니다.
A 레코드가 연결 대상을 제공합니다
A는 이름에 대한 IPv4 주소 정보입니다. school.test의 값은 서버 VLAN의 10.20.30.11입니다. DNS는 HTTP 서비스가 동작하는지 검사하지 않고 등록된 주소를 응답합니다. 포트 8080은 A 레코드에 들어 있지 않으며 URL과 애플리케이션 설정으로 선택합니다. 따라서 A가 맞아도 수신 포트를 잘못 쓰면 연결은 실패할 수 있습니다. 이름·레코드 종류·응답 주소와 후속 연결 포트를 각각 기록해 같은 단계의 값으로 혼동하지 않습니다.
권한 있는 응답과 재귀 조회를 구분합니다
권한 있는 서버는 자신이 맡은 이름 영역의 원본 정보를 제공합니다. 재귀 해석기는 사용자의 질의를 대신 해결하고 캐시를 활용할 수 있습니다. 이번 r1의 10.20.30.1은 실습 이름에 대해 AA 표시로 답하고 외부 이름은 REFUSED로 거절합니다. 재귀 기능을 제공하지 않으므로 인터넷 이름 조회가 안 되는 것은 과제 범위에서 오류가 아닙니다. 지정 서버에 직접 조회한 결과를 운영체제의 모든 이름 해석 경로가 같다는 증거로 사용하지 않습니다.
조회 명령의 비교 조건을 고정합니다
dig @10.20.30.1 school.test A +noedns +time=1 +tries=1로 서버와 종류·대기 조건을 지정합니다. 응답의 QUESTION은 질문, ANSWER는 레코드 결과, 헤더의 status는 처리 결과입니다. SERVER 항목도 확인해 원하는 곳에 물었는지 봅니다. 제공 DNS는 간단한 UDP 질의만 처리하므로 +noedns로 확장 질의 요소를 제외합니다. 이것은 교육 서버의 제약이며 실제 DNS 조사에서 모든 확장 기능을 꺼야 한다는 지침이 아닙니다.
TTL은 캐시의 유효 시간을 나타냅니다
이름 응답의 TTL 60은 받은 정보를 캐시에 보관할 수 있는 시간입니다. 현재 실습 서버를 직접 반복 조회하면 원본 TTL이 다시 60으로 보일 수 있습니다. 이것은 캐시가 만료되지 않았다는 뜻이 아니라 새 원본 응답을 받은 관측일 수 있습니다. 재귀 캐시에서 남은 시간이 감소하는 모습과 권한 응답의 TTL을 구분합니다. 재귀 캐시 서버는 구현하지 않습니다. 대신 dns_cache_probe.py가 실제 A 응답을 단일 클라이언트 캐시에 저장하고 1초 뒤 저장 값을 재사용해 남은 TTL의 감소를 검사합니다. 만료 경계는 별도 계산 모형으로 판단합니다.
캐시 변경은 관측 위치마다 다릅니다
원본을 바꾸어도 이미 저장된 응답이 즉시 사라지지는 않습니다. 캐시에 응답을 저장한 시각과 그때의 TTL을 기준으로 남은 시간을 계산합니다. 변경 순간에 TTL을 낮추어도 이전 긴 TTL을 받은 캐시는 바로 새 값을 알지 못할 수 있습니다. 반대로 권한 서버에 새 값이 보인다고 모든 사용자에게 전파가 끝났다고 말하지 않습니다. 변경 검증에서는 원본·재귀 해석기·애플리케이션의 관측 시각과 주소를 나누어 남깁니다.
NXDOMAIN은 이름이 없다는 응답입니다
missing.school.test를 질문하면 이번 서버는 NXDOMAIN을 반환합니다. 이는 DNS 메시지를 받았으며 요청한 이름이 없다고 응답했다는 뜻입니다. 질의 제한 시간이 지나도 응답을 받지 못한 상황과 다릅니다. 존재하는 이름에서 A 대신 다른 레코드 종류를 물어 답이 비는 경우에는 이름 자체가 없는 NXDOMAIN과 구분해야 합니다. 제공 서버는 school.test의 AAAA 질의에 NOERROR와 빈 답을 주므로 주소가 없는 종류와 이름 부재를 비교할 수 있습니다.
짧은 출력만 보면 상태를 잃습니다
dig +short는 주소 확인에는 편하지만 빈 출력으로 NXDOMAIN과 빈 답·질의 실패를 전부 구분하기 어렵습니다. 따라서 오류 조사에는 헤더와 응답 상태를 보존합니다. dig의 종료 코드만으로 이름 존재를 판정하지 않고 status: NXDOMAIN 같은 필드를 함께 읽습니다. SERVFAIL은 질의 해결 실패의 상태이고 REFUSED는 거절입니다. 어느 상태든 이름이 없다는 뜻으로 통일하면 실제 서버 장애와 정책 거절을 잘못 고칠 수 있습니다.
실습 서버의 한계를 드러냅니다
제공 service.py는 작은 A 응답과 실습 이름의 부재를 보여주는 교육 앱입니다. TCP 질의, 위임, DNSSEC, SOA 기반 음수 캐시를 구현하지 않습니다. NXDOMAIN의 상태 확인을 위한 앱이며 운영 권한 서버의 완전한 구현이 아닙니다. 실제 음수 캐시를 검증하려면 적절한 SOA와 재귀 서버가 필요합니다. 여기서는 코드의 성공 범위를 A·TTL·AA·NXDOMAIN으로 제한하고 나머지는 확인 대기나 범위 밖이라고 기록합니다.
hosts와 DNS를 혼동하지 않습니다
일반 애플리케이션은 시스템 설정에 따라 hosts나 로컬 해석 기능을 거칠 수 있고 dig는 지정 DNS 서버에 질의합니다. 두 결과가 다르면 각각의 조회 경로와 이름을 비교합니다. 이번 웹 검사에서는 검증한 A 주소를 curl --resolve로 고정하므로 이름 기반 URL을 유지하면서 DNS 질의 자체를 우회합니다. 이 요청 성공은 DNS가 정상이라는 독립 증거가 아닙니다. 먼저 dig 결과를 얻고 후속 연결에서 원래 이름을 유지하는 시험으로 구분합니다.
레코드 오류를 수정합니다
DNS starter의 record가 서버 주소표와 다릅니다. services.json의 record를 10.20.30.11로 맞추고 python3 test_services.py의 FAIL: record가 사라지는지 봅니다. dns는 DNS 수신자의 주소이고 record는 질문에 응답할 웹 서버 주소입니다. 둘을 모두 같은 값으로 바꾸는 것은 역할 혼동입니다. Linux 검사에서는 ANSWER에 정확한 주소가 있는지와 TTL 60을 함께 검사하고 전체 질의에서 AA 표시를 확인합니다.
응답 없는 DNS를 조사합니다
timed out 또는 no servers could be reached는 유효한 DNS 답을 받지 못했다는 단서입니다. 먼저 질의 대상 주소와 UDP 53 수신자를 확인하고 학생에서 r1의 서버 VLAN 주소까지 왕복 경로가 있는지 조사합니다. 공개 DNS를 대신 넣어 school.test 조회를 시도하면 실습 영역을 모르는 서버에 묻는 셈입니다. 원래 질의 대상의 경로와 서비스 상태를 고친 뒤 같은 질문을 다시 실행해야 원인과 수정의 관계를 설명할 수 있습니다.
이름의 경계를 통제합니다
실습 이름은 school.test와 그 하위 이름으로 제한합니다. 외부 이름에는 REFUSED로 답하고 호스트나 공유 망에 DNS 포트를 열지 않습니다. 이름 문자열은 대소문자와 끝의 점에 따른 표시 차이가 있을 수 있으므로 질의 종류와 논리 이름을 중심으로 비교합니다. 등록된 web.school.test와 school.test는 같은 A 값을 사용하지만 서로 다른 이름입니다. 한 이름이 성공했다고 오타가 있는 다른 이름까지 정상이라고 보고하지 않습니다.
DNS 증거 묶음을 제출합니다
정상 이름의 전체 응답과 주소·TTL, 없는 이름의 NXDOMAIN 응답을 한 묶음으로 제출합니다. 질의한 서버와 실행 시각을 포함하고 DNS 오류를 TCP 오류와 다른 행에 적습니다. 캐시 계산 모형의 시간은 가상 입력임을 표시합니다. 운영체제 캐시를 실제로 지우지 않았다면 그렇게 적고 변경이 모두 전파됐다는 문장을 피합니다. 관련 도구의 세부 옵션과 일반 이름 해석 경로는 더 읽기로 이어가며 이번 제출물은 학교망의 실측에 집중합니다.
기술 확인: DNS의 TTL·AA·응답 코드의 공식 명세를 참고했습니다. 설명과 학교망 예제는 이 레슨의 과제에 맞춰 작성했습니다.
따라하기
TTL 만료 경계를 계산합니다
패킷 관측이 아닌 결정적인 계산 예제입니다. 이 출력의 범위만 판단합니다.
stored=100;ttl=60
for now in [100,159,160,161]:
print(now,max(0,stored+ttl-now),now<stored+ttl)실행 결과
100 60 True 159 1 True 160 0 False 161 0 False
수정한 설정을 검사합니다
압축을 푼 루트에서 starter의 잘못된 필드를 수정합니다. 다음 출력은 solution 설정을 실제 실행한 결과입니다. 서비스 패킷 전송의 증거는 아닙니다.
python3 test_services.py실행 결과
PASS: transport PASS: web-name PASS: pool PASS: reservation PASS: gateway PASS: dns PASS: record PASS: timers
Linux에서 실제 서비스를 검증합니다
다음 명령은 Linux 외부 검증 대기입니다. check.sh가 실제 A·TTL·AA와 이름 부재 응답 및 단일 클라이언트 캐시의 감소을 확인합니다. 상세 수치와 메시지는 실행 후 생성된 services.csv로 확인합니다. 서비스 관측 명령은 35초 실행 중에 사용하며 종료 뒤에는 망이 정리됩니다.
sudo bash check.sh
# 별도 관측은 서비스가 실행 중인 동안 수행합니다.
sudo ip netns exec bcnet-s1 dig @10.20.30.1 school.test A +noedns +time=1 +tries=1
sudo ip netns exec bcnet-s1 dig @10.20.30.1 missing.school.test A +noedns +time=1 +tries=1판단 근거를 제출합니다
질의 대상·이름·종류·AA·TTL·status를 표로 정리합니다. +short의 빈 결과만으로 NXDOMAIN을 단정하지 않고 전체 헤더를 보존합니다.
확인 문제
실습
starter.zip을 푼 루트에서 services.json의 record을 본문의 학교망 계약에 맞춰 수정합니다. python3 test_services.py로 일부 실패를 확인한 뒤 수정 결과를 검사합니다. Linux VM에서 sudo bash check.sh로 실제 단계 증거를 services.csv에 생성합니다. README의 검사 범위와 앱 제약을 보고서에 적고 미확인은 대기로 표시합니다.
실행 명령
sudo bash check.sh
기대 결과
설정 검사 8건과 Linux의 DHCP·DNS·TCP·TLS·HTTP 검사가 통과하고 소유한 망을 정리합니다.
모범 답안
모범 답안 내려받기더 읽기
면접 질문
- DNS 오류와 서버 연결 오류를 구분하는 방법을 설명합니다.