[v9_10] further restrict update-policy local
4762. [func] "update-policy local" is now restricted to updates
from local addresses. (Previously, other addresses
were allowed so long as updates were signed by the
local session key.) [RT #45492]
This commit is contained in:
@@ -171,6 +171,7 @@ EXTERN isc_boolean_t ns_g_notcp INIT(ISC_FALSE);
|
||||
EXTERN isc_boolean_t ns_g_disable6 INIT(ISC_FALSE);
|
||||
EXTERN isc_boolean_t ns_g_disable4 INIT(ISC_FALSE);
|
||||
EXTERN unsigned int ns_g_tat_interval INIT(24*3600);
|
||||
EXTERN isc_boolean_t ns_g_fixedlocal INIT(ISC_FALSE);
|
||||
|
||||
|
||||
#ifdef HAVE_GEOIP
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: interfacemgr.c,v 1.101 2011/11/09 18:44:03 each Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
#include <config.h>
|
||||
@@ -949,11 +947,22 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
|
||||
}
|
||||
|
||||
if (adjusting == ISC_FALSE) {
|
||||
/*
|
||||
* If running with -T fixedlocal, then we only
|
||||
* want 127.0.0.1 and ::1 in the localhost ACL.
|
||||
*/
|
||||
if (ns_g_fixedlocal &&
|
||||
!isc_netaddr_isloopback(&interface.address))
|
||||
{
|
||||
goto listenon;
|
||||
}
|
||||
|
||||
result = setup_locals(mgr, &interface);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto ignore_interface;
|
||||
}
|
||||
|
||||
listenon:
|
||||
ll = (family == AF_INET) ? mgr->listenon4 : mgr->listenon6;
|
||||
dolistenon = ISC_TRUE;
|
||||
for (le = ISC_LIST_HEAD(ll->elts);
|
||||
|
||||
@@ -611,17 +611,25 @@ parse_command_line(int argc, char *argv[]) {
|
||||
dns_zone_mkey_month = atoi(p);
|
||||
if (dns_zone_mkey_month < dns_zone_mkey_day)
|
||||
ns_main_earlyfatal("bad mkeytimer");
|
||||
} else if (!strcmp(isc_commandline_argument, "notcp"))
|
||||
} else if (!strcmp(isc_commandline_argument, "notcp")) {
|
||||
ns_g_notcp = ISC_TRUE;
|
||||
else if (!strncmp(isc_commandline_argument, "tat=", 4))
|
||||
} else if (!strncmp(isc_commandline_argument,
|
||||
"tat=", 4))
|
||||
{
|
||||
ns_g_tat_interval =
|
||||
atoi(isc_commandline_argument + 4);
|
||||
else if (!strcmp(isc_commandline_argument,
|
||||
"keepstderr"))
|
||||
} else if (!strcmp(isc_commandline_argument,
|
||||
"keepstderr"))
|
||||
{
|
||||
ns_g_keepstderr = ISC_TRUE;
|
||||
else
|
||||
} else if (!strcmp(isc_commandline_argument,
|
||||
"fixedlocal"))
|
||||
{
|
||||
ns_g_fixedlocal = ISC_TRUE;
|
||||
} else {
|
||||
fprintf(stderr, "unknown -T flag '%s\n",
|
||||
isc_commandline_argument);
|
||||
}
|
||||
break;
|
||||
case 'U':
|
||||
ns_g_udpdisp = parse_int(isc_commandline_argument,
|
||||
|
||||
@@ -813,8 +813,11 @@ typedef struct {
|
||||
/* The signature's name if the request was signed. */
|
||||
dns_name_t *signer;
|
||||
|
||||
/* The address of the client if the request was received via TCP. */
|
||||
isc_netaddr_t *tcpaddr;
|
||||
/* The address of the client. */
|
||||
isc_netaddr_t *addr;
|
||||
|
||||
/* Whether the request was sent via TCP. */
|
||||
isc_boolean_t tcp;
|
||||
|
||||
/* The ssu table to check against. */
|
||||
dns_ssutable_t *table;
|
||||
@@ -835,16 +838,17 @@ ssu_checkrule(void *data, dns_rdataset_t *rrset) {
|
||||
if (rrset->type == dns_rdatatype_rrsig ||
|
||||
rrset->type == dns_rdatatype_nsec)
|
||||
return (ISC_R_SUCCESS);
|
||||
result = dns_ssutable_checkrules(ssuinfo->table, ssuinfo->signer,
|
||||
ssuinfo->name, ssuinfo->tcpaddr,
|
||||
rrset->type, ssuinfo->key);
|
||||
result = dns_ssutable_checkrules2(ssuinfo->table, ssuinfo->signer,
|
||||
ssuinfo->name, ssuinfo->addr,
|
||||
ssuinfo->tcp, &ns_g_server->aclenv,
|
||||
rrset->type, ssuinfo->key);
|
||||
return (result == ISC_TRUE ? ISC_R_SUCCESS : ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
ssu_checkall(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
|
||||
dns_ssutable_t *ssutable, dns_name_t *signer,
|
||||
isc_netaddr_t *tcpaddr, dst_key_t *key)
|
||||
isc_netaddr_t *addr, isc_boolean_t tcp, dst_key_t *key)
|
||||
{
|
||||
isc_result_t result;
|
||||
ssu_check_t ssuinfo;
|
||||
@@ -852,7 +856,8 @@ ssu_checkall(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
|
||||
ssuinfo.name = name;
|
||||
ssuinfo.table = ssutable;
|
||||
ssuinfo.signer = signer;
|
||||
ssuinfo.tcpaddr = tcpaddr;
|
||||
ssuinfo.addr = addr;
|
||||
ssuinfo.tcp = tcp;
|
||||
ssuinfo.key = key;
|
||||
result = foreach_rrset(db, ver, name, ssu_checkrule, &ssuinfo);
|
||||
return (ISC_TF(result == ISC_R_SUCCESS));
|
||||
@@ -2686,38 +2691,33 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
|
||||
if (ssutable != NULL) {
|
||||
isc_netaddr_t *tcpaddr, netaddr;
|
||||
isc_netaddr_t netaddr;
|
||||
dst_key_t *tsigkey = NULL;
|
||||
/*
|
||||
* If this is a TCP connection then pass the
|
||||
* address of the client through for tcp-self
|
||||
* and 6to4-self otherwise pass NULL. This
|
||||
* provides weak address based authentication.
|
||||
*/
|
||||
if (TCPCLIENT(client)) {
|
||||
isc_netaddr_fromsockaddr(&netaddr,
|
||||
&client->peeraddr);
|
||||
tcpaddr = &netaddr;
|
||||
} else
|
||||
tcpaddr = NULL;
|
||||
isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
|
||||
|
||||
if (client->message->tsigkey != NULL)
|
||||
tsigkey = client->message->tsigkey->key;
|
||||
|
||||
if (rdata.type != dns_rdatatype_any) {
|
||||
if (!dns_ssutable_checkrules(ssutable,
|
||||
client->signer,
|
||||
name, tcpaddr,
|
||||
rdata.type,
|
||||
tsigkey))
|
||||
if (!dns_ssutable_checkrules2
|
||||
(ssutable, client->signer, name, &netaddr,
|
||||
ISC_TF(TCPCLIENT(client)),
|
||||
&ns_g_server->aclenv,
|
||||
rdata.type, tsigkey))
|
||||
{
|
||||
FAILC(DNS_R_REFUSED,
|
||||
"rejected by secure update");
|
||||
}
|
||||
} else {
|
||||
if (!ssu_checkall(db, ver, name, ssutable,
|
||||
client->signer, tcpaddr,
|
||||
client->signer,
|
||||
&netaddr,
|
||||
ISC_TF(TCPCLIENT(client)),
|
||||
tsigkey))
|
||||
{
|
||||
FAILC(DNS_R_REFUSED,
|
||||
"rejected by secure update");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,7 +378,7 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
|
||||
|
||||
result = dns_ssutable_addrule(table, ISC_TRUE,
|
||||
ns_g_server->session_keyname,
|
||||
DNS_SSUMATCHTYPE_SUBDOMAIN,
|
||||
DNS_SSUMATCHTYPE_LOCAL,
|
||||
dns_zone_getorigin(zone),
|
||||
1, &any);
|
||||
|
||||
|
||||
@@ -20,13 +20,12 @@
|
||||
#
|
||||
|
||||
rm -f */named.memstats
|
||||
rm -f */named.run
|
||||
rm -f */named.run */ans.run
|
||||
rm -f Kxxx.*
|
||||
rm -f dig.out.*
|
||||
rm -f jp.out.ns3.*
|
||||
rm -f ns*/named.lock
|
||||
rm -f ns1/*.jnl ns2/*.jnl ns3/*.jnl
|
||||
rm -f ns1/example.db ns1/unixtime.db ns1/update.db ns1/other.db ns1/keytests.db
|
||||
rm -f */*.jnl
|
||||
rm -f ns1/example.db ns1/unixtime.db ns1/yyyymmddvv.db ns1/update.db ns1/other.db ns1/keytests.db
|
||||
rm -f ns1/many.test.db
|
||||
rm -f ns1/md5.key ns1/sha1.key ns1/sha224.key ns1/sha256.key ns1/sha384.key
|
||||
@@ -42,6 +41,7 @@ rm -f ns3/example.db
|
||||
rm -f ns3/many.test.bk
|
||||
rm -f ns3/nsec3param.test.db
|
||||
rm -f ns3/too-big.test.db
|
||||
rm -f ns5/local.db
|
||||
rm -f nsupdate.out*
|
||||
rm -f typelist.out.*
|
||||
rm -f ns1/sample.db
|
||||
|
||||
20
bin/tests/system/nsupdate/ns5/local.db.in
Normal file
20
bin/tests/system/nsupdate/ns5/local.db.in
Normal file
@@ -0,0 +1,20 @@
|
||||
; Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
$ORIGIN .
|
||||
$TTL 300 ; 5 minutes
|
||||
local.nil IN SOA ns5.local.nil. hostmaster.local.nil. (
|
||||
1 ; serial
|
||||
2000 ; refresh (2000 seconds)
|
||||
2000 ; retry (2000 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
local.nil. NS ns5.local.nil.
|
||||
ns5.local.nil. A 10.53.0.5
|
||||
|
||||
$ORIGIN local.nil.
|
||||
a A 10.10.10.10
|
||||
1
bin/tests/system/nsupdate/ns5/named.args
Normal file
1
bin/tests/system/nsupdate/ns5/named.args
Normal file
@@ -0,0 +1 @@
|
||||
-m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T fixedlocal
|
||||
37
bin/tests/system/nsupdate/ns5/named.conf
Normal file
37
bin/tests/system/nsupdate/ns5/named.conf
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
controls { /* empty */ };
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.5;
|
||||
notify-source 10.53.0.5;
|
||||
transfer-source 10.53.0.5;
|
||||
port 5300;
|
||||
pid-file "named.pid";
|
||||
session-keyfile "session.key";
|
||||
listen-on { 10.53.0.5; };
|
||||
recursion no;
|
||||
notify yes;
|
||||
minimal-responses no;
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-sha256;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.5 port 9953 allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
zone "local.nil" {
|
||||
type master;
|
||||
file "local.db";
|
||||
update-policy local;
|
||||
};
|
||||
@@ -66,3 +66,5 @@ $DDNSCONFGEN -q -r $RANDFILE -a hmac-sha512 -k sha512-key -z keytests.nil > ns1/
|
||||
|
||||
cp ns1/sample.db.in ns1/sample.db
|
||||
cp ns2/sample.db.in ns2/sample.db
|
||||
|
||||
cp -f ns5/local.db.in ns5/local.db
|
||||
|
||||
@@ -475,6 +475,44 @@ then
|
||||
echo "I:failed"; status=1
|
||||
fi
|
||||
|
||||
n=`expr $n + 1`
|
||||
ret=0
|
||||
echo "I:check that 'update-policy local' works from localhost address ($n)"
|
||||
$NSUPDATE -p 5300 -k ns5/session.key > nsupdate.out.$n 2>&1 << END || ret=1
|
||||
server 10.53.0.5 5300
|
||||
local 127.0.0.1 5300
|
||||
update add fromlocal.local.nil. 600 A 1.2.3.4
|
||||
send
|
||||
END
|
||||
grep REFUSED nsupdate.out.$n > /dev/null 2>&1 && ret=1
|
||||
$DIG @10.53.0.5 -p 5300 \
|
||||
+tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
|
||||
fromlocal.local.nil. > dig.out.ns5.$n || ret=1
|
||||
grep fromlocal dig.out.ns5.$n > /dev/null 2>&1 || ret=1
|
||||
if test $ret -ne 0
|
||||
then
|
||||
echo "I:failed"; status=1
|
||||
fi
|
||||
|
||||
n=`expr $n + 1`
|
||||
ret=0
|
||||
echo "I:check that 'update-policy local' fails from non-localhost address ($n)"
|
||||
$NSUPDATE -p 5300 -k ns5/session.key > nsupdate.out.$n 2>&1 << END && ret=1
|
||||
server 10.53.0.5 5300
|
||||
local 10.53.0.1 5300
|
||||
update add nonlocal.local.nil. 600 A 4.3.2.1
|
||||
send
|
||||
END
|
||||
grep REFUSED nsupdate.out.$n > /dev/null 2>&1 || ret=1
|
||||
$DIG @10.53.0.5 -p 5300 \
|
||||
+tcp +noadd +nosea +nostat +noquest +nocomm +nocmd \
|
||||
nonlocal.local.nil. > dig.out.ns5.$n || ret=1
|
||||
grep nonlocal dig.out.ns5.$n > /dev/null 2>&1 && ret=1
|
||||
if test $ret -ne 0
|
||||
then
|
||||
echo "I:failed"; status=1
|
||||
fi
|
||||
|
||||
n=`expr $n + 1`
|
||||
ret=0
|
||||
echo "I:check that changes to the DNSKEY RRset TTL do not have side effects ($n)"
|
||||
|
||||
Reference in New Issue
Block a user