diff -Naur bind-9.4.0/geodns.INSTALL bind-9.4.0.oden/geodns.INSTALL --- bind-9.4.0/geodns.INSTALL 1970-01-01 01:00:00.000000000 +0100 +++ bind-9.4.0.oden/geodns.INSTALL 2007-04-16 20:19:31.000000000 +0200 @@ -0,0 +1,28 @@ +Installation of BIND 9.2.4 with geodns patch +-------------------------------------------- + +This document explains how to install BIND the geodns patch. We will use +/usr/local/src/ to unpack source code and /usr/local/bind as installation +directory for BIND. + +1) Download BIND 9.2.4 from http://www.isc.org/sw/bind/ +2) Download GeoIP C API from http://www.maxmind.com/app/c +3) Unpack both in /usr/local/src/ +4) Compile GeoIP and install in /usr/local/geoip/ +5) Type the following commands, changing path names if you want to install +in different paths: + +cd /usr/local/src +patch -p0 < bind-9.2.4-geodns-patch/patch.diff +cd bind-9.2.4 +CFLAGS="-I/usr/local/geoip/include" LDFLAGS="-L/usr/local/geoip/lib -lGeoIP" ./configure --prefix=/usr/local/bind +make && make install + +6) Now that BIND is installed, you can configure it. We provide a sample +config file in named.conf-sample. Basically, define your views and in +the match-clients clause include the list of countries to match as in: + +match-clients { country_PO; country_DE; country_AR; }; + +7) Run BIND with /usr/local/bind/sbin/named -c <config file> +8) Test it and use it. diff -Naur bind-9.4.0/geodns.named.conf-sample bind-9.4.0.oden/geodns.named.conf-sample --- bind-9.4.0/geodns.named.conf-sample 1970-01-01 01:00:00.000000000 +0100 +++ bind-9.4.0.oden/geodns.named.conf-sample 2007-04-16 20:19:31.000000000 +0200 @@ -0,0 +1,52 @@ +options { + directory "/var/bind"; + + listen-on-v6 { none; }; + + pid-file "/var/run/named/named.pid"; +}; + + + +view "us" { + // Match clients from US & Canada + match-clients { country_US; country_CA; }; + // Provide recursive service to internal clients only. + recursion no; + zone "example.com" { + type master; + file "pri/example-us.db"; + }; + zone "." IN { + type hint; + file "named.ca"; + }; +}; +view "latin" { + // Match from Argentina, Chile and Brazil + match-clients { country_AR; country_CL; country_BR; }; + // Provide recursive service to internal clients only. + recursion no; + zone "example.com" { + type master; + file "pri/example-latin.db"; + }; + zone "." IN { + type hint; + file "named.ca"; + }; +}; +view "other" { + // Match all others + match-clients { any; }; + // Refuse recursive service to external clients. + recursion no; + zone "example.com" { + type master; + file "pri/example-other.db"; + }; + zone "." IN { + type hint; + file "named.ca"; + }; +}; diff -Naur bind-9.4.0/lib/dns/acl.c bind-9.4.0.oden/lib/dns/acl.c --- bind-9.4.0/lib/dns/acl.c 2006-03-02 01:37:21.000000000 +0100 +++ bind-9.4.0.oden/lib/dns/acl.c 2007-04-17 13:59:16.000000000 +0200 @@ -21,12 +21,18 @@ #include <config.h> +#ifdef GEOIP +#include <GeoIP.h> +#endif #include <isc/mem.h> #include <isc/string.h> #include <isc/util.h> #include <dns/acl.h> +#ifdef GEOIP +static GeoIP *geoip = NULL; +#endif isc_result_t dns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target) { isc_result_t result; @@ -209,6 +215,28 @@ goto matched; break; +#ifdef GEOIP + case dns_aclelementtype_ipcountry: + /* We only match V4 addresses */ + if (reqaddr->family == AF_INET) { + /* Country match */ + + if (NULL == geoip) { + geoip = GeoIP_new(GEOIP_MEMORY_CACHE); + } + if (NULL != geoip) { + const char *value; + + value = GeoIP_country_code_by_addr(geoip,inet_ntoa(reqaddr->type.in)); + if ((NULL != value) && (2 == strlen(value))) { + if ((e->u.country[0] == value[0]) && (e->u.country[1] == value[1])) { + goto matched; + } + } + } + } + break; +#endif case dns_aclelementtype_keyname: if (reqsigner != NULL && dns_name_equal(reqsigner, &e->u.keyname)) diff -Naur bind-9.4.0/lib/dns/include/dns/acl.h bind-9.4.0.oden/lib/dns/include/dns/acl.h --- bind-9.4.0/lib/dns/include/dns/acl.h 2006-03-02 01:37:21.000000000 +0100 +++ bind-9.4.0.oden/lib/dns/include/dns/acl.h 2007-04-17 13:59:16.000000000 +0200 @@ -47,6 +47,9 @@ typedef enum { dns_aclelementtype_ipprefix, +#ifdef GEOIP + dns_aclelementtype_ipcountry, +#endif dns_aclelementtype_keyname, dns_aclelementtype_nestedacl, dns_aclelementtype_localhost, @@ -55,6 +58,9 @@ } dns_aclelemettype_t; typedef struct dns_aclipprefix dns_aclipprefix_t; +#ifdef GEOIP +typedef char dns_aclipcountry[3]; +#endif struct dns_aclipprefix { isc_netaddr_t address; /* IP4/IP6 */ @@ -66,6 +72,9 @@ isc_boolean_t negative; union { dns_aclipprefix_t ip_prefix; +#ifdef GEOIP + dns_aclipcountry country; +#endif dns_name_t keyname; dns_acl_t *nestedacl; } u; diff -Naur bind-9.4.0/lib/isccfg/aclconf.c bind-9.4.0.oden/lib/isccfg/aclconf.c --- bind-9.4.0/lib/isccfg/aclconf.c 2006-03-02 01:37:22.000000000 +0100 +++ bind-9.4.0.oden/lib/isccfg/aclconf.c 2007-04-17 13:59:16.000000000 +0200 @@ -228,6 +228,14 @@ } else if (strcasecmp(name, "none") == 0) { de->type = dns_aclelementtype_any; de->negative = ISC_TF(! de->negative); +#ifdef GEOIP + } else if ((0 == (strncmp("country_", name, 8))) && (10 == strlen(name))) { + /* It is a country code */ + de->type = dns_aclelementtype_ipcountry; + de->u.country[0] = name[8]; + de->u.country[1] = name[9]; + de->u.country[2] = '\0'; +#endif } else { de->type = dns_aclelementtype_nestedacl; result = convert_named_acl(ce, cctx, lctx,