<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
<HEAD>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
    <TITLE>Rate Limiting Fragments of ARM Chapter 6</TITLE>
</HEAD>
<BODY>
<P>

<!-- grammar -->
<PRE>
    [<span class="optional"> rate-limit {
        [<span class="optional"> responses-per-second <em class="replaceable"><code>number</code></em> ; </span>]
        [<span class="optional"> errors-per-second <em class="replaceable"><code>number</code></em> ; </span>]
        [<span class="optional"> nxdomains-per-second <em class="replaceable"><code>number</code></em> ; </span>]
        [<span class="optional"> window <em class="replaceable"><code>number</code></em> ; </span>]
        [<span class="optional"> log-only <em class="replaceable"><code>yes_or_no</code></em> ; </span>]
        [<span class="optional"> qps-scale <em class="replaceable"><code>number</code></em> ; </span>]
        [<span class="optional"> IPv4-prefix-length <em class="replaceable"><code>number</code></em> ; </span>]
        [<span class="optional"> IPv6-prefix-length <em class="replaceable"><code>number</code></em> ; </span>]
        [<span class="optional"> slip <em class="replaceable"><code>number</code></em> ; </span>]
        [<span class="optional"> exempt-clients  { <em class="replaceable"><code>address_match_list</code></em> } ; </span>]
        [<span class="optional"> max-table-size <em class="replaceable"><code>number</code></em> ; </span>]
        [<span class="optional"> min-table-size <em class="replaceable"><code>number</code></em> ; </span>]
      } ; </span>]
</PRE>
<HR>
<P>
<!-- logging -->
<P>
            Following are the available categories and brief descriptions
            of the types of log information they contain. More
            categories may be added in future <acronym class="acronym">BIND</acronym> releases.
          </p>
<div class=informaltable><table border=1>
<colgroup>
<col>
<col>
</colgroup><tbody>
<tr>
<td>
                    <p><span><strong class="command">rate-limit</strong></span></p>
</td>
<td>
                    <p>
                      The start and periodic notices of continued rate limiting
                      of a stream of responses are logged at
                      <span><strong class="command">info</strong></span> severity in this category.
                      Various internal performance data such as expansions
                      of the table is logged debug 1 level and higher.
                      Rate limiting of individual requests
                      is logged in the <span><strong class="command">queries</strong></span> category.
                    </p>
</td>
</tr>
              </tbody>
            </tgroup>
</table>
<P>
<HR>
<P>
          
<p>
            Excessive UDP identical responses to a DNS client can be discarded
            by configuring a
            <span><strong class="command">rate-limit</strong></span> clause in an
            <span><strong class="command">options</strong></span> statement.
            This mechanism keeps BIND 9 from being used
            in amplifying reflection denial of service attacks
            as well as protecting BIND 9 itself from some denial of service
            attacks.
          </p>

<p>
            Rate limiting works by setting
            <span><strong class="command">responses-per-second</strong></span>
            to a number of repetitions per second for responses for a given name
            and record type to a DNS client.
          </p>

<p>
            Note that <span><strong class="command">responses-per-second</strong></span> is a limit on
            identical responses instead of a limit on all responses or
            even all responses to a single client.
            10 identical responses per second is a generous limit except perhaps
            when many clients are using a single IP address via network
            address translation (NAT).
            Even when NAT is involved,
            it can be argued that clients using NAT should
            be using a small number of caching DNS servers.
          </p>

<p>
            On the other hand, the notion of "identical responses"
            and "single DNS client" cannot be simplistic.
            All responses to a CDIR block with prefix
            length specified with <span><strong class="command">IPv4-prefix-length</strong></span>
            (default 24) or <span><strong class="command">IPv6-prefix-length</strong></span>
            (default 56) are assumed to come from a single DNS client.
          </p>

<p>
            Requests for a name that result in DNS NXDOMAIN
            errors are considered identical.
            This controls some attacks using random names, but
            accomodates servers that expect many legitimate NXDOMAIN responses
            such as anti-spam blacklists.
            By default the limit on NXDOMAIN errors is the same as the
            <span><strong class="command">responses-per-second</strong></span> value,
            but it can be set separately with
            <span><strong class="command">nxdomains-per-second</strong></span>.
          </p>

<p>
            All requests for all names or types that result in DNS errors
            such as SERVFAIL and FORMERR (but not NXDOMAIN) are considered
            identical.
            This controls attacks using invalid requests or distant,
            broken authoritative servers.
            By default the limit on errors is the same as the
            <span><strong class="command">responses-per-second</strong></span> value,
            but it can be set separately with
            <span><strong class="command">errors-per-second</strong></span>.
          </p>

<p>
            Rate limiting uses a "credit" or "token bucket" scheme.
            Each identical response has a conceptual account
            that is given <span><strong class="command">responses-per-second</strong></span>,
            <span><strong class="command">errors-per-second</strong></span>, and
            <span><strong class="command">nxdomains-per-second</strong></span> credits every second.
            A DNS request triggering some desired response debits
            the account by one.
            Responses are not sent while the account is negative.
            The account cannot become more positive than
            the per-second limit
            or more negative than <span><strong class="command">window</strong></span>
            times the per-second limit.
            A DNS client that sends requests that are not
            answered can penalized for up to <span><strong class="command">window</strong></span> seconds
            (default 15).
          </p>

<p>
            Responses generated from local wildcards are counted and limited
            as if they were for the parent domain name.
            This prevents flooding by requesting random.wild.example.com.
            For similar reasons, NXDOMAIN responses are counted and rate
            limited as if they were for nearest valid domain name.
          </p>

<p>
            Many attacks using DNS involve UDP requests with forged source
            addresses.
            Rate limiting prevents the use of BIND 9 to flood the network
            of a forged victim, but could let a third party block responses
            to legitimate requests.
            There is a mechanism that can answer some legitimate
            requests from a client whose address is being forged in a flood.
            Setting <span><strong class="command">slip</strong></span> to 2 (its default) causes every
            other UDP request to be answered with a small response
            claiming that the response would have been truncated.
            The small size and relative infrequency of the response make
            it unattractive for abuse of third parties.
            <span><strong class="command">slip</strong></span> must be between 0 and 10.
            0 disables the mechanism.
            Some error responses cannot be replaced with responses
            with the <literal>TC</literal> flag, and so are simply
            leaked at the <span><strong class="command">slip</strong></span> rate.
          </p>

<p>
            When the approximate query per second rate exceeds
            the <span><strong class="command">qps-scale</strong></span> value,
            the <span><strong class="command">responses-per-second</strong></span>,
            <span><strong class="command">errors-per-second</strong></span>,
            <span><strong class="command">nxdomains-per-second</strong></span>,
            and <span><strong class="command">slip</strong></span> values are reduced by the
            ratio current rate to the <span><strong class="command">qps-scale</strong></span> value.
            This feature can tighten defenses during attacks.
            The limits for IP addresses using TCP are not reduced.
            Note that responses sent via TCP are not subject to rate limits.
          </p>

<p>
            Communities of DNS clients can be given their own parameters or no
            rate limiting by putting
            <span><strong class="command">rate-limit</strong></span> statements in <span><strong class="command">view</strong></span>
            statements instead of the global <span><strong class="command">option</strong></span>
            statement.
            DNS clients within a view can be exempted from rate limits
            with the <span><strong class="command">exempt-clients</strong></span> clause.
          </p>

<p>
            The maximum size of the table used to track requests and so
            rate limit responses is set with <span><strong class="command">max-table-size</strong></span>.
            Each entry in the table is between 40 and 80 bytes.
            The default of 10,000 is suitable for a server receiving
            5000 DNS requests/second.
            10,000 entries require about 1 megabyte.
            To reduce cold start costs including those in growing the
            table, <span><strong class="command">min-table-size</strong></span> (default 1000)
            can set the minimum table size.
            Enable logging to monitor expansions of the table and inform
            non-default choises for the initial and maximum table size.
          </p>

<p>
            Use <span><strong class="command">log-only yes</strong></span> to test rate limiting parameters
            without actually dropping any requests.
          </p>

<p>
            Responses dropped by rate limits are included in the
            <span><strong class="command">RateDropped</strong></span> and <span><strong class="command">QryDropped</strong></span>
            statistics.
            Responses that truncated by rate limits are included in
            <span><strong class="command">RateSlipped</strong></span> and <span><strong class="command">RespTruncated</strong></span>.
        
</BODY>
</HTML>