Raspberry Pi as a DNS server ============================ Terms: Domain Name System, DNS: the networking system translating host names into (numerical) network addresses. Domain Name: a name for a group of servers connected to the internet. IP Address: a network addressable location, unique within its network. IPv4, the still most common form of address, is written as four sets of 8-bit numbers, separated by dots. 71.96.207.243 is a valid IP address. Top-Level Domain, TLD: the most general part of a domain name. Trailing part of a domain name. .com, .net, .gov, .mil, .us. Control over TLDs is delegated to certain organizations by ICANN (Internet Corporation for Assigned Names and Numbers). These organizations then distribute domain names under their TLD through domain registrars. Hosts: within a domain, the domain owner assigns IP addresses from the range assigned to the owner by the owner's ISP to servers, then associates these addresses with hostnames. SubDomain: a group within a domain, named by prefixing the domain name with an arbitrary group name, separated by dot, such as subdomain.domain.topleveldomain, for instance engineering.google.com. Fully Qualified Domain Name, FQDN: a hostname, followed by a domain name, ending with the TLD. mail.keck.us. is a FQDN. sun1533.ssd.usa.alcatel.com is a hostname within a subdomain within a subdomain within the alcatel.com domain. Domain-Level Name Server: a server designated to translate host and domain names into IP addresses. An authoritive name server provides answers to queries about hosts and domains under their control. A caching or forwarding name server accepts, resolves queries for servers not under their control. Zone File: a text file that maps hostnames into IP addresses. Zone files contain a DNS server's configuration. Records: individual entries in a zone file. Root Server: DNS is a hierarchical system. At this time there are 13 root servers. To resolve an FQDN into an IP address, a query is sent to one of these 13 servers to find the address for one of the name servers of the FQDN's TLD. Name Server Installation ======================== Some software packages need to be installed on a Pi. Bring up your Pi to the latest patch level (sudo apt-get update ; sudo apt-get upgrade), then install BIND (Berkely Internet Name Domain): sudo apt-get install -y bind9 bind9utils dnsutils Once configuration is complete, reboot your Pi. If named (Bind's process) doesn't come up automatically, configure systemd to start bind9: sudo systemctl enable bind9 Name Server Configuration ========================= Most of named's configuration resides in zone files, here named db.something: pi@pi2b00:/etc/bind $ pwd /etc/bind pi@pi2b00:/etc/bind $ ls -ls total 92 4 -rw-r--r-- 1 root root 3923 Jan 15 2018 bind.keys 4 -rw-r--r-- 1 root root 237 Jan 15 2018 db.0 4 -rw-r--r-- 1 root root 271 Jan 15 2018 db.127 4 -rw-r--r-- 1 root root 237 Jan 15 2018 db.255 4 -rw-r--r-- 1 root root 353 Jan 15 2018 db.empty [...] 4 -rw-r--r-- 1 root bind 1317 Jan 30 16:31 db.keck.us 4 -rw-r--r-- 1 root bind 684 Jan 30 16:31 db.keck.us.rev [...] 4 -rw-r--r-- 1 root root 270 Jan 15 2018 db.local 4 -rw-r--r-- 1 root root 3171 Jan 15 2018 db.root 4 -rw-r--r-- 1 root bind 463 Jan 15 2018 named.conf 4 -rw-r--r-- 1 root bind 490 Jan 15 2018 named.conf.default-zones 4 -rw-r--r-- 1 root bind 609 Jan 30 16:36 named.conf.keck 4 -rw-r--r-- 1 root bind 199 Jan 30 16:42 named.conf.local 4 -rw-r--r-- 1 root bind 890 Jan 29 11:51 named.conf.options 4 -rw-r----- 1 bind bind 77 Jan 29 11:51 rndc.key 4 -rw-r--r-- 1 root root 1319 Jan 30 16:42 zones.rfc1918 pi@pi2b00:/etc/bind $ Prepare zone files first, then tell named to read them by including them from within named.conf.local: pi@pi2b00:/etc/bind $ cat named.conf // This is the primary configuration file for the BIND DNS server named. // // Please read /usr/share/doc/bind9/README.Debian.gz for information on the // structure of BIND configuration files in Debian, *BEFORE* you customize // this configuration file. // // If you are just adding zones, please do that in /etc/bind/named.conf.local include "/etc/bind/named.conf.options"; include "/etc/bind/named.conf.local"; include "/etc/bind/named.conf.default-zones"; pi@pi2b00:/etc/bind $ cat named.conf.local // // Do any local configuration here // // Consider adding the 1918 zones here, if they are not used in your // organization include "/etc/bind/named.conf.keck"; include "/etc/bind/zones.rfc1918"; pi@pi2b00:/etc/bind $ named.conf.keck points to our own zone files: pi@pi2b00:/etc/bind $ pwd /etc/bind pi@pi2b00:/etc/bind $ cat named.conf.keck zone "keck.us" { type master; file "/etc/bind/db.keck.us"; }; [...] zone "207.96.71.IN-ADDR.ARPA" { type master; file "/etc/bind/db.keck.us.rev"; }; pi@pi2b00:/etc/bind $ The first zone file contains translations from host names into IP addresses, the second translations from addresses into hostnames. This is a current zone file: pi@pi2b00:/etc/bind $ pwd /etc/bind pi@pi2b00:/etc/bind $ cat db.keck.us $TTL 3600 @ IN SOA NS0.keck.us. keck.mail.keck.us. ( 2019013001 ; Serial 3600 ; Refresh 1800 ; Retry 1209600 ; Expire 36000 ) ; Error TTL IN NS NS0.keck.us. IN NS NS1.keck.us. IN MX 100 mail.keck.us. IN MX 200 mail.keck.cx. gate IN A 71.96.207.243 mail IN A 71.96.207.243 smtp IN A 71.96.207.243 pop IN A 71.96.207.243 ns0 IN A 71.96.207.243 cxgate IN A 71.96.207.243 www IN A 71.96.207.244 ns1 IN A 71.96.207.244 radio IN A 71.96.207.244 ftp IN A 71.96.207.246 keck.us. IN A 71.96.207.243 gate.keck.us. IN TXT "v=spf1 a mx ip4:71.96.207.243/32 ip4:71.96.207.244/32 ptr:mail.keck.us mx:mail.keck.us -all" radio.keck.us. IN TXT "v=spf1 a mx ip4:71.96.207.243/32 ip4:71.96.207.244/32 ptr:mail.keck.us mx:mail.keck.us -all" mail.keck.us. IN TXT "v=spf1 a mx ip4:71.96.207.243/32 ip4:71.96.207.244/32 ptr:mail.keck.us mx:mail.keck.us -all" www.keck.us. IN TXT "v=spf1 a mx ip4:71.96.207.243/32 ip4:71.96.207.244/32 ptr:mail.keck.us mx:mail.keck.us -all" keck.us. IN TXT "v=spf1 a mx ip4:71.96.207.243/32 ip4:71.96.207.244/32 ptr:mail.keck.us mx:mail.keck.us -all" pi@pi2b00:/etc/bind $ A zone file starts with a "Time To Live" (TTL) line, followed by a "Start Of Authority" (SOA) record: $TTL 3600 @ IN SOA NS0.keck.us. keck.mail.keck.us. ( 2014042101 ; Serial 3600 ; Refresh 1800 ; Retry 1209600 ; Expire 36000 ) ; Error TTL The "@" refers to the zone for this zone file, as specified the "zone" entry in named.conf.keck. It could be replaced with the actual zone name. IN stands for internet, SOA designates the following as the Start of Authority secord. NS0.keck.us is this name server, keck.mail.keck.us becomes the email address of this zone's administrator, after replacing the first dot with "@". If the account contains a dot, the dot is replaced with "\": firstname.lastname@domain.com becomes firstname\lastname.domain.com. Comments start with ";". The serial number is a unique value for the current contents of the zone file. When changing a zone file, also change the serial number. Not doing so causes the change to propagate slowly, or not at all. The recommended format for the serial number is the date of the change, given as YYYYMMDD, followed by an integer, in case multiple changes are applied and published on the same day. The refresh interval is the amount of time that the a slave name server will wait before polling the master for zone file changes. If a slave name server cannot connect to the master when the refresh period is up, it will wait the amount of time provided by the retry interval, then try to poll the master again. If a slave name server has not been able to contact the master for this amount of time specified by the expiration value, it no longer returns responses as an authoritative source for this zone. This is the amount of time that the name server will cache a name error if it cannot find the requested name in this file. The remainder of the zone file contains NS, A, AAAA, MX, TXT and CNAME records: An NS record designates a name server: IN NS NS0.keck.us. IN NS NS1.keck.us. For the keck.us zone, there are two autoritive name servers, ns0.keck.us and ns1.keck.us. Name servers don't have to reside in the same zone they provide DNS for. An A record defines an IPv4 address, an AAAA record an IPv6 address: mail IN A 71.96.207.243 www IN A 71.96.207.244 It is good practice to resolve the domain name itself into an address. Ideally a name and/or web server reside(s) at that address: keck.us. IN A 71.96.207.243 To operate a domain, the owner has to provide, in addition to physical hosting, two services, DNS and email. An MX-record designates mail servers for a domain's servers. The format is hostname IN MX priority mailserver-FQDN. Mailer daemons try to connect to mail server in increasing order of priority. Text records are used to provide arbitrary information about a domain, such as public keys, DKIM keys, or, in this case SPF (Sender-permitted From) records, stating that there are two server originating email for keck.us. CNAME records define an alias for canonical name for your server (one defined by an A or AAAA record). For instance, we could have an A name record defining the "server1" host and then use the "www" as an alias for this host: server1 IN A 111.111.111.111 www IN CNAME server1 CAA records are used to specify which Certificate Authorities (CAs) are allowed to issue SSL/TLS certificates for your domain. As of September 8, 2017 all CAs are required to check for these records before issuing a certificate. If no record is present, any CA may issue a certificate. Otherwise, only the specified CAs may issue certificates. CAA records can be applied to single hosts, or entire domains: example.com. IN CAA 0 issue "letsencrypt.org" The host, IN, and record type (CAA) are common DNS fields. The CAA-specific information above is the 0 issue "letsencrypt.org" portion. It is made up of three parts: flags (0), tags (issue), and values ("letsencrypt.org"). Flags are an integer which indicates how a CA should handle tags it doesn't understand. If the flag is 0, the record will be ignored. If 1, the CA must refuse to issue the certificate. Tags are strings that denote the purpose of a CAA record. Currently they can be issue to authorize a CA to create certificates for a specific hostname, issuewild to authorize wildcard certificates, or iodef to define a URL where CAs can report policy violations. Values are a string associated with the record's tag. For issue and issuewild this will typically be the domain of the CA you're granting the permission to. For iodef this may be the URL of a contact form, or a mailto: link for email feedback. Use dig to fetch CAA records using the following options: dig example.com type257 For more detailed information about CAA records, read RFC 6844, PTR records are used define a name associated with an IP address. PTR records are the inverse of an A or AAAA record. PTR records are unique in that they begin at the .arpa root and are delegated to the owners of the IP addresses. The Regional Internet Registries (RIRs) manage the IP address delegation to organization and service providers. The Regional Internet Registries include APNIC, ARIN, RIPE NCC, LACNIC, and AFRINIC: pi@pi2b00:/etc/bind $ cat db*rev $TTL 3600 @ IN SOA mail.keck.us. keck.mail.keck.us. ( 2011061301 ; Serial 3600 ; Refresh 1800 ; Retry 1209600 ; Expire 3600 ) ; Minimum IN NS mail.keck.us. ; 2.110.151.209.IN-ADDR.ARPA. IN PTR mail.keck.us. ; 2.110.151.209.IN-ADDR.ARPA. IN PTR gate.keck.us. ; 3.110.151.209.IN-ADDR.ARPA. IN PTR www.keck.us. ; 33.201.6.66.IN-ADDR.ARPA. IN PTR mail.keck.us. ; 33.201.6.66.IN-ADDR.ARPA. IN PTR gate.keck.us. ; 34.201.6.66.IN-ADDR.ARPA. IN PTR www.keck.us. 243.207.96.71.IN-ADDR.ARPA. IN PTR mail.keck.us. 243.207.96.71.IN-ADDR.ARPA. IN PTR gate.keck.us. 244.207.96.71.IN-ADDR.ARPA. IN PTR www.keck.us. 246.207.96.71.IN-ADDR.ARPA. IN PTR ftp.keck.us. pi@pi2b00:/etc/bind $ A Pi's named installation comes with a zone file for non-routed, private IP address ranges: pi@pi2b00:/etc/bind $ cat zones.rfc* zone "10.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "16.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "17.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "18.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "19.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "20.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "21.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "22.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "23.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "24.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "25.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "26.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "27.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "28.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "29.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "30.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; zone "31.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; # zone "168.192.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; pi@pi2b00:/etc/bind $ When setting up a name server for a private network, comment out the zone(s) designating db.empty as the zone file for your private IP address ranges. Named does not check configuration files for changes. To reload configuration, restart the server, or (faster) send it a SIGHUP: pi@pi2b00:/etc/bind $ ps -ef | grep named bind 391 1 0 20:36 ? 00:00:03 /usr/sbin/named -f -u bind pi 1568 753 0 21:28 pts/0 00:00:00 grep --color=auto named pi@pi2b00:/etc/bind $ sudo kill -HUP 391 pi@pi2b00:/etc/bind $ ps -ef | grep named bind 391 1 0 20:36 ? 00:00:03 /usr/sbin/named -f -u bind pi 1582 753 0 21:29 pts/0 00:00:00 grep --color=auto named pi@pi2b00:/etc/bind $ Further reading: https://blogs.akamai.com/2019/02/protecting-your-domain-names-taking-the-first-steps.html http://www.my-music.mine.nu/images/rpi_raspbianwheezy_dns_server.pdf http://www.zytrax.com/books/dns/ https://blogs.akamai.com/2019/02/protecting-your-domain-names-taking-the-first-steps.html https://hackaday.com/2022/03/15/run-your-own-server-for-fun-and-zero-profit/