도메인의 IP를 조회하는 명령어인 nslookup을 공부하며 생긴 궁금증을 해소하는 과정을 담아봤습니다.
nslookup?
도메인이 사용하는 IP를 조회할 수 있는 간단한 명령어입니다.
nslookup의 동작 구조
nslookup의 대략적인 동작 과정은 다음과 같습니다.
- /etc/hosts 에서 요구하는 도메인 이름을 조회 -> 조회 성공 시 반환
- /etc/resolv.conf 에서 캐시 내역을 확인
- 캐시가 있으면 반환
- 캐시가 없으면 도메인 질의 수행
위 과정에서 다음과 같은 궁금증이 생겨 AWS EC2 환경에서 테스트를 수행해봤습니다.
- /etc/hosts 파일을 수정해서 임의의 도메인을 8.8.8.8로 연결지을 수 있을까?
- 캐시가 없는 경우 DNS 서버로 요청을 보낼텐데, 이 과정을 눈으로 확인할 수 없을까?
- 캐싱되어 있는 도메인 정보일텐데, 왜 또 DNS 서버로 요청을 보낼까?(2번에서 파생됨)
1. /etc/hosts 파일을 수정해서 임의의 도메인을 8.8.8.8로 연결지을 수 있을까?
nslookup은 명령어 수행 시 가장 먼저 /etc/hosts 파일을 확인합니다.
이때, 요청된 도메인이 hosts에 매핑되어 있을 경우 해당 정보를 반환하는데요.
이 파일에 임의의 도메인(osnie.com)을 8.8.8.8 도메인으로 매핑시켜보겠습니다.
이렇게 될 경우, osnie.com을 향하는 요청(ping, curl ..)은 모두 8.8.8.8로 요청될 것입니다.
- 127.0.0.1 localhost ... 는 IPv4의 루프백 도메인 이름을 설정합니다.(기본값)
- ::1 localhost6 ... 는 IPv6의 루프백 도메인 이름을 설정합니다.(기본값)
- 8.8.8.8 osnie.com 은 onsie.com 도메인 요청을 8.8.8.8으로 매핑시킵니다.(추가한 값)
설정한 후, ping을 수행해봅시다.
의도한대로 osnie.com 도메인의 요청이 8.8.8.8 주소로 매핑되어 요청이 나가고 있습니다.
2. 캐시가 없는 경우 DNS 서버로 요청을 보낼텐데, 이 과정을 눈으로 확인할 수 없을까?
/etc/hosts에 정보가 없는 경우 /etc/resolv.conf 캐시를 확인합니다.
캐시가 없으면, DNS 서버로 요청을 보내 IP 정보를 얻어오는데요.
이 과정을 눈으로 확인하고 싶었습니다.(실제로 그렇게 진행되는지)
실제로 확인하기 위해 DNS 서버로 요청되는 패킷을 확인하고자 하였고,
패킷 캡쳐 도구인 wireshark의 cli 버전인 tshark를 사용하기로 했습니다.
캡쳐할 네트워크 디바이스는 enX0이며, 53번 포트(DNS 프로토콜) 을 사용하는 패킷을 캡쳐해보겠습니다.
새로운 터미널을 열어 google.com에 curl 요청을 해보겠습니다.
Capturing on 'enX0'
76 8.951678418 172.31.35.251 → 172.31.0.2 DNS 70 Standard query 0x89e9 A google.com
77 8.951702008 172.31.35.251 → 172.31.0.2 DNS 70 Standard query 0xdeed AAAA google.com
78 8.952883730 172.31.0.2 → 172.31.35.251 DNS 86 Standard query response 0x89e9 A google.com A 142.250.76.142
79 8.952883844 172.31.0.2 → 172.31.35.251 DNS 98 Standard query response 0xdeed AAAA google.com AAAA 2404:6800:400a:80e::200e
DNS 프로토콜을 이용한 요청이 감지됐습니다.
각 라인에서 A와 AAAA는 각각 IPv4, IPv6 주소를 의미합니다.
이로써, 캐시가 없는 경우 DNS 서버로 IP 조회 요청을 하는 것까지 패킷을 통해 눈으로 확인할 수 있었습니다.
3. 캐싱되어 있는 도메인 정보일텐데, 왜 또 DNS 서버로 요청을 보낼까?(2번에서 파생됨)
여기서 요청을 한 번 더 보내봅시다.
Capturing on 'enX0'
76 8.951678418 172.31.35.251 → 172.31.0.2 DNS 70 Standard query 0x89e9 A google.com
77 8.951702008 172.31.35.251 → 172.31.0.2 DNS 70 Standard query 0xdeed AAAA google.com
78 8.952883730 172.31.0.2 → 172.31.35.251 DNS 86 Standard query response 0x89e9 A google.com A 142.250.76.142
79 8.952883844 172.31.0.2 → 172.31.35.251 DNS 98 Standard query response 0xdeed AAAA google.com AAAA 2404:6800:400a:80e::200e
881 671.643138660 172.31.35.251 → 172.31.0.2 DNS 70 Standard query 0xf05c A google.com
882 671.643160663 172.31.35.251 → 172.31.0.2 DNS 70 Standard query 0x665f AAAA google.com
883 671.643969741 172.31.0.2 → 172.31.35.251 DNS 86 Standard query response 0xf05c A google.com A 142.250.76.142
884 671.644091274 172.31.0.2 → 172.31.35.251 DNS 98 Standard query response 0x665f AAAA google.com AAAA 2404:6800:400a:80a::200e
이상합니다. 이미 한 번 보냈던 내용이므로 캐싱되는 것이 맞을텐데, DNS 요청 패킷이 나갑니다.
[ec2-user@ip-172-31-35-251 ~]$ systemd-resolve --statistics
DNSSEC supported by current servers: no
Transactions
Current Transactions: 0
Total Transactions: 0
Cache
Current Cache Size: 0
Cache Hits: 0
Cache Misses: 0
DNSSEC Verdicts
Secure: 0
Insecure: 0
Bogus: 0
Indeterminate: 0
resolve의 캐시 통계를 봐도 캐싱된 기록이 없습니다.
이유를 찾아보니, 아마존 리눅스에서는 DNS 캐싱을 교묘하게 동작하지 않도록 바꿔놨다고 합니다 (참고 블로그)
블로그를 통해 아마존 리눅스에서 수동으로 DNS 캐싱을 활성화 하였고 다시 한 번 시도해봤습니다.
캐싱이 정상적으로 동작합니다. 패킷을 추적해보아도 두 번째 요청부터는 DNS 요청이 나가지 않는 것으로 확인됐습니다.
결과적으로 위에서 서술한 nslookup 동작 과정은 오해가 없었고, 아마존 리눅스의 이상한(?) 설정으로 인해 캐시가 동작하지 않았던 것으로 생각할 수 있습니다.
마치며
nslookup의 동작 과정을 살펴보며 더불어 많은 것들을 알게되었습니다.
아직 많이 부족한 지식이지만 조금씩이나마 채워져 가는 것이 참 재밌는 거 같습니다.
'알아보자!' 카테고리의 다른 글
Java String의 hashCode()와 equals()에 대해 알아보기! (3) | 2025.08.11 |
---|---|
JAVA 명령어 동작 흐름 알아보기! (JAVA_HOME만 바꿨는데 왜 버전이 바뀔까?) (1) | 2025.07.03 |
도커 컨테이너의 네임스페이스를 체감(?)해보자 (0) | 2025.04.07 |
JWT를 이용한 로그아웃 구현 (1) | 2024.02.28 |
JWT(JSON Web Token) 구성 요소 (0) | 2024.02.24 |