109.4 Configure client side DNS¶
Weight: 2
Candidates should be able to configure DNS on a client host.
Objectives
- Query remote DNS servers.
- Configure local name resolution and use remote DNS servers.
- Modify the order in which name resolution is done.
- Debug errors related to name resolution.
- Awareness of systemd-resolved
Terms
/etc/hosts, /etc/resolv.conf, /etc/nsswitch.conf, host, dig, getent
How a name is resolved¶
Nobody can remember the IP address of every server. Name resolution turns easy names into numbers (and back). The Domain Name System (DNS) does this on the internet: it turns yahoo.com into an address like 206.190.36.45. Every time you ping or browse to a name, a lookup happens first:
$ ping x.org
PING x.org (131.252.210.176) 56(84) bytes of data.
64 bytes from annarchy.freedesktop.org (131.252.210.176): icmp_seq=1 ttl=45 time=338 ms
Programs do not talk to DNS directly. They call functions of the standard C library (glibc on Linux), and those functions follow this path:
program (ping, firefox, ssh)
|
v
glibc reads /etc/nsswitch.conf ---> "hosts: files dns"
| | |
| v v
| /etc/hosts DNS servers from /etc/resolv.conf
v
the answer goes back to the program
The same process is used for other names too: user names, group names, port numbers and more. This page is about host names.
Three files decide everything on the client: /etc/nsswitch.conf (the order), /etc/hosts (local names) and /etc/resolv.conf (which DNS servers to ask).
/etc/resolv.conf: which DNS servers to ask¶
This file configures resolution through DNS. Each line is an option name followed by its value:
$ cat /etc/resolv.conf
# Generated by NetworkManager
search lpi.org
nameserver 10.0.0.53
nameserver fd00:ffff::2:53
options timeout:3
| Option | Meaning |
|---|---|
nameserver |
the IPv4 or IPv6 address of a DNS server. Up to three are used. If there is no nameserver line, the resolver uses a name server on the local machine |
search |
domains to add to a short name. With search lpi.org, looking up learning really looks up learning.lpi.org. Up to six domains |
domain |
the local domain name, also used for short names. If missing, it is everything after the first . in the host name |
options |
resolver settings, like timeout:3: wait 3 seconds for a server before giving up |
Another example, with two servers and a search domain:
$ cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 192.168.1.1
nameserver 4.2.2.4
search nagato.net
Here a short name like tv is tried as tv.nagato.net.
domain and search cannot be used together. If both are in the file, the last one wins.
Many systems write this file automatically (startup scripts, NetworkManager, systemd-resolved). A comment like # Generated by NetworkManager warns you that your manual changes will be overwritten. Editing it by hand is fine for a quick test, but for a permanent change, configure the tool that generates it.
/etc/hosts: local names¶
/etc/hosts is static name resolution: a table on your own machine, edited by root. The first column is the IP address (IPv4 or IPv6), the rest are names for it:
127.0.0.1 localhost
127.0.1.1 proxy
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.0.0.1 gateway.lpi.org gateway gw
10.0.1.53 dns1.lpi.org
10.0.2.53 dns2.lpi.org
172.16.12.134 linuxclass wonderland
192.168.59.231 mass1
It is used for names where DNS is not possible, like the loopback addresses, for important infrastructure (gateway, DNS servers) and for small LANs or tests.
Normally /etc/hosts is checked before DNS, so an entry here wins over DNS. DNS does not know mass1, but ping still finds it:
$ dig mass1
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 39464
...
$ ping mass1
PING mass1 (192.168.59.231) 56(84) bytes of data.
NXDOMAIN means "no such name" in DNS, yet ping works because the name is in /etc/hosts. In the same way, a line like 127.0.0.1 facebook.com sends your browser to your own machine instead of the real site. When a name resolves to a "wrong" address, check /etc/hosts first.
/etc/nsswitch.conf: the order of resolution¶
The Name Service Switch file tells glibc where to look for each kind of name, and in which order. The first column is the database (hosts, passwd, services...), the next columns are the sources, tried from left to right:
passwd: files sss
group: files sss
hosts: files mdns4_minimal [NOTFOUND=return] dns myhostname
services: nis [NOTFOUND=return] files
The hosts: line controls host name resolution. Here: first files (/etc/hosts), then mdns4_minimal (local multicast DNS), then dns (the servers in /etc/resolv.conf). To change the order of name resolution, change the order on this line. For example hosts: dns files asks DNS before /etc/hosts.
Common sources:
| Source | Meaning |
|---|---|
files |
local files, like /etc/hosts or /etc/passwd |
dns |
the DNS servers in /etc/resolv.conf |
nis |
NIS (Network Information Service, also called yellow pages), an old central service, rarely used because of its weak security |
resolve |
systemd-resolved |
A column in square brackets, [result=action], adds a simple condition to the source on its left: "if that source gave this result, do this action". A ! means "if the result is not this":
| Example | Meaning |
|---|---|
nis [NOTFOUND=return] files |
NIS worked but did not find the name: stop here. If NIS was not reachable, go on to files |
dns [!UNAVAIL=return] files |
DNS was available: stop, even if it found nothing. Only if DNS was unavailable, try files |
Anything after # is a comment. man nsswitch.conf explains every option.
DNS records and classes¶
The record types you will meet:
| Type | Holds |
|---|---|
A |
an IPv4 address |
AAAA |
an IPv6 address |
MX |
a mail server for the domain, with a priority number |
NS |
a name server of the domain |
SOA |
the start of authority: main information about the zone |
PTR |
a reverse record: the name for an IP address |
DNS also has three classes: IN (internet, TCP/IP, the one you always see), CH (ChaosNet, an old dead network) and HS (Hesiod, which stores things like passwd entries in DNS).
getent: what the system really resolves¶
getent reads entries from any name service database, through nsswitch.conf, exactly like a real program would. Give it the database and, optionally, a name. With only a database it lists all entries:
$ getent hosts
127.0.0.1 localhost
127.0.1.1 proxy
10.0.1.53 dns1.lpi.org
10.0.2.53 dns2.lpi.org
127.0.0.1 localhost ip6-localhost ip6-loopback
$ getent hosts mass1
192.168.59.231 mass1
-s forces one source, which helps you see where an answer comes from:
$ getent -s files hosts learning.lpi.org
::1 learning.lpi.org
$ getent -s dns hosts learning.lpi.org
208.94.166.198 learning.lpi.org
$ getent hosts kernel.org
139.178.84.217 kernel.org
$ getent -s files hosts mass1 # -s: force one source (files or dns)
This is the key difference for the exam: host and dig only ask DNS, while getent follows nsswitch (so it sees /etc/hosts too). Use getent to check how real requests will resolve.
host: simple DNS lookups¶
host is the easy tool. Give it a name and it returns the A, AAAA and MX records. Give it an IP address and it returns the PTR record (a reverse lookup):
$ host kernel.org
kernel.org has address 139.178.84.217
kernel.org has IPv6 address 2604:1380:4641:c500::1
kernel.org mail is handled by 10 smtp1.kernel.org.
$ host -t A kernel.org # only the IPv4 address
$ host -t MX kernel.org # only the mail servers
$ host 139.178.84.217 # reverse lookup: IP -> name (PTR)
Another example:
$ host wikipedia.org
wikipedia.org has address 208.80.154.224
wikipedia.org has IPv6 address 2620:0:861:ed1a::1
wikipedia.org mail is handled by 10 mx1001.wikimedia.org.
wikipedia.org mail is handled by 50 mx2001.wikimedia.org.
$ host 208.80.154.224
224.154.80.208.in-addr.arpa domain name pointer text-lb.eqiad.wikimedia.org.
-t asks for one record type:
$ host -t NS lpi.org
lpi.org name server dns1.easydns.com.
lpi.org name server dns3.easydns.ca.
lpi.org name server dns2.easydns.net.
$ host -t SOA lpi.org
lpi.org has SOA record dns1.easydns.com. zone.easydns.com. 1593109612 3600 600 1209600 300
To ask a specific DNS server instead of the ones in /etc/resolv.conf, put it as the last argument:
$ host -t MX lpi.org dns1.easydns.com
Using domain server:
Name: dns1.easydns.com
Address: 64.68.192.10#53
Aliases:
lpi.org mail is handled by 0 aspmx.l.google.com.
lpi.org mail is handled by 5 alt1.aspmx.l.google.com.
lpi.org mail is handled by 10 aspmx2.googlemail.com.
dig: detailed DNS queries¶
dig is made for querying DNS servers. It is very verbose, so it is too much for a quick lookup, but it is the right tool for troubleshooting DNS. By default it asks for the A record:
$ dig x.org
; <<>> DiG 9.10.3-P4-RedHat-9.10.3-12.P4.fc23 <<>> x.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7483
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;x.org. IN A
;; ANSWER SECTION:
x.org. 1625 IN A 131.252.210.176
;; Query time: 35 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Sun Apr 17 12:45:02 IRDT 2016
;; MSG SIZE rcvd: 50
How to read it:
- HEADER:
status: NOERRORmeans it worked.NXDOMAINmeans the name does not exist. - QUESTION SECTION: what was asked (an
Arecord of classINforx.org). - ANSWER SECTION: the result. The second column,
1625, is the TTL (Time To Live): how many seconds this answer may stay in a cache. - AUTHORITY and ADDITIONAL sections (when present): the domain's name servers (
NS) and theirAandAAAArecords. - The last lines: how long it took and which SERVER answered, very useful when debugging.
Like host, -t chooses the record type:
$ dig -t SOA lpi.org
...
;; ANSWER SECTION:
lpi.org. 600 IN SOA dns1.easydns.com. zone.easydns.com. 1593109612 3600 600 1209600 300
@server sends the query to a specific DNS server. A name can have many answers: here google.com has several addresses and your computer may use any of them:
$ dig @8.8.8.8 google.com
...
;; ANSWER SECTION:
google.com. 112 IN A 173.194.32.133
google.com. 112 IN A 173.194.32.136
google.com. 112 IN A 173.194.32.132
...
;; SERVER: 8.8.8.8#53(8.8.8.8)
This is a simple debugging trick: if dig @8.8.8.8 name works but a plain dig name fails, the problem is your configured DNS server, not the name.
Options that start with + tune the query and output. +short shows only the result, and +nocookie turns off the cookie extension:
$ dig +short lpi.org
65.39.134.165
$ dig +short -t SOA lpi.org
dns1.easydns.com. zone.easydns.com. 1593109612 3600 600 1209600 300
$ dig +nocookie -t MX lpi.org
For example dig +short x.org prints only the address. Default options you always want can go in ~/.digrc.
systemd-resolved¶
You only need to be aware of it. systemd-resolved is a systemd service that provides DNS, mDNS and LLMNR. It listens for DNS requests on 127.0.0.53. It is not a full DNS server: it forwards the questions to the servers from its own configuration or from /etc/resolv.conf. To use it through nsswitch, add resolve to the hosts: line in /etc/nsswitch.conf. The package with its library may not be installed by default. Its own configuration is in /etc/systemd/resolved.conf, and it is what generates /etc/resolv.conf on many systems (often as a symlink). resolvectl status shows its current servers.
Summary¶
When a program needs an address, glibc reads /etc/nsswitch.conf and follows the hosts: line from left to right, usually files (meaning /etc/hosts) then dns (meaning the servers in /etc/resolv.conf), so changing that files dns order is how I change resolution priority, with [result=action] items adding conditions like [NOTFOUND=return]. In /etc/resolv.conf I set up to three nameserver lines, up to six search domains (or a domain, but the last of the two wins) and options like timeout, remembering that a manager such as NetworkManager usually generates it and may overwrite my changes. /etc/hosts holds static local names that are checked before DNS and normally win over it, so an entry there overrides the real answer and it is the first thing I check when a name resolves strangely. For queries, getent hosts shows what the system truly resolves through nsswitch, honouring both files and DNS (-s picks one source), host gives a quick answer (-t for a record type, a server as the last argument, an IP for a reverse lookup), and dig gives the full picture with the TTL and the answering SERVER (-t, @server, +short); comparing dig @8.8.8.8 with a plain dig tells me whether my resolver or the name is the problem. Finally, I am aware that systemd-resolved is the systemd resolver listening on 127.0.0.53, used through resolve in nsswitch.conf.