mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Warning when using --bind-interfaces and routeable addresses.
This commit is contained in:
@@ -632,6 +632,8 @@ int main (int argc, char **argv)
|
||||
|
||||
if (bind_fallback)
|
||||
my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
|
||||
|
||||
warn_bound_listeners();
|
||||
|
||||
if (!option_bool(OPT_NOWILD))
|
||||
for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
|
||||
@@ -856,6 +858,7 @@ int main (int argc, char **argv)
|
||||
enumerate_interfaces(0);
|
||||
/* NB, is_dad_listeners() == 1 --> we're binding interfaces */
|
||||
create_bound_listeners(0);
|
||||
warn_bound_listeners();
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
|
||||
@@ -454,7 +454,7 @@ struct ipsets {
|
||||
struct irec {
|
||||
union mysockaddr addr;
|
||||
struct in_addr netmask; /* only valid for IPv4 */
|
||||
int tftp_ok, dhcp_ok, mtu, done, dad, dns_auth, index, multicast_done;
|
||||
int tftp_ok, dhcp_ok, mtu, done, warned, dad, dns_auth, index, multicast_done;
|
||||
char *name;
|
||||
struct irec *next;
|
||||
};
|
||||
@@ -988,6 +988,7 @@ unsigned char *skip_questions(struct dns_header *header, size_t plen);
|
||||
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
|
||||
char *name, int isExtract, int extrabytes);
|
||||
int in_arpa_name_2_addr(char *namein, struct all_addr *addrp);
|
||||
int private_net(struct in_addr addr, int ban_localhost);
|
||||
|
||||
/* auth.c */
|
||||
#ifdef HAVE_AUTH
|
||||
@@ -1068,6 +1069,7 @@ void check_servers(void);
|
||||
int enumerate_interfaces(int reset);
|
||||
void create_wildcard_listeners(void);
|
||||
void create_bound_listeners(int die);
|
||||
void warn_bound_listeners(void);
|
||||
int is_dad_listeners(void);
|
||||
int iface_check(int family, struct all_addr *addr, char *name, int *auth_dns);
|
||||
int loopback_exception(int fd, int family, struct all_addr *addr, char *name);
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
#include "dnsmasq.h"
|
||||
|
||||
#ifndef IN6_IS_ADDR_ULA
|
||||
#define IN6_IS_ADDR_ULA(a) ((((__const uint32_t *) (a))[0] & htonl (0xfe00000)) == htonl (0xfc000000))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
|
||||
int indextoname(int fd, int index, char *name)
|
||||
@@ -383,7 +387,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
||||
iface->dns_auth = auth_dns;
|
||||
iface->mtu = mtu;
|
||||
iface->dad = dad;
|
||||
iface->done = iface->multicast_done = 0;
|
||||
iface->done = iface->multicast_done = iface->warned = 0;
|
||||
iface->index = if_index;
|
||||
if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1)))
|
||||
{
|
||||
@@ -824,6 +828,59 @@ void create_bound_listeners(int dienow)
|
||||
}
|
||||
}
|
||||
|
||||
/* In --bind-interfaces, the only access control is the addresses we're listening on.
|
||||
There's nothing to avoid a query to the address of an internal interface arriving via
|
||||
an external interface where we don't want to accept queries, except that in the usual
|
||||
case the addresses of internal interfaces are RFC1918. When bind-interfaces in use,
|
||||
and we listen on an address that looks like it's probably globally routeable, shout.
|
||||
|
||||
The fix is to use --bind-dynamic, which actually checks the arrival interface too.
|
||||
Tough if your platform doesn't support this.
|
||||
*/
|
||||
|
||||
void warn_bound_listeners(void)
|
||||
{
|
||||
struct irec *iface;
|
||||
int advice = 0;
|
||||
|
||||
for (iface = daemon->interfaces; iface; iface = iface->next)
|
||||
if (option_bool(OPT_NOWILD) && !iface->dns_auth)
|
||||
{
|
||||
int warn = 0;
|
||||
if (iface->addr.sa.sa_family == AF_INET)
|
||||
{
|
||||
if (!private_net(iface->addr.in.sin_addr, 1))
|
||||
{
|
||||
inet_ntop(AF_INET, &iface->addr.in.sin_addr, daemon->addrbuff, ADDRSTRLEN);
|
||||
warn = 1;
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else
|
||||
{
|
||||
if (!IN6_IS_ADDR_LINKLOCAL(&iface->addr.in6.sin6_addr) &&
|
||||
!IN6_IS_ADDR_SITELOCAL(&iface->addr.in6.sin6_addr) &&
|
||||
!IN6_IS_ADDR_ULA(&iface->addr.in6.sin6_addr) &&
|
||||
!IN6_IS_ADDR_LOOPBACK(&iface->addr.in6.sin6_addr))
|
||||
{
|
||||
inet_ntop(AF_INET6, &iface->addr.in6.sin6_addr, daemon->addrbuff, ADDRSTRLEN);
|
||||
warn = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (warn)
|
||||
{
|
||||
iface->warned = advice = 1;
|
||||
my_syslog(LOG_WARNING,
|
||||
_("LOUD WARNING: listening on %s may accept requests via interfaces other than %s. "),
|
||||
daemon->addrbuff, iface->name);
|
||||
}
|
||||
}
|
||||
|
||||
if (advice)
|
||||
my_syslog(LOG_WARNING, _("LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)."));
|
||||
}
|
||||
|
||||
int is_dad_listeners(void)
|
||||
{
|
||||
struct irec *iface;
|
||||
|
||||
@@ -724,7 +724,7 @@ int check_source(struct dns_header *header, size_t plen, unsigned char *pseudohe
|
||||
}
|
||||
|
||||
/* is addr in the non-globally-routed IP space? */
|
||||
static int private_net(struct in_addr addr, int ban_localhost)
|
||||
int private_net(struct in_addr addr, int ban_localhost)
|
||||
{
|
||||
in_addr_t ip_addr = ntohl(addr.s_addr);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user