HEX
Server: Apache/2.4.58 (Ubuntu)
System: Linux ns3133907 6.8.0-86-generic #87-Ubuntu SMP PREEMPT_DYNAMIC Mon Sep 22 18:03:36 UTC 2025 x86_64
User: cssnetorguk (1024)
PHP: 8.2.28
Disabled: NONE
Upload Files
File: //proc/self/root/usr/share/doc/bind9-doc/arm/chapter6.html
<!DOCTYPE html>
<html class="writer-html5" lang="en" data-content_root="./">
<head>
  <meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>6. Advanced Configurations &mdash; BIND 9 9.18.39-0ubuntu0.24.04.2-Ubuntu documentation</title>
      <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" />
      <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" />
      <link rel="stylesheet" type="text/css" href="_static/custom.css?v=9ab34431" />

  
  
        <script src="_static/jquery.js?v=8dae8fb0"></script>
        <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
        <script src="_static/documentation_options.js?v=9d4ae9d2"></script>
        <script src="_static/doctools.js?v=888ff710"></script>
        <script src="_static/sphinx_highlight.js?v=dc90522c"></script>
    <script src="_static/js/theme.js"></script>
    <link rel="index" title="Index" href="genindex.html" />
    <link rel="search" title="Search" href="search.html" />
    <link rel="next" title="7. Security Configurations" href="chapter7.html" />
    <link rel="prev" title="5. DNSSEC" href="chapter5.html" /> 
</head>

<body class="wy-body-for-nav"> 
  <div class="wy-grid-for-nav">
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >

          
          
          <a href="index.html" class="icon icon-home">
            BIND 9
          </a>
              <div class="version">
                9.18.39-0ubuntu0.24.04.2-Ubuntu
              </div>
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
              <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="chapter1.html">1. Introduction to DNS and BIND 9</a></li>
<li class="toctree-l1"><a class="reference internal" href="chapter2.html">2. Resource Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="chapter3.html">3. Configurations and Zone Files</a></li>
<li class="toctree-l1"><a class="reference internal" href="chapter4.html">4. Name Server Operations</a></li>
<li class="toctree-l1"><a class="reference internal" href="chapter5.html">5. DNSSEC</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">6. Advanced Configurations</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#dynamic-update">6.1. Dynamic Update</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#the-journal-file">6.1.1. The Journal File</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#notify">6.2. NOTIFY</a></li>
<li class="toctree-l2"><a class="reference internal" href="#incremental-zone-transfers-ixfr">6.3. Incremental Zone Transfers (IXFR)</a></li>
<li class="toctree-l2"><a class="reference internal" href="#split-dns">6.4. Split DNS</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#example-split-dns-setup">6.4.1. Example Split DNS Setup</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#ipv6-support-in-bind-9">6.5. IPv6 Support in BIND 9</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#address-lookups-using-aaaa-records">6.5.1. Address Lookups Using AAAA Records</a></li>
<li class="toctree-l3"><a class="reference internal" href="#address-to-name-lookups-using-nibble-format">6.5.2. Address-to-Name Lookups Using Nibble Format</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#dynamically-loadable-zones-dlz">6.6. Dynamically Loadable Zones (DLZ)</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#configuring-dlz">6.6.1. Configuring DLZ</a></li>
<li class="toctree-l3"><a class="reference internal" href="#sample-dlz-module">6.6.2. Sample DLZ Module</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#dynamic-database-dyndb">6.7. Dynamic Database (DynDB)</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#configuring-dyndb">6.7.1. Configuring DynDB</a></li>
<li class="toctree-l3"><a class="reference internal" href="#sample-dyndb-module">6.7.2. Sample DynDB Module</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#catalog-zones">6.8. Catalog Zones</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#principle-of-operation">6.8.1. Principle of Operation</a></li>
<li class="toctree-l3"><a class="reference internal" href="#configuring-catalog-zones">6.8.2. Configuring Catalog Zones</a></li>
<li class="toctree-l3"><a class="reference internal" href="#catalog-zone-format">6.8.3. Catalog Zone Format</a></li>
<li class="toctree-l3"><a class="reference internal" href="#catalog-zone-custom-properties">6.8.4. Catalog Zone Custom Properties</a></li>
<li class="toctree-l3"><a class="reference internal" href="#change-of-ownership-coo">6.8.5. Change of Ownership (coo)</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#dns-firewalls-and-response-policy-zones">6.9. DNS Firewalls and Response Policy Zones</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#why-use-a-dns-firewall">6.9.1. Why Use a DNS Firewall?</a></li>
<li class="toctree-l3"><a class="reference internal" href="#what-can-a-dns-firewall-do">6.9.2. What Can a DNS Firewall Do?</a></li>
<li class="toctree-l3"><a class="reference internal" href="#creating-and-maintaining-rpz-rule-sets">6.9.3. Creating and Maintaining RPZ Rule Sets</a></li>
<li class="toctree-l3"><a class="reference internal" href="#limitations-of-dns-rpz">6.9.4. Limitations of DNS RPZ</a></li>
<li class="toctree-l3"><a class="reference internal" href="#dns-firewall-usage-examples">6.9.5. DNS Firewall Usage Examples</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#a-real-world-example-of-dns-rpz-s-value">6.9.5.1. A Real-World Example of DNS RPZ’s Value</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#keeping-firewall-policies-updated">6.9.6. Keeping Firewall Policies Updated</a></li>
<li class="toctree-l3"><a class="reference internal" href="#performance-and-scalability-when-using-multiple-rpzs">6.9.7. Performance and Scalability When Using Multiple RPZs</a></li>
<li class="toctree-l3"><a class="reference internal" href="#practical-tips-for-dns-firewalls-and-dns-rpz">6.9.8. Practical Tips for DNS Firewalls and DNS RPZ</a></li>
<li class="toctree-l3"><a class="reference internal" href="#creating-a-simple-walled-garden-triggered-by-ip-address">6.9.9. Creating a Simple Walled Garden Triggered by IP Address</a></li>
<li class="toctree-l3"><a class="reference internal" href="#a-known-inconsistency-in-dns-rpz-s-nsdname-and-nsip-rules">6.9.10. A Known Inconsistency in DNS RPZ’s NSDNAME and NSIP Rules</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#dns-delegation">6.9.10.1. DNS Delegation</a></li>
<li class="toctree-l4"><a class="reference internal" href="#a-quick-review-of-dns-iteration">6.9.10.2. A Quick Review of DNS Iteration</a></li>
<li class="toctree-l4"><a class="reference internal" href="#enter-rpz">6.9.10.3. Enter RPZ</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#example-using-rpz-to-disable-mozilla-doh-by-default">6.9.11. Example: Using RPZ to Disable Mozilla DoH-by-Default</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="chapter7.html">7. Security Configurations</a></li>
<li class="toctree-l1"><a class="reference internal" href="reference.html">8. Configuration Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="chapter9.html">9. Troubleshooting</a></li>
<li class="toctree-l1"><a class="reference internal" href="chapter10.html">10. Building BIND 9</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Appendices</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="notes.html">Release Notes</a></li>
<li class="toctree-l1"><a class="reference internal" href="changelog.html">Changelog</a></li>
<li class="toctree-l1"><a class="reference internal" href="dnssec-guide.html">DNSSEC Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="history.html">A Brief History of the DNS and BIND</a></li>
<li class="toctree-l1"><a class="reference internal" href="general.html">General DNS Reference Information</a></li>
<li class="toctree-l1"><a class="reference internal" href="manpages.html">Manual Pages</a></li>
</ul>

        </div>
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="index.html">BIND 9</a>
      </nav>

      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="Page navigation">
  <ul class="wy-breadcrumbs">
      <li><a href="index.html" class="icon icon-home" aria-label="Home"></a></li>
      <li class="breadcrumb-item active"><span class="section-number">6. </span>Advanced Configurations</li>
      <li class="wy-breadcrumbs-aside">
            <a href="_sources/chapter6.rst.txt" rel="nofollow"> View page source</a>
      </li>
  </ul>
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
             
  <section id="advanced-configurations">
<span id="advanced"></span><h1><span class="section-number">6. </span>Advanced Configurations<a class="headerlink" href="#advanced-configurations" title="Link to this heading"></a></h1>
<section id="dynamic-update">
<span id="id1"></span><h2><span class="section-number">6.1. </span>Dynamic Update<a class="headerlink" href="#dynamic-update" title="Link to this heading"></a></h2>
<p>Dynamic update is a method for adding, replacing, or deleting records in
a primary server by sending it a special form of DNS messages. The format
and meaning of these messages is specified in <span class="target" id="index-0"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2136.html"><strong>RFC 2136</strong></a>.</p>
<p>Dynamic update is enabled by including an <a class="reference internal" href="reference.html#namedconf-statement-allow-update" title="namedconf-statement-allow-update"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">allow-update</span></code></a> or an
<a class="reference internal" href="reference.html#namedconf-statement-update-policy" title="namedconf-statement-update-policy"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">update-policy</span></code></a> clause in the <a class="reference internal" href="reference.html#namedconf-statement-zone" title="namedconf-statement-zone"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">zone</span></code></a> statement.</p>
<p>If the zone’s <a class="reference internal" href="reference.html#namedconf-statement-update-policy" title="namedconf-statement-update-policy"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">update-policy</span></code></a> is set to <code class="docutils literal notranslate"><span class="pre">local</span></code>, updates to the zone
are permitted for the key <code class="docutils literal notranslate"><span class="pre">local-ddns</span></code>, which is generated by
<a class="reference internal" href="manpages.html#std-iscman-named"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named</span></code></a> at startup. See <a class="reference internal" href="reference.html#dynamic-update-policies"><span class="std std-ref">Dynamic Update Policies</span></a> for more details.</p>
<p>Dynamic updates using Kerberos-signed requests can be made using the
TKEY/GSS protocol, either by setting the <a class="reference internal" href="reference.html#namedconf-statement-tkey-gssapi-keytab" title="namedconf-statement-tkey-gssapi-keytab"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">tkey-gssapi-keytab</span></code></a> option
or by setting both the <a class="reference internal" href="reference.html#namedconf-statement-tkey-gssapi-credential" title="namedconf-statement-tkey-gssapi-credential"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">tkey-gssapi-credential</span></code></a> and
<a class="reference internal" href="reference.html#namedconf-statement-tkey-domain" title="namedconf-statement-tkey-domain"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">tkey-domain</span></code></a> options. Once enabled, Kerberos-signed requests are
matched against the update policies for the zone, using the Kerberos
principal as the signer for the request.</p>
<p>Updating of secure zones (zones using DNSSEC) follows <span class="target" id="index-1"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc3007.html"><strong>RFC 3007</strong></a>: RRSIG,
NSEC, and NSEC3 records affected by updates are automatically regenerated
by the server using an online zone key. Update authorization is based on
transaction signatures and an explicit server policy.</p>
<section id="the-journal-file">
<span id="journal"></span><h3><span class="section-number">6.1.1. </span>The Journal File<a class="headerlink" href="#the-journal-file" title="Link to this heading"></a></h3>
<p>All changes made to a zone using dynamic update are stored in the zone’s
journal file. This file is automatically created by the server when the
first dynamic update takes place. The name of the journal file is formed
by appending the extension <code class="docutils literal notranslate"><span class="pre">.jnl</span></code> to the name of the corresponding
zone file unless specifically overridden. The journal file is in a
binary format and should not be edited manually.</p>
<p>The server also occasionally writes (“dumps”) the complete contents
of the updated zone to its zone file. This is not done immediately after
each dynamic update because that would be too slow when a large zone is
updated frequently. Instead, the dump is delayed by up to 15 minutes,
allowing additional updates to take place. During the dump process,
transient files are created with the extensions <code class="docutils literal notranslate"><span class="pre">.jnw</span></code> and
<code class="docutils literal notranslate"><span class="pre">.jbk</span></code>; under ordinary circumstances, these are removed when the
dump is complete, and can be safely ignored.</p>
<p>When a server is restarted after a shutdown or crash, it replays the
journal file to incorporate into the zone any updates that took place
after the last zone dump.</p>
<p>Changes that result from incoming incremental zone transfers are also
journaled in a similar way.</p>
<p>The zone files of dynamic zones cannot normally be edited by hand
because they are not guaranteed to contain the most recent dynamic
changes; those are only in the journal file. The only way to ensure
that the zone file of a dynamic zone is up-to-date is to run
<a class="reference internal" href="manpages.html#cmdoption-rndc-arg-stop"><code class="xref std std-option docutils literal notranslate"><span class="pre">rndc</span> <span class="pre">stop</span></code></a>.</p>
<p>To make changes to a dynamic zone manually, follow these steps:
first, disable dynamic updates to the zone using
<a class="reference internal" href="manpages.html#cmdoption-rndc-arg-freeze"><code class="xref std std-option docutils literal notranslate"><span class="pre">rndc</span> <span class="pre">freeze</span> <span class="pre">zone</span></code></a>. This updates the zone file with the
changes stored in its <code class="docutils literal notranslate"><span class="pre">.jnl</span></code> file. Then, edit the zone file. Finally, run
<a class="reference internal" href="manpages.html#cmdoption-rndc-arg-thaw"><code class="xref std std-option docutils literal notranslate"><span class="pre">rndc</span> <span class="pre">thaw</span> <span class="pre">zone</span></code></a> to reload the changed zone and re-enable dynamic
updates.</p>
<p><a class="reference internal" href="manpages.html#cmdoption-rndc-arg-sync"><code class="xref std std-option docutils literal notranslate"><span class="pre">rndc</span> <span class="pre">sync</span> <span class="pre">zone</span></code></a> updates the zone file with changes from the
journal file without stopping dynamic updates; this may be useful for
viewing the current zone state. To remove the <code class="docutils literal notranslate"><span class="pre">.jnl</span></code> file after
updating the zone file, use <a class="reference internal" href="manpages.html#cmdoption-rndc-arg-sync"><code class="xref std std-option docutils literal notranslate"><span class="pre">rndc</span> <span class="pre">sync</span> <span class="pre">-clean</span></code></a>.</p>
</section>
</section>
<section id="notify">
<span id="id2"></span><h2><span class="section-number">6.2. </span>NOTIFY<a class="headerlink" href="#notify" title="Link to this heading"></a></h2>
<p>DNS NOTIFY is a mechanism that allows primary servers to notify their
secondary servers of changes to a zone’s data. In response to a NOTIFY message
from a primary server, the secondary checks to see that its version of
the zone is the current version and, if not, initiates a zone transfer.</p>
<p>For more information about DNS NOTIFY, see the description of the
<a class="reference internal" href="reference.html#namedconf-statement-notify" title="namedconf-statement-notify"><code class="xref namedconf namedconf-ref docutils literal notranslate"><span class="pre">notify</span></code></a> and <a class="reference internal" href="reference.html#namedconf-statement-also-notify" title="namedconf-statement-also-notify"><code class="xref namedconf namedconf-ref docutils literal notranslate"><span class="pre">also-notify</span></code></a> statements.
The NOTIFY protocol is specified in <span class="target" id="index-2"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc1996.html"><strong>RFC 1996</strong></a>.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>As a secondary zone can also be a primary to other secondaries, <a class="reference internal" href="manpages.html#std-iscman-named"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named</span></code></a>, by
default, sends NOTIFY messages for every zone it loads.</p>
</div>
</section>
<section id="incremental-zone-transfers-ixfr">
<span id="incremental-zone-transfers"></span><h2><span class="section-number">6.3. </span>Incremental Zone Transfers (IXFR)<a class="headerlink" href="#incremental-zone-transfers-ixfr" title="Link to this heading"></a></h2>
<p>The incremental zone transfer (IXFR) protocol is a way for secondary servers
to transfer only changed data, instead of having to transfer an entire
zone. The IXFR protocol is specified in <span class="target" id="index-3"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc1995.html"><strong>RFC 1995</strong></a>.</p>
<p>When acting as a primary server, BIND 9 supports IXFR for those zones where the
necessary change history information is available. These include primary
zones maintained by dynamic update and secondary zones whose data was
obtained by IXFR. For manually maintained primary zones, and for secondary
zones obtained by performing a full zone transfer (AXFR), IXFR is
supported only if the option <a class="reference internal" href="reference.html#namedconf-statement-ixfr-from-differences" title="namedconf-statement-ixfr-from-differences"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">ixfr-from-differences</span></code></a> is set to
<code class="docutils literal notranslate"><span class="pre">yes</span></code>.</p>
<p>When acting as a secondary server, BIND 9 attempts to use IXFR unless it is
explicitly disabled. For more information about disabling IXFR, see the
description of the <a class="reference internal" href="reference.html#namedconf-statement-request-ixfr" title="namedconf-statement-request-ixfr"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">request-ixfr</span></code></a> clause of the <a class="reference internal" href="reference.html#namedconf-statement-server" title="namedconf-statement-server"><code class="xref namedconf namedconf-ref docutils literal notranslate"><span class="pre">server</span></code></a> statement.</p>
<p>When a secondary server receives a zone via AXFR, it creates a new copy of the
zone database and then swaps it into place; during the loading process, queries
continue to be served from the old database with no interference. When receiving
a zone via IXFR, however, changes are applied to the running zone, which may
degrade query performance during the transfer. If a server receiving an IXFR
request determines that the response size would be similar in size to an AXFR
response, it may wish to send AXFR instead. The threshold at which this
determination is made can be configured using the
<a class="reference internal" href="reference.html#namedconf-statement-max-ixfr-ratio" title="namedconf-statement-max-ixfr-ratio"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">max-ixfr-ratio</span></code></a> option.</p>
</section>
<section id="split-dns">
<span id="id3"></span><h2><span class="section-number">6.4. </span>Split DNS<a class="headerlink" href="#split-dns" title="Link to this heading"></a></h2>
<p>Setting up different views of the DNS space to internal
and external resolvers is usually referred to as a <em>split DNS</em> setup.
There are several reasons an organization might want to set up its DNS
this way.</p>
<p>One common reason to use split DNS is to hide
“internal” DNS information from “external” clients on the Internet.
There is some debate as to whether this is actually useful.
Internal DNS information leaks out in many ways (via email headers, for
example) and most savvy “attackers” can find the information they need
using other means. However, since listing addresses of internal servers
that external clients cannot possibly reach can result in connection
delays and other annoyances, an organization may choose to use split
DNS to present a consistent view of itself to the outside world.</p>
<p>Another common reason for setting up a split DNS system is to allow
internal networks that are behind filters or in <span class="target" id="index-4"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc1918.html"><strong>RFC 1918</strong></a> space (reserved
IP space, as documented in <span class="target" id="index-5"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc1918.html"><strong>RFC 1918</strong></a>) to resolve DNS on the Internet.
Split DNS can also be used to allow mail from outside back into the
internal network.</p>
<section id="example-split-dns-setup">
<span id="split-dns-sample"></span><h3><span class="section-number">6.4.1. </span>Example Split DNS Setup<a class="headerlink" href="#example-split-dns-setup" title="Link to this heading"></a></h3>
<p>Let’s say a company named <em>Example, Inc.</em> (<code class="docutils literal notranslate"><span class="pre">example.com</span></code>) has several
corporate sites that have an internal network with reserved Internet
Protocol (IP) space and an external demilitarized zone (DMZ), or
“outside” section of a network, that is available to the public.</p>
<p>Example, Inc. wants its internal clients to be able to resolve
external hostnames and to exchange mail with people on the outside. The
company also wants its internal resolvers to have access to certain
internal-only zones that are not available at all outside of the
internal network.</p>
<p>To accomplish this, the company sets up two sets of name
servers. One set is on the inside network (in the reserved IP
space) and the other set is on bastion hosts, which are “proxy”
hosts in the DMZ that can talk to both sides of its network.</p>
<p>The internal servers are configured to forward all queries, except
queries for <code class="docutils literal notranslate"><span class="pre">site1.internal</span></code>, <code class="docutils literal notranslate"><span class="pre">site2.internal</span></code>,
<code class="docutils literal notranslate"><span class="pre">site1.example.com</span></code>, and <code class="docutils literal notranslate"><span class="pre">site2.example.com</span></code>, to the servers in the
DMZ. These internal servers have complete sets of information for
<code class="docutils literal notranslate"><span class="pre">site1.example.com</span></code>, <code class="docutils literal notranslate"><span class="pre">site2.example.com</span></code>, <code class="docutils literal notranslate"><span class="pre">site1.internal</span></code>, and
<code class="docutils literal notranslate"><span class="pre">site2.internal</span></code>.</p>
<p>To protect the <code class="docutils literal notranslate"><span class="pre">site1.internal</span></code> and <code class="docutils literal notranslate"><span class="pre">site2.internal</span></code> domains, the
internal name servers must be configured to disallow all queries to
these domains from any external hosts, including the bastion hosts.</p>
<p>The external servers, which are on the bastion hosts, are configured
to serve the “public” version of the <code class="docutils literal notranslate"><span class="pre">site1.example.com</span></code> and <code class="docutils literal notranslate"><span class="pre">site2.example.com</span></code>
zones. This could include things such as the host records for public
servers (<code class="docutils literal notranslate"><span class="pre">www.example.com</span></code> and <code class="docutils literal notranslate"><span class="pre">ftp.example.com</span></code>) and mail exchange
(MX) records (<code class="docutils literal notranslate"><span class="pre">a.mx.example.com</span></code> and <code class="docutils literal notranslate"><span class="pre">b.mx.example.com</span></code>).</p>
<p>In addition, the public <code class="docutils literal notranslate"><span class="pre">site1.example.com</span></code> and <code class="docutils literal notranslate"><span class="pre">site2.example.com</span></code> zones should
have special MX records that contain wildcard (<code class="docutils literal notranslate"><span class="pre">*</span></code>) records pointing to
the bastion hosts. This is needed because external mail servers
have no other way of determining how to deliver mail to those internal
hosts. With the wildcard records, the mail is delivered to the
bastion host, which can then forward it on to internal hosts.</p>
<p>Here’s an example of a wildcard MX record:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">*</span>   <span class="n">IN</span> <span class="n">MX</span> <span class="mi">10</span> <span class="n">external1</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">com</span><span class="o">.</span>
</pre></div>
</div>
<p>Now that they accept mail on behalf of anything in the internal network,
the bastion hosts need to know how to deliver mail to internal
hosts. The resolvers on the bastion
hosts need to be configured to point to the internal name servers
for DNS resolution.</p>
<p>Queries for internal hostnames are answered by the internal servers,
and queries for external hostnames are forwarded back out to the DNS
servers on the bastion hosts.</p>
<p>For all of this to work properly, internal clients need to be
configured to query <em>only</em> the internal name servers for DNS queries.
This could also be enforced via selective filtering on the network.</p>
<p>If everything has been set properly, Example, Inc.’s internal clients
are now able to:</p>
<ul class="simple">
<li><p>Look up any hostnames in the <code class="docutils literal notranslate"><span class="pre">site1.example.com</span></code> and <code class="docutils literal notranslate"><span class="pre">site2.example.com</span></code>
zones.</p></li>
<li><p>Look up any hostnames in the <code class="docutils literal notranslate"><span class="pre">site1.internal</span></code> and
<code class="docutils literal notranslate"><span class="pre">site2.internal</span></code> domains.</p></li>
<li><p>Look up any hostnames on the Internet.</p></li>
<li><p>Exchange mail with both internal and external users.</p></li>
</ul>
<p>Hosts on the Internet are able to:</p>
<ul class="simple">
<li><p>Look up any hostnames in the <code class="docutils literal notranslate"><span class="pre">site1.example.com</span></code> and <code class="docutils literal notranslate"><span class="pre">site2.example.com</span></code>
zones.</p></li>
<li><p>Exchange mail with anyone in the <code class="docutils literal notranslate"><span class="pre">site1.example.com</span></code> and <code class="docutils literal notranslate"><span class="pre">site2.example.com</span></code>
zones.</p></li>
</ul>
<p>Here is an example configuration for the setup just described above.
Note that this is only configuration information; for information on how
to configure the zone files, see <a class="reference internal" href="chapter3.html#sample-configuration"><span class="std std-ref">Configurations and Zone Files</span></a>.</p>
<p>Internal DNS server config:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">acl</span> <span class="n">internals</span> <span class="p">{</span> <span class="mf">172.16.72.0</span><span class="o">/</span><span class="mi">24</span><span class="p">;</span> <span class="mf">192.168.1.0</span><span class="o">/</span><span class="mi">24</span><span class="p">;</span> <span class="p">};</span>

<span class="n">acl</span> <span class="n">externals</span> <span class="p">{</span> <span class="n">bastion</span><span class="o">-</span><span class="n">ips</span><span class="o">-</span><span class="n">go</span><span class="o">-</span><span class="n">here</span><span class="p">;</span> <span class="p">};</span>

<span class="n">options</span> <span class="p">{</span>
    <span class="o">...</span>
    <span class="o">...</span>
    <span class="n">forward</span> <span class="n">only</span><span class="p">;</span>
    <span class="o">//</span> <span class="n">forward</span> <span class="n">to</span> <span class="n">external</span> <span class="n">servers</span>
    <span class="n">forwarders</span> <span class="p">{</span>
    <span class="n">bastion</span><span class="o">-</span><span class="n">ips</span><span class="o">-</span><span class="n">go</span><span class="o">-</span><span class="n">here</span><span class="p">;</span>
    <span class="p">};</span>
    <span class="o">//</span> <span class="n">sample</span> <span class="n">allow</span><span class="o">-</span><span class="n">transfer</span> <span class="p">(</span><span class="n">no</span> <span class="n">one</span><span class="p">)</span>
    <span class="n">allow</span><span class="o">-</span><span class="n">transfer</span> <span class="p">{</span> <span class="n">none</span><span class="p">;</span> <span class="p">};</span>
    <span class="o">//</span> <span class="n">restrict</span> <span class="n">query</span> <span class="n">access</span>
    <span class="n">allow</span><span class="o">-</span><span class="n">query</span> <span class="p">{</span> <span class="n">internals</span><span class="p">;</span> <span class="n">externals</span><span class="p">;</span> <span class="p">};</span>
    <span class="o">//</span> <span class="n">restrict</span> <span class="n">recursion</span>
    <span class="n">allow</span><span class="o">-</span><span class="n">recursion</span> <span class="p">{</span> <span class="n">internals</span><span class="p">;</span> <span class="p">};</span>
    <span class="o">...</span>
    <span class="o">...</span>
<span class="p">};</span>

<span class="o">//</span> <span class="n">sample</span> <span class="n">primary</span> <span class="n">zone</span>
<span class="n">zone</span> <span class="s2">&quot;site1.example.com&quot;</span> <span class="p">{</span>
  <span class="nb">type</span> <span class="n">primary</span><span class="p">;</span>
  <span class="n">file</span> <span class="s2">&quot;m/site1.example.com&quot;</span><span class="p">;</span>
  <span class="o">//</span> <span class="n">do</span> <span class="n">normal</span> <span class="n">iterative</span> <span class="n">resolution</span> <span class="p">(</span><span class="n">do</span> <span class="ow">not</span> <span class="n">forward</span><span class="p">)</span>
  <span class="n">forwarders</span> <span class="p">{</span> <span class="p">};</span>
  <span class="n">allow</span><span class="o">-</span><span class="n">query</span> <span class="p">{</span> <span class="n">internals</span><span class="p">;</span> <span class="n">externals</span><span class="p">;</span> <span class="p">};</span>
  <span class="n">allow</span><span class="o">-</span><span class="n">transfer</span> <span class="p">{</span> <span class="n">internals</span><span class="p">;</span> <span class="p">};</span>
<span class="p">};</span>

<span class="o">//</span> <span class="n">sample</span> <span class="n">secondary</span> <span class="n">zone</span>
<span class="n">zone</span> <span class="s2">&quot;site2.example.com&quot;</span> <span class="p">{</span>
  <span class="nb">type</span> <span class="n">secondary</span><span class="p">;</span>
  <span class="n">file</span> <span class="s2">&quot;s/site2.example.com&quot;</span><span class="p">;</span>
  <span class="n">primaries</span> <span class="p">{</span> <span class="mf">172.16.72.3</span><span class="p">;</span> <span class="p">};</span>
  <span class="n">forwarders</span> <span class="p">{</span> <span class="p">};</span>
  <span class="n">allow</span><span class="o">-</span><span class="n">query</span> <span class="p">{</span> <span class="n">internals</span><span class="p">;</span> <span class="n">externals</span><span class="p">;</span> <span class="p">};</span>
  <span class="n">allow</span><span class="o">-</span><span class="n">transfer</span> <span class="p">{</span> <span class="n">internals</span><span class="p">;</span> <span class="p">};</span>
<span class="p">};</span>

<span class="n">zone</span> <span class="s2">&quot;site1.internal&quot;</span> <span class="p">{</span>
  <span class="nb">type</span> <span class="n">primary</span><span class="p">;</span>
  <span class="n">file</span> <span class="s2">&quot;m/site1.internal&quot;</span><span class="p">;</span>
  <span class="n">forwarders</span> <span class="p">{</span> <span class="p">};</span>
  <span class="n">allow</span><span class="o">-</span><span class="n">query</span> <span class="p">{</span> <span class="n">internals</span><span class="p">;</span> <span class="p">};</span>
  <span class="n">allow</span><span class="o">-</span><span class="n">transfer</span> <span class="p">{</span> <span class="n">internals</span><span class="p">;</span> <span class="p">}</span>
<span class="p">};</span>

<span class="n">zone</span> <span class="s2">&quot;site2.internal&quot;</span> <span class="p">{</span>
  <span class="nb">type</span> <span class="n">secondary</span><span class="p">;</span>
  <span class="n">file</span> <span class="s2">&quot;s/site2.internal&quot;</span><span class="p">;</span>
  <span class="n">primaries</span> <span class="p">{</span> <span class="mf">172.16.72.3</span><span class="p">;</span> <span class="p">};</span>
  <span class="n">forwarders</span> <span class="p">{</span> <span class="p">};</span>
  <span class="n">allow</span><span class="o">-</span><span class="n">query</span> <span class="p">{</span> <span class="n">internals</span> <span class="p">};</span>
  <span class="n">allow</span><span class="o">-</span><span class="n">transfer</span> <span class="p">{</span> <span class="n">internals</span><span class="p">;</span> <span class="p">}</span>
<span class="p">};</span>
</pre></div>
</div>
<p>External (bastion host) DNS server configuration:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">acl</span> <span class="n">internals</span> <span class="p">{</span> <span class="mf">172.16.72.0</span><span class="o">/</span><span class="mi">24</span><span class="p">;</span> <span class="mf">192.168.1.0</span><span class="o">/</span><span class="mi">24</span><span class="p">;</span> <span class="p">};</span>

<span class="n">acl</span> <span class="n">externals</span> <span class="p">{</span> <span class="n">bastion</span><span class="o">-</span><span class="n">ips</span><span class="o">-</span><span class="n">go</span><span class="o">-</span><span class="n">here</span><span class="p">;</span> <span class="p">};</span>

<span class="n">options</span> <span class="p">{</span>
  <span class="o">...</span>
  <span class="o">...</span>
  <span class="o">//</span> <span class="n">sample</span> <span class="n">allow</span><span class="o">-</span><span class="n">transfer</span> <span class="p">(</span><span class="n">no</span> <span class="n">one</span><span class="p">)</span>
  <span class="n">allow</span><span class="o">-</span><span class="n">transfer</span> <span class="p">{</span> <span class="n">none</span><span class="p">;</span> <span class="p">};</span>
  <span class="o">//</span> <span class="n">default</span> <span class="n">query</span> <span class="n">access</span>
  <span class="n">allow</span><span class="o">-</span><span class="n">query</span> <span class="p">{</span> <span class="nb">any</span><span class="p">;</span> <span class="p">};</span>
  <span class="o">//</span> <span class="n">restrict</span> <span class="n">cache</span> <span class="n">access</span>
  <span class="n">allow</span><span class="o">-</span><span class="n">query</span><span class="o">-</span><span class="n">cache</span> <span class="p">{</span> <span class="n">internals</span><span class="p">;</span> <span class="n">externals</span><span class="p">;</span> <span class="p">};</span>
  <span class="o">//</span> <span class="n">restrict</span> <span class="n">recursion</span>
  <span class="n">allow</span><span class="o">-</span><span class="n">recursion</span> <span class="p">{</span> <span class="n">internals</span><span class="p">;</span> <span class="n">externals</span><span class="p">;</span> <span class="p">};</span>
  <span class="o">...</span>
  <span class="o">...</span>
<span class="p">};</span>

<span class="o">//</span> <span class="n">sample</span> <span class="n">secondary</span> <span class="n">zone</span>
<span class="n">zone</span> <span class="s2">&quot;site1.example.com&quot;</span> <span class="p">{</span>
  <span class="nb">type</span> <span class="n">primary</span><span class="p">;</span>
  <span class="n">file</span> <span class="s2">&quot;m/site1.foo.com&quot;</span><span class="p">;</span>
  <span class="n">allow</span><span class="o">-</span><span class="n">transfer</span> <span class="p">{</span> <span class="n">internals</span><span class="p">;</span> <span class="n">externals</span><span class="p">;</span> <span class="p">};</span>
<span class="p">};</span>

<span class="n">zone</span> <span class="s2">&quot;site2.example.com&quot;</span> <span class="p">{</span>
  <span class="nb">type</span> <span class="n">secondary</span><span class="p">;</span>
  <span class="n">file</span> <span class="s2">&quot;s/site2.foo.com&quot;</span><span class="p">;</span>
  <span class="n">primaries</span> <span class="p">{</span> <span class="n">another_bastion_host_maybe</span><span class="p">;</span> <span class="p">};</span>
  <span class="n">allow</span><span class="o">-</span><span class="n">transfer</span> <span class="p">{</span> <span class="n">internals</span><span class="p">;</span> <span class="n">externals</span><span class="p">;</span> <span class="p">}</span>
<span class="p">};</span>
</pre></div>
</div>
<p>In the <code class="docutils literal notranslate"><span class="pre">resolv.conf</span></code> (or equivalent) on the bastion host(s):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">search</span> <span class="o">...</span>
<span class="n">nameserver</span> <span class="mf">172.16.72.2</span>
<span class="n">nameserver</span> <span class="mf">172.16.72.3</span>
<span class="n">nameserver</span> <span class="mf">172.16.72.4</span>
</pre></div>
</div>
</section>
</section>
<section id="ipv6-support-in-bind-9">
<span id="ipv6"></span><h2><span class="section-number">6.5. </span>IPv6 Support in BIND 9<a class="headerlink" href="#ipv6-support-in-bind-9" title="Link to this heading"></a></h2>
<p>BIND 9 fully supports all currently defined forms of IPv6 name-to-address
and address-to-name lookups. It also uses IPv6 addresses to
make queries when running on an IPv6-capable system.</p>
<p>For forward lookups, BIND 9 supports only AAAA records. <span class="target" id="index-6"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc3363.html"><strong>RFC 3363</strong></a>
deprecated the use of A6 records, and client-side support for A6 records
was accordingly removed from BIND 9. However, authoritative BIND 9 name
servers still load zone files containing A6 records correctly, answer
queries for A6 records, and accept zone transfer for a zone containing
A6 records.</p>
<p>For IPv6 reverse lookups, BIND 9 supports the traditional “nibble”
format used in the <code class="docutils literal notranslate"><span class="pre">ip6.arpa</span></code> domain, as well as the older, deprecated
<code class="docutils literal notranslate"><span class="pre">ip6.int</span></code> domain. Older versions of BIND 9 supported the “binary label”
(also known as “bitstring”) format, but support of binary labels has
been completely removed per <span class="target" id="index-7"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc3363.html"><strong>RFC 3363</strong></a>. Many applications in BIND 9 do not
understand the binary label format at all anymore, and return an
error if one is given. In particular, an authoritative BIND 9 name server will
not load a zone file containing binary labels.</p>
<section id="address-lookups-using-aaaa-records">
<h3><span class="section-number">6.5.1. </span>Address Lookups Using AAAA Records<a class="headerlink" href="#address-lookups-using-aaaa-records" title="Link to this heading"></a></h3>
<p>The IPv6 AAAA record is a parallel to the IPv4 A record, and, unlike the
deprecated A6 record, specifies the entire IPv6 address in a single
record. For example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ORIGIN example.com.
host            3600    IN      AAAA    2001:db8::1
</pre></div>
</div>
<p>Use of IPv4-in-IPv6 mapped addresses is not recommended. If a host has
an IPv4 address, use an A record, not a AAAA, with
<code class="docutils literal notranslate"><span class="pre">::ffff:192.168.42.1</span></code> as the address.</p>
</section>
<section id="address-to-name-lookups-using-nibble-format">
<h3><span class="section-number">6.5.2. </span>Address-to-Name Lookups Using Nibble Format<a class="headerlink" href="#address-to-name-lookups-using-nibble-format" title="Link to this heading"></a></h3>
<p>When looking up an address in nibble format, the address components are
simply reversed, just as in IPv4, and <code class="docutils literal notranslate"><span class="pre">ip6.arpa.</span></code> is appended to the
resulting name. For example, the following commands produce a reverse name
lookup for a host with address <code class="docutils literal notranslate"><span class="pre">2001:db8::1</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0  14400   IN    PTR    (
                    host.example.com. )
</pre></div>
</div>
</section>
</section>
<section id="dynamically-loadable-zones-dlz">
<span id="dlz-info"></span><h2><span class="section-number">6.6. </span>Dynamically Loadable Zones (DLZ)<a class="headerlink" href="#dynamically-loadable-zones-dlz" title="Link to this heading"></a></h2>
<p>Dynamically Loadable Zones (DLZ) are an extension to BIND 9 that allows
zone data to be retrieved directly from an external database. There is
no required format or schema.</p>
<p>There are number of contributed DLZ modules for several different database
backends, including MySQL and LDAP, but they are not actively maintained.</p>
<p>The DLZ module provides data to <a class="reference internal" href="manpages.html#std-iscman-named"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named</span></code></a> in text
format, which is then converted to DNS wire format by <a class="reference internal" href="manpages.html#std-iscman-named"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named</span></code></a>. This
conversion, and the lack of any internal caching, places significant
limits on the query performance of DLZ modules. Consequently, DLZ is not
recommended for use on high-volume servers. However, it can be used in a
hidden primary configuration, with secondaries retrieving zone updates via
AXFR. Note, however, that DLZ has no built-in support for DNS notify;
secondary servers are not automatically informed of changes to the zones in the
database.</p>
<section id="configuring-dlz">
<h3><span class="section-number">6.6.1. </span>Configuring DLZ<a class="headerlink" href="#configuring-dlz" title="Link to this heading"></a></h3>
<dl class="namedconf statement">
<dt class="sig sig-object namedconf" id="namedconf-statement-dlz">
<span class="sig-name descname"><span class="pre">dlz</span></span><a class="headerlink" href="#namedconf-statement-dlz" title="Link to this definition"></a></dt>
<dd><p><strong>Grammar zone (primary, redirect, secondary): </strong><code class="docutils literal notranslate"><span class="pre">dlz</span> <span class="pre">&lt;string&gt;;</span></code></p>
<p><strong>Grammar topmost, view: </strong><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dlz</span> <span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="p">{</span>
	<span class="n">database</span> <span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span><span class="p">;</span>
	<span class="n">search</span> <span class="o">&lt;</span><span class="n">boolean</span><span class="o">&gt;</span><span class="p">;</span>
<span class="p">};</span> <span class="o">//</span> <span class="n">may</span> <span class="n">occur</span> <span class="n">multiple</span> <span class="n">times</span>
</pre></div>
</div>
</p>
<p><strong>Blocks: </strong>topmost, view, zone (primary, redirect, secondary)</p>
<p><strong>Tags: </strong>zone</p>
<p><p>Configures a Dynamically Loadable Zone (DLZ) database in <a class="reference internal" href="manpages.html#std-iscman-named.conf"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named.conf</span></code></a>.</p>
</p>
</dd></dl>

<p>A DLZ database is configured with a <a class="reference internal" href="#namedconf-statement-dlz" title="namedconf-statement-dlz"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">dlz</span></code></a> statement in <a class="reference internal" href="manpages.html#std-iscman-named.conf"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named.conf</span></code></a>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dlz</span> <span class="n">example</span> <span class="p">{</span>
<span class="n">database</span> <span class="s2">&quot;dlopen driver.so args&quot;</span><span class="p">;</span>
<span class="n">search</span> <span class="n">yes</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
<p>This specifies a DLZ module to search when answering queries; the module
is implemented in <code class="docutils literal notranslate"><span class="pre">driver.so</span></code> and is loaded at runtime by the dlopen
DLZ driver. Multiple <a class="reference internal" href="#namedconf-statement-dlz" title="namedconf-statement-dlz"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">dlz</span></code></a> statements can be specified.</p>
<dl class="namedconf statement">
<dt class="sig sig-object namedconf" id="namedconf-statement-search">
<span class="sig-name descname"><span class="pre">search</span></span><a class="headerlink" href="#namedconf-statement-search" title="Link to this definition"></a></dt>
<dd><p><strong>Grammar: </strong><code class="docutils literal notranslate"><span class="pre">search</span> <span class="pre">&lt;boolean&gt;;</span></code></p>
<p><strong>Blocks: </strong>dlz, view.dlz</p>
<p><strong>Tags: </strong>query</p>
<p><p>Specifies whether a Dynamically Loadable Zone (DLZ) module is queried for an answer to a query name.</p>
</p>
</dd></dl>

<p>When answering a query, all DLZ modules with <a class="reference internal" href="#namedconf-statement-search" title="namedconf-statement-search"><code class="xref namedconf namedconf-ref docutils literal notranslate"><span class="pre">search</span></code></a> set to <code class="docutils literal notranslate"><span class="pre">yes</span></code> are
queried to see whether they contain an answer for the query name. The best
available answer is returned to the client.</p>
<p>The <a class="reference internal" href="#namedconf-statement-search" title="namedconf-statement-search"><code class="xref namedconf namedconf-ref docutils literal notranslate"><span class="pre">search</span></code></a> option in the above example can be omitted, because
<code class="docutils literal notranslate"><span class="pre">yes</span></code> is the default value.</p>
<p>If <a class="reference internal" href="#namedconf-statement-search" title="namedconf-statement-search"><code class="xref namedconf namedconf-ref docutils literal notranslate"><span class="pre">search</span></code></a> is set to <code class="docutils literal notranslate"><span class="pre">no</span></code>, this DLZ module is <em>not</em> searched
for the best match when a query is received. Instead, zones in this DLZ
must be separately specified in a zone statement. This allows users to
configure a zone normally using standard zone-option semantics, but
specify a different database backend for storage of the zone’s data.
For example, to implement NXDOMAIN redirection using a DLZ module for
backend storage of redirection rules:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dlz</span> <span class="n">other</span> <span class="p">{</span>
       <span class="n">database</span> <span class="s2">&quot;dlopen driver.so args&quot;</span><span class="p">;</span>
       <span class="n">search</span> <span class="n">no</span><span class="p">;</span>
<span class="p">};</span>

<span class="n">zone</span> <span class="s2">&quot;.&quot;</span> <span class="p">{</span>
       <span class="nb">type</span> <span class="n">redirect</span><span class="p">;</span>
       <span class="n">dlz</span> <span class="n">other</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
</section>
<section id="sample-dlz-module">
<h3><span class="section-number">6.6.2. </span>Sample DLZ Module<a class="headerlink" href="#sample-dlz-module" title="Link to this heading"></a></h3>
<p>For guidance in the implementation of DLZ modules, the <code class="docutils literal notranslate"><span class="pre">example</span></code>
directory in the [gitlab.isc.org/isc-projects/dlz-modules](<a class="reference external" href="https://gitlab.isc.org/isc-projects/dlz-modules/-/tree/main/example?ref_type=heads">https://gitlab.isc.org/isc-projects/dlz-modules/-/tree/main/example?ref_type=heads</a>)
contains a basic dynamically linkable DLZ module - i.e., one which can be loaded
at runtime by the “dlopen” DLZ driver. The example sets up a single zone, whose
name is passed to the module as an argument in the <a class="reference internal" href="#namedconf-statement-dlz" title="namedconf-statement-dlz"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">dlz</span></code></a> statement:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dlz</span> <span class="n">other</span> <span class="p">{</span>
       <span class="n">database</span> <span class="s2">&quot;dlopen driver.so example.nil&quot;</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
<p>In the above example, the module is configured to create a zone
“example.nil”, which can answer queries and AXFR requests and accept
DDNS updates. At runtime, prior to any updates, the zone contains an
SOA, NS, and a single A record at the apex:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">example</span><span class="o">.</span><span class="n">nil</span><span class="o">.</span>  <span class="mi">3600</span>    <span class="n">IN</span>      <span class="n">SOA</span>     <span class="n">example</span><span class="o">.</span><span class="n">nil</span><span class="o">.</span> <span class="n">hostmaster</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">nil</span><span class="o">.</span> <span class="p">(</span>
                          <span class="mi">123</span> <span class="mi">900</span> <span class="mi">600</span> <span class="mi">86400</span> <span class="mi">3600</span>
                      <span class="p">)</span>
<span class="n">example</span><span class="o">.</span><span class="n">nil</span><span class="o">.</span>  <span class="mi">3600</span>    <span class="n">IN</span>      <span class="n">NS</span>      <span class="n">example</span><span class="o">.</span><span class="n">nil</span><span class="o">.</span>
<span class="n">example</span><span class="o">.</span><span class="n">nil</span><span class="o">.</span>  <span class="mi">1800</span>    <span class="n">IN</span>      <span class="n">A</span>       <span class="mf">10.53.0.1</span>
</pre></div>
</div>
<p>The sample driver can retrieve information about the
querying client and alter its response on the basis of this
information. To demonstrate this feature, the example driver responds to
queries for “source-addr.``zonename``&gt;/TXT” with the source address of
the query. Note, however, that this record will <em>not</em> be included in
AXFR or ANY responses. Normally, this feature is used to alter
responses in some other fashion, e.g., by providing different address
records for a particular name depending on the network from which the
query arrived.</p>
<p>Documentation of the DLZ module API can be found in
[README](<a class="reference external" href="https://gitlab.isc.org/isc-projects/dlz-modules/-/raw/main/example/README">https://gitlab.isc.org/isc-projects/dlz-modules/-/raw/main/example/README</a>). This
repository also contains the header file
[dlz_minimal.h](<a class="reference external" href="https://gitlab.isc.org/isc-projects/dlz-modules/-/raw/main/modules/include/dlz_minimal.h">https://gitlab.isc.org/isc-projects/dlz-modules/-/raw/main/modules/include/dlz_minimal.h</a>),
which defines the API and should be included by any dynamically linkable DLZ
module.</p>
</section>
</section>
<section id="dynamic-database-dyndb">
<span id="dyndb-info"></span><h2><span class="section-number">6.7. </span>Dynamic Database (DynDB)<a class="headerlink" href="#dynamic-database-dyndb" title="Link to this heading"></a></h2>
<p>Dynamic Database, or DynDB, is an extension to BIND 9 which, like DLZ (see
<a class="reference internal" href="#dlz-info"><span class="std std-ref">Dynamically Loadable Zones (DLZ)</span></a>), allows zone data to be retrieved from an external
database. Unlike DLZ, a DynDB module provides a full-featured BIND zone
database interface. Where DLZ translates DNS queries into real-time
database lookups, resulting in relatively poor query performance, and is
unable to handle DNSSEC-signed data due to its limited API, a DynDB
module can pre-load an in-memory database from the external data source,
providing the same performance and functionality as zones served
natively by BIND.</p>
<p>A DynDB module supporting LDAP has been created by Red Hat and is
available from <a class="reference external" href="https://pagure.io/bind-dyndb-ldap">https://pagure.io/bind-dyndb-ldap</a>.</p>
<p>A sample DynDB module for testing and developer guidance is included
with the BIND source code, in the directory
<code class="docutils literal notranslate"><span class="pre">bin/tests/system/dyndb/driver</span></code>.</p>
<section id="configuring-dyndb">
<h3><span class="section-number">6.7.1. </span>Configuring DynDB<a class="headerlink" href="#configuring-dyndb" title="Link to this heading"></a></h3>
<dl class="namedconf statement">
<dt class="sig sig-object namedconf" id="namedconf-statement-dyndb">
<span class="sig-name descname"><span class="pre">dyndb</span></span><a class="headerlink" href="#namedconf-statement-dyndb" title="Link to this definition"></a></dt>
<dd><p><strong>Grammar: </strong><code class="docutils literal notranslate"><span class="pre">dyndb</span> <span class="pre">&lt;string&gt;</span> <span class="pre">&lt;quoted_string&gt;</span> <span class="pre">{</span> <span class="pre">&lt;unspecified-text&gt;</span> <span class="pre">};</span> <span class="pre">//</span> <span class="pre">may</span> <span class="pre">occur</span> <span class="pre">multiple</span> <span class="pre">times</span></code></p>
<p><strong>Blocks: </strong>topmost, view</p>
<p><strong>Tags: </strong>zone</p>
<p><p>Configures a DynDB database in <a class="reference internal" href="manpages.html#std-iscman-named.conf"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named.conf</span></code></a>.</p>
</p>
</dd></dl>

<p>A DynDB database is configured with a <a class="reference internal" href="#namedconf-statement-dyndb" title="namedconf-statement-dyndb"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">dyndb</span></code></a> statement in
<a class="reference internal" href="manpages.html#std-iscman-named.conf"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named.conf</span></code></a>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dyndb</span> <span class="n">example</span> <span class="s2">&quot;driver.so&quot;</span> <span class="p">{</span>
    <span class="n">parameters</span>
<span class="p">};</span>
</pre></div>
</div>
<p>The file <code class="docutils literal notranslate"><span class="pre">driver.so</span></code> is a DynDB module which implements the full DNS
database API. Multiple <a class="reference internal" href="#namedconf-statement-dyndb" title="namedconf-statement-dyndb"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">dyndb</span></code></a> statements can be specified, to load
different drivers or multiple instances of the same driver. Zones
provided by a DynDB module are added to the view’s zone table, and are
treated as normal authoritative zones when BIND responds to
queries. Zone configuration is handled internally by the DynDB module.</p>
<p>The parameters are passed as an opaque string to the DynDB module’s
initialization routine. Configuration syntax differs depending on
the driver.</p>
</section>
<section id="sample-dyndb-module">
<h3><span class="section-number">6.7.2. </span>Sample DynDB Module<a class="headerlink" href="#sample-dyndb-module" title="Link to this heading"></a></h3>
<p>For guidance in the implementation of DynDB modules, the directory
<code class="docutils literal notranslate"><span class="pre">bin/tests/system/dyndb/driver</span></code> contains a basic DynDB module. The
example sets up two zones, whose names are passed to the module as
arguments in the <a class="reference internal" href="#namedconf-statement-dyndb" title="namedconf-statement-dyndb"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">dyndb</span></code></a> statement:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dyndb</span> <span class="n">sample</span> <span class="s2">&quot;sample.so&quot;</span> <span class="p">{</span> <span class="n">example</span><span class="o">.</span><span class="n">nil</span><span class="o">.</span> <span class="n">arpa</span><span class="o">.</span> <span class="p">};</span>
</pre></div>
</div>
<p>In the above example, the module is configured to create a zone,
“example.nil”, which can answer queries and AXFR requests and accept
DDNS updates. At runtime, prior to any updates, the zone contains an
SOA, NS, and a single A record at the apex:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">example</span><span class="o">.</span><span class="n">nil</span><span class="o">.</span>  <span class="mi">86400</span>    <span class="n">IN</span>      <span class="n">SOA</span>     <span class="n">example</span><span class="o">.</span><span class="n">nil</span><span class="o">.</span> <span class="n">example</span><span class="o">.</span><span class="n">nil</span><span class="o">.</span> <span class="p">(</span>
                                              <span class="mi">0</span> <span class="mi">28800</span> <span class="mi">7200</span> <span class="mi">604800</span> <span class="mi">86400</span>
                                      <span class="p">)</span>
<span class="n">example</span><span class="o">.</span><span class="n">nil</span><span class="o">.</span>  <span class="mi">86400</span>    <span class="n">IN</span>      <span class="n">NS</span>      <span class="n">example</span><span class="o">.</span><span class="n">nil</span><span class="o">.</span>
<span class="n">example</span><span class="o">.</span><span class="n">nil</span><span class="o">.</span>  <span class="mi">86400</span>    <span class="n">IN</span>      <span class="n">A</span>       <span class="mf">127.0.0.1</span>
</pre></div>
</div>
<p>When the zone is updated dynamically, the DynDB module determines
whether the updated RR is an address (i.e., type A or AAAA); if so,
it automatically updates the corresponding PTR record in a reverse
zone. Note that updates are not stored permanently; all updates are lost when the
server is restarted.</p>
</section>
</section>
<section id="catalog-zones">
<span id="catz-info"></span><h2><span class="section-number">6.8. </span>Catalog Zones<a class="headerlink" href="#catalog-zones" title="Link to this heading"></a></h2>
<p>A “catalog zone” is a special DNS zone that contains a list of other
zones to be served, along with their configuration parameters. Zones
listed in a catalog zone are called “member zones.” When a catalog zone
is loaded or transferred to a secondary server which supports this
functionality, the secondary server creates the member zones
automatically. When the catalog zone is updated (for example, to add or
delete member zones, or change their configuration parameters), those
changes are immediately put into effect. Because the catalog zone is a
normal DNS zone, these configuration changes can be propagated using the
standard AXFR/IXFR zone transfer mechanism.</p>
<p>The format and behavior of catalog zones are specified in <span class="target" id="index-8"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc9432.html"><strong>RFC 9432</strong></a>.</p>
<section id="principle-of-operation">
<h3><span class="section-number">6.8.1. </span>Principle of Operation<a class="headerlink" href="#principle-of-operation" title="Link to this heading"></a></h3>
<p>Normally, if a zone is to be served by a secondary server, the
<a class="reference internal" href="manpages.html#std-iscman-named.conf"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named.conf</span></code></a> file on the server must list the zone, or the zone must
be added using <a class="reference internal" href="manpages.html#cmdoption-rndc-arg-addzone"><code class="xref std std-option docutils literal notranslate"><span class="pre">rndc</span> <span class="pre">addzone</span></code></a>. In environments with a large number of
secondary servers, and/or where the zones being served are changing
frequently, the overhead involved in maintaining consistent zone
configuration on all the secondary servers can be significant.</p>
<p>A catalog zone is a way to ease this administrative burden: it is a DNS
zone that lists member zones that should be served by secondary servers.
When a secondary server receives an update to the catalog zone, it adds,
removes, or reconfigures member zones based on the data received.</p>
<p>To use a catalog zone, it must first be set up as a normal zone on both the
primary and secondary servers that are configured to use it. It
must also be added to a <a class="reference internal" href="#namedconf-statement-catalog-zones" title="namedconf-statement-catalog-zones"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">catalog-zones</span></code></a> list in the <a class="reference internal" href="reference.html#namedconf-statement-options" title="namedconf-statement-options"><code class="xref namedconf namedconf-ref docutils literal notranslate"><span class="pre">options</span></code></a> or
<a class="reference internal" href="reference.html#namedconf-statement-view" title="namedconf-statement-view"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">view</span></code></a> statement in <a class="reference internal" href="manpages.html#std-iscman-named.conf"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named.conf</span></code></a>. This is comparable to the way a
policy zone is configured as a normal zone and also listed in a
<a class="reference internal" href="reference.html#namedconf-statement-response-policy" title="namedconf-statement-response-policy"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">response-policy</span></code></a> statement.</p>
<p>To use the catalog zone feature to serve a new member zone:</p>
<ul class="simple">
<li><p>Set up the member zone to be served on the primary as normal. This
can be done by editing <a class="reference internal" href="manpages.html#std-iscman-named.conf"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named.conf</span></code></a> or by running
<a class="reference internal" href="manpages.html#cmdoption-rndc-arg-addzone"><code class="xref std std-option docutils literal notranslate"><span class="pre">rndc</span> <span class="pre">addzone</span></code></a>.</p></li>
<li><p>Add an entry to the catalog zone for the new member zone. This can
be done by editing the catalog zone’s zone file and running
<a class="reference internal" href="manpages.html#cmdoption-rndc-arg-reload"><code class="xref std std-option docutils literal notranslate"><span class="pre">rndc</span> <span class="pre">reload</span></code></a>, or by updating the zone using <a class="reference internal" href="manpages.html#std-iscman-nsupdate"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">nsupdate</span></code></a>.</p></li>
</ul>
<p>The change to the catalog zone is propagated from the primary to all
secondaries using the normal AXFR/IXFR mechanism. When the secondary receives the
update to the catalog zone, it detects the entry for the new member
zone, creates an instance of that zone on the secondary server, and points
that instance to the <a class="reference internal" href="reference.html#namedconf-statement-primaries" title="namedconf-statement-primaries"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">primaries</span></code></a> specified in the catalog zone data. The
newly created member zone is a normal secondary zone, so BIND
immediately initiates a transfer of zone contents from the primary. Once
complete, the secondary starts serving the member zone.</p>
<p>Removing a member zone from a secondary server requires only
deleting the member zone’s entry in the catalog zone; the change to the
catalog zone is propagated to the secondary server using the normal
AXFR/IXFR transfer mechanism. The secondary server, on processing the
update, notices that the member zone has been removed, stops
serving the zone, and removes it from its list of configured zones.
However, removing the member zone from the primary server must be done
by editing the configuration file or running
<a class="reference internal" href="manpages.html#cmdoption-rndc-arg-delzone"><code class="xref std std-option docutils literal notranslate"><span class="pre">rndc</span> <span class="pre">delzone</span></code></a>.</p>
</section>
<section id="configuring-catalog-zones">
<h3><span class="section-number">6.8.2. </span>Configuring Catalog Zones<a class="headerlink" href="#configuring-catalog-zones" title="Link to this heading"></a></h3>
<dl class="namedconf statement">
<dt class="sig sig-object namedconf" id="namedconf-statement-catalog-zones">
<span class="sig-name descname"><span class="pre">catalog-zones</span></span><a class="headerlink" href="#namedconf-statement-catalog-zones" title="Link to this definition"></a></dt>
<dd><p><strong>Grammar: </strong><code class="docutils literal notranslate"><span class="pre">catalog-zones</span> <span class="pre">{</span> <span class="pre">zone</span> <span class="pre">&lt;string&gt;</span> <span class="pre">[</span> <span class="pre">default-primaries</span> <span class="pre">[</span> <span class="pre">port</span> <span class="pre">&lt;integer&gt;</span> <span class="pre">]</span>&#160; <span class="pre">{</span> <span class="pre">(</span> <span class="pre">&lt;remote-servers&gt;</span> <span class="pre">|</span> <span class="pre">&lt;ipv4_address&gt;</span> <span class="pre">[</span> <span class="pre">port</span> <span class="pre">&lt;integer&gt;</span> <span class="pre">]</span> <span class="pre">|</span> <span class="pre">&lt;ipv6_address&gt;</span> <span class="pre">[</span> <span class="pre">port</span> <span class="pre">&lt;integer&gt;</span> <span class="pre">]</span> <span class="pre">)</span> <span class="pre">[</span> <span class="pre">key</span> <span class="pre">&lt;string&gt;</span> <span class="pre">]</span> <span class="pre">[</span> <span class="pre">tls</span> <span class="pre">&lt;string&gt;</span> <span class="pre">];</span> <span class="pre">...</span> <span class="pre">}</span> <span class="pre">]</span> <span class="pre">[</span> <span class="pre">zone-directory</span> <span class="pre">&lt;quoted_string&gt;</span> <span class="pre">]</span> <span class="pre">[</span> <span class="pre">in-memory</span> <span class="pre">&lt;boolean&gt;</span> <span class="pre">]</span> <span class="pre">[</span> <span class="pre">min-update-interval</span> <span class="pre">&lt;duration&gt;</span> <span class="pre">];</span> <span class="pre">...</span> <span class="pre">};</span></code></p>
<p><strong>Blocks: </strong>options, view</p>
<p><strong>Tags: </strong>zone</p>
<p><p>Configures catalog zones in <a class="reference internal" href="manpages.html#std-iscman-named.conf"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named.conf</span></code></a>.</p>
</p>
</dd></dl>

<p>Catalog zones are configured with a <a class="reference internal" href="#namedconf-statement-catalog-zones" title="namedconf-statement-catalog-zones"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">catalog-zones</span></code></a> statement in the
<a class="reference internal" href="reference.html#namedconf-statement-options" title="namedconf-statement-options"><code class="xref namedconf namedconf-ref docutils literal notranslate"><span class="pre">options</span></code></a> or <a class="reference internal" href="reference.html#namedconf-statement-view" title="namedconf-statement-view"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">view</span></code></a> section of <a class="reference internal" href="manpages.html#std-iscman-named.conf"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named.conf</span></code></a>. For example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">catalog</span><span class="o">-</span><span class="n">zones</span> <span class="p">{</span>
    <span class="n">zone</span> <span class="s2">&quot;catalog.example&quot;</span>
         <span class="n">default</span><span class="o">-</span><span class="n">primaries</span> <span class="p">{</span> <span class="mf">10.53.0.1</span><span class="p">;</span> <span class="p">}</span>
         <span class="ow">in</span><span class="o">-</span><span class="n">memory</span> <span class="n">no</span>
         <span class="n">zone</span><span class="o">-</span><span class="n">directory</span> <span class="s2">&quot;catzones&quot;</span>
         <span class="nb">min</span><span class="o">-</span><span class="n">update</span><span class="o">-</span><span class="n">interval</span> <span class="mi">10</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
<p>This statement specifies that the zone <code class="docutils literal notranslate"><span class="pre">catalog.example</span></code> is a catalog
zone. This zone must be properly configured in the same view. In most
configurations, it would be a secondary zone.</p>
<p>The options following the zone name are not required, and may be
specified in any order.</p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">default-masters</span></code></dt><dd><p>Synonym for <code class="docutils literal notranslate"><span class="pre">default-primaries</span></code>.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">default-primaries</span></code></dt><dd><p>This option defines the default primaries for member
zones listed in a catalog zone, and can be overridden by options within
a catalog zone. If no such options are included, then member zones
transfer their contents from the servers listed in this option.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">in-memory</span></code></dt><dd><p>This option, if set to <code class="docutils literal notranslate"><span class="pre">yes</span></code>, causes member zones to be
stored only in memory. This is functionally equivalent to configuring a
secondary zone without a <a class="reference internal" href="reference.html#namedconf-statement-file" title="namedconf-statement-file"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">file</span></code></a> option. The default is <code class="docutils literal notranslate"><span class="pre">no</span></code>; member
zones’ content is stored locally in a file whose name is
automatically generated from the view name, catalog zone name, and
member zone name.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">zone-directory</span></code></dt><dd><p>This option causes local copies of member zones’ zone files to be
stored in the specified directory, if <code class="docutils literal notranslate"><span class="pre">in-memory</span></code> is not set to
<code class="docutils literal notranslate"><span class="pre">yes</span></code>. The default is to store zone files in the server’s working
directory. A non-absolute pathname in <code class="docutils literal notranslate"><span class="pre">zone-directory</span></code> is assumed
to be relative to the working directory.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">min-update-interval</span></code></dt><dd><p>This option sets the minimum interval between updates to catalog
zones, in seconds. If an update to a catalog zone (for example, via
IXFR) happens less than <code class="docutils literal notranslate"><span class="pre">min-update-interval</span></code> seconds after the
most recent update, the changes are not carried out until this
interval has elapsed. The default is 5 seconds.</p>
</dd>
</dl>
<p>Catalog zones are defined on a per-view basis. Configuring a non-empty
<a class="reference internal" href="#namedconf-statement-catalog-zones" title="namedconf-statement-catalog-zones"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">catalog-zones</span></code></a> statement in a view automatically turns on
<a class="reference internal" href="reference.html#namedconf-statement-allow-new-zones" title="namedconf-statement-allow-new-zones"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">allow-new-zones</span></code></a> for that view. This means that <a class="reference internal" href="manpages.html#cmdoption-rndc-arg-addzone"><code class="xref std std-option docutils literal notranslate"><span class="pre">rndc</span> <span class="pre">addzone</span></code></a>
and <a class="reference internal" href="manpages.html#cmdoption-rndc-arg-delzone"><code class="xref std std-option docutils literal notranslate"><span class="pre">rndc</span> <span class="pre">delzone</span></code></a> also work in any view that supports catalog
zones.</p>
</section>
<section id="catalog-zone-format">
<h3><span class="section-number">6.8.3. </span>Catalog Zone Format<a class="headerlink" href="#catalog-zone-format" title="Link to this heading"></a></h3>
<p>A catalog zone is a regular DNS zone; therefore, it must have a single
<code class="docutils literal notranslate"><span class="pre">SOA</span></code> and at least one <code class="docutils literal notranslate"><span class="pre">NS</span></code> record.</p>
<p>A record stating the version of the catalog zone format is also
required. If the version number listed is not supported by the server,
then a catalog zone may not be used by that server.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span>    <span class="n">IN</span> <span class="n">SOA</span> <span class="o">.</span> <span class="o">.</span> <span class="mi">2016022901</span> <span class="mi">900</span> <span class="mi">600</span> <span class="mi">86400</span> <span class="mi">1</span>
<span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span>    <span class="n">IN</span> <span class="n">NS</span> <span class="n">invalid</span><span class="o">.</span>
<span class="n">version</span><span class="o">.</span><span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span>    <span class="n">IN</span> <span class="n">TXT</span> <span class="s2">&quot;2&quot;</span>
</pre></div>
</div>
<p>Note that this record must have the domain name
<code class="docutils literal notranslate"><span class="pre">version.catalog-zone-name</span></code>. The data
stored in a catalog zone is indicated by the domain name label
immediately before the catalog zone domain. Currently BIND supports catalog zone
schema versions “1” and “2”.</p>
<p>Also note that the catalog zone must have an NS record in order to be a valid
DNS zone, and using the value “invalid.” for NS is recommended.</p>
<p>A member zone is added by including a <code class="docutils literal notranslate"><span class="pre">PTR</span></code> resource record in the
<code class="docutils literal notranslate"><span class="pre">zones</span></code> sub-domain of the catalog zone. The record label can be any unique label.
The target of the PTR record is the member zone name. For example, to add member zones
<code class="docutils literal notranslate"><span class="pre">domain.example</span></code> and <code class="docutils literal notranslate"><span class="pre">domain2.example</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">5960775</span><span class="n">ba382e7a4e09263fc06e7c00569b6a05c</span><span class="o">.</span><span class="n">zones</span><span class="o">.</span><span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span> <span class="n">IN</span> <span class="n">PTR</span> <span class="n">domain</span><span class="o">.</span><span class="n">example</span><span class="o">.</span>
<span class="n">uniquelabel</span><span class="o">.</span><span class="n">zones</span><span class="o">.</span><span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span> <span class="n">IN</span> <span class="n">PTR</span> <span class="n">domain2</span><span class="o">.</span><span class="n">example</span><span class="o">.</span>
</pre></div>
</div>
<p>The label is necessary to identify custom properties (see below) for a specific member zone.
Also, the zone state can be reset by changing its label, in which case BIND will remove
the member zone and add it back.</p>
</section>
<section id="catalog-zone-custom-properties">
<h3><span class="section-number">6.8.4. </span>Catalog Zone Custom Properties<a class="headerlink" href="#catalog-zone-custom-properties" title="Link to this heading"></a></h3>
<p>BIND uses catalog zones custom properties to define different properties which
can be set either globally for the whole catalog
zone or for a single member zone. Global custom properties override the settings
in the configuration file, and member zone custom properties override global
custom properties.</p>
<p>For the version “1” of the schema custom properties must be placed without a special suffix.</p>
<p>For the version “2” of the schema custom properties must be placed under the “.ext” suffix.</p>
<p>Global custom properties are set at the apex of the catalog zone, e.g.:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">primaries</span><span class="o">.</span><span class="n">ext</span><span class="o">.</span><span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span>    <span class="n">IN</span> <span class="n">AAAA</span> <span class="mi">2001</span><span class="p">:</span><span class="n">db8</span><span class="p">::</span><span class="mi">1</span>
</pre></div>
</div>
<p>BIND currently supports the following custom properties:</p>
<ul>
<li><p>A simple <a class="reference internal" href="reference.html#namedconf-statement-primaries" title="namedconf-statement-primaries"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">primaries</span></code></a> definition:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">primaries</span><span class="o">.</span><span class="n">ext</span><span class="o">.</span><span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span>    <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.0.2.1</span>
</pre></div>
</div>
<p>This custom property defines a primary server for the member zones, which can be
either an A or AAAA record. If multiple primaries are set, the order in
which they are used is random.</p>
<p>Note: <code class="docutils literal notranslate"><span class="pre">masters</span></code> can be used as a synonym for <a class="reference internal" href="reference.html#namedconf-statement-primaries" title="namedconf-statement-primaries"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">primaries</span></code></a>.</p>
</li>
<li><p>A <a class="reference internal" href="reference.html#namedconf-statement-primaries" title="namedconf-statement-primaries"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">primaries</span></code></a> with a TSIG key defined:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">label</span><span class="o">.</span><span class="n">primaries</span><span class="o">.</span><span class="n">ext</span><span class="o">.</span><span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span>     <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.0.2.2</span>
<span class="n">label</span><span class="o">.</span><span class="n">primaries</span><span class="o">.</span><span class="n">ext</span><span class="o">.</span><span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span>     <span class="n">IN</span> <span class="n">TXT</span> <span class="s2">&quot;tsig_key_name&quot;</span>
</pre></div>
</div>
<p>This custom property defines a primary server for the member zone with a TSIG
key set. The TSIG key must be configured in the configuration file.
<code class="docutils literal notranslate"><span class="pre">label</span></code> can be any valid DNS label.</p>
<p>Note: <code class="docutils literal notranslate"><span class="pre">masters</span></code> can be used as a synonym for <a class="reference internal" href="reference.html#namedconf-statement-primaries" title="namedconf-statement-primaries"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">primaries</span></code></a>.</p>
</li>
<li><p><a class="reference internal" href="reference.html#namedconf-statement-allow-query" title="namedconf-statement-allow-query"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">allow-query</span></code></a> and <a class="reference internal" href="reference.html#namedconf-statement-allow-transfer" title="namedconf-statement-allow-transfer"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">allow-transfer</span></code></a> ACLs:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>allow-query.ext.catalog.example.   IN APL 1:10.0.0.1/24
allow-transfer.ext.catalog.example.    IN APL !1:10.0.0.1/32 1:10.0.0.0/24
</pre></div>
</div>
<p>These custom properties are the equivalents of <a class="reference internal" href="reference.html#namedconf-statement-allow-query" title="namedconf-statement-allow-query"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">allow-query</span></code></a> and
<a class="reference internal" href="reference.html#namedconf-statement-allow-transfer" title="namedconf-statement-allow-transfer"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">allow-transfer</span></code></a> options in a zone declaration in the <a class="reference internal" href="manpages.html#std-iscman-named.conf"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named.conf</span></code></a>
configuration file. The ACL is processed in order; if there is no
match to any rule, the default policy is to deny access. For the
syntax of the APL RR, see <span class="target" id="index-9"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc3123.html"><strong>RFC 3123</strong></a>.</p>
</li>
</ul>
<p>The member zone-specific custom properties are defined the same way as global
custom properties, but in the member zone subdomain:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">primaries</span><span class="o">.</span><span class="n">ext</span><span class="mf">.5960775</span><span class="n">ba382e7a4e09263fc06e7c00569b6a05c</span><span class="o">.</span><span class="n">zones</span><span class="o">.</span><span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.0.2.2</span>
<span class="n">label</span><span class="o">.</span><span class="n">primaries</span><span class="o">.</span><span class="n">ext</span><span class="mf">.5960775</span><span class="n">ba382e7a4e09263fc06e7c00569b6a05c</span><span class="o">.</span><span class="n">zones</span><span class="o">.</span><span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span> <span class="n">IN</span> <span class="n">AAAA</span> <span class="mi">2001</span><span class="p">:</span><span class="n">db8</span><span class="p">::</span><span class="mi">2</span>
<span class="n">label</span><span class="o">.</span><span class="n">primaries</span><span class="o">.</span><span class="n">ext</span><span class="mf">.5960775</span><span class="n">ba382e7a4e09263fc06e7c00569b6a05c</span><span class="o">.</span><span class="n">zones</span><span class="o">.</span><span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span> <span class="n">IN</span> <span class="n">TXT</span> <span class="s2">&quot;tsig_key_name&quot;</span>
<span class="n">allow</span><span class="o">-</span><span class="n">query</span><span class="o">.</span><span class="n">ext</span><span class="mf">.5960775</span><span class="n">ba382e7a4e09263fc06e7c00569b6a05c</span><span class="o">.</span><span class="n">zones</span><span class="o">.</span><span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span> <span class="n">IN</span> <span class="n">APL</span> <span class="mi">1</span><span class="p">:</span><span class="mf">10.0.0.0</span><span class="o">/</span><span class="mi">24</span>
<span class="n">primaries</span><span class="o">.</span><span class="n">ext</span><span class="o">.</span><span class="n">uniquelabel</span><span class="o">.</span><span class="n">zones</span><span class="o">.</span><span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.0.2.3</span>
</pre></div>
</div>
<p>Custom properties defined for a specific zone override the
global custom properties defined in the catalog zone. These in turn override the
global options defined in the <a class="reference internal" href="#namedconf-statement-catalog-zones" title="namedconf-statement-catalog-zones"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">catalog-zones</span></code></a> statement in the
configuration file.</p>
<p>Note that none of the global records for a custom property are inherited if any
records are defined for that custom property for the specific zone. For example,
if the zone had a <a class="reference internal" href="reference.html#namedconf-statement-primaries" title="namedconf-statement-primaries"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">primaries</span></code></a> record of type A but not AAAA, it
would <em>not</em> inherit the type AAAA record from the global custom property
or from the global option in the configuration file.</p>
</section>
<section id="change-of-ownership-coo">
<h3><span class="section-number">6.8.5. </span>Change of Ownership (coo)<a class="headerlink" href="#change-of-ownership-coo" title="Link to this heading"></a></h3>
<p>BIND supports the catalog zones “Change of Ownership” (coo) property. When the
same entry which exists in one catalog zone is added into another catalog zone,
the default behavior for BIND is to ignore it, and continue serving the zone
using the catalog zone where it was originally existed, unless it is removed
from there, then it can be added into the new one.</p>
<p>Using the <code class="docutils literal notranslate"><span class="pre">coo</span></code> property it is possible to gracefully move a zone from one
catalog zone into another, by letting the catalog consumers know that it is
permitted to do so. To do that, the original catalog zone should be updated with
a new record with <code class="docutils literal notranslate"><span class="pre">coo</span></code> custom property:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">uniquelabel</span><span class="o">.</span><span class="n">zones</span><span class="o">.</span><span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span> <span class="n">IN</span> <span class="n">PTR</span> <span class="n">domain2</span><span class="o">.</span><span class="n">example</span><span class="o">.</span>
<span class="n">coo</span><span class="o">.</span><span class="n">uniquelabel</span><span class="o">.</span><span class="n">zones</span><span class="o">.</span><span class="n">catalog</span><span class="o">.</span><span class="n">example</span><span class="o">.</span> <span class="n">IN</span> <span class="n">PTR</span> <span class="n">catalog2</span><span class="o">.</span><span class="n">example</span><span class="o">.</span>
</pre></div>
</div>
<p>Here, the <code class="docutils literal notranslate"><span class="pre">catalog.example</span></code> catalog zone gives permission for the member zone
with label “uniquelabel” to be transferred into <code class="docutils literal notranslate"><span class="pre">catalog2.example</span></code> catalog
zone. Catalog consumers which support the <code class="docutils literal notranslate"><span class="pre">coo</span></code> property will then take note,
and when the zone is finally added into <code class="docutils literal notranslate"><span class="pre">catalog2.example</span></code> catalog zone,
catalog consumers will change the ownership of the zone from <code class="docutils literal notranslate"><span class="pre">catalog.example</span></code>
to <code class="docutils literal notranslate"><span class="pre">catalog2.example</span></code>. BIND’s implementation simply deletes the zone from the
old catalog zone and adds it back into the new catalog zone, which also means
that all associated state for the just migrated zone will be reset, including
when the unique label is the same.</p>
<p>The record with <code class="docutils literal notranslate"><span class="pre">coo</span></code> custom property can be later deleted by the
catalog zone operator after confirming that all the consumers have received
it and have successfully changed the ownership of the zone.</p>
</section>
</section>
<section id="dns-firewalls-and-response-policy-zones">
<h2><span class="section-number">6.9. </span>DNS Firewalls and Response Policy Zones<a class="headerlink" href="#dns-firewalls-and-response-policy-zones" title="Link to this heading"></a></h2>
<p>A DNS firewall examines DNS traffic and allows some responses to pass
through while blocking others. This examination can be based on several
criteria, including the name requested, the data (such as an IP address)
associated with that name, or the name or IP address of the name server
that is authoritative for the requested name.  Based on these criteria, a
DNS firewall can be configured to discard, modify, or replace the original
response, allowing administrators more control over what systems can access
or be accessed from their networks.</p>
<p>DNS Response Policy Zones (RPZ) are a form of DNS firewall in which the
firewall rules are expressed within the DNS itself - encoded in an open,
vendor-neutral format as records in specially constructed DNS zones.</p>
<p>Using DNS zones to configure policy allows policy to be shared from
one server to another using the standard DNS zone transfer mechanism.
This allows a DNS operator to maintain their own firewall policies and
share them easily amongst their internal name servers, or to subscribe to
external firewall policies such as commercial or cooperative “threat
feeds,” or both.</p>
<p><a class="reference internal" href="manpages.html#std-iscman-named"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named</span></code></a> can subscribe to up to 64 Response Policy Zones, each of which
encodes a separate policy rule set.  Each rule is stored in a DNS resource
record set (RRset) within the RPZ, and consists of a <strong>trigger</strong> and an
<strong>action</strong>.  There are five types of triggers and six types of actions.</p>
<p>A response policy rule in a DNS RPZ can be triggered as follows:</p>
<ul class="simple">
<li><p>by the IP address of the client</p></li>
<li><p>by the query name</p></li>
<li><p>by an address which would be present in a truthful response</p></li>
<li><p>by the name or address of an authoritative name server responsible for
publishing the original response</p></li>
</ul>
<p>A response policy action can be one of the following:</p>
<ul class="simple">
<li><p>to synthesize a “domain does not exist” (NXDOMAIN) response</p></li>
<li><p>to synthesize a “name exists but there are no records of the requested
type” (NODATA) response</p></li>
<li><p>to drop the response</p></li>
<li><p>to switch to TCP by sending a truncated UDP response that requires the
DNS client to try again with TCP</p></li>
<li><p>to replace/override the response’s data with specific data (provided
within the response policy zone)</p></li>
<li><p>to exempt the response from further policy processing</p></li>
</ul>
<p>The most common use of a DNS firewall is to “poison” a domain name, IP
address, name server name, or name server IP address. Poisoning is usually
done by forcing a synthetic “domain does not exist” (NXDOMAIN) response.
This means that if an administrator maintains a list of known “phishing”
domains, these names can be made unreachable by customers or end users just
by adding a firewall policy into the recursive DNS server, with a trigger
for each known “phishing” domain, and an action in every case forcing a
synthetic NXDOMAIN response. It is also possible to use a data-replacement
action such as answering for these known “phishing” domains with the name
of a local web server that can display a warning page. Such a web server
would be called a “walled garden.”</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Authoritative name servers can be responsible for many different domains.
If DNS RPZ is used to poison all domains served by some authoritative
name server name or address, the effects can be quite far-reaching. Users
are advised to ensure that such authoritative name servers do not also
serve domains that should not be poisoned.</p>
</div>
<section id="why-use-a-dns-firewall">
<span id="why-dns-firewall"></span><h3><span class="section-number">6.9.1. </span>Why Use a DNS Firewall?<a class="headerlink" href="#why-use-a-dns-firewall" title="Link to this heading"></a></h3>
<p>Criminal and network abuse traffic on the Internet often uses the Domain
Name System (DNS), so protection against these threats should include DNS
firewalling.  A DNS firewall can selectively intercept DNS queries for
known network assets including domain names, IP addresses, and name
servers. Interception can mean rewriting a DNS response to direct a web
browser to a “walled garden,” or simply making any malicious network assets
invisible and unreachable.</p>
</section>
<section id="what-can-a-dns-firewall-do">
<span id="what-dns-firewalls-do"></span><h3><span class="section-number">6.9.2. </span>What Can a DNS Firewall Do?<a class="headerlink" href="#what-can-a-dns-firewall-do" title="Link to this heading"></a></h3>
<p>Firewalls work by applying a set of rules to a traffic flow, where each
rule consists of a trigger and an action. Triggers determine which messages
within the traffic flow are handled specially, and actions determine what
that special handling is. For a DNS firewall, the traffic flow to be
controlled consists of responses sent by a recursive DNS server to its
end-user clients. Some true responses are not safe for all clients, so the
policy rules in a DNS firewall allow some responses to be intercepted and
replaced with safer content.</p>
</section>
<section id="creating-and-maintaining-rpz-rule-sets">
<span id="rpz-rule-sets"></span><h3><span class="section-number">6.9.3. </span>Creating and Maintaining RPZ Rule Sets<a class="headerlink" href="#creating-and-maintaining-rpz-rule-sets" title="Link to this heading"></a></h3>
<p>In DNS RPZ, the DNS firewall policy rule set is stored in a DNS zone, which
is maintained and synchronized using the same tools and methods as for any
other DNS zone. The primary name server for a DNS RPZ may be an internal
server, if an administrator is creating and maintaining their own DNS
policy zone, or it may be an external name server (such as a security
vendor’s server), if importing a policy zone published externally. The
primary copy of the DNS firewall policy can be a DNS “zone file” which is
either edited by hand or generated from a database. A DNS zone can also be
edited indirectly using DNS dynamic updates (for example, using the
“nsupdate” shell level utility).</p>
<p>DNS RPZ allows firewall rules to be expressed in a DNS zone format and then
carried to subscribers as DNS data. A recursive DNS server which is capable
of processing DNS RPZ synchronizes these DNS firewall rules using the same
standard DNS tools and protocols used for secondary name service. The DNS
policy information is then promoted to the DNS control plane inside the
customer’s DNS resolver, making that server into a DNS firewall.</p>
<p>A security company whose products include threat intelligence feeds can use
a DNS Response Policy Zone (RPZ) as a delivery channel to customers.
Threats can be expressed as known-malicious IP addresses and subnets,
known-malicious domain names, and known-malicious domain name servers. By
feeding this threat information directly into customers’ local DNS
resolvers, providers can transform these DNS servers into a distributed DNS
firewall.</p>
<p>When a customer’s DNS resolver is connected by a realtime subscription to a
threat intelligence feed, the provider can protect the customer’s end users
from malicious network elements (including IP addresses and subnets, domain
names, and name servers) immediately as they are discovered. While it may
take days or weeks to “take down” criminal and abusive infrastructure once
reported, a distributed DNS firewall can respond instantly.</p>
<p>Other distributed TCP/IP firewalls have been on the market for many years,
and enterprise users are now comfortable importing real-time threat
intelligence from their security vendors directly into their firewalls.
This intelligence can take the form of known-malicious IP addresses or
subnets, or of patterns which identify known-malicious email attachments,
file downloads, or web addresses (URLs). In some products it is also
possible to block DNS packets based on the names or addresses they carry.</p>
</section>
<section id="limitations-of-dns-rpz">
<span id="rpz-limitations"></span><h3><span class="section-number">6.9.4. </span>Limitations of DNS RPZ<a class="headerlink" href="#limitations-of-dns-rpz" title="Link to this heading"></a></h3>
<p>We’re often asked if DNS RPZ could be used to set up redirection to a CDN.
For example, if “mydomain.com” is a normal domain with SOA, NS, MX, TXT
records etc., then if someone sends an A or AAAA query for “mydomain.com”,
can we use DNS RPZ on an authoritative nameserver to return “CNAME
mydomain.com.my-cdn-provider.net”?</p>
<p>The problem with this suggestion is that there is no way to CNAME only A
and AAAA queries, not even with RPZ.</p>
<p>The underlying reason is that if the authoritative server answers with a
CNAME, the recursive server making that query will cache the response.
Thereafter (while the CNAME is still in cache), it assumes that there are
no records of any non-CNAME type for the name that was being queried, and
directs subsequent queries for all other types directly to the target name
of the CNAME record.</p>
<p>To be clear, this is not a limitation of RPZ; it is a function of the way
the DNS protocol works. It’s simply not possible to use “partial” CNAMES to
help when setting up CDNs because doing this will break other functionality
such as email routing.</p>
<p>Similarly, following the DNS protocol definition, wildcards in the form of
<code class="docutils literal notranslate"><span class="pre">*.example</span></code> records might behave in unintuitive ways. For a detailed
definition of wildcards in DNS, please see <span class="target" id="index-10"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc4592.html"><strong>RFC 4592</strong></a>, especially section 2.</p>
</section>
<section id="dns-firewall-usage-examples">
<span id="dns-firewall-examples"></span><h3><span class="section-number">6.9.5. </span>DNS Firewall Usage Examples<a class="headerlink" href="#dns-firewall-usage-examples" title="Link to this heading"></a></h3>
<p>Here are some scenarios in which a DNS firewall might be useful.</p>
<p>Some known threats are based on an IP address or subnet (IP address range).
For example, an analysis may show that all addresses in a “class C” network
are used by a criminal gang for “phishing” web servers. With a DNS firewall
based on DNS RPZ, a firewall policy can be created such as “if a DNS lookup
would result in an address from this class C network, then answer instead
with an NXDOMAIN indication.” That simple rule would prevent any end users
inside customers’ networks from being able to look up any domain name used
in this phishing attack – without having to know in advance what those
names might be.</p>
<p>Other known threats are based on domain names. An analysis may determine
that a certain domain name or set of domain names is being or will shortly
be used for spamming, phishing, or other Internet-based attacks which all
require working domain names. By adding name-triggered rules to a
distributed DNS firewall, providers can protect customers’ end users from
any attacks which require them to be able to look up any of these malicious
names. The names can be wildcards (for example, *.evil.com), and these
wildcards can have exceptions if some domains are not as malicious as
others (if *.evil.com is bad, then not.evil.com might be an exception).</p>
<p>Alongside growth in electronic crime has come growth of electronic criminal
expertise. Many criminal gangs now maintain their own extensive DNS
infrastructure to support a large number of domain names and a diverse set
of IP addressing resources. Analyses show in many cases that the only truly
fixed assets criminal organizations have are their name servers, which are
by nature slightly less mobile than other network assets. In such cases,
DNS administrators can anchor their DNS firewall policies in the abusive
name server names or name server addresses, and thus protect their
customers’ end users from threats where neither the domain name nor the IP
address of that threat is known in advance.</p>
<p>Electronic criminals rely on the full resiliency of DNS just as the rest of
digital society does. By targeting criminal assets at the DNS level we can
deny these criminals the resilience they need. A distributed DNS firewall
can leverage the high skills of a security company to protect a large
number of end users. DNS RPZ, as the first open and vendor-neutral
distributed DNS firewall, can be an effective way to deliver threat
intelligence to customers.</p>
<section id="a-real-world-example-of-dns-rpz-s-value">
<h4><span class="section-number">6.9.5.1. </span>A Real-World Example of DNS RPZ’s Value<a class="headerlink" href="#a-real-world-example-of-dns-rpz-s-value" title="Link to this heading"></a></h4>
<p>The Conficker malware worm (<a class="reference external" href="https://en.wikipedia.org/wiki/Conficker">https://en.wikipedia.org/wiki/Conficker</a>) was
first detected in 2008. Although it is no longer an active threat, the
techniques described here can be applied to other DNS threats.</p>
<p>Conficker used a domain generation algorithm (DGA) to choose up to 50,000
command and control domains per day. It would be impractical to create
an RPZ that contains so many domain names and changes so much on a daily
basis. Instead, we can trigger RPZ rules based on the names of the name
servers that are authoritative for the command and control domains, rather
than trying to trigger on each of 50,000 different (daily) query names.
Since the well-known name server names for Conficker’s domain names are
never used by nonmalicious domains, it is safe to poison all lookups that
rely on these name servers.  Here is an example that achieves this result:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ORIGIN rpz.example.com.
ns.0xc0f1c3a5.com.rpz-nsdname  CNAME  *.walled-garden.example.com.
ns.0xc0f1c3a5.net.rpz-nsdname  CNAME  *.walled-garden.example.com.
ns.0xc0f1c3a5.org.rpz-nsdname  CNAME  *.walled-garden.example.com.
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">*</span></code> at the beginning of these CNAME target names is special, and it
causes the original query name to be prepended to the CNAME target. So if a
user tries to visit the Conficker command and control domain
racaldftn.com.ai (which was a valid Conficker command and control
domain name on 19-October-2011), the RPZ-configured recursive name server
will send back this answer:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>racaldftn.com.ai.     CNAME     racaldftn.com.ai.walled-garden.example.com.
racaldftn.com.ai.walled-garden.example.com.     A      192.168.50.3
</pre></div>
</div>
<p>This example presumes that the following DNS content has also been created,
which is not part of the RPZ zone itself but is in another domain:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ORIGIN walled-garden.example.com.
*     A     192.168.50.3
</pre></div>
</div>
<p>Assuming that we’re running a web server listening on 192.168.50.3 that
always displays a warning message no matter what uniform resource
identifier (URI) is used, the above RPZ configuration will instruct the web
browser of any infected end user to connect to a “server name” consisting
of their original lookup name (racaldftn.com.ai) prepended to the walled
garden domain name (walled-garden.example.com). This is the name that will
appear in the web server’s log file, and having the full name in that log
file will facilitate an analysis as to which users are infected with what
virus.</p>
</section>
</section>
<section id="keeping-firewall-policies-updated">
<span id="firewall-updates"></span><h3><span class="section-number">6.9.6. </span>Keeping Firewall Policies Updated<a class="headerlink" href="#keeping-firewall-policies-updated" title="Link to this heading"></a></h3>
<p>It is vital for overall system performance that incremental zone transfers
(see <span class="target" id="index-11"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc1995.html"><strong>RFC 1995</strong></a>) and real-time change notification (see <span class="target" id="index-12"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc1996.html"><strong>RFC 1996</strong></a>) be
used to synchronize DNS firewall rule sets between the publisher’s primary
copy of the rule set and the subscribers’ working copies of the rule set.</p>
<p>If DNS dynamic updates are used to maintain a DNS RPZ rule set, the name
server automatically calculates a stream of deltas for use when sending
incremental zone transfers to the subscribing name servers. Sending a
stream of deltas – known as an “incremental zone transfer” or IXFR – is
usually much faster than sending the full zone every time it changes, so
it’s worth the effort to use an editing method that makes such incremental
transfers possible.</p>
<p>Administrators who edit or periodically regenerate a DNS RPZ rule set and
whose primary name server uses BIND can enable the
<a class="reference internal" href="reference.html#namedconf-statement-ixfr-from-differences" title="namedconf-statement-ixfr-from-differences"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">ixfr-from-differences</span></code></a> option, which tells the primary name server to
calculate the differences between each new zone and the preceding version,
and to make these differences available as a stream of deltas for use in
incremental zone transfers to the subscribing name servers. This will look
something like the following:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">options</span><span class="w"> </span><span class="p">{</span>
<span class="w">          </span><span class="c1">// ...</span>
<span class="w">          </span><span class="n">ixfr</span><span class="o">-</span><span class="n">from</span><span class="o">-</span><span class="n">differences</span><span class="w"> </span><span class="n">yes</span><span class="p">;</span>
<span class="w">          </span><span class="c1">// ...</span>
<span class="p">};</span>
</pre></div>
</div>
<p>As mentioned above, the simplest and most common use of a DNS firewall is
to poison domain names known to be purely malicious, by simply making them
disappear. All DNS RPZ rules are expressed as resource record sets
(RRsets), and the way to express a “force a name-does-not-exist condition”
is by adding a CNAME pointing to the root domain (<code class="docutils literal notranslate"><span class="pre">.</span></code>). In practice this
looks like:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ORIGIN rpz.example.com.
malicious1.org          CNAME .
*.malicious1.org        CNAME .
malicious2.org          CNAME .
*.malicious2.org        CNAME .
</pre></div>
</div>
<p>Two things are noteworthy in this example. First, the malicious names are
made relative within the response policy zone. Since there is no trailing
dot following “.org” in the above example, the actual RRsets created within
this response policy zone are, after expansion:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>malicious1.org.rpz.example.com.         CNAME .
*.malicious1.org.rpz.example.com.       CNAME .
malicious2.org.rpz.example.com.         CNAME .
*.malicious2.org.rpz.example.com.       CNAME .
</pre></div>
</div>
<p>Second, for each name being poisoned, a wildcard name is also listed.
This is because a malicious domain name probably has or may potentially
have malicious subdomains.</p>
<p>In the above example, the relative domain names <cite>malicious1.org</cite> and
<cite>malicious2.org</cite> will match only the real domain names <cite>malicious1.org</cite>
and <cite>malicious2.org</cite>, respectively. The relative domain names
<cite>*.malicious1.org</cite> and <cite>*.malicious2.org</cite> will match any
<cite>subdomain.of.malicious1.org</cite> or <cite>subdomain.of.malicious2.org</cite>,
respectively.</p>
<p>This example forces an NXDOMAIN condition as its policy action, but other
policy actions are also possible.</p>
</section>
<section id="performance-and-scalability-when-using-multiple-rpzs">
<span id="multiple-rpz-performance"></span><h3><span class="section-number">6.9.7. </span>Performance and Scalability When Using Multiple RPZs<a class="headerlink" href="#performance-and-scalability-when-using-multiple-rpzs" title="Link to this heading"></a></h3>
<p>Since version 9.10, BIND can be configured to have different response
policies depending on the identity of the querying client and the nature of
the query. To configure BIND response policy, the information is placed
into a zone file whose only purpose is conveying the policy information to
BIND. A zone file containing response policy information is called a
Response Policy Zone, or RPZ, and the mechanism in BIND that uses the
information in those zones is called DNS RPZ.</p>
<p>It is possible to use as many as 64 separate RPZ files in a single instance
of BIND, and BIND is not significantly slowed by such heavy use of RPZ.</p>
<p>(Note: by default, BIND 9.11 only supports up to 32 RPZ files, but this
can be increased to 64 at compile time. All other supported versions of
BIND support 64 by default.)</p>
<p>Each one of the policy zone files can specify policy for as many
different domains as necessary. The limit of 64 is on the number of
independently-specified policy collections and not the number of zones
for which they specify policy.</p>
<p>Policy information from all of the policy zones together are stored in a
special data structure allowing simultaneous lookups across all policy
zones to be performed very rapidly. Looking up a policy rule is
proportional to the logarithm of the number of rules in the largest
single policy zone.</p>
</section>
<section id="practical-tips-for-dns-firewalls-and-dns-rpz">
<span id="rpz-practical-tips"></span><h3><span class="section-number">6.9.8. </span>Practical Tips for DNS Firewalls and DNS RPZ<a class="headerlink" href="#practical-tips-for-dns-firewalls-and-dns-rpz" title="Link to this heading"></a></h3>
<p>Administrators who subscribe to an externally published DNS policy zone and
who have a large number of internal recursive name servers should create an
internal name server called a “distribution master” (DM). The DM is a
secondary (stealth secondary) name server from the publisher’s point of
view; that is, the DM is fetching zone content from the external server.
The DM is also a primary name server from the internal recursive name
servers’ point of view: they fetch zone content from the DM.  In this
configuration the DM is acting as a gateway between the external publisher
and the internal subscribers.</p>
<p>The primary server must know the unicast listener address of every
subscribing recursive server, and must enumerate all of these addresses as
destinations for real time zone change notification (as described in
<span class="target" id="index-13"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc1996.html"><strong>RFC 1996</strong></a>). So if an enterprise-wide RPZ is called “rpz.example.com” and
if the unicast listener addresses of four of the subscribing recursive name
servers are 192.0.200.1, 192.0.201.1, 192.0.202.1, and 192.0.203.1, the
primary server’s configuration looks like this:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">zone</span><span class="w"> </span><span class="s">&quot;rpz.example.com&quot;</span><span class="w"> </span><span class="p">{</span>
<span class="w">     </span><span class="n">type</span><span class="w"> </span><span class="n">primary</span><span class="p">;</span>
<span class="w">     </span><span class="n">file</span><span class="w"> </span><span class="s">&quot;primary/rpz.example.com&quot;</span><span class="p">;</span>
<span class="w">     </span><span class="n">notify</span><span class="w"> </span><span class="n">explicit</span><span class="p">;</span>
<span class="w">     </span><span class="n">also</span><span class="o">-</span><span class="n">notify</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="mf">192.0.200.1</span><span class="p">;</span>
<span class="w">                   </span><span class="mf">192.0.201.1</span><span class="p">;</span>
<span class="w">                   </span><span class="mf">192.0.202.1</span><span class="p">;</span>
<span class="w">                   </span><span class="mf">192.0.203.1</span><span class="p">;</span><span class="w"> </span><span class="p">};</span>
<span class="w">     </span><span class="n">allow</span><span class="o">-</span><span class="n">transfer</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="mf">192.0.200.1</span><span class="p">;</span>
<span class="w">                      </span><span class="mf">192.0.201.1</span><span class="p">;</span>
<span class="w">                      </span><span class="mf">192.0.202.1</span><span class="p">;</span>
<span class="w">                      </span><span class="mf">192.0.203.1</span><span class="p">;</span><span class="w"> </span><span class="p">};</span>
<span class="w">     </span><span class="n">allow</span><span class="o">-</span><span class="n">query</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">localhost</span><span class="p">;</span><span class="w"> </span><span class="p">};</span>
<span class="p">};</span>
</pre></div>
</div>
<p>Each recursive DNS server that subscribes to the policy zone must be
configured as a secondary server for the zone, and must also be configured
to use the policy zone for local response policy. To subscribe a recursive
name server to a response policy zone where the unicast listener address
of the primary server is 192.0.220.2, the server’s configuration should
look like this:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">options</span><span class="w"> </span><span class="p">{</span>
<span class="w">     </span><span class="c1">// ...</span>
<span class="w">     </span><span class="n">response</span><span class="o">-</span><span class="n">policy</span><span class="w"> </span><span class="p">{</span>
<span class="w">          </span><span class="n">zone</span><span class="w"> </span><span class="s">&quot;rpz.example.com&quot;</span><span class="p">;</span>
<span class="w">     </span><span class="p">};</span>
<span class="w">     </span><span class="c1">// ...</span>
<span class="p">};</span>

<span class="n">zone</span><span class="w"> </span><span class="s">&quot;rpz.example.com&quot;</span><span class="p">;</span>
<span class="w">     </span><span class="n">type</span><span class="w"> </span><span class="n">secondary</span><span class="p">;</span>
<span class="w">     </span><span class="n">primaries</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="mf">192.0.222.2</span><span class="p">;</span><span class="w"> </span><span class="p">};</span>
<span class="w">     </span><span class="n">file</span><span class="w"> </span><span class="s">&quot;secondary/rpz.example.com&quot;</span><span class="p">;</span>
<span class="w">     </span><span class="n">allow</span><span class="o">-</span><span class="n">query</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">localhost</span><span class="p">;</span><span class="w"> </span><span class="p">};</span>
<span class="w">     </span><span class="n">allow</span><span class="o">-</span><span class="n">transfer</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">none</span><span class="p">;</span><span class="w"> </span><span class="p">};</span>
<span class="p">};</span>
</pre></div>
</div>
<p>Note that queries are restricted to “localhost,” since query access is
never used by DNS RPZ itself, but may be useful to DNS operators for use in
debugging. Transfers should be disallowed to prevent policy information
leaks.</p>
<p>If an organization’s business continuity depends on full connectivity with
another company whose ISP also serves some criminal or abusive customers,
it’s possible that one or more external RPZ providers – that is, security
feed vendors – may eventually add some RPZ rules that could hurt a
company’s connectivity to its business partner. Users can protect
themselves from this risk by using an internal RPZ in addition to any
external RPZs, and by putting into their internal RPZ some “pass-through”
rules to prevent any policy action from affecting a DNS response that
involves a business partner.</p>
<p>A recursive DNS server can be connected to more than one RPZ, and these are
searched in order. Therefore, to protect a network from dangerous policies
which may someday appear in external RPZ zones, administrators should list
the internal RPZ zones first.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">options</span><span class="w"> </span><span class="p">{</span>
<span class="w">     </span><span class="c1">// ...</span>
<span class="w">     </span><span class="n">response</span><span class="o">-</span><span class="n">policy</span><span class="w"> </span><span class="p">{</span>
<span class="w">          </span><span class="n">zone</span><span class="w"> </span><span class="s">&quot;rpz.example.com&quot;</span><span class="p">;</span>
<span class="w">          </span><span class="n">zone</span><span class="w"> </span><span class="s">&quot;rpz.security-vendor-1.com&quot;</span><span class="p">;</span>
<span class="w">          </span><span class="n">zone</span><span class="w"> </span><span class="s">&quot;rpz.security-vendor-2.com&quot;</span><span class="p">;</span>
<span class="w">     </span><span class="p">};</span>
<span class="w">     </span><span class="c1">// ...</span>
<span class="p">};</span>
</pre></div>
</div>
<p>Within an internal RPZ, there need to be rules describing the network
assets of business partners whose communications need to be protected.
Although it is not generally possible to know what domain names they use,
administrators will be aware of what address space they have and perhaps
what name server names they use.</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ORIGIN rpz.example.com.
8.0.0.0.10.rpz-ip                CNAME   rpz-passthru.
16.0.0.45.128.rpz-nsip           CNAME   rpz-passthru.
ns.partner1.com.rpz-nsdname      CNAME   rpz-passthru.
ns.partner2.com.rpz-nsdname      CNAME   rpz-passthru.
</pre></div>
</div>
<p>Here, we know that answers in address block 10.0.0.0/8 indicate a business
partner, as well as answers involving any name server whose address is in
the 128.45.0.0/16 address block, and answers involving the name servers
whose names are ns.partner1.com or ns.partner2.com.</p>
<p>The above example demonstrates that when matching by answer IP address (the
.rpz-ip owner), or by name server IP address (the .rpz-nsip owner) or by
name server domain name (the .rpz-nsdname owner), the special RPZ marker
(.rpz-ip, .rpz-nsip, or .rpz-nsdname) does not appear as part of the CNAME
target name.</p>
<p>By triggering these rules using the known network assets of a partner,
and using the “pass-through” policy action, no later RPZ processing
(which in the above example refers to the “rpz.security-vendor-1.com” and
“rpz.security-vendor-2.com” policy zones) will have any effect on DNS
responses for partner assets.</p>
</section>
<section id="creating-a-simple-walled-garden-triggered-by-ip-address">
<span id="walled-garden-ip-address"></span><h3><span class="section-number">6.9.9. </span>Creating a Simple Walled Garden Triggered by IP Address<a class="headerlink" href="#creating-a-simple-walled-garden-triggered-by-ip-address" title="Link to this heading"></a></h3>
<p>It may be the case that the only thing known about an attacker is the IP
address block they are using for their “phishing” web servers. If the
domain names and name servers they use are unknown, but it is known that
every one of their “phishing” web servers is within a small block of IP
addresses, a response can be triggered on all answers that would include
records in this address range, using RPZ rules that look like the following
example:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ORIGIN rpz.example.com.
22.0.212.94.109.rpz-ip          CNAME   drop.garden.example.com.
*.212.94.109.in-addr.arpa       CNAME   .
*.213.94.109.in-addr.arpa       CNAME   .
*.214.94.109.in-addr.arpa       CNAME   .
*.215.94.109.in-addr.arpa       CNAME   .
</pre></div>
</div>
<p>Here, if a truthful answer would include an A (address) RR (resource
record) whose value were within the 109.94.212.0/22 address block, then a
synthetic answer is sent instead of the truthful answer. Assuming the query
is for www.malicious.net, the synthetic answer is:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>www.malicious.net.              CNAME   drop.garden.example.com.
drop.garden.example.com.        A       192.168.7.89
</pre></div>
</div>
<p>This assumes that <cite>drop.garden.example.com</cite> has been created as real DNS
content, outside of the RPZ:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ORIGIN example.com.
drop.garden                     A       192.168.7.89
</pre></div>
</div>
<p>In this example, there is no “*” in the CNAME target name, so the original
query name will not be present in the walled garden web server’s log file.
This is an undesirable loss of information, and is shown here for example
purposes only.</p>
<p>The above example RPZ rules would also affect address-to-name (also
known as “reverse DNS”) lookups for the unwanted addresses. If a mail
or web server receives a connection from an address in the example’s
109.94.212.0/22 address block, it will perform a PTR record lookup to
find the domain name associated with that IP address.</p>
<p>This kind of address-to-name translation is usually used for diagnostic or
logging purposes, but it is also common for email servers to reject any
email from IP addresses which have no address-to-name translation. Most
mail from such IP addresses is spam, so the lack of a PTR record here has
some predictive value.  By using the “force name-does-not-exist” policy
trigger on all lookups in the PTR name space associated with an address
block, DNS administrators can give their servers a hint that these IP
addresses are probably sending junk.</p>
</section>
<section id="a-known-inconsistency-in-dns-rpz-s-nsdname-and-nsip-rules">
<span id="known-rpz-inconsistency"></span><h3><span class="section-number">6.9.10. </span>A Known Inconsistency in DNS RPZ’s NSDNAME and NSIP Rules<a class="headerlink" href="#a-known-inconsistency-in-dns-rpz-s-nsdname-and-nsip-rules" title="Link to this heading"></a></h3>
<p>Response Policy Zones define several possible triggers for each rule, and
among these two are known to produce inconsistent results. This is not a
bug; rather, it relates to inconsistencies in the DNS delegation model.</p>
<section id="dns-delegation">
<h4><span class="section-number">6.9.10.1. </span>DNS Delegation<a class="headerlink" href="#dns-delegation" title="Link to this heading"></a></h4>
<p>In DNS authority data, an NS RRset that is not at the apex of a DNS zone
creates a sub-zone.  That sub-zone’s data is separate from the current (or
“parent”) zone, and it can have different authoritative name servers than
the current zone. In this way, the root zone leads to COM, NET, ORG, and so
on, each of which have their own name servers and their own way of managing
their authoritative data. Similarly, ORG has delegations to ISC.ORG and to
millions of other “dot-ORG” zones, each of which can have its own set of
authoritative name servers. In the parlance of the protocol, these NS
RRsets below the apex of a zone are called “delegation points.” An
NS RRset at a delegation point contains a list of authoritative servers
to which the parent zone is delegating authority for all names at or below
the delegation point.</p>
<p>At the apex of every zone there is also an NS RRset. Ideally, this
so-called “apex NS RRset” should be identical to the “delegation point NS
RRset” in the parent zone, but this ideal is not always achieved. In the
real DNS, it’s almost always easier for a zone administrator to update one
of these NS RRsets than the other, so that one will be correct and the
other out of date. This inconsistency is so common that it’s been
necessarily rendered harmless: domains that are inconsistent in this way
are less reliable and perhaps slower, but they still function as long as
there is some overlap between each of the NS RRsets and the truth. (“Truth”
in this case refers to the actual set of name servers that are
authoritative for the zone.)</p>
</section>
<section id="a-quick-review-of-dns-iteration">
<h4><span class="section-number">6.9.10.2. </span>A Quick Review of DNS Iteration<a class="headerlink" href="#a-quick-review-of-dns-iteration" title="Link to this heading"></a></h4>
<p>In DNS recursive name servers, an incoming query that cannot be answered
from the local cache is sent to the closest known delegation point for the
query name. For example, if a server is looking up XYZZY.ISC.ORG and it
the name servers for ISC.ORG, then it sends the query to those servers
directly; however, if it has never heard of ISC.ORG before, it must first
send the query to the name servers for ORG (or perhaps even to the root
zone that is the parent of ORG).</p>
<p>When it asks one of the parent name servers, that server will not have an
answer, so it sends a “referral” consisting only of the “delegation point
NS RRset.” Once the server receives this referral, it “iterates” by sending
the same query again, but this time to name servers for a more specific
part of the query name.  Eventually this iteration terminates, usually by
getting an answer or a “name error” (NXDOMAIN) from the query name’s
authoritative server, or by encountering some type of server failure.</p>
<p>When an authoritative server for the query name sends an answer, it has the
option of including a copy of the zone’s apex NS RRset. If this occurs, the
recursive name server caches this NS RRset, replacing the delegation point
NS RRset that it had received during the iteration process. In the parlance
of the DNS, the delegation point NS RRset is “glue,” meaning
non-authoritative data, or more of a hint than a real truth. On the other
hand, the apex NS RRset is authoritative data, coming as it does from the
zone itself, and it is considered more credible than the “glue.” For this
reason, it’s a little bit more important that the apex NS RRset be correct
than that the delegation point NS RRset be correct, since the former will
quickly replace the latter, and will be used more often for a longer total
period of time.</p>
<p>Importantly, the authoritative name server need not include its apex NS
RRset in any answers, and recursive name servers do not ordinarily query
directly for this RRset. Therefore it is possible for the apex NS RRset to
be completely wrong without any operational ill-effects, since the wrong
data need not be exposed. Of course, if a query comes in for this NS RRset,
most recursive name servers will forward the query to the zone’s authority
servers, since it’s bad form to return “glue” data when asked a specific
question. In these corner cases, bad apex NS RRset data can cause a zone to
become unreachable unpredictably, according to what other queries the
recursive name server has processed.</p>
<p>There is another kind of “glue,” for name servers whose names are below
delegation points. If ORG delegates ISC.ORG to NS-EXT.ISC.ORG, the ORG
server needs to know an address for NS-EXT.ISC.ORG and return this address
as part of the delegation response. However, the name-to-address binding
for this name server is only authoritative inside the ISC.ORG zone;
therefore, the A or AAAA RRset given out with the delegation is
non-authoritative “glue,” which is replaced by an authoritative RRset if
one is seen. As with apex NS RRsets, the real A or AAAA RRset is not
automatically queried for by the recursive name server, but is queried for
if an incoming query asks for this RRset.</p>
</section>
<section id="enter-rpz">
<h4><span class="section-number">6.9.10.3. </span>Enter RPZ<a class="headerlink" href="#enter-rpz" title="Link to this heading"></a></h4>
<p>RPZ has two trigger types that are intended to allow policy zone authors to
target entire groups of domains based on those domains all being served by
the same DNS servers: NSDNAME and NSIP. The NSDNAME and NSIP rules are
matched against the name and IP address (respectively) of the nameservers
of the zone the answer is in, and all of its parent zones. In its default
configuration, BIND actively fetches any missing NS RRsets and address
records.  If, in the process of attempting to resolve the names of all of
these delegated server names, BIND receives a SERVFAIL response for any of
the queries, then it aborts the policy rule evaluation and returns SERVFAIL
for the query. This is technically neither a match nor a non-match of the
rule.</p>
<p>Every “.” in a fully qualified domain name (FQDN) represents a potential
delegation point. When BIND goes searching for parent zone NS RRsets (and,
in the case of NSIP, their accompanying address records), it has to check
every possible delegation point. This can become a problem for some
specialized pseudo-domains, such as some domain name and network reputation
systems, that have many “.” characters in the names. It is further
complicated if that system also has non-compliant DNS servers that silently
drop queries for NS and SOA records. This forces BIND to wait for those
queries to time out before it can finish evaluating the policy rule, even
if this takes longer than a reasonable client typically waits for an answer
(delays of over 60 seconds have been observed).</p>
<p>While both of these cases do involve configurations and/or servers that are
technically “broken,” they may still “work” outside of RPZ NSIP and NSDNAME
rules because of redundancy and iteration optimizations.</p>
<p>There are two RPZ options, <code class="docutils literal notranslate"><span class="pre">nsip-wait-recurse</span></code> and <code class="docutils literal notranslate"><span class="pre">nsdname-wait-recurse</span></code>,
that alter BIND’s behavior by allowing it to use only those records that
already exist in the cache when evaluating NSIP and NSDNAME rules,
respectively.</p>
<p>Therefore NSDNAME and NSIP rules are unreliable. The rules may be matched
against either the apex NS RRset or the “glue” NS RRset, each with their
associated addresses (that also might or might not be “glue”). It’s in the
administrator’s interests to discover both the delegation name server names
and addresses, and the apex name server names and authoritative address
records, to ensure correct use of NS and NSIP triggers in RPZ. Even then,
there may be collateral damage to completely unrelated domains that
otherwise “work,” just by having NSIP and NSDNAME rules.</p>
</section>
</section>
<section id="example-using-rpz-to-disable-mozilla-doh-by-default">
<span id="rpz-disable-mozilla-doh"></span><h3><span class="section-number">6.9.11. </span>Example: Using RPZ to Disable Mozilla DoH-by-Default<a class="headerlink" href="#example-using-rpz-to-disable-mozilla-doh-by-default" title="Link to this heading"></a></h3>
<p>Mozilla announced in September 2019 that they would enable DNS-over-HTTPS
(DoH) for all US-based users of the Firefox browser, sending all their DNS
queries to predefined DoH providers (Cloudflare’s 1.1.1.1 service in
particular). This is a concern for some network administrators who do not
want their users’ DNS queries to be rerouted unexpectedly. However,
Mozilla provides a mechanism to disable the DoH-by-default setting:
if the Mozilla-owned domain <a class="reference external" href="https://support.mozilla.org/en-US/kb/canary-domain-use-application-dnsnet">use-application-dns.net</a>
returns an NXDOMAIN response code, Firefox will not use DoH.</p>
<p>To accomplish this using RPZ:</p>
<ol class="arabic simple">
<li><p>Create a polizy zone file called <code class="docutils literal notranslate"><span class="pre">mozilla.rpz.db</span></code> configured so
that NXDOMAIN will be returned for any query to <code class="docutils literal notranslate"><span class="pre">use-application-dns.net</span></code>:</p></li>
</ol>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$TTL  604800
$ORIGIN       mozilla.rpz.
@     IN      SOA     localhost. root.localhost. 1 604800 86400 2419200 604800
@     IN      NS      localhost.
use-application-dns.net CNAME .
</pre></div>
</div>
<ol class="arabic simple" start="2">
<li><p>Add the zone into the BIND configuration (usually <a class="reference internal" href="manpages.html#std-iscman-named.conf"><code class="xref std std-iscman docutils literal notranslate"><span class="pre">named.conf</span></code></a>):</p></li>
</ol>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">zone</span><span class="w"> </span><span class="n">mozilla</span><span class="p">.</span><span class="n">rpz</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="n">type</span><span class="w"> </span><span class="n">primary</span><span class="p">;</span>
<span class="w">    </span><span class="n">file</span><span class="w"> </span><span class="s">&quot;/&lt;PATH_TO&gt;/mozilla.rpz.db&quot;</span><span class="p">;</span>
<span class="w">    </span><span class="n">allow</span><span class="o">-</span><span class="n">query</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">localhost</span><span class="p">;</span><span class="w"> </span><span class="p">};</span>
<span class="p">};</span>
</pre></div>
</div>
<ol class="arabic simple" start="3">
<li><p>Enable use of the Response Policy Zone for all incoming queries
by adding the <a class="reference internal" href="reference.html#namedconf-statement-response-policy" title="namedconf-statement-response-policy"><code class="xref any namedconf namedconf-ref docutils literal notranslate"><span class="pre">response-policy</span></code></a> directive into the <code class="docutils literal notranslate"><span class="pre">options</span> <span class="pre">{}</span></code>
section:</p></li>
</ol>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">options</span><span class="w"> </span><span class="p">{</span>
<span class="w">      </span><span class="n">response</span><span class="o">-</span><span class="n">policy</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">zone</span><span class="w"> </span><span class="n">mozilla</span><span class="p">.</span><span class="n">rpz</span><span class="p">;</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">break</span><span class="o">-</span><span class="n">dnssec</span><span class="w"> </span><span class="n">yes</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
<ol class="arabic simple" start="4">
<li><p>Reload the configuration and test whether the Response Policy
Zone that was just added is in effect:</p></li>
</ol>
<div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp"># </span>rndc<span class="w"> </span>reload
<span class="gp"># </span>dig<span class="w"> </span>IN<span class="w"> </span>A<span class="w"> </span>use-application-dns.net<span class="w"> </span>@&lt;IP_ADDRESS_OF_YOUR_RESOLVER&gt;
<span class="gp"># </span>dig<span class="w"> </span>IN<span class="w"> </span>AAAA<span class="w"> </span>use-application-dns.net<span class="w"> </span>@&lt;IP_ADDRESS_OF_YOUR_RESOLVER&gt;
</pre></div>
</div>
<p>The response should return NXDOMAIN instead of the list of IP addresses,
and the BIND 9 log should contain lines like this:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>09-Sep-2019 18:50:49.439 client @0x7faf8e004a00 ::1#54175 (use-application-dns.net): rpz QNAME NXDOMAIN rewrite use-application-dns.net/AAAA/IN via use-application-dns.net.mozilla.rpz
09-Sep-2019 18:50:49.439 client @0x7faf8e007800 127.0.0.1#62915 (use-application-dns.net): rpz QNAME NXDOMAIN rewrite use-application-dns.net/AAAA/IN via use-application-dns.net.mozilla.rpz
</pre></div>
</div>
<p>Note that this is the simplest possible configuration; specific
configurations may be different, especially for administrators who are
already using other response policy zones, or whose servers are configured
with multiple views.</p>
</section>
</section>
</section>


           </div>
          </div>
          <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
        <a href="chapter5.html" class="btn btn-neutral float-left" title="5. DNSSEC" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
        <a href="chapter7.html" class="btn btn-neutral float-right" title="7. Security Configurations" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>&#169; Copyright 2025, Internet Systems Consortium.</p>
  </div>

  Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
    provided by <a href="https://readthedocs.org">Read the Docs</a>.
   

</footer>
        </div>
      </div>
    </section>
  </div>
  <script>
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script> 

</body>
</html>