LabHub
배우기 러닝패스 코스

ネットワーク基礎 — Linux VM で手を動かす

名前が解決される道を最後まで辿る

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

이 실습은 VM 에서 돕니다

우분투 24.04 는 systemd-resolved 가 이름 해석을 맡습니다. 여기에 dnsmasq내 DNS 서버를 하나 더 세워 두 층을 오가며 이름이 어디서 답을 얻는지 봅니다. dnsmasq 는 이미 설치되어 있지만 서비스가 실패한 채입니다 — 그 이유를 찾는 것이 3단계입니다.

목표

/etc/resolv.conf 의 스텁 주소가 무엇인지, 진짜 상류 서버는 어디인지, 내 DNS 서버를 특정 도메인에만 물리려면 어떻게 하는지, /etc/hosts 가 왜 DNS 를 이기는지를 명령으로 확인합니다.

왜 중요한가

"안 된다" 의 첫 갈림길이 이름입니다. 그런데 요즘 리눅스에서 이름 해석은 한 층이 아닙니다 — 애플리케이션은 libc 의 getaddrinfo 를 부르고, 그것은 nsswitch.conf 순서대로 /etc/hosts 를 먼저 보고, 그다음 resolv.conf 의 스텁(127.0.0.53)에 묻고, 스텁은 링크별 설정을 보고 상류로 넘깁니다. dig 는 이 중 마지막 단계만 직접 두드립니다. 그래서 dig 는 되는데 curl 은 안 되는 일이 실제로 생기고, 어느 층이 다른지 알아야 고칠 수 있습니다.

단계

  1. /etc/resolv.conf 가 가리키는 실제 파일 경로와 nameserver 줄을 /root/dns/resolv.txt 에 저장하세요.
  2. 스텁이 실제로 묻는 상류 DNS 서버 주소를 /root/dns/upstream.txtupstream=<주소> 한 줄로 저장하세요.
  3. dnsmasq 가 왜 안 뜨는지 찾아, 포트 53 을 잡고 있는 프로세스를 보여 주는 ss 출력을 /root/dns/port53.txt 에 저장하세요.
  4. 더미 인터페이스 dns010.53.0.1/24 를 붙이고, /etc/dnsmasq.d/lab.conf 로 dnsmasq 가 10.53.0.1 에서만 듣고 app.lab.internal10.53.0.10, db.lab.internal10.53.0.20 을 답하게 해서 서비스를 살리세요.
  5. dig @10.53.0.1 app.lab.internal 의 전체 출력을 /root/dns/dig.txt 에 저장하세요.
  6. resolvectldns0 링크에 DNS 서버 10.53.0.1 과 라우팅 도메인 ~lab.internal 을 지정해 getent hosts app.lab.internal 이 되게 하고, resolvectl status dns0/root/dns/link.txt 에 저장하세요.
  7. /etc/hosts10.53.0.99 db.lab.internal 을 넣고, getentdig @10.53.0.1 의 답을 /root/dns/hosts.txtgetent=·dig= 두 줄로 저장하세요.
  8. /root/dns/report.mdstub=·upstream=·local= 세 줄, dnsmasq 의 질의 로그에서 app.lab.internal 줄 하나, 그리고 /etc/hosts 가 DNS 를 이기는 이유를 적으세요.

참고

resolv.conf 의 정체

/etc/resolv.conf 가 가리키는 실제 파일 경로와 nameserver 줄을 /root/dns/resolv.txt 에 저장하세요.

readlink -f /etc/resolv.conf 가 심링크 끝의 진짜 경로를 줍니다. grep nameserver /etc/resolv.conf 로 스텁 주소를 봅니다. 둘을 한 파일에 넣으세요.

진짜 서버는 어디인가

스텁이 실제로 묻는 상류 DNS 서버 주소를 /root/dns/upstream.txtupstream=<주소> 한 줄로 저장하세요.

resolvectl status 의 링크 항목에 Current DNS Server 가 있습니다. 기본 경로 인터페이스(enp1s0)의 값입니다. resolvectl dns enp1s0 이 더 짧습니다.

dnsmasq 는 왜 안 뜨나

dnsmasq 가 왜 안 뜨는지 찾아, 포트 53 을 잡고 있는 프로세스를 보여 주는 ss 출력을 /root/dns/port53.txt 에 저장하세요.

systemctl status dnsmasqjournalctl -u dnsmasqAddress already in use 가 있습니다. 누가 잡았는지는 ss -ulpn 'sport = :53'-p 가 프로세스 이름을 보여 줍니다(root 여야 합니다).

내 DNS 서버를 세운다

더미 인터페이스 dns010.53.0.1/24 를 붙이고, /etc/dnsmasq.d/lab.conf 로 dnsmasq 가 10.53.0.1 에서만 듣고 app.lab.internal10.53.0.10, db.lab.internal10.53.0.20 을 답하게 해서 서비스를 살리세요.

ip link add dns0 type dummy 뒤 주소·UP. 설정은 listen-address=10.53.0.1bind-interfaces 로 그 주소만 잡게 하고, address=/app.lab.internal/10.53.0.10 처럼 이름을 박습니다. no-resolv 는 상류를 안 쓰겠다는 뜻입니다. 끝나면 systemctl restart dnsmasqsystemctl is-active dnsmasq.

dig 로 직접 묻는다

dig @10.53.0.1 app.lab.internal 의 전체 출력을 /root/dns/dig.txt 에 저장하세요.

@서버 는 resolv.conf 를 무시하고 그 서버에 바로 묻습니다. 출력의 ANSWER SECTION 에 A 레코드가, 머리에 status: NOERROR 가 보여야 합니다.

스텁에 내 서버를 물린다

resolvectldns0 링크에 DNS 서버 10.53.0.1 과 라우팅 도메인 ~lab.internal 을 지정해 getent hosts app.lab.internal 이 되게 하고, resolvectl status dns0/root/dns/link.txt 에 저장하세요.

resolvectl dns dns0 10.53.0.1resolvectl domain dns0 '~lab.internal'. ~ 가 붙은 도메인은 '이 도메인 질의는 이 링크의 서버로 보내라' 는 라우팅 규칙입니다. 확인은 getent hosts app.lab.internal — 10.53.0.10 이 나와야 합니다.

/etc/hosts 가 이긴다

/etc/hosts10.53.0.99 db.lab.internal 을 넣고, getentdig @10.53.0.1 의 답을 /root/dns/hosts.txtgetent=·dig= 두 줄로 저장하세요.

echo '10.53.0.99 db.lab.internal' >> /etc/hosts. 그 뒤 getent hosts db.lab.internal | awk '{print $1}'dig @10.53.0.1 db.lab.internal +short. 두 값이 다릅니다 — 그것이 이 단계의 요점입니다.

무엇을 배웠나

/root/dns/report.mdstub=·upstream=·local= 세 줄, dnsmasq 의 질의 로그에서 app.lab.internal 줄 하나, 그리고 /etc/hosts 가 DNS 를 이기는 이유를 적으세요.

stub 는 1단계의 nameserver, upstream 은 2단계의 값, local 은 내 dnsmasq 주소입니다. 로그는 journalctl -u dnsmasq --no-pager | grep 'query\[A\] app.lab.internal'. 이유에는 nsswitch 또는 files 라는 말이 들어가야 합니다.