Commit 501941f0 authored by Evan Hunt's avatar Evan Hunt
Browse files

[master] add geoip support

3504.	[func]		Add support for ACLs based on geographic location,
			using MaxMind GeoIP databases. Based on code
			contributed by Ken Brownfield <kb@slide.com>.
			[RT #30681]
parent dad65f7c
3504. [func] Add support for ACLs based on geographic location,
using MaxMind GeoIP databases. Based on code
contributed by Ken Brownfield <kb@slide.com>.
[RT #30681]
3503. [doc] Clarify size_spec syntax. [RT #32449]
3502. [func] zone-statistics: "no" is now a synonym for "none",
......
......@@ -82,7 +82,7 @@ SUBDIRS = unix
TARGETS = named@EXEEXT@ lwresd@EXEEXT@
OBJS = builtin.@O@ client.@O@ config.@O@ control.@O@ \
controlconf.@O@ interfacemgr.@O@ \
controlconf.@O@ geoip.@O@ interfacemgr.@O@ \
listenlist.@O@ log.@O@ logconf.@O@ main.@O@ notify.@O@ \
query.@O@ server.@O@ sortlist.@O@ statschannel.@O@ \
tkeyconf.@O@ tsigconf.@O@ update.@O@ xfrout.@O@ \
......@@ -96,7 +96,7 @@ UOBJS = unix/os.@O@ unix/dlz_dlopen_driver.@O@
SYMOBJS = symtbl.@O@
SRCS = builtin.c client.c config.c control.c \
controlconf.c interfacemgr.c \
controlconf.c geoip.c interfacemgr.c \
listenlist.c log.c logconf.c main.c notify.c \
query.c server.c sortlist.c statschannel.c symtbl.c symtbl-empty.c \
tkeyconf.c tsigconf.c update.c xfrout.c \
......
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*! \file */
#include <config.h>
#ifdef HAVE_GEOIP
#include <named/log.h>
#include <named/geoip.h>
#include <dns/geoip.h>
#include <GeoIP.h>
static dns_geoip_databases_t geoip_table = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static void
init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition,
GeoIPOptions method, const char *name)
{
char *info;
GeoIP *db;
REQUIRE(dbp != NULL);
db = *dbp;
if (db != NULL) {
GeoIP_delete(db);
db = *dbp = NULL;
}
if (! GeoIP_db_avail(edition)) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
"GeoIP %s DB not available", name);
return;
}
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
"initializing GeoIP %s DB", name);
db = GeoIP_open_type(edition, method);
if (db == NULL) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"failed to initialize GeoIP %s DB; "
"geoip matches using this database will fail",
name);
return;
}
info = GeoIP_database_info(db);
if (info != NULL)
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
"%s", info);
*dbp = db;
}
static GeoIPDBTypes
choose_rev(GeoIPDBTypes primary, GeoIPDBTypes secondary, const char *name) {
if (GeoIP_db_avail(primary))
return (primary);
if (GeoIP_db_avail(secondary))
return (secondary);
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
"GeoIP %s DB: neither revision available", name);
return (0);
}
#endif /* HAVE_GEOIP */
void
ns_geoip_init(void) {
#ifndef HAVE_GEOIP
return;
#else
if (ns_g_geoip == NULL)
ns_g_geoip = &geoip_table;
#endif
}
void
ns_geoip_load(char *dir) {
#ifndef HAVE_GEOIP
return;
#else
GeoIPOptions method;
GeoIPDBTypes edition;
#ifdef _WIN32
method = GEOIP_STANDARD;
#else
method = GEOIP_MMAP_CACHE;
#endif
ns_geoip_init();
if (dir != NULL) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
"using \"%s\" as GeoIP directory", dir);
GeoIP_setup_custom_directory(dir);
}
init_geoip_db(&ns_g_geoip->country_v4, GEOIP_COUNTRY_EDITION,
method, "Country (IPv4)");
#ifdef HAVE_GEOIP_V6
init_geoip_db(&ns_g_geoip->country_v6, GEOIP_COUNTRY_EDITION_V6,
method, "Country (IPv6)");
#endif
edition = choose_rev(GEOIP_CITY_EDITION_REV0,
GEOIP_CITY_EDITION_REV1, "City (IPv4)");
if (edition != 0)
init_geoip_db(&ns_g_geoip->city_v4, edition,
method, "City (IPv4)");
#if defined(HAVE_GEOIP_V6) && defined(HAVE_GEOIP_CITY_V6)
edition = choose_rev(GEOIP_CITY_EDITION_REV0_V6,
GEOIP_CITY_EDITION_REV1_V6, "City (IPv6)");
if (edition != 0)
init_geoip_db(&ns_g_geoip->city_v6, edition,
method, "City (IPv6)");
#endif
edition = choose_rev(GEOIP_REGION_EDITION_REV0,
GEOIP_REGION_EDITION_REV1, "Region");
if (edition != 0)
init_geoip_db(&ns_g_geoip->region, edition, method, "Region");
init_geoip_db(&ns_g_geoip->isp, GEOIP_ISP_EDITION,
method, "ISP");
init_geoip_db(&ns_g_geoip->org, GEOIP_ORG_EDITION,
method, "Org");
init_geoip_db(&ns_g_geoip->as, GEOIP_ASNUM_EDITION,
method, "AS");
init_geoip_db(&ns_g_geoip->domain, GEOIP_DOMAIN_EDITION,
method, "Domain");
init_geoip_db(&ns_g_geoip->netspeed, GEOIP_NETSPEED_EDITION,
method, "NetSpeed");
#endif /* HAVE_GEOIP */
}
#ifndef _GEOIP_H
#define _GEOIP_H
#ifdef HAVE_GEOIP
#include <GeoIP.h>
#include <GeoIPCity.h>
void ns_geoip_init(void);
void ns_geoip_load(char *dir);
extern dns_geoip_databases_t *ns_g_geoip;
#endif /* HAVE_GEOIP */
#endif
......@@ -29,6 +29,7 @@
#include <isccfg/aclconf.h>
#include <isccfg/cfg.h>
#include <dns/acl.h>
#include <dns/zone.h>
#include <dst/dst.h>
......@@ -161,6 +162,10 @@ EXTERN isc_boolean_t ns_g_noaa INIT(ISC_FALSE);
EXTERN unsigned int ns_g_delay INIT(0);
EXTERN isc_boolean_t ns_g_nonearest INIT(ISC_FALSE);
#ifdef HAVE_GEOIP
EXTERN dns_geoip_databases_t *ns_g_geoip INIT(NULL);
#endif
#undef EXTERN
#undef INIT
......
......@@ -106,6 +106,9 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
result = dns_aclenv_init(mctx, &mgr->aclenv);
if (result != ISC_R_SUCCESS)
goto cleanup_listenon;
#ifdef HAVE_GEOIP
mgr->aclenv.geoip = ns_g_geoip;
#endif
mgr->references = 1;
mgr->magic = IFMGR_MAGIC;
......
......@@ -95,6 +95,7 @@
#include <named/client.h>
#include <named/config.h>
#include <named/control.h>
#include <named/geoip.h>
#include <named/interfacemgr.h>
#include <named/log.h>
#include <named/logconf.h>
......@@ -110,6 +111,9 @@
#include <named/ns_smf_globals.h>
#include <stdlib.h>
#endif
#ifdef HAVE_GEOIP
#include <named/geoip.h>
#endif /* HAVE_GEOIP */
#ifndef PATH_MAX
#define PATH_MAX 1024
......@@ -3762,6 +3766,10 @@ create_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist,
if (result != ISC_R_SUCCESS)
return (result);
#ifdef HAVE_GEOIP
view->aclenv.geoip = ns_g_geoip;
#endif
ISC_LIST_APPEND(*viewlist, view, link);
dns_view_attach(view, viewp);
return (ISC_R_SUCCESS);
......@@ -5083,6 +5091,24 @@ load_configuration(const char *filename, ns_server_t *server,
}
isc__socketmgr_setreserved(ns_g_socketmgr, reserved);
#ifdef HAVE_GEOIP
/*
* Initialize GeoIP databases from the configured location.
* This should happen before configuring any ACLs, so that we
* know what databases are available and can reject any GeoIP
* ACLs that can't work.
*/
obj = NULL;
result = ns_config_get(maps, "geoip-directory", &obj);
if (result == ISC_R_SUCCESS && cfg_obj_isstring(obj)) {
char *dir;
DE_CONST(cfg_obj_asstring(obj), dir);
ns_geoip_load(dir);
} else
ns_geoip_load(NULL);
ns_g_aclconfctx->geoip = ns_g_geoip;
#endif /* HAVE_GEOIP */
/*
* Configure various server options.
*/
......@@ -6069,6 +6095,10 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
if (server->blackholeacl != NULL)
dns_acl_detach(&server->blackholeacl);
#ifdef HAVE_GEOIP
dns_geoip_shutdown();
#endif
dns_db_detach(&server->in_roothints);
isc_task_endexclusive(server->task);
......@@ -6090,7 +6120,6 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
server->task = NULL;
/* Initialize configuration data with default values. */
result = isc_quota_init(&server->xfroutquota, 10);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
result = isc_quota_init(&server->tcpquota, 10);
......@@ -6098,9 +6127,16 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
result = isc_quota_init(&server->recursionquota, 100);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
result = dns_aclenv_init(mctx, &server->aclenv);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
#ifdef HAVE_GEOIP
/* Initialize GeoIP before using ACL environment */
ns_geoip_init();
server->aclenv.geoip = ns_g_geoip;
#endif
/* Initialize server data structures. */
server->zonemgr = NULL;
server->interfacemgr = NULL;
......
......@@ -21,7 +21,7 @@ top_srcdir = @top_srcdir@
@BIND9_MAKE_INCLUDES@
SUBDIRS = dlzexternal filter-aaaa lwresd rpz rsabigexponent tkey tsiggss
SUBDIRS = dlzexternal filter-aaaa geoip lwresd rpz rsabigexponent tkey tsiggss
TARGETS =
@BIND9_MAKE_RULES@
......
# Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.4 2011/07/28 23:47:58 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
@BIND9_VERSION@
@BIND9_MAKE_INCLUDES@
CINCLUDES = ${ISC_INCLUDES}
CDEFINES =
CWARNINGS =
DNSLIBS =
ISCLIBS = .
DNSDEPLIBS =
ISCDEPLIBS =
DEPLIBS =
LIBS = @LIBS@
TARGETS = geoip@EXEEXT@
FILTEROBJS = geoip.@O@
SRCS = geoip.c
@BIND9_MAKE_RULES@
all: geoip@EXEEXT@
geoip@EXEEXT@: ${FILTEROBJS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${FILTEROBJS} ${LIBS}
clean distclean::
rm -f ${TARGETS}
#!/bin/sh
#
# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
rm -f ns2/named.conf
rm -f ns2/example[1234567].db
rm -f dig.out.*
10.53.0.1/32 AU
10.53.0.2/32 US
10.53.0.3/32 GB
10.53.0.4/32 CA
10.53.0.5/32 CL
10.53.0.6/32 DE
10.53.0.7/32 EH
10.53.0.1/32 AS100001 One Systems, Inc.
10.53.0.2/32 AS100002 Two Technology Ltd.
10.53.0.3/32 AS100003 Three Network Labs
10.53.0.4/32 AS100004 Four University
10.53.0.5/32 AS100005 Five Telecom
10.53.0.6/32 AS100006 Six Company
10.53.0.7/32 AS100007 Seven Communications
fd92:7065:b8e:ffff::1/128,AS100001 One Systems, Inc.
fd92:7065:b8e:ffff::2/128,AS100002 Two Technology Ltd.
fd92:7065:b8e:ffff::3/128,AS100003 Three Network Labs
fd92:7065:b8e:ffff::4/128,AS100004 Four University
fd92:7065:b8e:ffff::5/128,AS100005 Five Telecom
fd92:7065:b8e:ffff::6/128,AS100006 Six Company
fd92:7065:b8e:ffff::7/128,AS100007 Seven Communications
10.53.0.1/32,US,CA,"Redwood City",94063,37.4914,-122.2110,807,650
10.53.0.2/32,US,CA,"Santa Cruz",95060,37.0448,-122.1021,828,831
10.53.0.3/32,US,OK,"Oklahoma City",73120,35.5798,-97.5731,650,405
10.53.0.4/32,US,VA,Ashland,23005,37.7563,-77.4888,556,804
10.53.0.5/32,US,GA,Atlanta,30345,33.8477,-84.2814,524,404
10.53.0.6/32,US,CO,Morrison,80465,39.6081,-105.2072,751,303
10.53.0.7/32,US,AK,Ketchikan,99901,55.6153,-131.5848,747,907
"fd92:7065:b8e:ffff::1","fd92:7065:b8e:ffff::1","US","CA","Redwood City","94063",37.4914,-122.2110,807,650
"fd92:7065:b8e:ffff::2","fd92:7065:b8e:ffff::2","US","CA","Santa Cruz","95060",37.0448,-122.1021,828,831
"fd92:7065:b8e:ffff::3","fd92:7065:b8e:ffff::3","US","OK","Oklahoma City","73120",35.5798,-97.5731,650,405
"fd92:7065:b8e:ffff::4","fd92:7065:b8e:ffff::4","DE","07","Lotte","",52.2833,7.9167,0,0
"fd92:7065:b8e:ffff::5","fd92:7065:b8e:ffff::5","US","GA","Atlanta","30345",33.8477,-84.2814,524,404
"fd92:7065:b8e:ffff::6","fd92:7065:b8e:ffff::6","US","CO","Morrison","80465",39.6081,-105.2072,751,303
"fd92:7065:b8e:ffff::7","fd92:7065:b8e:ffff::7","US","AK","Ketchikan","99901",55.6153,-131.5848,747,907
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment