DNS(Domain Name System)이라고 불리는 인터넷 프로토콜은 IP(Internet Protocol) 기반의 주소 체계에서 숫자로 기억하기 힘든 서버 주소를 대체하기 위해 개발되었습니다.
IP기반의 인터넷에서 각 노드들(예를 들어 개인용 컴퓨터 등)은 자신들을 구분하기 위해 자신만의 IP 주소를 가지고 있습니다.
이 IP 주소를 가지고 우리는 친숙한 네이버나 다음부터 미국의 구글에 접속할 수 있습니다.
그런데 우리는 인터넷에서 어떤 사이트에 접근하고자 할때 웹 브라우저의 주소창에 IP 주소를 입력하지 않습니다.
대신에 다른 웹사이트와 구분되는 특정한 문자열을 입력합니다. 예를 들어 네이버에 접근하려면 naver.com
을 입력하고 다음에 접근하려면 daum.net
을 입력합니다.
그 이유는 IP 주소가 도메인 네임
이라는 것과 1:1로 매핑되어 있기 때문입니다.
도메인 네임(Domain Name)은 숫자로 이루어진 IP 주소를 특정한 문자열로 나타낸 것입니다.
그러면 IP Name이라고 하면 될 것을 왜 도메인이라는 용어를 사용했을까요?
도메인 네임에는 계층구조가 존재합니다. 도메인 네임들을 떠올려 봅시다.
naver.com
, google.com
, gov.kr
, wikipedia.org
, chungbuk.ac.kr
, velog.io
이들의 공통점은 중간에 점(dot: .)으로 구분된다는 것입니다. 도메인 네임은 점을 통해 계층을 분리하며 오른쪽에서 왼쪽으로 갈수록 도메인의 범위가 작아집니다.
그래서 도메인 쿼리를 보낼 때에는 보통 왼쪽에서 오른쪽의 DNS 서버에 요청을 보내게 됩니다.
chungbuk.ac.kr
을 예시로 보겠습니다.
이러한 도메인 이름을 통해 구분되는 각각의 도메인 네임 서비스 서버들은 하나의 도메인 네임 서버가 너무 많은 도메인 네임을 처리하는 것을 방지할 수 있습니다.
또한 도메인 이름을 통해 해당 사이트가 어떤 성향을 가진 사이트인지도 유추가 가능해진다는 장점이 있습니다.
naver.com
과 google.com
은 서로 다른 나라에 속한 서비스 입니다.
하지만 같은 com
이라는 최상위 도메인(분야)안에 속하기 때문에 상업 조직이 만든 웹 사이트라는 것을 유추해볼 수 있습니다.
이런 DNS를 사용하기 위해서 컴퓨터에서는 DNS 서버에 쿼리를 보내어 해당 도메인 네임에 대한 IP를 가져옵니다.
DNS 쿼리의 경우 크게 Request와 Reply로 구분할 수 있습니다.
아래는 DNS Request와 DNS Reply 패킷의 일부입니다. 어느쪽이 Request이고 Reply일까요?
플래그를 보면 알 수 있습니다. 가장 상위 flag를 보면 위 그림에는 Message is a query
가 아래 그림에는 Message is a response
라고 적혀 있는 것을 확인할 수 있습니다.
또한 Queries
에 어떤 도메인 주소에 대한 IP 주소가 필요한지가 나타나 있습니다. 각각의 Query들의 총 개수는 Questions에 저장되어 보내집니다.
만약 더 딥한 내용이 궁금하시다면 RFC1035에서 DNS에 대한 더욱 상세한 내용을 확인해 볼 수 있습니다.
https://datatracker.ietf.org/doc/html/rfc1035
from scapy.all import *
targetName = 'www.example.com'
dstIP = '8.8.8.8' #DNS 서버 주소
Qdsec = DNSQR(qname=targetName)
dns = DNS(id=100, qr=0, #id는 트랜잭션 ID입니다.
qdcount=1, qd=Qdsec) #questions은 1입니다.
ip = IP(dst=dstIP) #src가 없으면 자기 자신입니다.
udp = UDP(dport=53) #DNS의 널리 알려진 포트 53을 이용합니다.
Requestpkt = ip/udp/dns
send(Requestpkt)
위 예시와 같이 적절하게 수정하여 DNS 쿼리를 보내볼 수 있습니다.