mail us  |  mail this page

contact us
training  | 
tech stuff  | 

BIND 9 Support

BIND9 - Response Policy Zone Configuration

Response Policy Zone (RPZ) is a BIND9.10+ feature - the basic capability was released with BIND9.8 but has gone through a number of iterations and upgrades. The BIND9.10 feature set is defined here (RPZ Format 3). Earlier specifications, and their BIND9 implementation, had somewhat fewer features that impaired their usefulness. The RPZ Format 3 specification anticipates future changes but has, so far, enabled backward and forward compatibility.

  1. response-policy statement
  2. Defining RPZ zones
    1. Operational Notes and Observations
  3. RPZ Policy Definitions
    1. Policy Actions
    2. Policy Triggers
  4. RPZ Examples
  5. Configuring a DNS firewall with RPZ

Note: RPZ is not a standard DNS feature defined by an IETF RFC (though we note an RFC draft submission in December 2016'ish). It is, however, an Open specification (currently Format 3) whose authors have made it freely available. It is Copyrighted by ISC but annotated "Distribution of this memo is unlimited, if full attribution is given". However, it must be noted that any specification changes/updates are at the whim of its authors. The RPZ specification defines the use of standard zone files whose RR definitions invoke Policy Actions by using Policy Triggers in what one may call a Policy Rule Set (though this term is not used in the specification). RPZ is invoked (and its behavior controlled) in BIND9 using a response-policy statement (in named.conf) which is unique to BIND9 and is not defined within the RPZ specification - other implementations will use their own configuration styles and parameter sets. RPZ, by default, does not invoke policy processing on DNSSEC responses (though this can be modified with the break-dnssec parameter). For those familiar with the technology, RPZ is similar to, but significantly more complex and flexible than, DNS Black Lists (DNSBL) - a reputational anti-spam technique.

Note: There are discrepancies between the RPZ specification (Format 3) and the BIND9 implementation (noted as [not in Format 3] in text). This page documents the BIND9 implementation, verified by source code inspection, unless otherwise noted.

In summary, RPZ allows the operator of a name server - in most, but not all cases, a recursive server (resolver) - to control the behavior of responses to queries. This has many implications. Most are entirely positive in that known "bad guys" can be prevented from causing malicious damage by eliminating them at their source - the DNS system. However, the same technology can also be used to implement less positive actions including outright blocking of sites or even TLDs for commercial or other more dubious reasons by ISPs, employers or other organizations that operate DNS infrastructure. It can clearly be argued that such technology already exists, albeit in different forms. This cat is already out of the bag. Nevertheless, RPZ, by reducing the entry-level threshold, may make it more ubiquitous and, in turn, more open to potential abuse and collateral damage effects. As a trivial example, debugging of user access problems may no longer be a simple question of checking all the usual suspects for error-free operation. There could now be one or more levels of RPZ processing in the round-trip between the user, their desired internet destination and its response path.

response-policy statement

The response-policy statement, which may appear in a global options or view clause, controls the behavior of RPZ policy processing and has, for BIND9, a rather unusual syntax:

Syntax

response-policy { zone zone-name 
   [ policy (given|disabled|passthru|drop|nxdomain|nodata|tcp-only| cname domain-name)
   [ recursive-only yes_or_no ] 
   [ max-policy-ttl seconds ] 
   [ log yes_or_no]
   ; ... } 
   [ recursive-only yes_or_no ] 
   [ max-policy-ttl seconds ]
   [ break-dnssec yes_or_no ]
   [ min-ns-dots number ]
   [ qname-wait-recurse yes_or_no ]
   [ nsip-wait-recurse yes_or_no] ;
# example
response-policy {zone "dontlike" ; zone "likeless" policy passthru;} recursive-only yes;

Items in bold are keywords. The response-policy statement is split into two sections. A zone section in which multiple (up to 32) zones together with zone specific behavior modification parameters are defined - zone specific parameters always override global definitions in the response-policy statement. The zone section is delimited by braces {}. The global section applies behavior control parameters to all the zones defined in the response-policy statement (unless overridden with zone specific parameters) and is delimited by the terminating ;. Multiple parameters in either the zone or global section are space separated.

Where:

  1. zone: The zone keyword starts a zone definition within the zone section of the response-policy statement. The zone-name must be a quoted string and defines the zones that will be searched (in the order in which they are defined - the zone definitions constitute an ordered set) when RPZ policy processing is invoked. There can be up to 32 zone definitions (BIND 9.10+). Each zone defined in the response-policy statement must also be defined within a normal zone clause, which may, in turn, be inside a view clause as shown below:

    options {
      ...
      response-policy {zone "evenless" ;
        zone "noway"; };
      ...
    };
    ...
    zone "evenless" {
      type master;
      file "master/evenless.map";
    	...
      };
    view "mordor" {
    ...
    zone "noway" {
      type slave;
      file "slave/noway.map";
      ...
      };
    };
    

  2. policy: Is an optional zone-specific parameter (cannot appear in the global section) and defines any override to the Policy Actions in the RPZ zone file.

    1. given: Is the default action and defines no overrides - the zone file Policy Actions are unchanged.

    2. disabled: All Policy Actions for this zone are disabled but all items are logged to the rpz category thus also making it a useful testing option since it will log all RPZ trigger events. Note: Even with logging severity info; RPZ only logs the owner-name (left-hand) Trigger not the substituted (re-written) RR/target-name part.

    3. passthru: Every Trigger in the RPZ zone is actioned as a PASSTHRU irrespective of its actual Policy Action.

    4. drop: Every Trigger in the RPZ zone is actioned as a DROP irrespective of its actual Policy Action.

    5. nxdomain: Every Trigger in the RPZ zone is actioned as an NXDOMAIN irrespective of its actual Policy Action.

    6. nodata: Every Trigger in the RPZ zone is actioned as a NODATA irrespective of its actual Policy Action.

    7. tcp-only: Every Trigger in the RPZ zone is actioned as TCP-ONLY irrespective of its actual Policy Action.

    8. cname domain: Every Trigger in the RPZ zone returns a CNAME with the defined domain value irrespective of its actual Policy Action. Thus, if policy cname badguy.example.com is defined in the response-policy statement for an RPZ zone then every RR in the zone that triggers policy processing will return CNAME badguy.example.com even if the Policy Trigger and Policy Action specified, say, some-name A 192.168.2.3 (a Local-data Policy Action).

  3. recursive-only May appear inside an specific zone definition (in the zone section) of a response-policy statement in which case it affects only that zone, or outside (in the global section) where it affects all zones (unless overridden by the same parameter inside any specific zone definition). recursive-only takes the values yes or no (seems pretty cut and dried). Yes (the default) indicates that the policy process is invoked only on recursive queries (RD bit = 1). No causes the policy process to be invoked on every query received by the server.

  4. max-policy-ttl: May appear inside an specific zone definition (in the zone section) of a response-policy statement in which case it affects only that zone, or outside (in the global section) where it affects all zones (unless overridden by the same parameter inside any specific zone definition). The outcome of policy processing changes the response in the resolvers cache. By default, irrespective, of the original response TTL, the modified response TTL is set to 5 seconds. Thus, if you want to force the responses to live in the cache for a long period then define a (much) longer ttl value with a parameter like, say, max-policy-ttl 172800 (2 days defined in seconds). Consider, however, that any updated RPZ zone files (master or slave) may modify the behavior of any policy trigger or action including removing it entirely. Modifying the default TTL value to an long time period - a superficially attractive strategy - may have the unintended consequence of marooning unnecessary records in the cache.

  5. log [BIND 9.11 feature] May only appear in a zone section. Takes the single value yes or no. Yes (default) indicates RPZ operations for the zone will be logged to the RPZ category. No suppresses RPZ logging for the zone.

  6. break-dnssec: May only appear in the global section of the response-policy statement. By default RPZ does not process queries that request DNSSEC data (DO = 1) or that have DNSSEC RRs in the answer. Setting break-dnssec yes will override this default and cause policy processing on all DNSSEC queriies. However, the constructed response will not have any DNSSEC material added and therefore cannot be verified by the client (it may have the unintended consequence of looking like a bogus response or even an injection attack to the client).

  7. min-ns-dots: May only appear in the global section of the response-policy statement. Defines the minimum number of dot separators that must appear in any query question name (the QNAME) to invoke policy processing. Thus, if min-ns-dots has a value of 1 (the default) all queries with a name (QNAME) of the form example.com, mail.example.com or those containing more dots will invoke policy processing. Those with zero dots will by-pass policy processing - in the example (and default) case this would by-pass policy processing for QNAMEs containing only root or a TLD name.

  8. qname-wait-recurse: May only appear in the global section of the response-policy statement. Takes the single value of either yes (default) or no. In normal operation, policy processing is invoked only when the results of any query are available (when the query process completes - successfully or unsuccessfully). This allows the "normal" resolver cache to contain the real results but can delay query response to the end user to an unacceptable level. The value no allows policy processing to occur when the query is received without waiting for a response. This behaviour control effectively only applies to QNAME Policy Triggers since all other triggers require query results to determine their actions.

  9. nsip-wait-recurse: [BIND 9.11 feature] May only appear in the global section of the response-policy statement. Takes the single value of either yes (default) or no. In normal operation, policy processing is invoked only when the results of any query are available (when the query process completes - successfully or unsuccessfully). This allows the "normal" resolver cache to contain the real results but can delay query response to the end user to an unacceptable level. The value no indicates that if the result of the Name Server lookup is in the cache the NS-IP Trigger will be processed normally. If the data is not available in the cache the NS-IP Trigger will be bypassed but the NS lookup operation will continue, meaning it will subsequently be cached and invoke normal NS-IP Policy Trigger operations. Essentially, no bypasses the first occurrence of all NS-IP Triggers.

response-policy examples.

RPZ Zones Files

RPZ uses zone files with normal RRs to define Policy Actions and Policy Triggers. The zone is defined in a normal zone clause which may be inside a view clause. RPZ zones may be queried (if a master only by a slave to read its SOA RR, if a slave, never) so their infrastructure records (SOA and NS) have to satisfy minimal zone validation rules, that is the SOA RR must exist, but since no delegation will result from, or any delegation be referred to, RPZ zones only a single NS RR is required which can take the name of localhost (further discussion at RPZ Domain Names) obviating the need for any corresponding A/AAAA RR (localhost is out-of-zone). RPZ zones can be masters or slaves in the normal manner, indeed the designers of RPZ envisaged that RPZ zone files may be distributed (using zone transfer) by commercial enterprises, affinity groups or other such organizations.

RPZ zones have special characteristics that merit special attention, in particular they are likely to be big and may, by their very nature, become the target of attackers. The following items may be worth consideration:

  1. Query limiting: As noted above an RPZ master only needs to be queried by a valid slave in order to read its SOA RR (for zone transfer action). An allow-query statement listing all slave servers or referencing an ACL clause is appropriate. An RPZ slave does not need to be queried at all. An allow-query {none;}; statement is appropriate to implement this.

  2. NOTIFY: Assuming RPZ is using a typical master/slave system then an attacker, by bombarding slaves with fake NOTIFY messages, can cause significant traffic to be generated from slaves to masters (reading the SOA RR). In a common scenario where a central RPZ zone may be distributed to many 100s or even 1000s of slaves this bogus traffic could become significant and constitute a DDoS attack. Since BIND9.9 the also-notify statement allows the same parameter set as the masters statement including the reference to a masters clause and a key, meaning that TSIG may now be used to authenticate NOTIFY messages. Use of a non-standard port for NOTIFY messages should not be overlooked as a trivial, but highly effective, method to filter out any unwanted traffic. Changing this port number from time to time, perhaps even frequently, will further help to make an attacker's life more miserable - always a good thing. The following fragment shows possible NOTIFY measures:

    // example.com named.conf fragment
    options {
     ...
    };
    // key clauses should always be included
    // include "keys/rpz-key.clause";
    // with read-only permission for bind/named
    key "rpz-key"{
     ...
    };
    masters "notify-these" {
     ...
    };
    // force use of TSIG to slave
    server 192.168.2.5 {
      keys ("rpz-key";};
    };
    zone "rpz.example.com" {
      type master;
      ...
      also-notify {"notify-these" port 7222 key "rpz-key";};
    };
    
    
    // slave server example.net named.conf fragment
    options }
     ...
     listen-on port 53 {192.168.2.17;}; // local IP std port
     listen-on port 7222 {192.168.2.17;}; // for notifies
    };
    // key clauses should always be included
    // include "keys/rpz-key.clause";
    // with read-only permission for bind/named
    key "rpz-key"{
     ...
    };
    // force use of TSIG in traffic from/to master
    server 10.0.150.3 {
      keys ("rpz-key";};
    };
    
    zone "rpz.example.com" {
      type slave;
      ...
      masters {10.0.150.3 port 7222 key "rpz-key";};
    };
    
  3. Zone Transfer: Unauthorised zone transfers normally constitute only a DoS/DDoS threat (exceptionally a content disclosure threat). Clearly, in the RPZ case the DoS/DDoS threat is significant but the content disclosure threat is acute. The use of TSIG, to authorize the requestor of the zone transfer, becomes essential in this context. An attacker could create a very useful DDoS attack (especially if a bot-army was included) simply by sending zone transfer requests even though doomed to failure - it always takes time to process negative responses and the TCP overhead would be invoked even in such failure case wasting system resources. Again, the use of a non-standard port (with frequent changes) helps to reduce DoS/DDoS potential. The fragment below shows the use of zone transfer techniques:

    Note: If NOTIFY messages are being authorized by TSIG then the same key should be used for NOTIFY and zone transfer. This reduces the chances of operational errors and key exposure during key distribution, especially if a large number of RPZ slave servers are active. It is also good practice to use a separate key for each slave. This minimizes the number of entities involved in the case of any key compromise or normal key roll-over (periodic replacement). When a large number of slaves are involved this can result in a complex control process for the master distribution point - not to mention a huge named.conf file.

    // master example.com named.conf fragment
    options {
     ...
    };
    // key clauses should always be included
    // include "keys/rpz-key.clause";
    // with read-only permission for bind/named
    key "rpz-key"{
     ...
    };
    // also-notify list
    masters "notify-these" {
     ...
    };
    // force use of TSIG in traffic from/to slave
    server 192.168.2.5 {
      keys ("rpz-key";};
    };
    zone "rpz.example.com" {
      type master;
      ...
      also-notify {"notify-these" port 7222 key "rpz-key";};
    };
    
    // slave server example.net named.conf fragment
    options }
     ...
    };
    // key clauses should always be included
    // include "keys/rpz-key.clause";
    // with read-only permission for bind/named
    key "rpz-key"{
     ...
    };
    // force use of TSIG in traffic from/to master
    server 10.0.150.3 {
      keys ("rpz-key";};
    };
    
    zone "rpz.example.com" {
      type slave;
      ...
      masters {10.0.150.3 port 7222 key "rpz-key";};
    };
    
  4. Zone size: RPZ zones are likely to be extremely large - perhaps > 1 million records. BIND 9.10 provides a new map option for named-compilezone and the masterfile-format statement to enable significantly faster zone load speeds. In addition, to minimize file transfer sizes, assuming one or more slaves will request zone transfers from the RPZ zone, the ixfr-from-differences statement can be used to create a difference file even if dynamic update is not being used. The following shows these features in use:

    Note: It appears that as of Jan 2015 Bind 9.10's map zone load feature is supported for all zones files EXCEPT RPZ zones. Strange ommission. We leave the section below intact since it can only be a matter of time before this changes since RPZ zones are likely to be among the biggest out there. RPZ really does need the fastest possible zone load service available.

    # convert zone from text to map format
    named-compilezone -f map -o master/rpz.map rpz.example.com master/rpz.zone
    
    // example.com named.conf fragment
    options {
     ...
     ixfr-from-differences yes;
     ...
    };
    zone "rpz.example.com"{
      type master;
      file "master/rpz.map";
      masterfile-format map;
      ...
    };
    
  5. RPZ Domain Names: RPZ zones have little visibily and therefore can beak most of the normal rules for zone naming and definition, indeed much of the documentation does in fact make this out to be a positive attribute that brings some inherent security benefits. Thus, it is permissible to use a domain name such as badguys, or slimeballs or slightly more prosaically, rpzlist. Indeed, this page uses this fact to have some fun with RPZ domain names. Since these strange'ish domain names are, by their very nature unreachable by any normal means they have instrinsic security - they cannot be queried, though that will not stop a potential attacker from attempting the query - even failed queries consitute a server load, and a lot of failed queries (from a bot army) can constitute a serious server load. So the first question regarding RPZ is - will my use of RPZ constitute a DoS/DDoS threat escalation? RPZ goes to some length to disguise its presence by allowing normal DNS operations to complete before invoking its processing. This means that a rogue operator will see no change in normal traffic originating from an RPZ-enabled site and thus no cause for alarm. (This behavior can be modified using qname-wait-recurse which should be carefully considered before implementation.) However, use of the Policy Actions NXDOMAIN and NODATA will cause domain name leakage due to the way the message is reported (the SOA RR of the RPZ domain is displayed in the Authority Section of the returned query). An obvious domain name, for example, RPZ-Badguys will be a sure give-away that RPZ is implemented and perhaps incur revenge attacks. An entirely prosaic domain name, containing no mention of RPZ, is perhaps a wiser choice, examples could include domain.example.com or first.example.com from within the end users domain name set, but with no corresponding zone RR, would still achieve the required goals. Furthermore, the suggested use of localhost (which will also appear in NXDOMAIN and NODATA responses) is a potential give-away that RPZ is in use. Any valid looking out-of-zone NS RR will suffice, such as ns27.example.net, or even a fairly visible domain-name, since it will never be used in any delegation processing.

Operational Notes:

  1. All owner-names (right-hand-names) that appear in an RPZ must be unqualified (or relative), that is they must not terminate with a dot. Unless, of course, you enjoy typing out the $ORIGIN name on each such name in which case they can be FQDNs.

  2. While it is always good practice to use an $ORIGIN name in every zone file it is practically essential for RPZ domains. BIND9 will synthesize missing $ORIGIN names from the name used in the zone file but this can have unintended side effects and reduce flexibility in zone naming as discussed next.

  3. The RPZ zone name as it appears in the $ORIGIN directive must look valid but is not otherwise significant in that it will never appear in a delegated query operation from a slave (slaves directly access the master using an IP address in a masters statement not a query operation). Indeed, for obvious reasons, users may wish to ensure RPZ zone domain names are not resolvable via any public name server.

  4. The response-policy statement will take up to 32 zone names. It is superficially attractive to group each Policy Trigger type into a separate zone file. Recall, however that policy processing will search the zone files in the order in which they appear in the response-policy statement thus significant negative search overheads could be incurred. It may make more sense to segregate files based on their search characteristics. For example, placing all address based triggers (CLIENT-IP, IP, NSIP) into a single file since these always begin with a numeric value whereas few QNAME or NSDNAME targets will. Alternatively, where such segregation is impossible or difficult, define smaller files before larger files in the response-policy statement order unless their hit frequency is extremely low. Finally, zone files are always sorted into canonical order, thus, specific rules-within-zone-files may not appear in the correct order, in this case separation into a separate zone file which appears earlier in the zone order may be the only solution.

Policy Definitions (Actions and Triggers)

The RPZ policy definition uses the terms Policy Actions and Policy Triggers. This can initially appear confusing (perhaps not just initially). RPZ systems use standard RRs within a zone file to define the required policy outcomes. The Policy Triggers are defined using the owner-name (right-hand) part of the RR and the Policy Actions use a combination of the RR type and the left-hand expression as shown below:

Standard RR Format owner-name (label) RR Type RR Parameters
Response Policy Use Policy Trigger Determines Policy Action

RPZ supports (BIND9.10) the following Policy Actions and Policy Triggers:

Policy Actions

  1. NXDOMAIN Return name does not exist.
  2. NODATA Return name exists but with no answer data.
  3. PASSTHRU Do nothing - normally defines an exception in a range.
  4. TCP-Only Force use of TCP. [not in Format 3]
  5. DROP Causes client timeout. [not in format 3]
  6. Local-Data Response data defined by RR and target-name/left-hand expression.

Policy Triggers

  1. QNAME Trigger on query name.
  2. CLIENT-IP Trigger on DNS client IP.
  3. IP Trigger on query response IP.
  4. NSDNAME Trigger on NS name during delegation.
  5. NS-IP Trigger on NS IP during delegation.

Policy Actions

Policy Actions define the required outcome or result and are relatively straightforward. They are defined using the RR type and target-name (left-hand-name) of the RR as shown in the table below:

Note: Any Policy Trigger can be used with any Policy Action while the table shows only the most common types used with each Policy Action.

Outcome Policy Trigger
(LH name)
RR RH Value Policy Action
NXDOMAIN QNAME
IP
NSDNAME
NSIP
CNAME . RPZ processing returns NXDOMAIN (name does not exist) irrespective of actual result received. Note: RFC2308 mandates that NXDOMAIN responses will have the SOA RR of the authoritative zone placed in the response Authority Section. When RPZ action takes place the authority (and hence the SOA RR returned) is the RPZ domain. RPZ Domain name leakage will result. (see operational note on RPZ domain names.)
NODATA QNAME
IP
NSDNAME
NSIP
CNAME *. RPZ processing returns NODATA (name exists but no answers returned) irrespective of actual result received. Note: RFC2308 mandates that NODATA responses will have the SOA RR of the authoritative zone placed in the response Authority Section. When RPZ action takes place the authority (and hence the SOA RR returned) is the RPZ domain. RPZ Domain name leakage will result. (see operational note on RPZ domain names.)
Unchanged QNAME
IP
NSDNAME
NSIP
CNAME rpz-passthru. PASSTHRU (was NOOP). This identifies an exception (a whitelisted name) and can be used to override an action covering, say, a large IP address block or a specific subdomain to reduce the number of zone file records required to implement any given policy. When rpz-passthru. is detected no RPZ policy processing takes place (the PASSTHRU Action) and the query is processed, and responded to, normally. There is an older (obsoleted, but still supported in the code for backward compatibility) form of PASSTHRU in which the LH domain-name and the RH domain-name are identical.
Nothing QNAME
IP
NSDNAME
NSIP
CNAME rpz-drop. DROP. No response is returned to the user query irrespective of results obtained. This has the effect of causing an end user timeout (which is typically 5 seconds or even longer) thus causing a slowdown in query retries and query load. (In the case of a specific response, such as NODATA, the end user may simply retry immediately with implications for query load.) This kind of action is sometimes referred to generically as a tar-pit strategy.
Truncated CLIENT-IP CNAME rpz-tcp-only. TCP-ONLY. Causes a truncated message to be sent (without TC set) forcing the user to retry with a TCP connection with its higher connection time overheaad. The objective of this trigger is to slow down clients known to be involved with DDoS amplification attacks. The effect of this Trigger is a one shot deal. The subsequent TCP connection will connect normally. The net effect is to slow down client processing by a relatively modest amount which may be better than nothing. This trigger is primarily intended to be used with the Client-IP Trigger but can be used with other trigger types if required.
Modified QNAME
IP
NSDNAME
NSIP
anything anything (Local-Data) This Policy Action allows the operator to define any desired outcome. As an example a CNAME RR (or A/AAAA RR) could be used to send the user to a web page describing what action had been taken, to make a commercial offer or, well, anything else imaginable. Example:
$ORIGIN rpz.example.com.
...
# sends any QNAME query to anything from
# example.org to block.example.com 
# which could be a web site or ...anything
example.org   CNAME block.example.net.
*.example.org CNAME block.example.com.
# two CNAMEs are required to block the entire domain
# the first could omitted if you want to 
# allow, say, MX queries or delegations to be handled normally

Policy Triggers

Policy Triggers need careful consideration since the most obvious trigger may not always be the most effective expressed either in terms of volume (how many RPZ RRs are needed to achieve a given result and how big is the resulting zone file - with its search time implications) or efficiency (eliminating the source of bad behavior will always be more effective than dealing with its results). It is worth spending the time to understand the detail implications and scope of each trigger type since serious collateral damage can result from poorly designed triggers or triggers with excessive scope. A key issue for policy designers may be to understand the detailed pathology of the problem they are trying to solve before rushing to design a solution. It may be relatively trivial to discover that domain A or B is generating a problem, however, it may be far more difficult, yet ultimately far more rewarding (not to say, effective), to discover what infrastructure (such as name servers) are supporting A or B since C or D (using the same infrastructure) may be just about to cause a problem. RPZ, certainly when used to prevent malicious behavior, is mostly about perceived reputation.

Policy Trigger - QNAME Trigger

The QNAME Trigger operates on the question name of a query. Thus, if a user wants to go a web site such as www.example.com they will issue a query for the A or AAAA RR with this name. Use of the wildcard format (*.example.com) offers an apparently easy way to block any specific site and all its subdomains (such as www in this case) in the RPZ zone file. It the most obvious trigger and indeed for singleton sites that have otherwise no distinguising pathology it may be the most efficient. However, in order to obtain the final response (policy processing, by default, is only invoked after the completion of the full query cycle) the recursive server will have to follow the delegation hierarchy which is exclusively related to the processing of NS RRs and their corresponding A/AAAA RRs. These NS/A/AAAA RRs will be available before (perhaps significantly before) the final query result (QNAME behaviour timing may be controlled by the qname-wait-recurse parameter). Thus, it may be worth exploring the use of NSDNAME or NSIP Triggers especially if these NS records or IP addresses are complicit in multiple malicious domains.

Policy Trigger - IP Trigger

The IP Trigger operates on the answer section to an A/AAAA query. Recursive processing involving handling the hierarchical delegations (which will involve receiving A/AAAA responses for NS RRs) is invisible to this trigger. If the NS names or addresses are significant then either the NSDNAME or NSIP Triggers must be used. IP Address blocking is a potentially very blunt weapon. As an example, most web servers today host multiple (perhaps in the 100s or 1,000s) of web sites each with a different domain name but with a single IP Address. Simply blocking an IP address without careful consideration may involve unacceptable collateral damage by blocking many other, entirely benign, web sites.

  1. IPv4 IP Trigger Name Format The keyword label of rpz-ip invokes this trigger type. The IPv4 address is written in the form prefix.a4.a3.a2.a1.rpz-ip that is, the IPv4 address is reversed in the normal manner for IPv4 Reverse maps, prepended with an IP Prefix and .rpz-ip is finally appended to this transformed address - this will always result (correctly) in an unqualified or relative name - it must not end with a dot. The following examples show a number of permutations:

    # blocking a single ip address of 192.168.2.3
    # rewritten as 192.168.2.3/32
    # IPv4 Trigger transform
    32.3.2.168.192.rpz-ip
    
    # blocking 32 IPv4s containing 192.168.2.73
    # rewritten as 192.168.2.73/27
    # IPv4 Trigger transform
    27.73.2.168.192.rpz-ip
    
    # blocking 256 IP of 192.168.2/24
    # rewritten as 192.168.2.0/24
    # IPv4 Trigger transform
    24.0.2.168.192.rpz-ip
    

    Note: All 4 IPv4 address elements must be present (they can be padded with 0) even if not required by the IP Prefix. If you need an IPv4 Calculator.

  2. IPv6 IP Trigger Name Format The keyword label of rpz-ip invokes this trigger type. The IPv6 address is written in the form prefix.w8.w7.w6.w5.w4.w3.w2.w1.rpz-ip that is, the IPv6 address elements separated by : are reversed, the : replaced with a dot, the IPv6 Prefix is prepended to this and finally .rpz-ip is appended to this transformed address - this will always result (correctly) in an unqualified or relative name - it must not end with a dot. The special string "zz" may be used as a substitute for the IPv6 address form ::. (Note: This format uses the IPv6 16-bit word elements and must not be confused with the normal IPv6 reverse address format which uses a nibble format.) The following examples show a number of permutations:

    # blocking a single ip address of 2001:db8:0:1::57
    # rewritten as 2001:db8:0:1::57/128
    # IPv6 Trigger transform
    128.57.zz.1.0.db8.2001.rpz-ip
    
    # blocking user allocation of 2001:db8.0.1::/48
    # rewritten as - unchanged
    # IPv6 Trigger transform
    48.zz.1.0.db8.2001.rpz-ip
    
    # blocking an IPv4-mapped IPv6 address 2001:db8:0:1:0:FFFF:192.168.05 
    # rewritten as 2001:db8:0:1:0:FFFF:C0A8:5/128 
    # IPv6 Trigger transform
    128.5.C0A8.FFFF.0.1.0.db8.2001.rpz-ip
    

    Note: If you need an IPv6 Calculator

Policy Trigger - Client IP Trigger [not in Format 3]

The Client IP Trigger operates on the client IP address - the IP address of the entity that initiated the query - unlike the IP-TRIGGER which operates on the A/AAAA RR in the query answer section). It is especially designed to deal with zombied (or otherwise infected systems) on the client size of the resolver which may be involved in DDoS amplification attacks. Used in conjunction with a Nothing (DROP) Policy Action to cause a likely (5 seconds or more) timeout in the client would also have the effect of mitigating traffic to the local server (as well, obviously, as the intended destination). However, such a strategy would make the client unable to access any external resources. A pretty draconian step.

The CLIENT-IP trigger uses the same IPv4 address format and IPv6 address format as IP-Trigger but "rpz-client-ip" is appended. Some examples:

# blocking a single client ip address of 192.168.2.3
# rewritten as 192.168.2.3/32
# IPv4 Trigger transform
32.3.2.168.192.rpz-client-ip

# blocking a single client ip address of 2001:db8:0:1::57
# rewritten as 2001:db8:0:1::57/128
# IPv6 Trigger transform
128.57.zz.1.0.db8.2001.rpz-client-ip

Policy Trigger - NSDNAME Trigger

The NSDNAME trigger is invoked through the use of the rpz-nsdname label. Policy processing involves searching NS RRs for the appearance of the defined name server during recursive processing of the delegation from the root to the final end user query result. NS results will obviously arrive before (if the NS RR is already in the cache due to previous, perhaps unrelated, queries, significantly before) the final query answer, so this trigger will occur earlier in the query processing than either the QNAME or IP Triggers. Again, this may be a blunt weapon. Any single name server may handle 100s or even 1,000s of zones and unacceptable collateral damage may result from blocking it. Equally, the 100s or 1,000s of zones serviced by this NS name may all be the source of problems in which case it becomes a highly effective solution. The exact pathology of the problem needs to be understood before this, extremely powerful, trigger is used. Examples:

# single name server block
ns1.example.com.rpz-nsdname

Policy Trigger - NSIP Trigger

The NSIP trigger is invoked through the use of the rpz-nsip label. Any server (with an IPv4 or IPv6 address) may have multiple names (the zone file contains multiple A/AAAA RRs). This is a trivial and normal configuration used by many organizations. Thus, a name of ns.example.com and ns35.example.com or even ns7.example.net may all resolve to the same IP address. The NSDNAME Trigger will not be completely effective in this case unless all possible NS names are discovered. The NSIP Trigger causes policy processing to search A/AAAA RRs answers returned when resolving NS RRs during recursive processing of the delegation from the root to the final end user query result. These results will obviously arrive before (if the A/AAAA RR is already in the cache due to previous, perhaps unrelated, queries, significantly before) the final query answer so this trigger will occur earlier in the query cycle than either the QNAME or IP Triggers. The same cautions hold here as for the NSDNAME Trigger. The name server(s) at this address may handle 100s or even 1,000s of zones and unacceptable collateral damage may result from blocking it. Equally the 100s or 1,000s of zones serviced by name servers at this address may all be the source of problems in which case it becomes a highly effective solution. The exact pathology of the problem needs to be understood before this, extremely powerful, trigger is used. The name format for the NSIP is exactly the same as that for the IPv4 Trigger or the IPv6 IP Trigger. Examples:

# blocking an NS IPv4 address of 192.168.2.3
# rewritten as 192.168.2.3/32
# IPv4 NSIP Trigger transform
32.3.2.168.192.rpz-nsip

# blocking an NS IPv6 address of 2001:db8:0:1::57
# rewritten as 2001:db8:0:1::57/128
# IPv6 NSIP transform
128.57.zz.1.0.db8.2001.rpz-nsip

Examples

This example shows the named.conf fragments (master and slave) to typically invoke RPZ (there is also an example of a RPZ firewall configuration):

// master example.con named.conf
options {
  ...
  // for discussion on domain names used in rpz
  response-policy {zone "domain.example.com";} max-policy-ttl 3600;
  ...
};
// also-notify list
masters "notify-these" {
 ...
};
// key clause should always use include
key "rpz-key" {
  ...
};
// force use of TSIG with this slave
server 192.168.2.5 {
  keys {"rpz-key";};
}
zone "domain.example.com" {
  type master;
  ...
  also-notify {"notify-these" port 7222 key "rpz-key";};
};

// slave example.com named.conf fragment
// slave server example.net named.conf fragment
options }
 ...
 listen-on port 53 {192.168.2.17;}; // local IP std port
 listen-on port 7222 {192.168.2.17;}; // for notifies
};
// key clauses should always be included
// include "keys/rpz-key.clause";
// with read-only permission for bind/named
key "rpz-key"{
 ...
};
// force use of TSIG in traffic from/to master
server 10.0.150.3 {
  keys ("rpz-key";};
};

zone "domain.example.com" {
  type slave;
  ...
  masters {10.0.150.3 port 7222 key "rpz-key";};
};

An example RPZ zone file containing an example of all Policy Triggers and Policy Actions:

$TTL 2h;
$ORIGIN domain.example.com.
@               SOA nsd.example.net. hostmaster.example.com ( 1 12h 15m 3w 2h)
                NS nsd.example.net.  // out-of-zone no A/AAAA RR required
; begin RPZ RR definitions

;; QNAME Trigger

; QNAME Trigger NXDOMAIN Action
; kills whole domain
example.org        CNAME .
*.example.org      CNAME .

; stops www.example.org etc.
; but would allow reading of MX/NS/SOA at apex
*.example.org      CNAME .

; QNAME Trigger NODATA Action
; kills whole domain
example.org        CNAME *.
*.example.org      CNAME *.

; QNAME Trigger PASSTHRU Action
; typically only used for bypass
mail.example.org        CNAME rpz-passthru.

; QNAME Trigger DROP Action
; kills whole domain
example.org        CNAME rpz-drop.
*.example.org      CNAME rpz-drop.

; QNAME Trigger Truncate Action
; kills whole domain
example.org        CNAME rpz-tcp-only.
*.example.org      CNAME rpz-tcp-only.

; QNAME Trigger Local-Data Action
; sends to a local website
; kills whole domain
example.org        CNAME explanation.example.com.
*.example.org      CNAME explanation.example.com.
// OR
; QNAME Trigger Local-Data Action
; where 192.168.2.5 is a dedicated (non shared) website
; kills whole domain
example.org        A 192.168.2.5
*.example.org      A 192.168.2.5

;; CLIENT-IP Trigger
;; with client IP or 192.168.2.3

; CLIENT-IP Trigger DROP Action
; kills all DNS activity from this client
32.3.2.168.192.rpz-client-ip CNAME rpz-drop.

; CLIENT-IP Trigger TCP-ONLY Action
; slows-up all DNS activity from this client
32.3.2.168.192.rpz-client-ip CNAME rpz-tcp-only.

;; IP Trigger
;; with IP range 192.168.254.0/24

; IP Trigger NXDOMAIN Action
; any answer containing IP range
24.0.254.168.192.rpz-ip CNAME .

; IP Trigger NODATA Action
; any answer containing IP range
24.0.254.168.192.rpz-ip CNAME *.

; IP Trigger DROP Action
; any answer containing IP range
24.0.254.168.192.rpz-ip CNAME rpz-drop.

; IP Trigger Local-Data Action
; any answer containing IP range
24.0.254.168.192.rpz-ip CNAME explanation.example.com.

; IP Trigger PASSTHRU Action
; exception for 192.168.254.47 from 192.168.254.0/24
32.47.254.168.192.rpz-ip CNAME rpz-passthru.

;; NSDNAME Trigger
;; if ns1.example.org appears in the authority section
;; of any answer

; NSDNAME Trigger NXDOMAIN Action
; kills specific name server
ns1.example.org.rpz-nsdname CNAME .
; this will kill any name servers from example.org
example.org.rpz-nsdname     CNAME .
*.example.org.rpz-nsdname   CNAME .

; NSDNAME Trigger NODATA Action
; kills specific name server
ns1.example.org.rpz-nsdname CNAME *.
; this will kill any name servers from example.org
example.org.rpz-nsdname     CNAME *.
*.example.org.rpz-nsdname   CNAME *.

; NSDNAME Trigger PASSTHRU Action
; exception for ns47.example.org
ns47.example.org.rpz-nsdname CNAME rpz-passthru.

; NSDNAME Trigger NODATA Action
; kills specific name server
ns1.example.org.rpz-nsdname CNAME rpz-drop.
; this will kill any name servers from example.org
example.org.rpz-nsdname     CNAME rpz-drop.
*.example.org.rpz-nsdname   CNAME rpz-drop.

; NSDNAME Trigger TCP-ONLY Action
; kills specific name server
ns1.example.org.rpz-nsdname CNAME rpz-drop.
; this will kill any name servers from example.org
example.org.rpz-nsdname     CNAME rpz-tcp-only.
*.example.org.rpz-nsdname   CNAME rpz-tcp-only.

; NSDNAME Trigger Local-Data Action
; send to a specific website
ns1.example.org.rpz-nsdname CNAME explanation.example.com.
; this will kill any name servers from example.org
example.org.rpz-nsdname     CNAME explanation.example.com.
*.example.org.rpz-nsdname   CNAME explanation.example.com.

;; NS-IP Trigger
;; if 192.168.2.7 appears in the Additional Section
;; of any answer

; NS-IP Trigger NXDOMAIN Action
32.7.2.168.192.rpz-nsip CNAME .

; NS-IP Trigger NODATA Action
32.7.2.168.192.rpz-nsip CNAME *.

; NS-IP Trigger DROP Action
32.7.2.168.192.rpz-nsip CNAME rpz-drop.

; NS-IP Trigger Local-Data Action
; send to a specific website
32.7.2.168.192.rpz-nsip CNAME explanation.example.com.

; NS-IP Trigger DROP Action
; for whole 192.168.2.7/27
27.7.2.168.192.rpz-nsip CNAME rpz-drop.
; with exception for 192.168.2.15
32.15.2.168.192.rpz-nsip CNAME rpz-passthru.



Problems, comments, suggestions, corrections (including broken links) or something to add? Please take the time from a busy life to 'mail us' (at top of screen), the webmaster (below) or info-support at zytrax. You will have a warm inner glow for the rest of the day.

Pro DNS and BIND by Ron Aitchison

Contents

tech info
guides home
dns articles
intro
contents
1 objectives
big picture
2 concepts
3 reverse map
4 dns types
quickstart
5 install bind
6 samples
reference
7 named.conf
8 zone records
operations
9 howtos
10 tools
11 trouble
programming
12 bind api's
security
13 dns security
bits & bytes
15 messages
resources
notes & tips
registration FAQ
dns resources
dns rfcs
change log

Creative Commons License
This work is licensed under a Creative Commons License.

If you are happy it's OK - but your browser is giving a less than optimal experience on our site. You could, at no charge, upgrade to a W3C STANDARDS COMPLIANT browser such as Firefox

Search

web zytrax.com

Share

Icons made by Icomoon from www.flaticon.com is licensed by CC 3.0 BY
share page via facebook tweet this page

Page

email us Send to a friend feature print this page Display full width page Decrease font size Increase font size

Resources

Systems

FreeBSD
NetBSD
OpenBSD
DragonFlyBSD
Linux.org
Debian Linux

Software

LibreOffice
OpenOffice
Mozilla
GitHub
GNU-Free SW Foundation
get-dns

Organizations

Open Source Initiative
Creative Commons

Misc.

Ibiblio - Library
Open Book Project
Open Directory
Wikipedia

Site

CSS Technology SPF Record Conformant Domain
Copyright © 1994 - 2024 ZyTrax, Inc.
All rights reserved. Legal and Privacy
site by zytrax
hosted by javapipe.com
web-master at zytrax
Page modified: February 26 2024.