Bind9 Policy
From: https://www.zytrax.com/books/dns/ch7/rpz.html
response-policy statement
Defining RPZ zones
Operational Notes and Observations
RPZ Policy Definitions
Policy Actions
Policy Triggers
RPZ Examples
Configuring a DNS firewall with RPZ
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.
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:
- 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";
...
};
};
- 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.
- given: Is the default action and defines no overrides - the zone file
Policy Actions are unchanged.
- 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.
- passthru: Every Trigger in the RPZ zone is actioned as a PASSTHRU
irrespective of its actual Policy Action.
- drop: Every Trigger in the RPZ zone is actioned as a DROP irrespective of
its actual Policy Action.
- nxdomain: Every Trigger in the RPZ zone is actioned as an NXDOMAIN
irrespective of its actual Policy Action.
- nodata: Every Trigger in the RPZ zone is actioned as a NODATA irrespective
of its actual Policy Action.
- tcp-only: Every Trigger in the RPZ zone is actioned as TCP-ONLY
irrespective of its actual Policy Action.
- 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).
- recursive-onlyMay 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.
- 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.
- 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.
- 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).
- 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.
- 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.
- 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:
- 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.
- 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";};
};
- 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";};
};
- 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;
...
};
- 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:
- 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.
- 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.
- 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.
- 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 | Lowner-name (label) | LRR Type RR Parameters
|
Response Policy Use | LPolicy Trigger | LDetermines Policy Action
|
RPZ supports (BIND9.10) the following Policy Actions and Policy Triggers:
Policy Actions
Policy Triggers
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.
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.
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.