Signed-off-by: Matthias Fischer matthias.fischer@ipfire.org --- lfs/dnsmasq | 2 + ...allow_to_exclude_ip_addresses_from_answer.patch | 184 +++++++++++++++++++++ ...rial_when_reloading_etc_hosts_and_friends.patch | 41 +++++ 3 files changed, 227 insertions(+) create mode 100644 src/patches/dnsmasq/013-auth-zone_allow_to_exclude_ip_addresses_from_answer.patch create mode 100644 src/patches/dnsmasq/014-Bump_auth_zone_serial_when_reloading_etc_hosts_and_friends.patch
diff --git a/lfs/dnsmasq b/lfs/dnsmasq index eb0f0ba..474dacc 100644 --- a/lfs/dnsmasq +++ b/lfs/dnsmasq @@ -85,6 +85,8 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/010-Zero_packet_buffers_before_building_output_to_reduce_risk_of_information_leakage.patch cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/011-Dont_reset_packet_length_on_transmission_in_case_of_retransmission.patch cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/012-Compile-time_check_on_buffer_sizes_for_leasefile_parsing_code.patch + cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/013-auth-zone_allow_to_exclude_ip_addresses_from_answer.patch + cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/014-Bump_auth_zone_serial_when_reloading_etc_hosts_and_friends.patch cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq-Add-support-to-read-ISC-DHCP-lease-file.patch
cd $(DIR_APP) && sed -i src/config.h \ diff --git a/src/patches/dnsmasq/013-auth-zone_allow_to_exclude_ip_addresses_from_answer.patch b/src/patches/dnsmasq/013-auth-zone_allow_to_exclude_ip_addresses_from_answer.patch new file mode 100644 index 0000000..bb5fe5d --- /dev/null +++ b/src/patches/dnsmasq/013-auth-zone_allow_to_exclude_ip_addresses_from_answer.patch @@ -0,0 +1,184 @@ +From 094bfaeb4ff69cae99387bc2ea07ff57632c89f5 Mon Sep 17 00:00:00 2001 +From: Mathias Kresin dev@kresin.me +Date: Sun, 24 Jul 2016 14:15:22 +0100 +Subject: [PATCH] auth-zone: allow to exclude ip addresses from answer. + +--- + man/dnsmasq.8 | 6 +++++- + src/auth.c | 61 ++++++++++++++++++++++++++++++++++++--------------------- + src/dnsmasq.h | 1 + + src/option.c | 21 ++++++++++++++++++-- + 4 files changed, 64 insertions(+), 25 deletions(-) + +diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 +index ac8d921..8910947 100644 +--- a/man/dnsmasq.8 ++++ b/man/dnsmasq.8 +@@ -739,7 +739,7 @@ a return code of SERVFAIL. Note that + setting this may affect DNS behaviour in bad ways, it is not an + extra-logging flag and should not be set in production. + .TP +-.B --auth-zone=<domain>[,<subnet>[/<prefix length>][,<subnet>[/<prefix length>].....]] ++.B --auth-zone=<domain>[,<subnet>[/<prefix length>][,<subnet>[/<prefix length>].....][,exclude:<subnet>[/<prefix length>]].....] + Define a DNS zone for which dnsmasq acts as authoritative server. Locally defined DNS records which are in the domain + will be served. If subnet(s) are given, A and AAAA records must be in one of the + specified subnets. +@@ -756,6 +756,10 @@ appear in the zone, but RFC1918 IPv4 addresses which should not. + Interface-name and address-literal subnet specifications may be used + freely in the same --auth-zone declaration. + ++It's possible to exclude certain IP addresses from responses. It can be ++used, to make sure that answers contain only global routeable IP ++addresses (by excluding loopback, RFC1918 and ULA addresses). ++ + The subnet(s) are also used to define in-addr.arpa and + ip6.arpa domains which are served for reverse-DNS queries. If not + specified, the prefix length defaults to 24 for IPv4 and 64 for IPv6. +diff --git a/src/auth.c b/src/auth.c +index 3c5c37f..f1ca2f5 100644 +--- a/src/auth.c ++++ b/src/auth.c +@@ -18,36 +18,53 @@ + + #ifdef HAVE_AUTH + +-static struct addrlist *find_subnet(struct auth_zone *zone, int flag, struct all_addr *addr_u) ++static struct addrlist *find_addrlist(struct addrlist *list, int flag, struct all_addr *addr_u) + { +- struct addrlist *subnet; +- +- for (subnet = zone->subnet; subnet; subnet = subnet->next) +- { +- if (!(subnet->flags & ADDRLIST_IPV6)) +- { +- struct in_addr netmask, addr = addr_u->addr.addr4; +- +- if (!(flag & F_IPV4)) +- continue; +- +- netmask.s_addr = htonl(~(in_addr_t)0 << (32 - subnet->prefixlen)); +- +- if (is_same_net(addr, subnet->addr.addr.addr4, netmask)) +- return subnet; +- } ++ do { ++ if (!(list->flags & ADDRLIST_IPV6)) ++ { ++ struct in_addr netmask, addr = addr_u->addr.addr4; ++ ++ if (!(flag & F_IPV4)) ++ continue; ++ ++ netmask.s_addr = htonl(~(in_addr_t)0 << (32 - list->prefixlen)); ++ ++ if (is_same_net(addr, list->addr.addr.addr4, netmask)) ++ return list; ++ } + #ifdef HAVE_IPV6 +- else if (is_same_net6(&(addr_u->addr.addr6), &subnet->addr.addr.addr6, subnet->prefixlen)) +- return subnet; ++ else if (is_same_net6(&(addr_u->addr.addr6), &list->addr.addr.addr6, list->prefixlen)) ++ return list; + #endif +- +- } ++ ++ } while ((list = list->next)); ++ + return NULL; + } + ++static struct addrlist *find_subnet(struct auth_zone *zone, int flag, struct all_addr *addr_u) ++{ ++ if (!zone->subnet) ++ return NULL; ++ ++ return find_addrlist(zone->subnet, flag, addr_u); ++} ++ ++static struct addrlist *find_exclude(struct auth_zone *zone, int flag, struct all_addr *addr_u) ++{ ++ if (!zone->exclude) ++ return NULL; ++ ++ return find_addrlist(zone->exclude, flag, addr_u); ++} ++ + static int filter_zone(struct auth_zone *zone, int flag, struct all_addr *addr_u) + { +- /* No zones specified, no filter */ ++ if (find_exclude(zone, flag, addr_u)) ++ return 0; ++ ++ /* No subnets specified, no filter */ + if (!zone->subnet) + return 1; + +diff --git a/src/dnsmasq.h b/src/dnsmasq.h +index 2bda5d0..27385a9 100644 +--- a/src/dnsmasq.h ++++ b/src/dnsmasq.h +@@ -340,6 +340,7 @@ struct auth_zone { + struct auth_name_list *next; + } *interface_names; + struct addrlist *subnet; ++ struct addrlist *exclude; + struct auth_zone *next; + }; + +diff --git a/src/option.c b/src/option.c +index d8c57d6..6cedef3 100644 +--- a/src/option.c ++++ b/src/option.c +@@ -1906,6 +1906,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma + new = opt_malloc(sizeof(struct auth_zone)); + new->domain = opt_string_alloc(arg); + new->subnet = NULL; ++ new->exclude = NULL; + new->interface_names = NULL; + new->next = daemon->auth_zones; + daemon->auth_zones = new; +@@ -1913,6 +1914,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma + while ((arg = comma)) + { + int prefixlen = 0; ++ int is_exclude = 0; + char *prefix; + struct addrlist *subnet = NULL; + struct all_addr addr; +@@ -1923,6 +1925,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma + if (prefix && !atoi_check(prefix, &prefixlen)) + ret_err(gen_err); + ++ if (strstr(arg, "exclude:") == arg) ++ { ++ is_exclude = 1; ++ arg = arg+8; ++ } ++ + if (inet_pton(AF_INET, arg, &addr.addr.addr4)) + { + subnet = opt_malloc(sizeof(struct addrlist)); +@@ -1960,8 +1968,17 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma + if (subnet) + { + subnet->addr = addr; +- subnet->next = new->subnet; +- new->subnet = subnet; ++ ++ if (is_exclude) ++ { ++ subnet->next = new->exclude; ++ new->exclude = subnet; ++ } ++ else ++ { ++ subnet->next = new->subnet; ++ new->subnet = subnet; ++ } + } + } + break; +-- +1.7.10.4 + diff --git a/src/patches/dnsmasq/014-Bump_auth_zone_serial_when_reloading_etc_hosts_and_friends.patch b/src/patches/dnsmasq/014-Bump_auth_zone_serial_when_reloading_etc_hosts_and_friends.patch new file mode 100644 index 0000000..054323b --- /dev/null +++ b/src/patches/dnsmasq/014-Bump_auth_zone_serial_when_reloading_etc_hosts_and_friends.patch @@ -0,0 +1,41 @@ +From c8328ecde896575b3cb81cf537747df531f90771 Mon Sep 17 00:00:00 2001 +From: Simon Kelley simon@thekelleys.org.uk +Date: Fri, 5 Aug 2016 16:54:58 +0100 +Subject: [PATCH] Bump auth zone serial when reloading /etc/hosts and friends. + +--- + CHANGELOG | 4 ++++ + src/dnsmasq.c | 2 ++ + 2 files changed, 6 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 9f1e404..4f89799 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -20,6 +20,10 @@ version 2.77 + Fix problem with --dnssec-timestamp whereby receipt + of SIGHUP would erroneously engage timestamp checking. + Thanks to Kevin Darbyshire-Bryant for this work. ++ ++ Bump zone serial on reloading /etc/hosts and friends ++ when providing authoritative DNS. Thanks to Harrald ++ Dunkel for spotting this. + + + version 2.76 +diff --git a/src/dnsmasq.c b/src/dnsmasq.c +index a47273f..3580bea 100644 +--- a/src/dnsmasq.c ++++ b/src/dnsmasq.c +@@ -1226,6 +1226,8 @@ static void async_event(int pipe, time_t now) + switch (ev.event) + { + case EVENT_RELOAD: ++ daemon->soa_sn++; /* Bump zone serial, as it may have changed. */ ++ + #ifdef HAVE_DNSSEC + if (daemon->dnssec_no_time_check && option_bool(OPT_DNSSEC_VALID) && option_bool(OPT_DNSSEC_TIME)) + { +-- +1.7.10.4 +