2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-03 08:05:21 +00:00

Commit rt25172 changes to HEAD including

- fix precedence among competing rules
  - improve ARM text including documenting rule precedence
  - try to rewrite CNAME chains until first hit
  - new "rpz" logging channel
  - same fix for "NS ." as in RT 24985
This commit is contained in:
Vernon Schryver
2011-10-13 01:32:34 +00:00
parent 2cb1c691ba
commit 9fee08f655
26 changed files with 1420 additions and 898 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -12,11 +12,11 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: clean.sh,v 1.3 2011/01/13 04:59:24 tbox Exp $
# $Id: clean.sh,v 1.4 2011/10/13 01:32:32 vjs Exp $
# Clean up after rpz tests.
rm -f dig.out* nsupdate.tmp
rm -f */named.memstats */named.run */session.key
rm -f ns3/bl*.db */*.jnl
rm -f proto.* dig.out* nsupdate.tmp
rm -f */named.memstats */named.run */named.rpz */session.key
rm -f ns3/bl*.db */*.jnl */*.core */*.pid

View File

@@ -12,17 +12,24 @@
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
; $Id: root.db,v 1.3 2011/01/13 04:59:24 tbox Exp $
; $Id: root.db,v 1.4 2011/10/13 01:32:33 vjs Exp $
$TTL 120
@ SOA s1. hostmaster.ns.s1. ( 1 3600 1200 604800 60 )
@ NS s1
s1. A 10.53.0.1
@ SOA ns. hostmaster.ns. ( 1 3600 1200 604800 60 )
@ NS ns.
ns. A 10.53.0.1
. A 10.53.0.1
; rewrite responses from this zone
tld2. NS ns.tld2.
ns.tld2. A 10.53.0.2
ns2.tld2. A 10.53.0.2
; requests come from here
tld3. NS ns.tld3.
ns.tld3. A 10.53.0.3
; rewrite responses from this zone
tld4. NS ns.tld4.
ns.tld4. A 10.53.0.4
ns2.tld4. A 10.53.0.4

View File

@@ -12,7 +12,8 @@
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
; $Id: hints,v 1.3 2011/01/13 04:59:25 tbox Exp $
; $Id: hints,v 1.4 2011/10/13 01:32:33 vjs Exp $
. 0 NS s1.
s1. 0 A 10.53.0.1
. 0 NS ns1.
ns1. 0 A 10.53.0.1

View File

@@ -14,7 +14,8 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: named.conf,v 1.3 2011/01/13 04:59:25 tbox Exp $ */
/* $Id: named.conf,v 1.4 2011/10/13 01:32:33 vjs Exp $ */
controls { /* empty */ };
@@ -34,4 +35,8 @@ zone "." { type hint; file "hints"; };
zone "tld2." {type master; file "tld2.db";};
zone "sub1.tld2." {type master; file "tld2.db";};
zone "sub2.sub1.tld2." {type master; file "tld2.db";};
zone "subsub.sub1.tld2." {type master; file "tld2.db";};
zone "sub2.tld2." {type master; file "tld2.db";};
zone "subsub.sub2.tld2." {type master; file "tld2.db";};
zone "sub3.tld2." {type master; file "tld2.db";};
zone "subsub.sub3.tld2." {type master; file "tld2.db";};

View File

@@ -12,46 +12,106 @@
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
; $Id: tld2.db,v 1.3 2011/01/13 04:59:25 tbox Exp $
; $Id: tld2.db,v 1.4 2011/10/13 01:32:33 vjs Exp $
; RPZ rewrite responses from this zone
$TTL 120
@ SOA tld2. hostmaster.ns.tld2. ( 1 3600 1200 604800 60 )
NS @
A 10.53.0.2
NS ns
NS ns2
NS . ; check for RT 24985
ns A 10.53.0.2
ns2 A 10.53.0.2
txt-only TXT "txt-only-tld2"
nodata TXT "nodata"
a12 A 12.12.12.12
AAAA 2001::12
TXT "a12 tld2 text"
a12-cname CNAME a12
a0-1 A 192.168.0.1
AAAA 2001:2::1
TXT "a0-1 text"
TXT "a0-1 tld2 text"
a3-1 A 192.168.3.1
AAAA 2001:2:3::1
TXT "a3-1 text"
TXT "a3-1 tld2 text"
a3-2 A 192.168.3.2
AAAA 2001:2:3::2
TXT "a3-2 text"
TXT "a3-2 tld2 text"
a3-3 A 192.168.3.3
AAAA 2001:2:3::3
TXT "a3-3 tld2 text"
a3-4 A 192.168.3.4
AAAA 2001:2:3::4
TXT "a3-4 tld2 text"
a3-5 A 192.168.3.5
AAAA 2001:2:3::5
TXT "a3-5 tld2 text"
a3-6 A 192.168.3.6
AAAA 2001:2:3::6
TXT "a3-6 tld2 text"
a3-7 A 192.168.3.7
AAAA 2001:2:3::7
TXT "a3-7 tld2 text"
a3-8 A 192.168.3.8
AAAA 2001:2:3::8
TXT "a3-8 tld2 text"
a3-9 A 192.168.3.9
AAAA 2001:2:3::9
TXT "a3-9 tld2 text"
a4-1 A 192.168.4.1
AAAA 2001:2:4::1
TXT "a4-1 text"
TXT "a4-1 tld2 text"
a4-1-aaaa AAAA 2001:2:4::1
a4-2 A 192.168.4.2
AAAA 2001:2:4::2
TXT "a4-2 text"
TXT "a4-2 tld2 text"
a4-2-cname CNAME a4-2
a4-3 A 192.168.4.3
AAAA 2001:2:4::3
TXT "a4-3 text"
TXT "a4-3 tld2 text"
a4-3-cname CNAME a4-3
a4-4 A 192.168.4.4
AAAA 2001:2:4::4
TXT "a4-4 text"
TXT "a4-4 tld2 text"
a4-5 CNAME a12
a4-5 A 192.168.4.5
AAAA 2001:2:4::5
TXT "a4-5 tld2 text"
a4-5-cname CNAME a4-5
a4-5-cname2 CNAME a4-5-cname
a4-5-cname3 CNAME a4-5-cname2
a4-6 A 192.168.4.6
AAAA 2001:2:4::6
TXT "a4-6 tld2 text"
a4-6-cname CNAME a4-6
a4-6-cname2 CNAME a4-6-cname
a4-6-cname3 CNAME a4-6-cname2
a5-1-2 A 192.168.5.1
A 192.168.5.2
TXT "a5-1-2 tld2 text"
a5-3 A 192.168.5.3
TXT "a5-3 tld2 text"
a5-4 A 192.168.5.4
TXT "a5-4 tld2 text"

View File

@@ -12,13 +12,15 @@
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
; $Id: base.db,v 1.5 2011/06/09 00:42:50 marka Exp $
; $Id: base.db,v 1.6 2011/10/13 01:32:33 vjs Exp $
; RPZ test
$TTL 120
@ SOA tld3. hostmaster.ns.tld3. ( 1 3600 1200 604800 60 )
@ NS ns.utld.
@ SOA blx. hostmaster.ns.blx. ( 1 3600 1200 604800 60 )
NS ns.tld.
ns A 10.53.0.3
; Poke the radix tree a little.
128.1111.2222.3333.4444.5555.6666.7777.8888.rpz-ip CNAME .
@@ -30,7 +32,8 @@ $TTL 120
128.zz.3333.4444.0.8777.8888.rpz-ip CNAME .
127.zz.3333.4444.0.8777.8888.rpz-ip CNAME .
; for testing rrset replacement
; regression testing for some old crashes
redirect IN A 127.0.0.1
*.redirect IN A 127.0.0.1
*.cname-redirect IN CNAME google.com.
*.credirect IN CNAME google.com.

View File

@@ -12,7 +12,8 @@
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
; $Id: hints,v 1.3 2011/01/13 04:59:25 tbox Exp $
; $Id: hints,v 1.4 2011/10/13 01:32:33 vjs Exp $
. 0 NS s1.
s1. 0 A 10.53.0.1
. 0 NS ns1.
ns1. 0 A 10.53.0.1

View File

@@ -14,9 +14,8 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: named.conf,v 1.3 2011/01/13 04:59:25 tbox Exp $ */
/* $Id: named.conf,v 1.4 2011/10/13 01:32:33 vjs Exp $ */
controls { /* empty */ };
options {
query-source address 10.53.0.3;
@@ -31,11 +30,16 @@ options {
response-policy {
zone "bl";
zone "bl-2";
zone "bl-given" policy given;
zone "bl-no-op" policy no-op;
zone "bl-passthru" policy passthru;
zone "bl-no-op" policy no-op; # obsolete for passthru
zone "bl-disabled" policy disabled;
zone "bl-nodata" policy nodata;
zone "bl-nxdomain" policy nxdomain;
zone "bl-cname" policy cname nodata.tld2.;
zone "bl-cname" policy cname txt-only.tld2.;
zone "bl-wildcname" policy cname *.tld4.;
zone "bl-garden" policy cname a12.tld2.;
};
};
@@ -48,30 +52,40 @@ controls {
};
logging {
category queries { default_stderr; };
# change "-c named.conf -d 99 -g" to "-c named.conf -d 99 -f"
# in ../start.pl to check the rpz log category
channel rpz { severity debug 10;
print-category yes; print-time yes; print-severity yes;
file "named.rpz";};
category rpz { default_stderr; rpz; };
category queries { default_stderr; rpz; };
category query-errors { default_stderr; };
};
zone "." { type hint; file "hints"; };
zone "bl." {type master; file "bl.db";
allow-update {any;};
};
allow-update {any;};};
zone "bl-2." {type master; file "bl-2.db";
allow-update {any;};};
zone "bl-given." {type master; file "bl-given.db";
allow-update {any;};
};
allow-update {any;};};
zone "bl-passthru." {type master; file "bl-passthru.db";
allow-update {any;};};
zone "bl-no-op." {type master; file "bl-no-op.db";
allow-update {any;};
};
allow-update {any;};};
zone "bl-disabled." {type master; file "bl-disabled.db";
allow-update {any;};};
zone "bl-nodata." {type master; file "bl-nodata.db";
allow-update {any;};
};
allow-update {any;};};
zone "bl-nxdomain." {type master; file "bl-nxdomain.db";
allow-update {any;};
};
allow-update {any;};};
zone "bl-cname." {type master; file "bl-cname.db";
allow-update {any;};
};
allow-update {any;};};
zone "bl-wildcname." {type master; file "bl-wildcname.db";
allow-update {any;};};
zone "bl-garden." {type master; file "bl-garden.db";
allow-update {any;};};
zone "crash1.tld2" {type master; file "crash1";};

View File

@@ -14,10 +14,11 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: setup.sh,v 1.3 2011/01/13 04:59:24 tbox Exp $
# $Id: setup.sh,v 1.4 2011/10/13 01:32:32 vjs Exp $
sh clean.sh
for NM in '' -given -no-op -nodata -nxdomain -cname; do
cp -f ns3/base.db ns3/bl$NM.db
# NO-OP is an obsolete synonym for PASSHTRU
for NM in '' -2 -given -disabled -passthru -no-op -nodata -nxdomain -cname -wildcname -garden; do
sed -e "/SOA/s/blx/bl$NM/g" ns3/base.db >ns3/bl$NM.db
done

View File

@@ -12,19 +12,64 @@
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
; $Id: test1,v 1.5 2011/06/09 03:10:17 marka Exp $
; $Id: test1,v 1.6 2011/10/13 01:32:32 vjs Exp $
; Use comment lines instead of blank lines to combine update requests into
; single requests
; Separate update requests for distinct TLDs with blank lines or 'send'
; End the file with a blank line or 'send'
server 10.53.0.3 5300
; QNAME tests
; NXDOMAIN
update add a0-1.tld2.bl. 300 CNAME .
;
; NODATA
update add a1-1.tld2.bl. 300 CNAME *.
update add a3-1.tld2.bl. 300 CNAME *.
; and no assert-botch
update add a1-2.tld2.bl. 300 DNAME example.com.
update add *.sub1.tld2.bl. 300 A 12.12.12.12
; 5
update add a3-2.tld2.bl. 300 DNAME example.com.
;
; NXDOMAIN for a4-2-cname.tld2 via its target a4-2.tld2.
; 6 and 7
update add a4-2.tld2.bl 300 CNAME .
; 8
; NODATA for a4-3-cname.tld2 via its target a4-3.tld2.
update add a4-3.tld2.bl 300 CNAME *.
;
; replace the A for a4-1.sub1.tld2 with 12.12.12.12
; 9
update add a4-1.sub1.tld2.bl. 300 A 12.12.12.12
;
; replace the A for *.sub2.tld2 with 12.12.12.12
; 10
update add a4-1.sub2.tld2.bl. 300 A 12.12.12.12
;
; replace NXDOMAIN for {nxc1,nxc2}.sub1.tld2 with 12.12.12.12 using CNAMEs
; 11
update add nxc1.sub1.tld2.bl. 300 CNAME a12.tld2.
; 12
update add nxc2.sub1.tld2.bl. 300 CNAME a12-cname.tld2.
;
; prefer the first conflicting zone
; 13
update add a4-4.tld2.bl. 300 A 127.0.0.1
send
update add a4-4.tld2.bl-2. 300 A 127.0.0.2
send
;
; wildcard CNAME
; 14
update add a3-6.tld2.bl. 300 CNAME *.tld4.
; 15
update add *.sub1.tld2.bl. 300 CNAME *.tld4.
; CNAME chains
; 16
update add a4-5.tld2.bl. 300 A 127.0.0.16
; 17
update add a4-6.tld2.bl. 300 CNAME .
update add a4-6-cname.tld2.bl. 300 A 127.0.0.17
send

View File

@@ -12,24 +12,47 @@
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
; $Id: test2,v 1.4 2011/01/13 19:30:41 each Exp $
; $Id: test2,v 1.5 2011/10/13 01:32:32 vjs Exp $
; Use comment lines instead of blank lines to combine update requests into
; single requests
; Separate update requests for distinct TLDs with blank lines or 'send'
; End the file with a blank line or 'send'
; IP tests
server 10.53.0.3 5300
; NODATA a3-1.tld2
update add 32.1.3.168.192.rpz-ip.bl 300 CNAME *.
; NXDOMAIN for network of a4-1.tld2
;
; NXDOMAIN for 192.168.4.0/24, the network of a4-1.tld2
update add 24.0.4.168.192.rpz-ip.bl 300 CNAME .
;
; poke hole in NXDOMAIN CIDR block to leave a4-1.tld2 unchanged
update add 32.1.4.168.192.rpz-ip.bl 300 CNAME 32.1.4.168.192
; NODATA a4-3.tld2
;
; NODATA for a4-3.tld2
update add 32.3.4.168.192.rpz-ip.bl 300 CNAME *.
;
; NXDOMAIN for IPv6 a3-1.tld2
update add 128.1.zz.3.2.2001.rpz-ip.bl 300 CNAME .
;
; apply the policy with the lexically smallest address of 192.168.5.1
; to an RRset of more than one A RR
update add 32.1.5.168.192.rpz-ip.bl 300 A 127.0.0.1
update add 32.2.5.168.192.rpz-ip.bl 300 A 127.0.0.2
;
; prefer first conflicting IP zone for a5-3.tld2
update add 32.3.5.168.192.rpz-ip.bl 300 A 127.0.0.1
send
update add 32.3.5.168.192.rpz-ip.bl-2 300 A 127.0.0.2
send
; prefer QNAME to IP for a5-4.tld2
update add 32.4.5.168.192.rpz-ip.bl 300 CNAME a12.tld2.
update add a5-4.tld2.bl 300 CNAME a14.tld4.
; wildcard CNAMEs
;update add

View File

@@ -12,11 +12,33 @@
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
; $Id: test3,v 1.4 2011/01/13 19:30:41 each Exp $
; $Id: test3,v 1.5 2011/10/13 01:32:32 vjs Exp $
; Use comment lines instead of blank lines to combine update requests into
; single requests
; Separate update requests for distinct TLDs with blank lines or 'send'
; End the file with a blank line or 'send'
; NSDNAME tests
server 10.53.0.3 5300
update add *.tld2.rpz-nsdname.bl. 300 CNAME .
; NXDOMAIN for *.sub1.tld2 by NSDNAME
update add *.sub1.tld2.rpz-nsdname.bl. 300 CNAME .
;
; walled garden for *.sub2.tld2
update add *.sub2.tld2.rpz-nsdname.bl. 300 CNAME a12-cname.tld2.
;
; exempt a3-2.tld2 and anything in 192.168.0.0/24
; also checks that IP policies are preferred over NSDNAME policies
update add a3-2.tld2.bl 300 CNAME a3-2.tld2.
update add 24.0.0.168.192.rpz-ip.bl 300 CNAME 24.0.0.168.192.
;
; prefer QNAME policy to NSDNAME policy
update add a4-1.tld2.bl. 300 A 12.12.12.12
;
; prefer policy for largest NS name
update add ns.sub3.tld2.rpz-nsdname.bl. 300 A 127.0.0.1
update add ns.subsub.sub3.tld2.rpz-nsdname.bl. 300 A 127.0.0.2
send

View File

@@ -12,11 +12,26 @@
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
; $Id: test4,v 1.4 2011/01/13 19:30:41 each Exp $
; $Id: test4,v 1.5 2011/10/13 01:32:33 vjs Exp $
; Use comment lines instead of blank lines to combine update requests into
; single requests
; Separate update requests for distinct TLDs with blank lines or 'send'
; End the file with a blank line or 'send'
; NSIP tests
server 10.53.0.3 5300
; NXDOMAIN for all of tld2 based on its server IP address
update add 32.2.0.53.10.rpz-nsip.bl. 300 CNAME .
;
; exempt a3-2.tld2 and anything in 192.168.0.0/24
; also checks that IP policies are preferred over NSIP policies
update add a3-2.tld2.bl 300 CNAME a3-2.tld2.
update add 24.0.0.168.192.rpz-ip.bl 300 CNAME 24.0.0.168.192.
;
; prefer NSIP policy to NSDNAME policy
update add ns.tld2.rpz-nsdname.bl. 300 CNAME 10.0.0.1
send

View File

@@ -12,25 +12,34 @@
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
; $Id: test5,v 1.4 2011/01/13 19:30:41 each Exp $
; $Id: test5,v 1.5 2011/10/13 01:32:33 vjs Exp $
; Use comment lines instead of blank lines to combine update requests into
; single requests
; Separate update requests for distinct TLDs with blank lines or 'send'
; End the file with a blank line or 'send'
; the policies or replacements specified in ns3/named.conf override these
server 10.53.0.3 5300
update add a3-1.tld2.bl-given. 300 CNAME .
send
server 10.53.0.3 5300
update add a3-2.tld2.bl-no-op. 300 CNAME .
update add a3-1.tld2.bl-given. 300 A 127.0.0.1
send
server 10.53.0.3 5300
update add a3-3.tld2.bl-nodata. 300 CNAME .
update add a3-2.tld2.bl-passthru. 300 A 127.0.0.2
send
server 10.53.0.3 5300
update add a3-4.tld2.bl-nxdomain. 300 CNAME *.
update add a3-3.tld2.bl-no-op. 300 A 127.0.0.3
send
server 10.53.0.3 5300
update add a3-5.tld2.bl-cname. 300 CNAME .
update add a3-4.tld2.bl-disabled. 300 A 127.0.0.4
send
update add a3-5.tld2.bl-nodata. 300 A 127.0.0.5
send
update add a3-6.tld2.bl-nxdomain. 300 A 127.0.0.6
send
update add a3-7.tld2.bl-cname. 300 A 127.0.0.7
send
update add a3-8.tld2.bl-wildcname. 300 A 127.0.0.8
update add *.sub9.tld2.bl-wildcname. 300 A 127.0.1.9
send
update add a3-10.tld2.bl-garden. 300 A 127.0.0.10
send

View File

@@ -12,19 +12,21 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: tests.sh,v 1.6 2011/06/09 03:10:17 marka Exp $
# $Id: tests.sh,v 1.7 2011/10/13 01:32:33 vjs Exp $
# test response policy zones (RPZ)
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
root=10.53.0.1
s2=10.53.0.2
s3=10.53.0.3
ns1=10.53.0.1 # root, defining the other two
ns2=10.53.0.2 # server whose answers are rewritten
ns3=10.53.0.3 # resolve that does the rewriting
ns4=10.53.0.4 # another server that is rewritten
DIGCMD="$DIG +noadd +nosea +nocmd -p 5300"
RNDCCMD="$RNDC -c ../common/rndc.conf -s $ns3 -p 9953"
HAVE_CORE=
USAGE="$0: [-x]"
while getopts "x" c; do
@@ -42,16 +44,21 @@ fi
trap 'exit 1' 1 2 15
digcmd () {
#echo I:dig +noadd +noauth +nosearch +time=1 +tries=1 -p 5300 $* 1>&2
$DIG +noadd +noauth +nosearch +time=1 +tries=1 -p 5300 $*
}
# set DIGNM=file name for dig output
# $1=target domain $2=optional query type $3=optional string
dignm () {
DIGNM=dig.out-$DIGNM_SUB-$1
if test -n "$3"; then
DIGNM=$DIGNM-$3
fi
if test -n "$2"; then
DIGNM=$DIGNM-`expr "x$2" : 'x-t *\(.*\)'`
fi
GROUP_NM=
TEST_NUM=0
make_dignm () {
TEST_NUM=`expr $TEST_NUM + 1`
DIGNM=dig.out$GROUP_NM-$TEST_NUM
while test -e $DIGNM; do
TEST_NUM="$TEST_NUM+"
DIGNM=dig.out$GROUP_NM-$TEST_NUM
done
}
setret () {
@@ -59,109 +66,159 @@ setret () {
echo "$*"
}
# (re)load the reponse policy zones with the rules in the file $TEST_FILE
load_db () {
if test -n "$TEST_FILE"; then
if $NSUPDATE -v $TEST_FILE; then : ; else
echo "I:failed to update policy zone with $TEST_FILE"
exit 1
fi
fi
}
restart () {
$RNDCCMD stop >/dev/null 2>&1
rm -f ns3/*.jnl
for NM in ns3/bl*.db; do
cp -f ns3/base.db $NM
done
(cd ..; $PERL start.pl --noclean --restart rpz ns3)
load_db
}
ckalive () {
$RNDCCMD status >/dev/null 2>&1 && return 0
HAVE_CORE=yes
setret "$1"
restart
return 1
}
# $1=message $2=optional test file name
start_group () {
ret=0
test -n "$1" && echo "I:checking $1"
TEST_FILE=$2
if test -n "$TEST_FILE"; then
GROUP_NM="-$TEST_FILE"
load_db
else
GROUP_NM=
fi
TEST_NUM=0
}
end_group () {
if test -n "$TEST_FILE"; then
sed -e 's/[ ]add[ ]/ delete /' $TEST_FILE | $NSUPDATE
TEST_FILE=
fi
status=`expr $status + $ret`
ckalive "I:failed; server crashed"
GROUP_NM=
}
# $1=dig args $2=other dig output file
ckresult () {
#ckalive "I:server crashed by 'dig $1'" || return 1
if $PERL ../digcomp.pl $DIGNM $2 >/dev/null; then
rm -f ${DIGNM}*
return 0
fi
setret "I:'dig $1' wrong; diff $DIGNM $2"
return 1
}
# check only that the server does not crash
# $1=target domain $2=optional query type
nocrash () {
digcmd $* @$ns3 >/dev/null
ckalive "I:server crashed by 'dig $*'"
}
# check rewrite to NXDOMAIN
# $1=target domain $2=optional query type
nxdomain () {
dignm $1 "$2"
$DIGCMD +noauth $1 $2 @$s3 >$DIGNM
$PERL ../digcomp.pl dig.out-nxdomain $DIGNM || setret " in $DIGNM"
make_dignm
digcmd +noauth $* @$ns3 \
| sed -e 's/^[a-z].* IN CNAME /;xxx &/' >$DIGNM
ckresult "$*" proto.nxdomain
}
# check rewrite to NODATA
# $1=target domain $2=optional query type
nodata () {
dignm $1 "$2"
$DIGCMD +noauth $1 $2 @$s3 >$DIGNM
$PERL ../digcomp.pl dig.out-nodata $DIGNM || setret " in $DIGNM"
make_dignm
digcmd +noauth $* @$ns3 \
| sed -e 's/^[a-z].* IN CNAME /;xxx &/' >$DIGNM
ckresult "$*" proto.nodata
}
# check rewrite to "A 12.12.12.12"
# modify the output so that it is easily matched, but save the original line
# $1=target domain $2=optional query type
a12 () {
dignm $1 "$2"
$DIGCMD +noauth $1 $2 @$s3 \
| sed -e "/^$1\. /{" \
-e "s/.*/;xxx &/p" -e "s/^;xxx $1/a12.tld2/" -e '}' \
>$DIGNM
$PERL ../digcomp.pl dig.out-a12 $DIGNM || ret=1
# check rewrite to an address
# modify the output so that it is easily compared, but save the original line
# $1=IPv4 address, $2=target domain $3=optional query type
addr () {
ADDR=$1
shift
ADDR_ESC=`echo "$ADDR" | sed -e 's/\./\\\\./g'`
make_dignm
digcmd +noauth $* @$ns3 >$DIGNM
#ckalive "I:server crashed by 'dig $*'" || return
if grep -i '^[a-z].* A '"$ADDR_ESC"'$' $DIGNM >/dev/null; then
rm -f ${DIGNM}*
return 0
fi
setret "I:'dig $*' wrong; no A $ADDR record in $DIGNM $2"
}
# check that a response is not rewritten
# $1=target domain $2=optional query type
nochange () {
dignm $1 "$2" ok
DIGNM_OK=$DIGNM
dignm $1 "$2"
$DIGCMD $1 $2 @$s3 >$DIGNM
$DIGCMD $1 $2 @$s2 >$DIGNM_OK
$PERL ../digcomp.pl $DIGNM_OK $DIGNM || ret=1
make_dignm
digcmd $* @$ns3 >$DIGNM
digcmd $* @$ns2 >${DIGNM}_OK
ckresult "$*" ${DIGNM}_OK && rm -f ${DIGNM}_OK
}
flush_db () {
if $RNDC -c ../common/rndc.conf -s $s3 -p 9953 freeze; then : ; else
echo "I:failed to freeze policy zone $1"
exit 1
fi
if $RNDC -c ../common/rndc.conf -s $s3 -p 9953 thaw; then : ; else
echo "I:failed to thaw policy zone $1"
exit 1
fi
# check against a 'here document'
here () {
make_dignm
sed -e 's/^[ ]*//' >${DIGNM}_OK
digcmd $* @$ns3 >$DIGNM
ckresult "$*" ${DIGNM}_OK
}
# $1=message $2=test file
start_test () {
ret=0
if test -n "$1"; then
echo "I:checking $1"
fi
PREV_FILE=$2
if test -n "$2"; then
DIGNM_SUB=`expr "$2" : 'test\(.\)'`
if $NSUPDATE -v $PREV_FILE; then : ; else
echo "I:failed to update policy zone $1 with $2"
exit 1
fi
#flush_db
else
DIGNM_SUB="${DIGNM_SUB}x"
fi
}
# make prototype files to check against rewritten results
digcmd +noauth nonexistent @$ns2 >proto.nxdomain
digcmd +noauth txt-only.tld2 @$ns2 >proto.nodata
end_test () {
if test $ret != 0; then
echo "I:failed"
else
rm -f dig.out-${DIGNM_SUB}*
fi
if test -n "$PREV_FILE"; then
sed -e 's/ add / delete /' $PREV_FILE | $NSUPDATE
status=`expr $status + $ret`
#flush_db
fi
}
# make NXDOMAIN and NODATA prototypes
echo "I:making prototype RPZ NXDOMAIN, NODATA, and CNAME results"
$DIGCMD +noauth nonexistent @$s2 >dig.out-nxdomain
$DIGCMD +noauth nodata.tld2 @$s2 >dig.out-nodata
$DIGCMD +noauth a12.tld2 @$s2 >dig.out-a12
status=0
start_test "RPZ QNAME rewrites" test1
start_group "QNAME rewrites" test1
nochange .
nxdomain a0-1.tld2
nodata a1-1.tld2
nodata a1-2.tld2
nodata sub.a1-2.tld2
a12 a4-1.sub1.tld2
end_test
nodata a3-1.tld2
nodata a3-2.tld2
nodata sub.a3-2.tld2 # 5 no crash on DNAME
nxdomain a4-2.tld2 # 6 rewrite based on CNAME target
nxdomain a4-2-cname.tld2 # 7
nodata a4-3-cname.tld2 # 8
addr 12.12.12.12 a4-1.sub1.tld2 # 9 A replacement
addr 12.12.12.12 a4-1.sub2.tld2 # 10 A replacement with wildcard
addr 12.12.12.12 nxc1.sub1.tld2 # 11 replace NXDOMAIN with CNAME
addr 12.12.12.12 nxc2.sub1.tld2 # 12 replace NXDOMAIN with CNAME chain
addr 127.0.0.1 a4-4.tld2 # 13 prefer 1st conflicting QNAME zone
addr 56.56.56.56 a3-6.tld2 # 14 wildcard CNAME
addr 57.57.57.57 a3-7.sub1.tld2 # 15 wildcard CNAME
addr 127.0.0.16 a4-5-cname3.tld2 # 16 CNAME chain
addr 127.0.0.17 a4-6-cname3.tld2 # 17 stop short in CNAME chain
end_group
start_test "RPZ IP rewrites" test2
start_group "IP rewrites" test2
nodata a3-1.tld2
nochange a3-2.tld2
nxdomain a3-99.tld2
nochange a4-1.tld2
nxdomain a4-2.tld2
nochange a4-2.tld2 -taaaa
@@ -170,9 +227,13 @@ nxdomain a4-2.tld2 -tany
nodata a4-3.tld2
nxdomain a3-1.tld2 -tAAAA
nochange a4-1-aaaa.tld2 -tAAAA
end_test
addr 127.0.0.1 a5-1-2.tld2 # 11 prefer smallest policy address
addr 127.0.0.1 a5-3.tld2 # 12 prefer first conflicting IP zone
addr 14.14.14.14 a5-4.tld2 # 13 prefer QNAME to IP
end_group
start_test "RPZ radix tree deletions"
# check that IP addresses for previous group were deleted from the radix tree
start_group "radix tree deletions"
nochange a3-1.tld2
nochange a3-2.tld2
nochange a4-1.tld2
@@ -183,94 +244,73 @@ nochange a4-2.tld2 -tany
nochange a4-3.tld2
nochange a3-1.tld2 -tAAAA
nochange a4-1-aaaa.tld2 -tAAAA
end_test
nochange a5-1-2.tld2
end_group
if ./rpz nsdname; then
start_test "RPZ NSDNAME rewrites" test3
start_group "NSDNAME rewrites" test3
nochange a3-1.tld2
nxdomain a3-1.sub1.tld2
nxdomain a3-1.sub2.sub1.tld2
end_test
nochange a3-1.tld2 +dnssec # 2 this once caused problems
nxdomain a3-1.sub1.tld2 # 3 NXDOMAIN *.sub1.tld2 by NSDNAME
nxdomain a3-1.subsub.sub1.tld2
nxdomain a3-1.subsub.sub1.tld2 -tany
addr 12.12.12.12 a4-2.subsub.sub2.tld2 # 6 walled garden for *.sub2.tld2
nochange a3-2.tld2. # 7 exempt rewrite by name
nochange a0-1.tld2. # 8 exempt rewrite by address block
addr 12.12.12.12 a4-1.tld2 # 9 prefer QNAME policy to NSDNAME
addr 127.0.0.1 a3-1.sub3.tld2 # 10 prefer policy for largest NSDNAME
addr 127.0.0.2 a3-1.subsub.sub3.tld2
nxdomain xxx.crash1.tld2 # 12 dns_db_detachnode() crash
end_group
else
echo "I:RPZ NSDNAME not checked; named was not built with --enable-rpz-nsdname"
echo "I:NSDNAME not checked; named not configured with --enable-rpz-nsdname"
fi
if ./rpz nsip; then
start_test "RPZ NSIP rewrites" test4
nxdomain a3-1.tld2
nochange .
end_test
start_group "NSIP rewrites" test4
nxdomain a3-1.tld2 # 1 NXDOMAIN for all of tld2 by NSIP
nochange a3-2.tld2. # 2 exempt rewrite by name
nochange a0-1.tld2. # 3 exempt rewrite by address block
nochange a3-1.tld4 # 4 different NS IP address
end_group
else
echo "I:RPZ NSIP not checked; named was not built with --enable-rpz-nsip"
echo "I:NSIP not checked; named not configured with --enable-rpz-nsip"
fi
start_test "RPZ policy overrides" test5
nxdomain a3-1.tld2
nochange a3-2.tld2
nodata a3-3.tld2
nxdomain a3-4.tld2
dignm a3-5.tld2 -tany
$DIGCMD +noauth a3-5.tld2 -tany @$s3 >$DIGNM
if grep CNAME $DIGNM >/dev/null; then : ; else
echo "'policy cname' failed"
ret=1
fi
end_test
# policies in ./test5 overridden by response-policy{} in ns3/named.conf
start_group "policy overrides" test5
addr 127.0.0.1 a3-1.tld2 # 1 bl-given
nochange a3-2.tld2 # 2 bl-passthru
nochange a3-3.tld2 # 3 bl-no-op obsolete for passthru
nochange a3-4.tld2 # 4 bl-disabled
nodata a3-5.tld2 # 5 bl-nodata
nxdomain a3-6.tld2 # 6 bl-nxdomain
here +noauth a3-7.tld2 -tany <<'EOF' # 7 bl_cname
;; status: NOERROR, x
a3-7.tld2. 300 IN CNAME txt-only.tld2.
txt-only.tld2. 120 IN TXT "txt-only-tld2"
EOF
addr 58.58.58.58 a3-8.tld2 # 8 bl_wildcname
addr 59.59.59.59 a3-9.sub9.tld2 # 9 bl_wildcname
addr 12.12.12.12 a3-10.tld2 # 10 bl-garden
end_group
ret=0
echo "I:checking RRSIG queries"
# We don't actually care about the query results; the important
# thing is the server handles RRSIG queries okay
$DIGCMD a3-1.tld2 -trrsig @$s3 > /dev/null 2>&1
$DIGCMD a3-2.tld2 -trrsig @$s3 > /dev/null 2>&1
$DIGCMD a3-5.tld2 -trrsig @$s3 > /dev/null 2>&1
$DIGCMD www.redirect -trrsig @$s3 > /dev/null 2>&1
$DIGCMD www.cname-redirect -trrsig @$s3 > /dev/null 2>&1
# check that miscellaneous bugs are still absent
start_group "crashes"
for Q in RRSIG SIG ANY 'ANY +dnssec'; do
nocrash a3-1.tld2 -t$Q
nocrash a3-2.tld2 -t$Q
nocrash a3-5.tld2 -t$Q
nocrash www.redirect -t$Q
nocrash www.credirect -t$Q
done
end_group
$RNDC -c ../common/rndc.conf -s $s3 -p 9953 status > /dev/null 2>&1 || ret=1
if [ $ret != 0 ]; then
echo "I:failed";
(cd ..; $PERL start.pl --noclean --restart rpz ns3)
fi
status=`expr $status + $ret`
ret=0
echo "I:checking SIG queries"
# We don't actually care about the query results; the important
# thing is the server handles SIG queries okay
$DIGCMD a3-1.tld2 -tsig @$s3 > /dev/null 2>&1
$DIGCMD a3-2.tld2 -tsig @$s3 > /dev/null 2>&1
$DIGCMD a3-5.tld2 -tsig @$s3 > /dev/null 2>&1
$DIGCMD www.redirect -tsig @$s3 > /dev/null 2>&1
$DIGCMD www.cname-redirect -tsig @$s3 > /dev/null 2>&1
$RNDC -c ../common/rndc.conf -s $s3 -p 9953 status > /dev/null 2>&1 || ret=1
if [ $ret != 0 ]; then
echo "I:failed";
(cd ..; $PERL start.pl --noclean --restart rpz ns3)
fi
status=`expr $status + $ret`
ret=0
echo "I:checking ANY queries"
# We don't actually care about the query results; the important
# thing is the server handles SIG queries okay
$DIGCMD a3-1.tld2 -tany @$s3 > /dev/null 2>&1
$DIGCMD a3-2.tld2 -tany @$s3 > /dev/null 2>&1
$DIGCMD a3-5.tld2 -tany @$s3 > /dev/null 2>&1
$DIGCMD www.redirect -tany @$s3 > /dev/null 2>&1
$DIGCMD www.cname-redirect -tany @$s3 > /dev/null 2>&1
$RNDC -c ../common/rndc.conf -s $s3 -p 9953 status > /dev/null 2>&1 || ret=1
if [ $ret != 0 ]; then
echo "I:failed";
(cd ..; $PERL start.pl --noclean --restart rpz ns3)
fi
status=`expr $status + $ret`
if test "$status" -eq 0; then
rm -f dig.out*
# restart the server to see if that creates a core file
if test -z "$HAVE_CORE"; then
$RNDCCMD halt
restart
test -s ns3/named.core && setret "I:found stray core file; memory leak?"
fi
echo "I:exit status: $status"

View File

@@ -15,7 +15,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: start.pl,v 1.27 2011/10/10 23:18:17 smann Exp $
# $Id: start.pl,v 1.28 2011/10/13 01:32:32 vjs Exp $
# Framework for starting test servers.
# Based on the type of server specified, check for port availability, remove
@@ -232,14 +232,15 @@ sub start_server {
# already been started
my $tries = 0;
while (!-s $pid_file) {
if (++$tries > 14) {
if (++$tries > 140) {
print "I:Couldn't start server $server (pid=$child)\n";
print "R:FAIL\n";
system "kill -9 $child" if ("$child" ne "");
system "$PERL $topdir/stop.pl $testdir";
exit 1;
}
sleep 1;
# sleep for 0.1 seconds
select undef,undef,undef,0.1;
}
# go back to the top level directory

View File

@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- File: $Id: Bv9ARM-book.xml,v 1.504 2011/10/06 11:50:20 marka Exp $ -->
<!-- File: $Id: Bv9ARM-book.xml,v 1.505 2011/10/13 01:32:33 vjs Exp $ -->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<title>BIND 9 Administrator Reference Manual</title>
@@ -4682,6 +4682,19 @@ category notify { null; };
</para>
</entry>
</row>
<row rowsep="0">
<entry colname="1">
<para><command>RPZ</command></para>
</entry>
<entry colname="2">
<para>
Information about errors in response policy zone files,
rewritten responses, and at the highest
<command>debug</command> levels, mere rewriting
attempts.
</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
@@ -5211,7 +5224,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
<optional> resolver-query-timeout <replaceable>number</replaceable> ; </optional>
<optional> deny-answer-addresses { <replaceable>address_match_list</replaceable> } <optional> except-from { <replaceable>namelist</replaceable> } </optional>;</optional>
<optional> deny-answer-aliases { <replaceable>namelist</replaceable> } <optional> except-from { <replaceable>namelist</replaceable> } </optional>;</optional>
<optional> response-policy { <replaceable>zone_name</replaceable> <optional> policy <replaceable>given</replaceable> | <replaceable>no-op</replaceable> | <replaceable>nxdomain</replaceable> | <replaceable>nodata</replaceable> | <replaceable>cname domain</replaceable> </optional> ; } ; </optional>
<optional> response-policy { <replaceable>zone_name</replaceable> <optional> policy given | disabled | passthru | nxdomain | nodata | cname <replaceable>domain</replaceable> </optional> ; } ; </optional>
};
</programlisting>
@@ -9323,68 +9336,109 @@ deny-answer-aliases { "example.net"; };
<para>
<acronym>BIND</acronym> 9 includes an intentionally limited
mechanism to modify DNS responses for recursive requests
similar to email anti-spam DNS blacklists.
All response policy zones are named in the
somewhat similar to email anti-spam DNS blacklists.
Responses can be changed to deny the existence of domains(NXDOMAIN),
deny the existence of IP addresses for domains (NODATA),
or contain other IP addresses or data.
</para>
<para>
The actions encoded in a response policy zone (RPZ) are applied
only to queries that ask for recursion (RD=1).
Response policy zones are named in the
<command>response-policy</command> option for the view or among the
global options if there is no response-policy option for the view.
</para>
<para>
The rules encoded in a response policy zone (RPZ) are applied
only to responses to queries that ask for recursion (RD=1).
RPZs are normal DNS zones containing RRsets
RPZs are ordinary DNS zones containing RRsets
that can be queried normally if allowed.
It is usually best to restrict those queries with something like
<command>allow-query {none; };</command> or
<command>allow-query { 127.0.0.1; };</command>.
<command>allow-query { localhost; };</command>.
</para>
<para>
There are four kinds of RPZ rewrite rules. QNAME rules are
applied to query names in requests and to targets of CNAME
records resolved in the process of generating the response.
The owner name of a QNAME rule is the query name relativized
There are four kinds of RPZ records, QNAME, IP, NSIP,
and NSDNAME.
QNAME records are applied to query names of requests and targets
of CNAME records resolved to generate the response.
The owner name of a QNAME RPZ record is the query name relativized
to the RPZ.
The records in a rewrite rule are usually A, AAAA, or special
CNAMEs, but can be any type except DNAME.
</para>
<para>
IP rules are triggered by addresses in A and AAAA records.
All IP addresses in A or AAAA RRsets are tested and the rule
longest prefix is applied. Ties between rules with equal prefixes
are broken in favor of the first RPZ mentioned in the
response-policy option.
The rule matching the smallest IP address is chosen among equal
prefix rules from a single RPZ.
IP rules are expressed in RRsets with owner names that are
subdomains of rpz-ip and encoding an IP address block, reversed
as in IN-ARPA.
prefix.B.B.B.B with prefix between 1 and 32 and B between 1 and 255
encodes an IPv4 address.
IPv6 addresses are encoded by with prefix.W.W.W.W.W.W.W.W or
prefix.WORDS.zz.WORDS. The words in the standard IPv6 text
representation are reversed, "::" is replaced with ".zz.",
and ":" becomes ".".
The second kind of RPZ record, an IP policy record,
is triggered by addresses in A and AAAA records
for the ANSWER sections of responses.
IP policy records have owner names that are
subdomains of <userinput>rpz-ip</userinput> relativized to the
RPZ origin name and encode an IP address or address block.
IPv4 addresses are encoded as
<userinput>prefixlength.B4.B3.B2.B1.rpz-ip</userinput>.
The prefix length must be between 1 and 32.
All four bytes, B4, B3, B2, and B1, must be present.
B4 is the decimal value of the least significant byte of the
IPv4 address as in IN-ADDR.ARPA.
IPv6 addresses are encoded in a format similar to the standard
IPv6 text representation,
<userinput>prefixlength.W8.W7.W6.W5.W4.W3.W2.W1.rpz-ip</userinput>.
Each of W8,...,W1 is a one to four digit hexadecimal number
representing 16 bits of the IPv6 address as in the standard text
representation of IPv6 addresses, but reversed as in IN-ADDR.ARPA.
All 8 words must be present except when consecutive
zero words are replaced with <userinput>.zz.</userinput>
analogous to double colons (::) in standard IPv6 text encodings.
The prefix length must be between 1 and 128.
</para>
<para>
NSDNAME rules match names in NS RRsets for the response or a
parent. They are encoded as subdomains of rpz-nsdomain relativized
NSDNAME policy records match names of authoritative servers
for the query name, a parent of the query name, a CNAME,
or a parent of a CNAME.
They are encoded as subdomains of
<userinput>rpz-nsdomain</userinput> relativized
to the RPZ origin name.
</para>
<para>
NSIP rules match IP addresses in A and AAAA RRsets for names of
responsible servers or the names that can be matched by NSDNAME
rules. The are encoded like IP rules except as subdomains of
rpz-nsip.
NSIP policy records match IP addresses in A and AAAA RRsets
for domains that can be checked against NSDNAME policy records.
The are encoded like IP policies except as subdomains of
<userinput>rpz-nsip</userinput>.
</para>
<para>
Authority verification issues and variations in authority data in
the current version of <acronym>BIND</acronym> 9 can cause
inconsistent results from NSIP and NSDNAME. So they are available
The query response is checked against all RPZs, so
two or more policy records can apply to a single response.
Because DNS responses can be rewritten according by at most a
single policy record, a single policy (other than
<command>DISABLED</command> policies) must be chosen.
Policies are chosen in the following order:
<itemizedlist>
<listitem>Among applicable zones, use the RPZ that appears first
in the response-policy option.
<listitem>Prefer QNAME to IP to NSDNAME to NSIP policy records
in a single RPZ
<listitem>Among applicable NSDNAME policy records, prefer the
policy record that matches the lexically smallest name
<listitem>Among IP or NSIP policy records, prefer the record
with the longest prefix.
<listitem>Among records with the same prefex length,
prefer the IP or NSIP policy record that matches
the smallest IP address.
</itemizedlist>
</para>
<para>
When the processing of a response is restarted to resolve
DNAME or CNAME records and an applicable policy record set has
not been found,
all RPZs are again consulted for the DNAME or CNAME names
and addresses.
</para>
<para>
Authority verification issues and variations in authority data
can cause inconsistent results for NSIP and NSDNAME policy records.
Glue NS records often differ from authoritative NS records.
So they are available
only when <acronym>BIND</acronym> is built with the
<userinput>--enable-rpz-nsip</userinput> or
<userinput>--enable-rpz-nsdname</userinput> options
@@ -9392,67 +9446,98 @@ deny-answer-aliases { "example.net"; };
</para>
<para>
Four policies can be expressed.
The <command>NXDOMAIN</command> policy causes a NXDOMAIN response
and is expressed with an RRset consisting of a single CNAME
whose target is the root domain (.).
<command>NODATA</command> generates NODATA or ANCOUNT=1 regardless
of query type.
It is expressed with a CNAME whose target is the wildcard
top-level domain (*.).
The <command>NO-OP</command> policy does not change the response
and is used to "poke holes" in policies for larger CIDR blocks or in
zones named later in the <command>response-policy</command> option.
The NO-OP policy is expressed by a CNAME with a target consisting
of the variable part of the owner name, such as "example.com." for
a QNAME rule or "128.1.0.0.127." for an IP rule.
The <command>CNAME</command> policy is used to replace the RRsets
of response.
A and AAAA RRsets are most common and useful to capture
an evil domain in a walled garden, but any valid set of RRsets
is possible.
RPZ record sets are special CNAME records or one or more
of any types of DNS record except DNAME or DNSSEC.
Except when a policy record is a CNAME, there can be more
more than one record and more than one type
in a set of policy records.
Except for three kinds of CNAME records that are illegal except
in policy zones, the records in a set are used in the response as if
their owner name were the query name. They are copied to the
response as dictated by their types.
<itemizedlist>
<listitem>A CNAME whose target is the root domain (.)
specifies the <command>NXDOMAIN</command> policy,
which generates an NXDOMAIN response.
<listitem>A CNAME whose target is the wildcard top-level
domain (*.) specifies the <command>NODATA</command> policy,
which rewrites the response to NODATA or ANCOUNT=1.
<listitem>A CNAME whose target is a wildcard hostname such
as *.example.com is used normally after the astrisk (*)
has been replaced with the query name.
These records are usually resolved with ordinary CNAMEs
outside the policy zones. They can be useful for logging.
<listitem>The <command>PASSTHRU</command> policy is specified
by a CNAME whose target is the variable part of its own
owner name. It causes the response to not be rewritten
and is most often used to "poke holes" in policies for
CIDR blocks.
</itemizedlist>
</para>
<para>
All of the policies in an RPZ can be overridden with a
<command>policy</command> clause.
<command>given</command> says "do not override."
<command>no-op</command> says "do nothing" regardless of the policy
in RPZ records.
<command>nxdomain</command> causes all RPZ rules to generate
NXDOMAIN results.
<command>nodata</command> gives nodata.
<command>cname domain</command> causes all RPZ rules to act as if
the consisted of a "cname domain" record.
The policies specified in individual records
in an RPZ can be overridden with a <command>policy</command> clause
in the <command>response-policy</command> option.
An organization using an RPZ provided by another organization might
use this mechanism to redirect domains to its own walled garden.
<itemizedlist>
<listitem><command>GIVEN</command> says "do not override."
<listitem><command>DISABLED</command> causes policy records to do
nothing but log what they might have done.
The response to the DNS query will be written according to
any matching policy records that are not disabled.
Policy zones overridden with <command>DISABLED</command> should
appear first, because they will often not be logged
if a higher precedence policy is found first.
<listitem><command>PASSTHRU</command> causes all policy records
to act as if they were CNAME records with targets the variable
part of their owner name. They protect the response from
being changed.
<listitem><command>NXDOMAIN</command> causes all RPZ records
to specify NXDOMAIN policies.
<listitem><command>NODATA</command> overrides with the
NODATA policy
<listitem><command>CNAME domain</command> causes all RPZ
policy records to act as if they were "cname domain" records.
</itemizedlist>
</para>
<para>
For example, you might use this option statement
</para>
<programlisting>response-policy { zone "bl"; };</programlisting>
<programlisting> response-policy { zone "badlist"; };</programlisting>
<para>
and this zone statement
</para>
<programlisting>zone "bl" {type master; file "example/bl"; allow-query {none;}; };</programlisting>
<programlisting> zone "badlist" {type master; file "master/badlist"; allow-query {none;}; };</programlisting>
<para>
with this zone file
</para>
<programlisting>$TTL 1H
@ SOA LOCALHOST. named-mgr.example.com (1 1h 15m 30d 2h)
NS LOCALHOST.
; QNAME rules
nxdomain.domain.com CNAME .
nodata.domain.com CNAME *.
bad.domain.com A 10.0.0.1
; QNAME policy records. There are no periods (.) after the owner names.
nxdomain.domain.com CNAME . ; NXDOMAIN policy
nodata.domain.com CNAME *. ; NODATA policy
bad.domain.com A 10.0.0.1 ; redirect to a walled garden
AAAA 2001:2::1
; do not rewrite (PASSTHRU) OK.DOMAIN.COM
ok.domain.com CNAME ok.domain.com.
*.badzone.domain.com CNAME garden.example.com.
; IP rules rewriting all answers for 127/8 except 127.0.0.1
8.0.0.0.127.ip CNAME .
32.1.0.0.127.ip CNAME 32.1.0.0.127.
bzone.domain.com CNAME garden.example.com.
; NSDNAME and NSIP rules
; redirect x.bzone.domain.com to x.bzone.domain.com.garden.example.com
*.bzone.domain.com CNAME *.garden.example.com.
; IP policy records that rewrite all answers for 127/8 except 127.0.0.1
8.0.0.0.127.rpz-ip CNAME .
32.1.0.0.127.rpz-ip CNAME 32.1.0.0.127. ; PASSTHRU for 127.0.0.1
; NSDNAME and NSIP policy records
ns.domain.com.rpz-nsdname CNAME .
48.zz.2.2001.rpz-nsip CNAME .
</programlisting>

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: db.c,v 1.98 2011/10/11 00:09:03 each Exp $ */
/* $Id: db.c,v 1.99 2011/10/13 01:32:33 vjs Exp $ */
/*! \file */
@@ -1017,10 +1017,11 @@ dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
isc_result_t
dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
dns_rdataset_t *ardataset, dns_rpz_st_t *st)
dns_rdataset_t *ardataset, dns_rpz_st_t *st,
dns_name_t *query_qname)
{
if (db->methods->rpz_findips == NULL)
return (ISC_R_NOTIMPLEMENTED);
return ((db->methods->rpz_findips)(rpz, rpz_type, zone, db, version,
ardataset, st));
ardataset, st, query_qname));
}

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: db.h,v 1.106 2011/10/11 00:09:03 each Exp $ */
/* $Id: db.h,v 1.107 2011/10/13 01:32:34 vjs Exp $ */
#ifndef DNS_DB_H
#define DNS_DB_H 1
@@ -178,7 +178,8 @@ typedef struct dns_dbmethods {
dns_zone_t *zone, dns_db_t *db,
dns_dbversion_t *version,
dns_rdataset_t *ardataset,
dns_rpz_st_t *st);
dns_rpz_st_t *st,
dns_name_t *query_qname);
isc_result_t (*findnodeext)(dns_db_t *db, dns_name_t *name,
isc_boolean_t create,
dns_clientinfomethods_t *methods,
@@ -1547,7 +1548,8 @@ dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st);
isc_result_t
dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
dns_rdataset_t *ardataset, dns_rpz_st_t *st);
dns_rdataset_t *ardataset, dns_rpz_st_t *st,
dns_name_t *query_qname);
/*%<
* Search the CDIR block tree of a response policy tree of trees for the best
* match to any of the IP addresses in an A or AAAA rdataset.
@@ -1560,6 +1562,10 @@ dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
* \li 'ardataset' is an A or AAAA rdataset of addresses to check
* \li 'found' specifies the previous best match if any or
* or NULL, an empty name, 0, DNS_RPZ_POLICY_MISS, and 0
*
* Returns:
* \li #ISC_R_SUCCESS
* \li #ISC_R_UNEXPECTED
*/
ISC_LANG_ENDDECLS

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: log.h,v 1.45 2009/12/18 22:16:49 each Exp $ */
/* $Id: log.h,v 1.46 2011/10/13 01:32:34 vjs Exp $ */
/*! \file dns/log.h
* \author Principal Authors: DCL */
@@ -42,6 +42,7 @@ LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[];
#define DNS_LOGCATEGORY_LAME_SERVERS (&dns_categories[9])
#define DNS_LOGCATEGORY_DELEGATION_ONLY (&dns_categories[10])
#define DNS_LOGCATEGORY_EDNS_DISABLED (&dns_categories[11])
#define DNS_LOGCATEGORY_RPZ (&dns_categories[12])
/* Backwards compatibility. */
#define DNS_LOGCATEGORY_GENERAL ISC_LOGCATEGORY_GENERAL

View File

@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rpz.h,v 1.3 2011/01/13 04:59:26 tbox Exp $ */
/* $Id: rpz.h,v 1.4 2011/10/13 01:32:34 vjs Exp $ */
#ifndef DNS_RPZ_H
#define DNS_RPZ_H 1
@@ -37,21 +37,24 @@ typedef enum {
DNS_RPZ_TYPE_BAD,
DNS_RPZ_TYPE_QNAME,
DNS_RPZ_TYPE_IP,
DNS_RPZ_TYPE_NSIP,
DNS_RPZ_TYPE_NSDNAME
DNS_RPZ_TYPE_NSDNAME,
DNS_RPZ_TYPE_NSIP
} dns_rpz_type_t;
/*
* Require DNS_RPZ_POLICY_NO_OP < DNS_RPZ_POLICY_NXDOMAIN <
* DNS_RPZ_POLICY_NODATA < DNS_RPZ_POLICY_CNAME.
* Require DNS_RPZ_POLICY_PASSTHRU < DNS_RPZ_POLICY_NXDOMAIN <
* DNS_RPZ_POLICY_NODATA < DNS_RPZ_POLICY_CNAME to choose among competing
* policies.
*/
typedef enum {
DNS_RPZ_POLICY_GIVEN = 0, /* 'given': what something else says */
DNS_RPZ_POLICY_NO_OP = 1, /* 'no-op': do not rewrite */
DNS_RPZ_POLICY_NXDOMAIN = 2, /* 'nxdomain': answer with NXDOMAIN */
DNS_RPZ_POLICY_NODATA = 3, /* 'nodata': answer with ANCOUNT=0 */
DNS_RPZ_POLICY_CNAME = 4, /* 'cname x': answer with x's rrsets */
DNS_RPZ_POLICY_RECORD = 5,
DNS_RPZ_POLICY_GIVEN = 0, /* 'given': what policy record says */
DNS_RPZ_POLICY_DISABLED = 1, /* 'cname x': answer with x's rrsets */
DNS_RPZ_POLICY_PASSTHRU = 2, /* 'passthru': do not rewrite */
DNS_RPZ_POLICY_NXDOMAIN = 3, /* 'nxdomain': answer with NXDOMAIN */
DNS_RPZ_POLICY_NODATA = 4, /* 'nodata': answer with ANCOUNT=0 */
DNS_RPZ_POLICY_CNAME = 5, /* 'cname x': answer with x's rrsets */
DNS_RPZ_POLICY_RECORD,
DNS_RPZ_POLICY_WILDCNAME,
DNS_RPZ_POLICY_MISS,
DNS_RPZ_POLICY_ERROR
} dns_rpz_policy_t;
@@ -65,10 +68,9 @@ struct dns_rpz_zone {
ISC_LINK(dns_rpz_zone_t) link;
int num;
dns_name_t origin; /* Policy zone name */
dns_name_t nsdname; /* RPZ_NSDNAME_ZONE.origin */
dns_rpz_policy_t policy; /* RPZ_POLICY_GIVEN or override */
dns_name_t cname; /* override name for
RPZ_POLICY_CNAME */
dns_name_t nsdname; /* DNS_RPZ_NSDNAME_ZONE.origin */
dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */
dns_name_t cname; /* override value for ..._CNAME */
};
/*
@@ -82,13 +84,15 @@ typedef struct dns_rpz_cidr dns_rpz_cidr_t;
typedef struct {
unsigned int state;
# define DNS_RPZ_REWRITTEN 0x0001
# define DNS_RPZ_DONE_QNAME 0x0002
# define DNS_RPZ_DONE_A 0x0004
# define DNS_RPZ_RECURSING 0x0008
# define DNS_RPZ_HAVE_IP 0x0010
# define DNS_RPZ_HAVE_NSIPv4 0x0020
# define DNS_RPZ_HAVE_NSIPv6 0x0040
# define DNS_RPZ_HAD_NSDNAME 0x0080
# define DNS_RPZ_DONE_QNAME 0x0002 /* qname checked */
# define DNS_RPZ_DONE_QNAME_IP 0x0004 /* IP addresses of qname checked */
# define DNS_RPZ_DONE_NSDNAME 0x0008 /* NS name missed; checking addresses */
# define DNS_RPZ_DONE_IPv4 0x0010
# define DNS_RPZ_RECURSING 0x0020
# define DNS_RPZ_HAVE_IP 0x0040 /* a policy zone has IP addresses */
# define DNS_RPZ_HAVE_NSIPv4 0x0080 /* IPv4 NISP addresses */
# define DNS_RPZ_HAVE_NSIPv6 0x0100 /* IPv6 NISP addresses */
# define DNS_RPZ_HAVE_NSDNAME 0x0200 /* NS names */
/*
* Best match so far.
*/
@@ -105,7 +109,7 @@ typedef struct {
dns_rdataset_t *rdataset;
} m;
/*
* State for chasing NS names and addresses including recursion.
* State for chasing IP addresses and NS names including recursion.
*/
struct {
unsigned int label;
@@ -114,7 +118,7 @@ typedef struct {
dns_rdatatype_t r_type;
isc_result_t r_result;
dns_rdataset_t *r_rdataset;
} ns;
} r;
/*
* State of real query while recursing for NSIP or NSDNAME.
*/
@@ -146,6 +150,7 @@ typedef struct {
#define DNS_RPZ_INFO_LEVEL ISC_LOG_INFO
#define DNS_RPZ_DEBUG_LEVEL1 ISC_LOG_DEBUG(1)
#define DNS_RPZ_DEBUG_LEVEL2 ISC_LOG_DEBUG(2)
#define DNS_RPZ_DEBUG_LEVEL3 ISC_LOG_DEBUG(3)
const char *
dns_rpz_type2str(dns_rpz_type_t type);
@@ -153,6 +158,9 @@ dns_rpz_type2str(dns_rpz_type_t type);
dns_rpz_policy_t
dns_rpz_str2policy(const char *str);
const char *
dns_rpz_policy2str(dns_rpz_policy_t policy);
void
dns_rpz_set_need(isc_boolean_t need);

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: log.c,v 1.47 2009/12/18 23:49:03 tbox Exp $ */
/* $Id: log.c,v 1.48 2011/10/13 01:32:33 vjs Exp $ */
/*! \file */
@@ -44,6 +44,7 @@ LIBDNS_EXTERNAL_DATA isc_logcategory_t dns_categories[] = {
{ "lame-servers", 0 },
{ "delegation-only", 0 },
{ "edns-disabled", 0 },
{ "rpz", 0 },
{ NULL, 0 }
};

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rbtdb.c,v 1.318 2011/10/12 23:09:35 marka Exp $ */
/* $Id: rbtdb.c,v 1.319 2011/10/13 01:32:33 vjs Exp $ */
/*! \file */
@@ -4588,15 +4588,19 @@ get_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
* Search the CDIR block tree of a response policy tree of trees for all of
* the IP addresses in an A or AAAA rdataset.
* Among the policies for all IPv4 and IPv6 addresses for a name, choose
* the longest prefix. Among those with the longest prefix, the first
* configured policy. Among answers for with the longest prefixes for
* two or more IP addresses in the A and AAAA rdatasets the lexically
* smallest address.
* the earliest configured policy,
* QNAME over IP over NSDNAME over NSIP,
* the longest prefix,
* the lexically smallest address.
* The caller must have already checked that any existing policy was not
* configured earlier than this policy zone and does not have a higher
* precedence type.
*/
static isc_result_t
rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
dns_rdataset_t *ardataset, dns_rpz_st_t *st)
dns_rdataset_t *ardataset, dns_rpz_st_t *st,
dns_name_t *query_qname)
{
dns_rbtdb_t *rbtdb;
struct in_addr ina;
@@ -4617,8 +4621,6 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
if (rbtdb->rpz_cidr == NULL) {
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
dns_db_detach(&db);
dns_zone_detach(&zone);
return (ISC_R_UNEXPECTED);
}
@@ -4653,17 +4655,19 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
continue;
/*
* Choose the policy with the longest matching prefix.
* Between policies with the same prefix, choose the first
* configured.
* If we already have a rule, discard this new rule if
* is not better.
* The caller has checked that st->m.rpz->num > rpz->num
* or st->m.rpz->num == rpz->num and st->m.type >= rpz_type
*/
if (st->m.policy != DNS_RPZ_POLICY_MISS) {
if (prefix < st->m.prefix)
if (st->m.policy != DNS_RPZ_POLICY_MISS &&
st->m.rpz->num == rpz->num &&
(st->m.type < rpz_type ||
(st->m.type == rpz_type &&
(st->m.prefix > prefix ||
(st->m.prefix == prefix &&
0 > dns_name_rdatacompare(st->qname, qname))))))
continue;
if (prefix == st->m.prefix &&
rpz->num > st->m.rpz->num)
continue;
}
/*
* We have rpz_st an entry with a prefix at least as long as
@@ -4677,8 +4681,8 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
char namebuf[DNS_NAME_FORMATSIZE];
dns_name_format(qname, namebuf, sizeof(namebuf));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
DNS_LOGMODULE_CACHE, DNS_RPZ_ERROR_LEVEL,
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
"rpz_findips findnode(%s): %s",
namebuf, isc_result_totext(result));
continue;
@@ -4702,7 +4706,8 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
} else {
rpz_policy = dns_rpz_decode_cname(&zrdataset,
selfname);
if (rpz_policy == DNS_RPZ_POLICY_RECORD)
if (rpz_policy == DNS_RPZ_POLICY_RECORD ||
rpz_policy == DNS_RPZ_POLICY_WILDCNAME)
result = DNS_R_CNAME;
}
ttl = zrdataset.ttl;
@@ -4715,21 +4720,36 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
/*
* Use an overriding action specified in the configuration file
*/
if (rpz->policy != DNS_RPZ_POLICY_GIVEN &&
rpz_policy != DNS_RPZ_POLICY_NO_OP)
rpz_policy = rpz->policy;
if (rpz->policy != DNS_RPZ_POLICY_GIVEN) {
/*
* We know the new prefix is at least as long as the current.
* Prefer the new answer if the new prefix is longer.
* Prefer the zone configured first if the prefixes are equal.
* With two actions from the same zone, prefer the action
* on the "smallest" name.
* only log DNS_RPZ_POLICY_DISABLED hits
*/
if (st->m.policy == DNS_RPZ_POLICY_MISS ||
prefix > st->m.prefix ||
rpz->num <= st->m.rpz->num ||
0 > dns_name_compare(qname, st->qname)) {
if (rpz->policy == DNS_RPZ_POLICY_DISABLED) {
if (isc_log_wouldlog(dns_lctx,
DNS_RPZ_INFO_LEVEL)) {
char qname_buf[DNS_NAME_FORMATSIZE];
char rpz_qname_buf[DNS_NAME_FORMATSIZE];
dns_name_format(query_qname, qname_buf,
sizeof(qname_buf));
dns_name_format(qname, rpz_qname_buf,
sizeof(rpz_qname_buf));
isc_log_write(dns_lctx,
DNS_LOGCATEGORY_RPZ,
DNS_LOGMODULE_RBTDB,
DNS_RPZ_INFO_LEVEL,
"disabled rpz %s %s rewrite"
" %s via %s",
dns_rpz_type2str(rpz_type),
dns_rpz_policy2str(rpz_policy),
qname_buf, rpz_qname_buf);
}
continue;
}
rpz_policy = rpz->policy;
}
if (dns_rdataset_isassociated(st->m.rdataset))
dns_rdataset_disassociate(st->m.rdataset);
if (st->m.node != NULL)
@@ -4745,14 +4765,14 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
st->m.ttl = ttl;
st->m.result = result;
dns_name_copy(qname, st->qname, NULL);
if (rpz_policy == DNS_RPZ_POLICY_RECORD &&
if ((rpz_policy == DNS_RPZ_POLICY_RECORD ||
rpz_policy == DNS_RPZ_POLICY_WILDCNAME) &&
result != DNS_R_NXRRSET) {
dns_rdataset_clone(&zrdataset,st->m.rdataset);
dns_db_attachnode(db, node, &st->m.node);
}
dns_db_attach(db, &st->m.db);
dns_zone_attach(zone, &st->m.zone);
}
if (dns_rdataset_isassociated(&zrdataset))
dns_rdataset_disassociate(&zrdataset);
}

View File

@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rpz.c,v 1.7 2011/01/17 04:27:23 marka Exp $ */
/* $Id: rpz.c,v 1.8 2011/10/13 01:32:34 vjs Exp $ */
/*! \file */
@@ -116,20 +116,17 @@ struct dns_rpz_cidr_node {
struct dns_rpz_cidr {
isc_mem_t *mctx;
isc_boolean_t had_nsdname;
isc_boolean_t have_nsdname; /* zone has NSDNAME record */
dns_rpz_cidr_node_t *root;
dns_name_t ip_name; /* RPZ_IP_ZONE.LOCALHOST. */
dns_name_t nsip_name; /* RPZ_NSIP_ZONE.LOCALHOST. */
dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.LOCALHOST */
};
static isc_boolean_t have_rpz_zones = ISC_FALSE;
const char *
dns_rpz_type2str(dns_rpz_type_t type)
{
dns_rpz_type2str(dns_rpz_type_t type) {
switch (type) {
case DNS_RPZ_TYPE_QNAME:
return ("QNAME");
@@ -143,31 +140,61 @@ dns_rpz_type2str(dns_rpz_type_t type)
break;
}
FATAL_ERROR(__FILE__, __LINE__,
"impossible response policy zone type %d", type);
"impossible rpz type %d", type);
return ("impossible");
}
dns_rpz_policy_t
dns_rpz_str2policy(const char *str)
{
dns_rpz_str2policy(const char *str) {
if (str == NULL)
return (DNS_RPZ_POLICY_ERROR);
if (!strcasecmp(str, "given"))
return (DNS_RPZ_POLICY_GIVEN);
if (!strcasecmp(str, "no-op"))
return (DNS_RPZ_POLICY_NO_OP);
if (!strcasecmp(str, "disabled"))
return (DNS_RPZ_POLICY_DISABLED);
if (!strcasecmp(str, "passthru"))
return (DNS_RPZ_POLICY_PASSTHRU);
if (!strcasecmp(str, "nxdomain"))
return (DNS_RPZ_POLICY_NXDOMAIN);
if (!strcasecmp(str, "nodata"))
return (DNS_RPZ_POLICY_NODATA);
if (!strcasecmp(str, "cname"))
return (DNS_RPZ_POLICY_CNAME);
/*
* Obsolete
*/
if (!strcasecmp(str, "no-op"))
return (DNS_RPZ_POLICY_PASSTHRU);
return (DNS_RPZ_POLICY_ERROR);
}
const char *
dns_rpz_policy2str(dns_rpz_policy_t policy) {
const char *str;
switch (policy) {
case DNS_RPZ_POLICY_PASSTHRU:
str = "PASSTHRU";
break;
case DNS_RPZ_POLICY_NXDOMAIN:
str = "NXDOMAIN";
break;
case DNS_RPZ_POLICY_NODATA:
str = "NODATA";
break;
case DNS_RPZ_POLICY_RECORD:
str = "records";
break;
case DNS_RPZ_POLICY_CNAME:
case DNS_RPZ_POLICY_WILDCNAME:
str = "CNAME";
break;
default:
str = "";
INSIST(0);
}
return (str);
}
/*
* Free the radix tree of a response policy database.
@@ -214,8 +241,6 @@ dns_rpz_cidr_free(dns_rpz_cidr_t **cidrp) {
*cidrp = NULL;
}
/*
* Forget a view's list of policy zones.
*/
@@ -244,20 +269,15 @@ dns_rpz_view_destroy(dns_view_t *view) {
* zone is in at least one view's list of policy zones.
*/
void
dns_rpz_set_need(isc_boolean_t need)
{
dns_rpz_set_need(isc_boolean_t need) {
have_rpz_zones = need;
}
isc_boolean_t
dns_rpz_needed(void)
{
dns_rpz_needed(void) {
return (have_rpz_zones);
}
/*
* Start a new radix tree for a response policy zone.
*/
@@ -313,12 +333,13 @@ dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin,
return (ISC_R_SUCCESS);
}
/*
* See if a policy zone has IP, NSIP, or NSDNAME rules or records.
*/
void
dns_rpz_enabled(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st) {
if (cidr == NULL)
return;
if (cidr->root != NULL &&
(cidr->root->flags & DNS_RPZ_CIDR_FG_IP) != 0)
st->state |= DNS_RPZ_HAVE_IP;
@@ -328,8 +349,8 @@ dns_rpz_enabled(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st) {
if (cidr->root != NULL &&
(cidr->root->flags & DNS_RPZ_CIDR_FG_NSIPv6) != 0)
st->state |= DNS_RPZ_HAVE_NSIPv6;
if (cidr->had_nsdname)
st->state |= DNS_RPZ_HAD_NSDNAME;
if (cidr->have_nsdname)
st->state |= DNS_RPZ_HAVE_NSDNAME;
}
static inline dns_rpz_cidr_flags_t
@@ -350,8 +371,6 @@ get_flags(const dns_rpz_cidr_key_t *ip, dns_rpz_cidr_bits_t prefix,
}
}
/*
* Mark a node as having IP or NSIP data and all of its parents
* as members of the IP or NSIP tree.
@@ -371,8 +390,6 @@ set_node_flags(dns_rpz_cidr_node_t *node, dns_rpz_type_t rpz_type) {
}
}
/*
* Make a radix tree node.
*/
@@ -409,24 +426,18 @@ new_node(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *ip,
return (node);
}
static void
badname(int level, dns_name_t *name, const char *comment)
{
badname(int level, dns_name_t *name, const char *comment) {
char printname[DNS_NAME_FORMATSIZE];
if (isc_log_wouldlog(dns_lctx, level)) {
dns_name_format(name, printname, sizeof(printname));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
DNS_LOGMODULE_RBTDB, level,
"invalid response policy name \"%s\"%s",
printname, comment);
"invalid rpz \"%s\"%s", printname, comment);
}
}
/*
* Convert an IP address from radix tree binary (host byte order) to
* to its canonical response policy domain name and its name in the
@@ -520,8 +531,6 @@ ip2name(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *tgt_ip,
return (ISC_R_SUCCESS);
}
/*
* Decide which kind of IP address response policy zone a name is in.
*/
@@ -548,8 +557,6 @@ set_type(dns_rpz_cidr_t *cidr, dns_name_t *name) {
return (DNS_RPZ_TYPE_QNAME);
}
/*
* Convert an IP address from canonical response policy domain name form
* to radix tree binary (host byte order).
@@ -695,26 +702,37 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
return (ISC_R_SUCCESS);
}
/*
* find first differing bit
* Find first differing bit.
*/
static int
ffbit(dns_rpz_cidr_word_t w) {
int bit;
if (w == 0)
return (DNS_RPZ_CIDR_WORD_BITS);
for (bit = 0; (w & (1U << (DNS_RPZ_CIDR_WORD_BITS-1))) == 0; bit++)
w <<= 1;
bit = DNS_RPZ_CIDR_WORD_BITS-1;
if ((w & 0xffff0000) != 0) {
w >>= 16;
bit -= 16;
}
if ((w & 0xff00) != 0) {
w >>= 8;
bit -= 8;
}
if ((w & 0xf0) != 0) {
w >>= 4;
bit -= 4;
}
if ((w & 0xc) != 0) {
w >>= 2;
bit -= 2;
}
if ((w & 2) != 0)
--bit;
return (bit);
}
/*
* find the first differing bit in two keys
* Find the first differing bit in two keys.
*/
static int
diff_keys(const dns_rpz_cidr_key_t *key1, dns_rpz_cidr_bits_t bits1,
@@ -741,14 +759,12 @@ diff_keys(const dns_rpz_cidr_key_t *key1, dns_rpz_cidr_bits_t bits1,
return (ISC_MIN(bit, maxbit));
}
/*
* Search a radix tree for an IP address for ordinary lookup
* or for a CIDR block adding or deleting an entry
* The tree read (for simple search) or write lock must be held by the caller.
*
* return ISC_R_SUCCESS, ISC_R_NOTFOUND, DNS_R_PARTIALMATCH, ISC_R_EXISTS,
* Return ISC_R_SUCCESS, ISC_R_NOTFOUND, DNS_R_PARTIALMATCH, ISC_R_EXISTS,
* ISC_R_NOMEMORY
*/
static isc_result_t
@@ -912,15 +928,12 @@ search(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *tgt_ip,
}
}
/*
* Add an IP address to the radix tree of a response policy database.
* The tree write lock must be held by the caller.
*/
void
dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name)
{
dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
dns_rpz_cidr_key_t tgt_ip;
dns_rpz_cidr_bits_t tgt_prefix;
dns_rpz_type_t type;
@@ -929,7 +942,7 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name)
return;
/*
* no worries if the new name is not an IP address
* No worries if the new name is not an IP address.
*/
type = set_type(cidr, name);
switch (type) {
@@ -937,7 +950,7 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name)
case DNS_RPZ_TYPE_NSIP:
break;
case DNS_RPZ_TYPE_NSDNAME:
cidr->had_nsdname = ISC_TRUE;
cidr->have_nsdname = ISC_TRUE;
return;
case DNS_RPZ_TYPE_QNAME:
case DNS_RPZ_TYPE_BAD:
@@ -953,15 +966,12 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name)
char printname[DNS_NAME_FORMATSIZE];
dns_name_format(name, printname, sizeof(printname));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
"duplicate response policy name \"%s\"",
printname);
"duplicate rpz name \"%s\"", printname);
}
}
/*
* Delete an IP address from the radix tree of a response policy database.
* The tree write lock must be held by the caller.
@@ -1000,7 +1010,7 @@ dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
/*
* Do not get excited about the deletion of interior rbt nodes.
*/
if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_DEBUG_LEVEL2, name,
if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_DEBUG_LEVEL3, name,
type, &tgt_ip, &tgt_prefix))
return;
if (ISC_R_SUCCESS != search(cidr, &tgt_ip, tgt_prefix, type,
@@ -1009,10 +1019,9 @@ dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
char printname[DNS_NAME_FORMATSIZE];
dns_name_format(name, printname, sizeof(printname));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
"missing response policy node \"%s\"",
printname);
"missing rpz node \"%s\"", printname);
}
return;
}
@@ -1073,8 +1082,6 @@ dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
} while (tgt != NULL);
}
/*
* Caller must hold tree lock.
* Return ISC_R_NOTFOUND
@@ -1124,8 +1131,6 @@ dns_rpz_cidr_find(dns_rpz_cidr_t *cidr, const isc_netaddr_t *netaddr,
canon_name, search_name));
}
/*
* Translate CNAME rdata to a QNAME response policy action.
*/
@@ -1148,21 +1153,31 @@ dns_rpz_decode_cname(dns_rdataset_t *rdataset, dns_name_t *selfname) {
if (dns_name_equal(&cname.cname, dns_rootname))
return (DNS_RPZ_POLICY_NXDOMAIN);
if (dns_name_iswildcard(&cname.cname)) {
/*
* CNAME *. means NODATA
*/
if (dns_name_countlabels(&cname.cname) == 2
&& dns_name_iswildcard(&cname.cname))
if (dns_name_countlabels(&cname.cname) == 2)
return (DNS_RPZ_POLICY_NODATA);
/*
* A qname of www.evil.com and a policy of
* *.evil.com CNAME *.garden.net
* gives a result of
* evil.com CNAME evil.com.garden.net
*/
if (dns_name_countlabels(&cname.cname) > 2)
return (DNS_RPZ_POLICY_WILDCNAME);
}
/*
* 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. means "do not rewrite"
*/
if (selfname != NULL && dns_name_equal(&cname.cname, selfname))
return (DNS_RPZ_POLICY_NO_OP);
return (DNS_RPZ_POLICY_PASSTHRU);
/*
* evil.com CNAME garden.net rewrites www.evil.com to www.garden.net.
* Any other rdata gives a response consisting of the rdata.
*/
return (DNS_RPZ_POLICY_RECORD);
}

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: namedconf.c,v 1.141 2011/09/06 22:29:33 smann Exp $ */
/* $Id: namedconf.c,v 1.142 2011/10/13 01:32:34 vjs Exp $ */
/*! \file */
@@ -1027,7 +1027,8 @@ static cfg_type_t cfg_type_masterformat = {
/*
* response-policy {
* zone <string> [ policy (given|no-op|nxdomain|nodata|cname <domain> ) ];
* zone <string> [ policy (given|disabled|passthru|
* nxdomain|nodata|cname <domain> ) ];
* };
*
* this is a chimera of doc_optional_keyvalue() and cfg_doc_enum()
@@ -1095,7 +1096,8 @@ cleanup:
}
static const char *rpz_policies[] = {
"given", "no-op", "nxdomain", "nodata", "cname", NULL
"given", "disabled", "passthru", "no-op", "nxdomain", "nodata",
"cname", NULL
};
static cfg_type_t cfg_type_rpz_policylist = {
"policies", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,