Diagnosing Name Resolution
Goal
You check what path name resolution goes through, and create yourself a situation in which "dig works but the app doesn't".
Why it matters
The application calls glibc's getaddrinfo(), and glibc asks in the order given by /etc/nsswitch.conf, in its hosts: line (usually files dns - that is, /etc/hosts first). dig, on the other hand, skips all of this and asks the nameserver in /etc/resolv.conf directly. If the answers of the two tools differ, the problem is not the DNS server but the stub resolver segment. This one fact shortens the question "dig works, so why doesn't the app" from hours to minutes.
Steps
You work in the /root/dns directory.
- Write the address of the first nameserver in
/etc/resolv.confto/root/dns/nameserver.txt. - In
/etc/hosts, register10.99.0.10under two names,app.labhub.localand the short nameapp. - From
/etc/nsswitch.conf, take the value of thehosts:entry (everything after the colon) and write it to/root/dns/order.txt. If the file does not exist, writeunavailable. - Ask for the same name
app.labhub.localwithgetentand withdig +shortrespectively, and write the results to/root/dns/compare.txtas the following two lines. If dig gives no answer at all, writenone.getent=<결과>(the result)dig=<결과 또는 none>(the result, or none)
- List the search domains of
/etc/resolv.confin/root/dns/search.txt, separated by spaces. If there are none,none. - Write the name obtained by looking up
10.99.0.10in reverse to/root/dns/reverse.txt. - In
/etc/hosts, registerapi.labhub.localon two lines.10.99.0.21first, then10.99.0.22after it. And write the IP thatgetent hosts api.labhub.localactually returns to/root/dns/first.txt. - Create
/root/dns/resolve.sh <이름>(the argument is a name). If resolution succeeds, it prints the following two lines and exits with code 0; if it fails, it reportsunresolvedand exits with exit code 3. If there is no argument, it is a nonzero code.name=<이름>(the name)ip=<주소>(the address)
Notes
getent hosts 이름(a name goes where the Korean word is) prints in the formIP 정식이름 별칭...(IP, canonical name, aliases).- You can ask briefly with
dig +short +time=2 +tries=1 이름(the name goes where the Korean word is). - Common mistake 1: in step 4, you must not judge it a failure because the dig result is empty. For a name that exists only in hosts, it is normal for DNS not to know it.
- Common mistake 2: in step 7, if you swap the order of the two lines, the result changes. The line written first wins.
Check the resolver address
Write the address of the first nameserver in /etc/resolv.conf to /root/dns/nameserver.txt.
It is the nameserver line of /etc/resolv.conf. If there are several, write only the first.
Register a name in the hosts file
In /etc/hosts, register 10.99.0.10 under two names, app.labhub.local and the short name app.
If you write several names after the IP on one line, they all become aliases. Check with getent.
Check the name service order
From /etc/nsswitch.conf, take the value of the hosts: entry (everything after the colon) and write it to /root/dns/order.txt. If the file does not exist, write unavailable.
It is the hosts: line of /etc/nsswitch.conf. Write only the value after the colon.
Compare getent and dig
Ask for the same name app.labhub.local with getent and with dig +short respectively, and write the results to /root/dns/compare.txt as the following two lines. If dig gives no answer at all, write none.
getent=<결과>(the result)dig=<결과 또는 none>(the result, or none)
Ask for the same name with the two tools. Think about why the results differ. If dig gets no answer at all, write none.
Check the search domains
List the search domains of /etc/resolv.conf in /root/dns/search.txt, separated by spaces. If there are none, none.
It is the search line of resolv.conf. If there is none, write none.
Reverse lookup
Write the name obtained by looking up 10.99.0.10 in reverse to /root/dns/reverse.txt.
If you put an IP into getent hosts, it works in reverse.
The same name on two lines, who wins
In /etc/hosts, register api.labhub.local on two lines. 10.99.0.21 first, then 10.99.0.22 after it. And write the IP that getent hosts api.labhub.local actually returns to /root/dns/first.txt.
The order changes the result. Write 21 first.
Create a name resolution helper
Create /root/dns/resolve.sh <이름> (the argument is a name). If resolution succeeds, it prints the following two lines and exits with code 0; if it fails, it reports unresolved and exits with exit code 3. If there is no argument, it is a nonzero code.
name=<이름>(the name)ip=<주소>(the address)
On success, print the name and IP and exit 0; on failure, unresolved and exit code 3.