Commit Diff
Diff:
7dcbf7dc0d5b65e90653e939ce6b13d3484427bc
ef111c479b0725f2b7a11392a07fb4f31d0ede8d
Commit:
ef111c479b0725f2b7a11392a07fb4f31d0ede8d
Tree:
7eba99bd2aef94a21f04b80974bcc56c874055bb
Author:
pjp <pjp@delphinusdns.org>
Committer:
pjp <pjp@delphinusdns.org>
Date:
Thu Sep 24 05:15:23 2020 UTC
Message:
add a bytelimit to rzone to limit how much one can AXFR from a remote site. Unfortunately this won't prevent a disk to fill up in most circumstances, but may give an operator more time to notice what's going on. It surely will prevent memory exhaustion if used carefully.
blob - 8f9095e60ec37973d419321208792b1cb9103ed1
blob + 08cc036ea12d8571e99c949ddd02f44895056d37
--- CHANGES
+++ CHANGES
@@ -21,13 +21,17 @@ Changes in RELEASE_1_5 from RELEASE_1_4
more security out of this
- in dddctl query allow a class to be specified (-c)
- added RP, HINFO and CAA RR support in all areas except dddctl query
-- added extra security measure to prevent DNS poisoning by AXFR
- add a SOA constraint on rzone's to constrain SOA refresh/retry/expire values
by default these are 60/60/60
- terminology changes blacklist->blocklist, whitelist->passlist,
anything_slave() to anything_ddd(), to keep with the times
- made the 3G database truly RW (before there was some memcpy'ing going on
that corrupted pointers making the databse RO).
+- added extra security measure to prevent DNS poisoning by AXFR
+- added a bytelimit to how much one can AXFR from a remote site. Unfortunately
+ this won't prevent a disk to fill up in most circumstances, but may give
+ an operator more time to notice what's going on. It surely will prevent
+ memory exhaustion if used carefully.
- improve on the speed of AXFR's for very large databases (tested on 1.4 million AAAA records, 2 seconds vs. 120 seconds).
[2019] Changes in RELEASE_1_4 from RELEASE_1_3
blob - 5f7f839d9bfddcd562462173525943a2804425af
blob + 90b1ef0818b660af5efc78d6eca81b4e72b68fc9
--- ddd-db.h
+++ ddd-db.h
@@ -27,7 +27,7 @@
*/
/*
- * $Id: ddd-db.h,v 1.54 2020/09/06 07:38:00 pjp Exp $
+ * $Id: ddd-db.h,v 1.55 2020/09/24 05:15:23 pjp Exp $
*/
#ifndef _DB_H
@@ -448,6 +448,7 @@ struct rzone {
char *filename;
struct soa soa;
struct soa_constraints constraints;
+ uint32_t bytelimit;
} *rz, *rz0;
struct raxfr_logic {
blob - 7d9c50c5bff9c7b49c5b802352b08a14c1d945ab
blob + a9b55f18f572625b916d84cb7eb1036ff7af83cd
--- delphinusdns.conf.5
+++ delphinusdns.conf.5
@@ -167,6 +167,7 @@ include "/etc/delphinusdns/delphinusdns.tsig";
rzone "ip6.centroid.eu." {
constraints 600, 600, 600;
+ bytelimit 65536;
; do make sure you have a tsig "" {} for this
tsigkey "pass";
masterport 10053;
@@ -229,7 +230,7 @@ tsig = "tsig" ("string") [ "{" cidrlist "}" ]
rzone = "rzone" ("string") [ "{" rzonelist "}" ]
rzonelist = ( opttsig | optmaster | optmasterport | optrzonename |
- optfilename | optconstraints )
+ optfilename | optconstraints | optbytelimit )
opttsig = "tsigkey" ("string") ;
optmaster = "master" ("cidr-address") ;
@@ -237,6 +238,7 @@ optmasterport = "masterport" (number) ;
optrzonename = "zonename" ("string") ;
optfilename = "filename" ("string") ;
optconstraints = "constraints" (number), (number), (number) ;
+optbytelimit = "bytelimit" (number) ;
forward = "forward" ("string") [ "{" forwardlist "}" ]
blob - f6d811366d066a252005ef2cfbf5eaa086045044
blob + 383124bcf4d511dc110b01ef69e093b6c95125b0
--- parse.y
+++ parse.y
@@ -21,7 +21,7 @@
*/
/*
- * $Id: parse.y,v 1.114 2020/08/26 07:17:26 pjp Exp $
+ * $Id: parse.y,v 1.115 2020/09/24 05:15:23 pjp Exp $
*/
%{
@@ -259,6 +259,7 @@ int drop_privs(char *, struct passwd *);
%token PASSLIST ZINCLUDE MASTER MASTERPORT TSIGAUTH
%token TSIG NOTIFYDEST NOTIFYBIND PORT FORWARD
%token INCOMINGTSIG DESTINATION CACHE STRICTX20
+%token BYTELIMIT
%token <v.string> POUND
%token <v.string> SEMICOLON
@@ -796,6 +797,17 @@ rzonestatement:
free ($1);
}
+ |
+ BYTELIMIT NUMBER SEMICOLON CRLF
+ {
+ rz = SLIST_FIRST(&rzones);
+ if (rz == NULL) {
+ return -1;
+ }
+
+ rz->active = 1;
+ rz->bytelimit = $2;
+ }
| comment CRLF
;
@@ -1752,6 +1764,7 @@ struct tab {
struct tab cmdtab[] = {
{ "axfrport", AXFRPORT, 0},
{ "axfr-for", AXFRFOR, STATE_IP },
+ { "bytelimit", BYTELIMIT, 0 },
{ "cache", CACHE, 0 },
{ "destination", DESTINATION, 0 },
{ "filter", FILTER, STATE_IP },
@@ -3869,6 +3882,7 @@ add_rzone(void)
lrz->constraints.refresh = 60;
lrz->constraints.retry = 60;
lrz->constraints.expire = 60;
+ lrz->bytelimit = (1024 * 1024 * 64); /* 64 MB */
SLIST_INSERT_HEAD(&rzones, lrz, rzone_entry);
blob - 5760c21f6f64a82f1811eaecbf61f6a1115989c1
blob + e6d7916ef6ab59a91b148abd3c560e72d7914a65
--- query.c
+++ query.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: query.c,v 1.13 2020/07/27 08:23:04 pjp Exp $
+ * $Id: query.c,v 1.14 2020/09/24 05:15:23 pjp Exp $
*/
#include <sys/types.h>
@@ -164,7 +164,7 @@ extern int raxfr_peek(FILE *, u_char *, u_char *, u_ch
extern int memcasecmp(u_char *, u_char *, int);
extern int tsig_pseudoheader(char *, uint16_t, time_t, HMAC_CTX *);
-extern int lookup_axfr(FILE *, int, char *, struct soa *, u_int32_t, char *, char *, int *, int *, int *, struct soa_constraints *);
+extern int lookup_axfr(FILE *, int, char *, struct soa *, u_int32_t, char *, char *, int *, int *, int *, struct soa_constraints *, uint32_t);
extern int insert_tsig(char *, char *);
extern int find_tsig_key(char *, int, char *, int);
extern int insert_tsig_key(char *, int, char *);
@@ -342,7 +342,7 @@ dig(int argc, char *argv[])
if ((format & ZONE_FORMAT) && f != NULL)
fprintf(f, "zone \"%s\" {\n", domainname);
- if (lookup_axfr(f, so, domainname, &mysoa, format, tsigkey, tsigpass, &segment, &answers, &additionalcount, &constraints) < 0) {
+ if (lookup_axfr(f, so, domainname, &mysoa, format, tsigkey, tsigpass, &segment, &answers, &additionalcount, &constraints, 0xffffffff) < 0) {
exit(1);
}
blob - e24983585873dca4d65c42823f661a03da379b7c
blob + 58dbb0cb2ac918912d178799a2d6d8f03fbb36b2
--- raxfr.c
+++ raxfr.c
@@ -26,7 +26,7 @@
*
*/
/*
- * $Id: raxfr.c,v 1.62 2020/08/08 05:51:48 pjp Exp $
+ * $Id: raxfr.c,v 1.63 2020/09/24 05:15:23 pjp Exp $
*/
#include <sys/types.h>
@@ -165,7 +165,7 @@ extern void dolog(int, char *, ...);
extern struct rbtree * find_rrset(ddDB *db, char *name, int namelen);
extern struct rrset * find_rr(struct rbtree *rbt, u_int16_t rrtype);
extern struct question *build_question(char *, int, int, char *);
-extern int lookup_axfr(FILE *, int, char *, struct soa *, u_int32_t, char *, char *, int *, int *, int *, struct soa_constraints *);
+extern int lookup_axfr(FILE *, int, char *, struct soa *, u_int32_t, char *, char *, int *, int *, int *, struct soa_constraints *, uint32_t);
extern int find_tsig_key(char *, int, char *, int);
extern int tsig_pseudoheader(char *, uint16_t, time_t, HMAC_CTX *);
@@ -2342,7 +2342,7 @@ do_raxfr(FILE *f, struct rzone *rzone)
if ((format & ZONE_FORMAT) && f != NULL)
fprintf(f, "zone \"%s\" {\n", rzone->zonename);
- if (lookup_axfr(f, so, rzone->zonename, &mysoa, format, ((dotsig == 0) ? NULL : rzone->tsigkey), humanpass, &segment, &answers, &additionalcount, &rzone->constraints) < 0) {
+ if (lookup_axfr(f, so, rzone->zonename, &mysoa, format, ((dotsig == 0) ? NULL : rzone->tsigkey), humanpass, &segment, &answers, &additionalcount, &rzone->constraints, rzone->bytelimit) < 0) {
/* close the zone */
if ((format & ZONE_FORMAT) && f != NULL)
fprintf(f, "}\n");
blob - d26b3c1e502b7bf85c0daf89bcc206091e787926
blob + c5cdc088853b4503a3eb956974bc25386ddf0306
--- util.c
+++ util.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: util.c,v 1.82 2020/08/08 05:51:48 pjp Exp $
+ * $Id: util.c,v 1.83 2020/09/24 05:15:23 pjp Exp $
*/
#include <sys/types.h>
@@ -118,7 +118,7 @@ int tsig_pseudoheader(char *, uint16_t, time_t, HMAC_C
char * bin2hex(char *, int);
u_int64_t timethuman(time_t);
char * bitmap2human(char *, int);
-int lookup_axfr(FILE *, int, char *, struct soa *, u_int32_t, char *, char *, int *, int *, int *, struct soa_constraints *);
+int lookup_axfr(FILE *, int, char *, struct soa *, u_int32_t, char *, char *, int *, int *, int *, struct soa_constraints *, uint32_t);
int dn_contains(char *name, int len, char *anchorname, int alen);
uint16_t udp_cksum(u_int16_t *, uint16_t, struct ip *, struct udphdr *);
uint16_t udp_cksum6(u_int16_t *, uint16_t, struct ip6_hdr *, struct udphdr *);
@@ -1825,7 +1825,7 @@ bitmap2human(char *bitmap, int len)
int
-lookup_axfr(FILE *f, int so, char *zonename, struct soa *mysoa, u_int32_t format, char *tsigkey, char *tsigpass, int *segment, int *answers, int *additionalcount, struct soa_constraints *constraints)
+lookup_axfr(FILE *f, int so, char *zonename, struct soa *mysoa, u_int32_t format, char *tsigkey, char *tsigpass, int *segment, int *answers, int *additionalcount, struct soa_constraints *constraints, uint32_t bytelimit)
{
char query[512];
char pseudo_packet[512];
@@ -2013,7 +2013,8 @@ lookup_axfr(FILE *f, int so, char *zonename, struct so
return -1;
}
- /* catch reply */
+ /* catch reply, totallen is reused here */
+ totallen = 0;
reply = calloc(1, 0xffff + 2);
if (reply == NULL) {
@@ -2073,6 +2074,14 @@ lookup_axfr(FILE *f, int so, char *zonename, struct so
perror("recv");
return -1;
}
+
+ totallen += len;
+
+ if (totallen >= bytelimit) {
+ fprintf(stderr, "download exceeded byte limit\n");
+ return -1;
+ }
+
rwh = (struct whole_header *)&reply[0];
bytes_received += ntohs(rwh->len);
repomaster@centroid.eu