Network Fundamentals — Hands-on in a Linux VM
Follow a Name All the Way Down
한국어 원문으로 표시합니다.
이 실습은 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 은 안 되는
일이 실제로 생기고, 어느 층이 다른지 알아야 고칠 수 있습니다.
단계
/etc/resolv.conf가 가리키는 실제 파일 경로와nameserver줄을/root/dns/resolv.txt에 저장하세요.- 스텁이 실제로 묻는 상류 DNS 서버 주소를
/root/dns/upstream.txt에upstream=<주소>한 줄로 저장하세요. - dnsmasq 가 왜 안 뜨는지 찾아, 포트 53 을 잡고 있는 프로세스를 보여 주는
ss출력을/root/dns/port53.txt에 저장하세요. - 더미 인터페이스
dns0에10.53.0.1/24를 붙이고,/etc/dnsmasq.d/lab.conf로 dnsmasq 가10.53.0.1에서만 듣고app.lab.internal→10.53.0.10,db.lab.internal→10.53.0.20을 답하게 해서 서비스를 살리세요. dig @10.53.0.1 app.lab.internal의 전체 출력을/root/dns/dig.txt에 저장하세요.resolvectl로dns0링크에 DNS 서버10.53.0.1과 라우팅 도메인~lab.internal을 지정해getent hosts app.lab.internal이 되게 하고,resolvectl status dns0을/root/dns/link.txt에 저장하세요./etc/hosts에10.53.0.99 db.lab.internal을 넣고,getent와dig @10.53.0.1의 답을/root/dns/hosts.txt에getent=·dig=두 줄로 저장하세요./root/dns/report.md에stub=·upstream=·local=세 줄, dnsmasq 의 질의 로그에서app.lab.internal줄 하나, 그리고/etc/hosts가 DNS 를 이기는 이유를 적으세요.
참고
readlink -f /etc/resolv.conf,resolvectl status,resolvectl dns,resolvectl domain.- 포트를 잡은 프로세스:
ss -ulpn 'sport = :53'.journalctl -u dnsmasq에 실패 이유가 있습니다. - dnsmasq 설정 열쇠:
listen-address=,bind-interfaces,no-resolv,log-queries,address=/이름/주소. 고친 뒤systemctl restart dnsmasq. - 흔한 실수 1:
bind-interfaces를 빼먹는 것. 그러면 dnsmasq 가 모든 주소의 53 을 잡으려다 스텁과 또 충돌합니다. - 흔한 실수 2: 6단계에서 도메인 앞의
~를 빼는 것.~가 없으면 검색 도메인이 되어 짧은 이름 뒤에 붙일 뿐, 질의를 그 서버로 보내지는 않습니다.
resolv.conf 의 정체
/etc/resolv.conf 가 가리키는 실제 파일 경로와 nameserver 줄을 /root/dns/resolv.txt 에 저장하세요.
readlink -f /etc/resolv.conf 가 심링크 끝의 진짜 경로를 줍니다. grep nameserver /etc/resolv.conf 로 스텁 주소를 봅니다. 둘을 한 파일에 넣으세요.
진짜 서버는 어디인가
스텁이 실제로 묻는 상류 DNS 서버 주소를 /root/dns/upstream.txt 에 upstream=<주소> 한 줄로 저장하세요.
resolvectl status 의 링크 항목에 Current DNS Server 가 있습니다. 기본 경로 인터페이스(enp1s0)의 값입니다. resolvectl dns enp1s0 이 더 짧습니다.
dnsmasq 는 왜 안 뜨나
dnsmasq 가 왜 안 뜨는지 찾아, 포트 53 을 잡고 있는 프로세스를 보여 주는 ss 출력을 /root/dns/port53.txt 에 저장하세요.
systemctl status dnsmasq 와 journalctl -u dnsmasq 에 Address already in use 가 있습니다. 누가 잡았는지는 ss -ulpn 'sport = :53' — -p 가 프로세스 이름을 보여 줍니다(root 여야 합니다).
내 DNS 서버를 세운다
더미 인터페이스 dns0 에 10.53.0.1/24 를 붙이고, /etc/dnsmasq.d/lab.conf 로 dnsmasq 가 10.53.0.1 에서만 듣고 app.lab.internal→10.53.0.10, db.lab.internal→10.53.0.20 을 답하게 해서 서비스를 살리세요.
ip link add dns0 type dummy 뒤 주소·UP. 설정은 listen-address=10.53.0.1 과 bind-interfaces 로 그 주소만 잡게 하고, address=/app.lab.internal/10.53.0.10 처럼 이름을 박습니다. no-resolv 는 상류를 안 쓰겠다는 뜻입니다. 끝나면 systemctl restart dnsmasq 후 systemctl is-active dnsmasq.
dig 로 직접 묻는다
dig @10.53.0.1 app.lab.internal 의 전체 출력을 /root/dns/dig.txt 에 저장하세요.
@서버 는 resolv.conf 를 무시하고 그 서버에 바로 묻습니다. 출력의 ANSWER SECTION 에 A 레코드가, 머리에 status: NOERROR 가 보여야 합니다.
스텁에 내 서버를 물린다
resolvectl 로 dns0 링크에 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.1 과 resolvectl domain dns0 '~lab.internal'. ~ 가 붙은 도메인은 '이 도메인 질의는 이 링크의 서버로 보내라' 는 라우팅 규칙입니다. 확인은 getent hosts app.lab.internal — 10.53.0.10 이 나와야 합니다.
/etc/hosts 가 이긴다
/etc/hosts 에 10.53.0.99 db.lab.internal 을 넣고, getent 와 dig @10.53.0.1 의 답을 /root/dns/hosts.txt 에 getent=·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.md 에 stub=·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 라는 말이 들어가야 합니다.