DNS: Difference between revisions

From 44Net Wiki
Jump to navigation Jump to search
Cross (talk | contribs)
Skeletal DNS page
 
Cross (talk | contribs)
No edit summary
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
= DNS: The Domain Name System =
= DNS: The Domain Name System =


The Domain Name System is the mechanism by which symbolic host names, such as ''kz2x.ampr.org'' are translated into numeric host IP addresses, such as 44.44.48.2.  It is heavily used on AMPRNet. Cleverly
The Domain Name System is the primary mechanism by which symbolic host names, such as ''kz2x.ampr.org'' are translated into numeric host IP addresses, such as 44.44.48.2.  It is implemented as a network protocol, with clients sending ''queries'' to servers, that uses the network itself to perform translations. The DNS protocol is an Internet standard that is defined by a set of "Request for Comment" documents, or RFCs; the current revision of the DNS specification is in [https://datatracker.ietf.org/doc/html/rfc1035 RFC1035].  It is used heavily on AMPRNet.
 
DNS is an Internet standard that is defined by a set of "Request for Comment" documents, or RFCs.  The current revision of the DNS specification is in [https://datatracker.ietf.org/doc/html/rfc1035 RFC1035].


== Historical Background ==
== Historical Background ==


Before DNS, individual sites on the Internet maintained a local mapping of host names to IP addresses in the form of a "hosts" file; this was often a text file resident on each Internet-connected computer.  However, as the network grew, this quickly became untenable: not only did the file itself become so large as to be unwieldy and slow to search, keeping it up to date required significant effort.  Furthermore, coordinating updates from many different organizations, and avoiding name collisions as new hosts were added, added even more complexity.
Before DNS, individual sites on the Internet maintained a local mapping of host names to IP addresses in the form of a "hosts" file; this was often a text file resident on each Internet-connected computer.  However, this quickly became untenable as the network grew: not only did the file itself become so large as to be unwieldy and slow to search, keeping it up to date required significant effort.  Furthermore, coordinating updates from many different organizations, and avoiding name collisions as new hosts were added, added even more complexity.


A clever insight was that the problem could be addressed using the network itself, by providing a network service that could translate between host names and IP addresses.  Early work around this idea ultimately lead to DNS.
A clever insight was that the problem could be addressed using the network itself, by providing a network service that could translate between host names and IP addresses.  Early work around this idea ultimately lead to the design of the DNS.


== Concepts ==
== Concepts ==


The DNS on the client/server model, in which ''client'' machines send name service queries to DNS ''servers'' scattered around the Internet, which in turn, provide answers.  The process of answering a query related to a host name is called "resolution."  Resolved queries may be "cached" by servers for some period of time, called the "time to live" or TTL, given by the source server.
The DNS uses the client/server model, in which ''client'' machines send name related ''queries'' to DNS ''servers'' scattered around the Internet, which in turn, provide answers.  The process of answering a query is called "resolution."  Resolved queries may be "cached" by servers for some period of time, called the "time to live" or TTL, given by the source server.  The DNS allows clients to make queries for a fixed set of types of information for a particular ''domain name''.  For example, one might request make an "address" (or "A") query for a name.  For each name, a set of "records" corresponding to these  information types name are input by an administrator and held in some DNS server; these are called "resource records" or "RRs".


=== Domains, Zones, and Authority ===
=== Domains, Zones, and Authority ===


Names are hierarchical, and organized into ''domains'': Starting from ".", the "root", and descending through a "top-level" domain (TLD) such ".org", then through an organizational domain such as "ampr". Each such level forms a "domain", so that ".org" and "ampr.org" are separate domains. This organization provides resilience against collisions, since names need only be unique within a domain, and and facilitating separation of administrative concerns.
Names are hierarchical, and organized into ''domains'': Starting from ".", the "root", and descending through a "top-level" domain (TLD) such ".org", then through an organizational domain such as "ampr". Each such level forms a "domain", so that ".org" and "ampr.org" are separate domains. This organization provides resilience against collisions, since names need only be unique within a domain, and facilitates separation of administrative concerns.


Collections of domains that fall under a single administrative entity form "zones".  A zone is said to be authoritative for the domains under its control, but not otherwise; non-authoritative data typically comes out of caches established in response to earlier queries.  Authoritative responses to queries always override cached data.
Collections of domains that fall under a single administrative entity form "zones".  A zone is said to be ''authoritative'' for the domains under its control, but not otherwise; non-authoritative data typically comes out of caches established in response to earlier queries.  Authoritative responses to queries always override cached data.
 
Just as domain names are hierarchical, DNS servers are also arranged into a logical hierarchy, where different servers are responsible for providing information about names at different levels of the domain hierarchy; this is done by means of ''NS'' resource records, which point to the name servers for a given domain.  At the root are a set of "root servers," the IP addresses of which are well-known: these provide information about top-level domains like ".org", and specifically include NS RRs for the name servers that are known to be authoritative for those domains.  Subsequent levels are organized similarly: each server at some level provides information about servers at the next level, and so on.


=== Servers, Resolvers, and Stub Resolvers ===
=== Servers, Resolvers, and Stub Resolvers ===


As mentioned, clients resolve queries about domain names by sending those queries to servers, but different kinds of servers play different roles:
As mentioned, clients resolve requests for information about domain names by sending queries to servers, but different kinds of servers play different roles:


* Servers, or Authoritative Servers, are the ultimate sources of authority for domains under some zone.  They accept queries answer them, either with resolved data or with an error, such as when a query is issued for name that does not exist.
* Non-Recursive, Authoritative Servers, or just Authoritative Servers, are the ultimate sources of authority for domains under a zone.  They only accept queries for the domains in the zones they are authoritative for and answer them either with resolved data or with an error, such as when a query is issued for name that does not exist.
* Resolvers, or Recursive Servers, are intermediaries; they accept "recursive" queries and forward these to other servers until they receive a definitive reply.  They then usually cache the results so that subsequent requests for the same query can be answered quickly.  The cached data expires once its TTL is exceeded.
* Resolvers, or Recursive Servers, are intermediaries; they accept "recursive" queries and forward these to other servers until they receive a definitive reply.  They then usually cache the results so that subsequent requests for the same query can be answered quickly.  The cached data expires once its TTL is exceeded.
* Stub resolvers are small bits of software embedded in client programs that make DNS queries: these program fragments send queries to remote servers and interpret the results, providing them the rest of the program.
* Stub resolvers are small bits of software embedded in client programs that make DNS queries: these program fragments send queries to remote servers and interpret the results, providing them to the rest of the program.
 
Usually, any program that wants to make use of the DNS will do so via a stub resolver, which will forward the query to some recursive server. The stub resolver learns what recursive server to send its queries to via some administrative mechanism; for example, a DHCP server might supply the IP address of the server to use, or the stub might look in a file on the local system.  The name servers the stub sends requests to must be given by IP address; doing otherwise would create a chicken and egg problem, since the whole point is that the DNS is way we translate names into addresses.
 
= Setting Up a Recursive Resolver on OpenBSD =
 
[https://www.openbsd.org OpenBSD] is a variant of Unix known for security and a focus on code correctness.  It also comes bundled with a high performance caching, validating, recursive DNS resolver package called [https://www.nlnetlabs.nl/projects/unbound/about/ Unbound]. Unbound is easily configured, we will give an example of doing so here.
 
== Configuring the unbound server ==
 
The first step is to configure the server by editing its configuration file, <code>/var/unbound/etc/unbound.conf</code>.  The format and allowable settings in this file are given in the man page, [https://man.openbsd.org/unbound.conf ''unbound.conf''(5)], but at a high level it contains several sections:
 
* A <code>server:</code> section allows us to set settings for the server itself.
* A <code>remote-control:</code> section lets setup access for a control client.
* An arbitrary number of optional zone-specific sections that allow us to configure options for those zones.  This gives us the ability to forward to specific authoritative servers for a zone and so on.
 
Here's an example of what a configuration file might look like:
 
<nowiki>server:
        interface: 0.0.0.0
        interface: ::0
 
        access-control: 0.0.0.0/0 refuse
        access-control: ::0/0 refuse
 
        access-control: 127.0.0.0/8 allow
        access-control: ::1 allow
 
        access-control: 44.0.0.0/9 allow
        access-control: 44.128.0.0/10 allow
 
        hide-identity: yes
        hide-version: yes
 
        # Perform DNSSEC validation.
        auto-trust-anchor-file: "/var/unbound/db/root.key"
        val-log-level: 2
 
        # Synthesize NXDOMAINs from DNSSEC NSEC chains.
        # https://tools.ietf.org/html/rfc8198
        #
        aggressive-nsec: yes
 
        # Use TCP for "forward-zone" requests. Useful if you are making
        # DNS requests over an SSH port forwarding.
        #tcp-upstream: yes
 
        # CA Certificates used for forward-tls-upstream (RFC7858) hostname
        # verification.  Since it's outside the chroot it is only loaded at
        # startup and thus cannot be changed via a reload.
        #tls-cert-bundle: "/etc/ssl/cert.pem"
 
remote-control:
        control-enable: yes
        control-interface: /var/run/unbound.sock
 
stub-zone:
        name: "ampr.org."
        stub-addr: 44.1.1.44
        stub-host: ns2.us.ardc.org
        stub-host: ns.ardc.org
        stub-host: ns1.de.ardc.org
        stub-host: a.gw4.uk
 
stub-zone:
        name: "44.in-addr.arpa."
        stub-addr: 44.1.1.44
        stub-host: ns2.us.ardc.org
        stub-host: ns.ardc.org
        stub-host: ns1.de.ardc.org
        stub-host: a.gw4.uk
        stub-first: yes
 
stub-zone:
        name: "128.44.in-addr.arpa."
        stub-addr: 44.1.1.44
        stub-host: ns2.us.ardc.org
        stub-host: ns.ardc.org
        stub-host: ns1.de.ardc.org
        stub-host: a.gw4.uk
        stub-first: yes
</nowiki>
 
This configuration sets some non-default options in the <code>server:</code> section, such as what interface to listen on for incoming connections, and options for what machines are allowed to send us queries.  Here, we listen on all addresses on all interfaces for both IPv4 and IPv6 and we allow any AMPRNet host to send us queries.
 
The <code>remote-control:</code> section enables and configures a Unix domain socket that allows us to control the unbound daemon with the client control program, <code>unbound-control</code>; this way, we can ask it for performance and usage statistics, force it to flush its cache, etc, without stopping and restarting it.
 
The most interesting parts are the <code>stub-zone:</code> sections.  These allow us to tell unbound about servers that are authoritative for particular zones, bypassing querying through the root for domains under those zones.  In the three sections given here, we tell it to query the ARDC-administered non-recursive authoritative servers for the ''ampr.org'', ''44.in-addr.arpa'' and ''128.44.in-addr.arpa'' zones; that is, for anything related to AMPRNet, we forward directly to the authoritative servers.
 
Note the <code>stub-first: yes</code> lines for the two reverse domains: some reverse domains are ''delegated'' to other services.  This line says to try the ARDC servers first, and if those return an error, to perform the standard query from the root.
 
Once the server is configured, we can enable it by adding a line to <code>/etc/rc.conf.local</code>:
 
<nowiki>unbound_flags=""</nowiki>
 
Now, if we reboot, we will find the unbound daemon running the next time we login.  We should be able to direct DNS queries to the local server now, and we can edit the <code>/etc/resolv.conf</code> file to include a reference to our unbound instance.  For example, our resolv.conf file might look something like:
 
<nowiki>lookup file bind
domain your-call.ampr.org
search your-call.ampr.org ampr.org
nameserver 127.0.0.1
</nowiki>
 
Of course, one likely wants to query one's own callsign based subdomain, not "your-call".
 
Now, other machines can be configured to connect to your unbound instance.  Here is an example from a machine at KZ2X:
 
<nowiki>lookup file bind
domain kz2x.ampr.org
search kz2x.ampr.org ampr.org
nameserver 44.44.48.29
nameserver 8.8.8.8
nameserver 1.1.1.1
</nowiki>
 
Note that <code>44.44.48.29</code> is the machine that runs unbound.


Usually, any program that wants to make use of the DNS will do so via a stub resolver, which will forward the query to some recursive server. The stub resolver learns about what recursive server to send its queries to via some administrative mechanism; for example, a DHCP server might supply the IP address of the server to use.
Congratulations!  You have set up a caching, validating, recursive resolver that can serve DNS to any machine on AMPRNet.

Latest revision as of 12:37, 2 June 2024

DNS: The Domain Name System

The Domain Name System is the primary mechanism by which symbolic host names, such as kz2x.ampr.org are translated into numeric host IP addresses, such as 44.44.48.2. It is implemented as a network protocol, with clients sending queries to servers, that uses the network itself to perform translations. The DNS protocol is an Internet standard that is defined by a set of "Request for Comment" documents, or RFCs; the current revision of the DNS specification is in RFC1035. It is used heavily on AMPRNet.

Historical Background

Before DNS, individual sites on the Internet maintained a local mapping of host names to IP addresses in the form of a "hosts" file; this was often a text file resident on each Internet-connected computer. However, this quickly became untenable as the network grew: not only did the file itself become so large as to be unwieldy and slow to search, keeping it up to date required significant effort. Furthermore, coordinating updates from many different organizations, and avoiding name collisions as new hosts were added, added even more complexity.

A clever insight was that the problem could be addressed using the network itself, by providing a network service that could translate between host names and IP addresses. Early work around this idea ultimately lead to the design of the DNS.

Concepts

The DNS uses the client/server model, in which client machines send name related queries to DNS servers scattered around the Internet, which in turn, provide answers. The process of answering a query is called "resolution." Resolved queries may be "cached" by servers for some period of time, called the "time to live" or TTL, given by the source server. The DNS allows clients to make queries for a fixed set of types of information for a particular domain name. For example, one might request make an "address" (or "A") query for a name. For each name, a set of "records" corresponding to these information types name are input by an administrator and held in some DNS server; these are called "resource records" or "RRs".

Domains, Zones, and Authority

Names are hierarchical, and organized into domains: Starting from ".", the "root", and descending through a "top-level" domain (TLD) such ".org", then through an organizational domain such as "ampr". Each such level forms a "domain", so that ".org" and "ampr.org" are separate domains. This organization provides resilience against collisions, since names need only be unique within a domain, and facilitates separation of administrative concerns.

Collections of domains that fall under a single administrative entity form "zones". A zone is said to be authoritative for the domains under its control, but not otherwise; non-authoritative data typically comes out of caches established in response to earlier queries. Authoritative responses to queries always override cached data.

Just as domain names are hierarchical, DNS servers are also arranged into a logical hierarchy, where different servers are responsible for providing information about names at different levels of the domain hierarchy; this is done by means of NS resource records, which point to the name servers for a given domain. At the root are a set of "root servers," the IP addresses of which are well-known: these provide information about top-level domains like ".org", and specifically include NS RRs for the name servers that are known to be authoritative for those domains. Subsequent levels are organized similarly: each server at some level provides information about servers at the next level, and so on.

Servers, Resolvers, and Stub Resolvers

As mentioned, clients resolve requests for information about domain names by sending queries to servers, but different kinds of servers play different roles:

  • Non-Recursive, Authoritative Servers, or just Authoritative Servers, are the ultimate sources of authority for domains under a zone. They only accept queries for the domains in the zones they are authoritative for and answer them either with resolved data or with an error, such as when a query is issued for name that does not exist.
  • Resolvers, or Recursive Servers, are intermediaries; they accept "recursive" queries and forward these to other servers until they receive a definitive reply. They then usually cache the results so that subsequent requests for the same query can be answered quickly. The cached data expires once its TTL is exceeded.
  • Stub resolvers are small bits of software embedded in client programs that make DNS queries: these program fragments send queries to remote servers and interpret the results, providing them to the rest of the program.

Usually, any program that wants to make use of the DNS will do so via a stub resolver, which will forward the query to some recursive server. The stub resolver learns what recursive server to send its queries to via some administrative mechanism; for example, a DHCP server might supply the IP address of the server to use, or the stub might look in a file on the local system. The name servers the stub sends requests to must be given by IP address; doing otherwise would create a chicken and egg problem, since the whole point is that the DNS is way we translate names into addresses.

Setting Up a Recursive Resolver on OpenBSD

OpenBSD is a variant of Unix known for security and a focus on code correctness. It also comes bundled with a high performance caching, validating, recursive DNS resolver package called Unbound. Unbound is easily configured, we will give an example of doing so here.

Configuring the unbound server

The first step is to configure the server by editing its configuration file, /var/unbound/etc/unbound.conf. The format and allowable settings in this file are given in the man page, unbound.conf(5), but at a high level it contains several sections:

  • A server: section allows us to set settings for the server itself.
  • A remote-control: section lets setup access for a control client.
  • An arbitrary number of optional zone-specific sections that allow us to configure options for those zones. This gives us the ability to forward to specific authoritative servers for a zone and so on.

Here's an example of what a configuration file might look like:

server:
        interface: 0.0.0.0
        interface: ::0

        access-control: 0.0.0.0/0 refuse
        access-control: ::0/0 refuse

        access-control: 127.0.0.0/8 allow
        access-control: ::1 allow

        access-control: 44.0.0.0/9 allow
        access-control: 44.128.0.0/10 allow

        hide-identity: yes
        hide-version: yes

        # Perform DNSSEC validation.
        auto-trust-anchor-file: "/var/unbound/db/root.key"
        val-log-level: 2

        # Synthesize NXDOMAINs from DNSSEC NSEC chains.
        # https://tools.ietf.org/html/rfc8198
        #
        aggressive-nsec: yes

        # Use TCP for "forward-zone" requests. Useful if you are making
        # DNS requests over an SSH port forwarding.
        #tcp-upstream: yes

        # CA Certificates used for forward-tls-upstream (RFC7858) hostname
        # verification.  Since it's outside the chroot it is only loaded at
        # startup and thus cannot be changed via a reload.
        #tls-cert-bundle: "/etc/ssl/cert.pem"

remote-control:
        control-enable: yes
        control-interface: /var/run/unbound.sock

stub-zone:
        name: "ampr.org."
        stub-addr: 44.1.1.44
        stub-host: ns2.us.ardc.org
        stub-host: ns.ardc.org
        stub-host: ns1.de.ardc.org
        stub-host: a.gw4.uk

stub-zone:
        name: "44.in-addr.arpa."
        stub-addr: 44.1.1.44
        stub-host: ns2.us.ardc.org
        stub-host: ns.ardc.org
        stub-host: ns1.de.ardc.org
        stub-host: a.gw4.uk
        stub-first: yes

stub-zone:
        name: "128.44.in-addr.arpa."
        stub-addr: 44.1.1.44
        stub-host: ns2.us.ardc.org
        stub-host: ns.ardc.org
        stub-host: ns1.de.ardc.org
        stub-host: a.gw4.uk
        stub-first: yes

This configuration sets some non-default options in the server: section, such as what interface to listen on for incoming connections, and options for what machines are allowed to send us queries. Here, we listen on all addresses on all interfaces for both IPv4 and IPv6 and we allow any AMPRNet host to send us queries.

The remote-control: section enables and configures a Unix domain socket that allows us to control the unbound daemon with the client control program, unbound-control; this way, we can ask it for performance and usage statistics, force it to flush its cache, etc, without stopping and restarting it.

The most interesting parts are the stub-zone: sections. These allow us to tell unbound about servers that are authoritative for particular zones, bypassing querying through the root for domains under those zones. In the three sections given here, we tell it to query the ARDC-administered non-recursive authoritative servers for the ampr.org, 44.in-addr.arpa and 128.44.in-addr.arpa zones; that is, for anything related to AMPRNet, we forward directly to the authoritative servers.

Note the stub-first: yes lines for the two reverse domains: some reverse domains are delegated to other services. This line says to try the ARDC servers first, and if those return an error, to perform the standard query from the root.

Once the server is configured, we can enable it by adding a line to /etc/rc.conf.local:

unbound_flags=""

Now, if we reboot, we will find the unbound daemon running the next time we login. We should be able to direct DNS queries to the local server now, and we can edit the /etc/resolv.conf file to include a reference to our unbound instance. For example, our resolv.conf file might look something like:

lookup file bind
domain your-call.ampr.org
search your-call.ampr.org ampr.org
nameserver 127.0.0.1

Of course, one likely wants to query one's own callsign based subdomain, not "your-call".

Now, other machines can be configured to connect to your unbound instance. Here is an example from a machine at KZ2X:

lookup file bind
domain kz2x.ampr.org
search kz2x.ampr.org ampr.org
nameserver 44.44.48.29
nameserver 8.8.8.8
nameserver 1.1.1.1

Note that 44.44.48.29 is the machine that runs unbound.

Congratulations! You have set up a caching, validating, recursive resolver that can serve DNS to any machine on AMPRNet.