PromleeBlog
sitemap
aboutMe

posting thumbnail
DNS 시스템 - 코딩과 함께 배우는 네트워크 7일차
DNS System - Learning Network with Coding Day 7

📅

🚀

들어가기 전에 🔗

지난 시간에는 웹 통신의 핵심 언어인 HTTP와 HTTPS에 대해 배웠습니다.
오늘은 우리가 웹 브라우저에 www.google.com처럼 사람이 읽기 쉬운 주소를 입력했을 때, 컴퓨터가 어떻게 이 주소를 이해하고 실제 서버를 찾아가는지 그 비밀을 풀어줄
DNS(Domain Name System)
에 대해 알아보겠습니다.

🚀

DNS란 무엇일까요? 인터넷의 전화번호부! 🔗

DNS는 'Domain Name System'의 줄임말로, 쉽게 말해
인터넷 세상의 거대한 전화번호부
와 같습니다.
우리가 친구의 전화번호를 이름으로 저장해두고 필요할 때 이름을 찾아 전화를 거는 것처럼, DNS는 www.google.com 같은 사람이 기억하기 쉬운 도메인 이름을 컴퓨터가 이해할 수 있는 숫자로 된 IP 주소(예: 172.217.160.142)로 바꿔주는 역할을 합니다.

만약 DNS가 없다면, 우리는 수많은 웹사이트의 복잡한 IP 주소를 전부 외워야 할 겁니다.
DNS 덕분에 우리는 편리하게 인터넷을 사용할 수 있는 것입니다.

DNS의 주요 역할 🔗


🚀

DNS는 어떻게 동작할까요? 🔗

우리가 웹 브라우저에 www.example.com을 입력하면, 어떤 과정을 거쳐 IP 주소를 얻게 될까요? 이 과정을 단계별로 따라가 봅시다.
  1. 1단계: 내 컴퓨터 안의 DNS 캐시 확인 (Browser/OS Cache)
    가장 먼저 우리 컴퓨터는 이전에 www.example.com에 접속한 적이 있는지 자신의 DNS 캐시(기록)를 확인합니다.
    만약 기록이 있고 유효하다면, 바로 IP 주소를 사용합니다.
    매우 빠름
  2. 2단계: 로컬 DNS 서버에게 물어보기 (Recursive Resolver)
    내 컴퓨터 캐시에 정보가 없다면, 인터넷 서비스 제공자(ISP)가 설정해둔
    로컬 DNS 서버
    (또는 사용자가 직접 설정한 DNS 서버, 예: Google Public DNS 8.8.8.8, Cloudflare DNS 1.1.1.1)에게 " www.example.com의 IP 주소 좀 알려줘!" 하고 물어봅니다.
    이 로컬 DNS 서버를
    재귀적 리졸버(Recursive Resolver)
    라고도 부릅니다.
    이 친구는 IP 주소를 찾을 때까지 대신 열심히 발로 뛰어줍니다.
  3. 3단계: 루트(Root) DNS 서버에게 길 안내받기
    로컬 DNS 서버도 해당 도메인 정보가 없다면, 세상에서 가장 높은 곳에 있는
    루트 DNS 서버
    에게 "혹시 .com 도메인을 관리하는 서버가 어딘지 아니?" 하고 물어봅니다.
    루트 서버는 전 세계에 13개가 있으며, 최상위 도메인(TLD) 서버의 주소를 알려줍니다.
  4. 4단계: TLD(최상위 도메인) DNS 서버에게 물어보기
    로컬 DNS 서버는 루트 서버가 알려준 .com 도메인을 관리하는
    TLD DNS 서버
    에게 "혹시 example.com 도메인을 관리하는 서버가 어딘지 아니?" 하고 물어봅니다.
    TLD 서버는 해당 도메인(example.com)을 실제로 관리하는
    권한 있는 네임서버(Authoritative Name Server)
    의 주소를 알려줍니다.
  5. 5단계: 권한 있는 네임서버(Authoritative Name Server)에게 최종 IP 주소 받기
    드디어 로컬 DNS 서버는 example.com 도메인의 정보를 직접 가지고 있는
    권한 있는 네임서버
    에게 " www.example.com의 IP 주소가 뭐야?" 하고 물어봅니다.
    권한 있는 네임서버는 "그거? xx.xx.xx.xx 야!" 하고 최종 IP 주소를 알려줍니다.
  6. 6단계: 로컬 DNS 서버가 내 컴퓨터에게 IP 주소 전달 및 캐싱
    로컬 DNS 서버는 알아낸 IP 주소를 우리 컴퓨터에게 전달해주고, 동시에 자신도 이 정보를 일정 시간 동안
    캐시
    에 저장해둡니다.
    그래야 다음에 또 같은 요청이 오면 빠르게 응답할 수 있으니까요.
  7. 7단계: 웹 브라우저가 IP 주소로 웹 서버에 접속
    이제 우리 컴퓨터(웹 브라우저)는 드디어 www.example.com의 IP 주소를 알게 되었고, 이 IP 주소를 이용해 해당 웹 서버에 접속하여 웹 페이지를 가져옵니다.
DNS 질의 과정
DNS 질의 과정

🚀

DNS 캐싱과 TTL 🔗

위의 과정을 보면 IP 주소를 한 번 알아내는 데 꽤 여러 단계를 거치는 것을 알 수 있습니다.
매번 이렇게 한다면 인터넷이 너무 느려지겠죠? 그래서 등장한 것이 바로
DNS 캐싱(Caching)
입니다.

DNS 캐싱은 한 번 조회했던 DNS 정보를 일정 시간 동안 저장해두고, 같은 요청이 오면 저장된 정보를 바로 사용하는 기술입니다.
이렇게 하면 응답 속도도 빨라지고, 상위 DNS 서버들의 부담도 줄일 수 있습니다.

TTL (Time To Live): 캐시 정보의 유효기간 🔗

DNS 캐시 정보에는
TTL(Time To Live)
이라는 값이 함께 저장됩니다.
TTL은 해당 캐시 정보가 얼마나 오랫동안 유효한지를 나타내는 시간(초 단위)입니다.
도메인 관리자는 자신의 도메인 정보에 대한 TTL 값을 설정할 수 있습니다.
TTL 시간이 지나면 캐시된 정보는 삭제되고, 다시 DNS 질의 과정을 거쳐 새로운 정보를 가져오게 됩니다.

TTL 값이 너무 길면 IP 주소가 변경되었을 때 즉시 반영되지 않아 접속 문제가 생길 수 있고, 너무 짧으면 캐시의 효과가 줄어들어 DNS 서버에 자주 물어보게 되어 비효율적일 수 있습니다.
그래서 적절한 TTL 값을 설정하는 것이 중요합니다.

실습: Python으로 도메인 이름의 IP 주소 알아보기 🔗

Python의 socket 모듈을 사용하면 특정 도메인 이름에 해당하는 IP 주소를 간단하게 조회할 수 있습니다.
import socket # 소켓 모듈 임포트
 
def get_ip_address(domain_name):
    """
    주어진 도메인 이름의 IP 주소를 반환합니다.
    """
    try:
        # socket.gethostbyname() 함수는 도메인 이름을 IP 주소로 변환합니다.
        ip_address = socket.gethostbyname(domain_name)
        return ip_address
    except socket.gaierror as e:
        # getaddrinfo error (예: 호스트를 찾을 수 없음)
        print(f"오류: '{domain_name}'의 IP 주소를 찾을 수 없습니다. ({e})")
        return None
 
 # 조회하고 싶은 도메인 이름을 입력받습니다.
domain_to_lookup = input("IP 주소를 조회할 도메인 이름을 입력하세요 (예: www.google.com): ")
 
if domain_to_lookup:
    ip = get_ip_address(domain_to_lookup)
    if ip:
        print(f"'{domain_to_lookup}'의 IP 주소는 '{ip}' 입니다.")
else:
    print("도메인 이름이 입력되지 않았습니다.")
 
 # 몇 가지 추가 예시
print("\n--- 추가 예시 ---")
common_domains = ["www.naver.com", "www.youtube.com", "nonexistentdomain123abc.com"]
for domain in common_domains:
    ip = get_ip_address(domain)
    if ip:
        print(f"'{domain}' -> IP: {ip}")
    else:
        print(f"'{domain}' -> IP 주소 조회 실패")
 
실행 결과
IP 주소를 조회할 도메인 이름을 입력하세요 (예: www.google.com): www.google.com
'www.google.com'의 IP 주소는 '142.250.76.132' 입니다.
 
--- 추가 예시 ---
'www.naver.com' -> IP: 23.217.65.16
'www.youtube.com' -> IP: 142.250.76.142
오류: 'nonexistentdomain123abc.com'의 IP 주소를 찾을 수 없습니다. ([Errno 8] nodename nor servname provided, or not known)
'nonexistentdomain123abc.com' -> IP 주소 조회 실패
위 코드는 사용자로부터 도메인 이름을 입력받아 socket.gethostbyname() 함수를 사용하여 해당 도메인의 IP 주소를 출력합니다.
존재하지 않는 도메인에 대해서는 오류 메시지를 보여줍니다. 이 실습을 통해 프로그램이 어떻게 DNS 조회를 수행하는지 간접적으로 경험할 수 있습니다.
실제 DNS 리졸버의 복잡한 과정을 모두 보여주는 것은 아니지만, 최종 결과를 얻는 과정을 보여줍니다.

🚀

DNS 스푸핑과 보안 대책 🔗

DNS는 매우 편리하지만, 안타깝게도 보안 위협에 노출될 수 있습니다.
대표적인 공격이 바로
DNS 스푸핑(DNS Spoofing)
또는
DNS 캐시 포이즈닝(DNS Cache Poisoning)
입니다.

DNS 스푸핑은 공격자가 DNS 서버를 속이거나 DNS 응답을 가로채서, 사용자가 올바른 도메인 이름을 입력했음에도 불구하고 가짜(악성) 웹사이트의 IP 주소로 연결하도록 만드는 공격입니다.
마치 전화번호부의 번호를 몰래 바꿔치기해서 엉뚱한 곳으로 전화를 걸게 만드는 것과 같습니다.

이렇게 되면 사용자는 정상적인 사이트로 착각하고 개인 정보나 금융 정보를 입력하여 탈취당할 수 있습니다.

DNS 보안을 위한 노력 🔗


🚀

결론 🔗

오늘은 인터넷의 필수 안내자인 DNS 시스템에 대해 자세히 알아보았습니다.
DNS는 우리가 사용하는 도메인 이름을 컴퓨터가 이해하는 IP 주소로 변환해주는 마법 같은 역할을 하며, 캐싱과 TTL을 통해 효율적으로 동작합니다.
Python의 socket 모듈을 이용해 간단한 DNS 조회 실습도 진행해보았습니다.

하지만 DNS의 편리함 이면에는 DNS 스푸핑과 같은 보안 위협도 존재하며, DNSSEC와 같은 보안 기술의 중요성도 함께 이해해야 합니다.
웹 개발자로서 DNS의 동작 원리를 아는 것은 웹 서비스의 성능 문제나 접속 오류를 해결하는 데 큰 도움이 될 것입니다.
다음 시간에는 네트워크 장비의 세계로 떠나, 라우터, 스위치, 허브가 각각 어떤 역할을 하는지 알아보겠습니다.

참고 🔗