Difference between revisions of "Network/DNS"
(Created page with "== PowerDNS == MySQL tables (and samples): <pre> DROP TABLE IF EXISTS `domains`; →!40101 SET @saved_cs_client = @@character_set_client: ; /*!40101 SET character_set_cli...") |
|||
(12 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | == Bind == | ||
+ | |||
+ | === Configuration === | ||
+ | |||
+ | Keep only the following 2 lines in '''named.conf''': | ||
+ | <pre> | ||
+ | include "/etc/bind/named.conf.options"; | ||
+ | include "/etc/bind/named.conf.local"; | ||
+ | </pre> | ||
+ | |||
+ | Replace the content of '''named.conf.local''' by: | ||
+ | <pre> | ||
+ | include "/etc/bind/geoip/GeoIP.acl"; | ||
+ | include "/etc/bind/geoip/GeoIPv6.acl"; | ||
+ | |||
+ | logging { | ||
+ | channel simple_log { | ||
+ | file "/var/log/named/bind.log" versions 3 size 5m; | ||
+ | //severity client; | ||
+ | print-time yes; | ||
+ | print-severity yes; | ||
+ | print-category yes; | ||
+ | }; | ||
+ | category default{ | ||
+ | simple_log; | ||
+ | }; | ||
+ | }; | ||
+ | |||
+ | |||
+ | view "America" { | ||
+ | match-clients { US; CA; }; | ||
+ | recursion no; | ||
+ | include "/etc/bind/named.conf.default-zones"; | ||
+ | //include "/etc/bind/named.conf.zones"; | ||
+ | zone "lunasys.fr" { | ||
+ | type master; | ||
+ | file "/etc/bind/geoip/us.lunasys.fr.hosts"; | ||
+ | }; | ||
+ | }; | ||
+ | |||
+ | |||
+ | view "Asia" { | ||
+ | match-clients { HK; CN; }; | ||
+ | recursion no; | ||
+ | include "/etc/bind/named.conf.default-zones"; | ||
+ | //include "/etc/bind/named.conf.zones"; | ||
+ | zone "lunasys.fr" { | ||
+ | type master; | ||
+ | file "/etc/bind/geoip/as.lunasys.fr.hosts"; | ||
+ | }; | ||
+ | }; | ||
+ | |||
+ | |||
+ | view "Europe" { | ||
+ | match-clients { FR; }; | ||
+ | recursion no; | ||
+ | include "/etc/bind/named.conf.default-zones"; | ||
+ | //include "/etc/bind/named.conf.zones"; | ||
+ | zone "lunasys.fr" { | ||
+ | type master; | ||
+ | file "/etc/bind/geoip/eu.lunasys.fr.hosts"; | ||
+ | }; | ||
+ | }; | ||
+ | |||
+ | |||
+ | view "Default" { | ||
+ | match-clients { any; }; | ||
+ | recursion no; | ||
+ | include "/etc/bind/named.conf.default-zones"; | ||
+ | //include “/etc/bind/named.conf.zones"; | ||
+ | zone "lunasys.fr" { | ||
+ | type master; | ||
+ | file "/etc/bind/geoip/us.lunasys.fr.hosts"; | ||
+ | }; | ||
+ | }; | ||
+ | </pre> | ||
+ | |||
+ | Create the log directory: | ||
+ | |||
+ | mkdir /var/log/named | ||
+ | chown bind /var/log/named | ||
+ | |||
+ | |||
+ | Setup all the zone files, with for example the file '''geoip/us.lunasys.fr.hosts''' for the US zone: | ||
+ | <pre> | ||
+ | $TTL 86400 ; 24 hours could have been written as 24h or 1d | ||
+ | $ORIGIN lunasys.fr. | ||
+ | @ 1D IN SOA ns1.lunasys.fr. hostmaster.lunasys.fr. ( | ||
+ | 2002022401 ; serial | ||
+ | 3H ; refresh | ||
+ | 15 ; retry | ||
+ | 1w ; expire | ||
+ | 3h ; minimum | ||
+ | ) | ||
+ | IN NS ns1.lunasys.fr. ; in the domain | ||
+ | IN MX 10 mail.google.com. | ||
+ | ; server host definitions | ||
+ | ns1 IN A 198.245.55.128 | ||
+ | yuki IN A 103.5.15.123 | ||
+ | yuko IN A 198.245.55.128 | ||
+ | </pre> | ||
+ | |||
+ | === GeoIP database === | ||
+ | |||
+ | Then write the GeoIP.acl and GeoIPv6.acl files with the following scripts. | ||
+ | |||
+ | These scripts are from [http://phix.me/geodns/ here]. | ||
+ | |||
+ | '''geoip.sh''': | ||
+ | <pre> | ||
+ | #!/bin/bash | ||
+ | |||
+ | [ -f GeoIPCountryCSV.zip ] || wget -T 5 -t 1 http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip | ||
+ | |||
+ | echo -n "Creating CBE (Country,Begin,End) CSV file..." | ||
+ | unzip -p GeoIPCountryCSV.zip GeoIPCountryWhois.csv | awk -F \" '{print $10","$6","$8}' > cbe.csv | ||
+ | echo -ne "DONE\nGenerating BIND GeoIP.acl file..." | ||
+ | |||
+ | (for c in $(awk -F , '{print $1}' cbe.csv | sort -u) | ||
+ | do | ||
+ | echo "acl \"$c\" {" | ||
+ | grep "^$c," cbe.csv | awk -F , 'function s(b,e,l,m,n) {l = int(log(e-b+1)/log(2)); m = 2^32-2^l; n = and(m,e); if (n == and(m,b)) printf "\t%u.%u.%u.%u/%u;\n",b/2^24%256,b/2^16%256,b/2^8%256,b%256,32-l; else {s(b,n-1); s(n,e)}} s($2,$3)' | ||
+ | echo -e "};\n" | ||
+ | done) > GeoIP.acl | ||
+ | |||
+ | rm -f cbe.csv | ||
+ | echo "DONE" | ||
+ | |||
+ | exit 0 | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | '''geoip_v6.py''': | ||
+ | <pre> | ||
+ | #!/usr/bin/python | ||
+ | |||
+ | from sys import stdin | ||
+ | from mpmath import mag | ||
+ | |||
+ | def s(b,e): | ||
+ | l = mag(e-b+1)-1 | ||
+ | m = 2**128-2**l | ||
+ | n = m & e | ||
+ | |||
+ | if n == m & b: | ||
+ | print '\t%x:%x:%x:%x:%x:%x:%x:%x/%u;' % tuple([b/2**p%65536 for p in xrange(112,-1,-16)]+[128-l]) | ||
+ | else: | ||
+ | s(b,n-1) | ||
+ | s(n,e) | ||
+ | </pre> | ||
+ | |||
+ | '''geoip_v6.sh''': | ||
+ | <pre> | ||
+ | for r in (map(int,l.split(',')[1:3]) for l in stdin): s(*r) | ||
+ | #!/bin/bash | ||
+ | |||
+ | d=http://geolite.maxmind.com/download/geoip/database/ | ||
+ | f=$(wget -qT 5 -t 1 -O- $d | egrep -o 'GeoIPv6-[0-9]{8}\.csv\.gz' | sort -r | head -1) | ||
+ | [ -z "$f" ] && exit 1; [ -f $f ] || wget -T 5 -t 1 $d$f || exit 1 | ||
+ | |||
+ | echo -n "Creating CBE (Country,Begin,End) CSV file..." | ||
+ | gunzip -c $f | awk -F \" '{print $10","$6","$8}' > cbe.csv | ||
+ | echo -e "DONE\nGenerating BIND GeoIPv6.acl file..." | ||
+ | |||
+ | (for c in $(awk -F , '{print $1}' cbe.csv | sort -u) | ||
+ | do | ||
+ | echo "$c" >&2 | ||
+ | echo "acl \"${c}v6\" {" | ||
+ | grep "^$c," cbe.csv | ./geoip_v6.py | sed 's \(:0\)\+/ ::/ ' | ||
+ | echo -e "};\n" | ||
+ | done) > GeoIPv6.acl | ||
+ | |||
+ | rm -f cbe.csv | ||
+ | echo "DONE" | ||
+ | |||
+ | exit 0 | ||
+ | </pre> | ||
+ | |||
+ | Move into '''/etc/bind/geoip''' in which the 3 scripts above must be present, and run both '''geoip_v6.sh''' and '''geoip_v6.sh'''. This will generate GeoIP.acl and GeoIPv6.acl. | ||
+ | |||
== PowerDNS == | == PowerDNS == | ||
− | MySQL tables (and samples): | + | === Installation (Debian) === |
+ | |||
+ | Install the package (tested in squeeze): | ||
+ | |||
+ | apt-get install pdns-server pdns-backend-geo pdns-backend-mysql mysql-server | ||
+ | |||
+ | === General Configuration === | ||
+ | |||
+ | Setup basic configuration in '''/etc/powerdns/pdns.conf''': | ||
+ | <pre> | ||
+ | allow-recursion=127.0.0.1 | ||
+ | config-dir=/etc/powerdns | ||
+ | daemon=yes | ||
+ | disable-axfr=yes | ||
+ | guardian=yes | ||
+ | lazy-recursion=yes | ||
+ | local-address=0.0.0.0 | ||
+ | local-port=53 | ||
+ | loglevel=8 | ||
+ | module-dir=/usr/lib/powerdns | ||
+ | setgid=pdns | ||
+ | setuid=pdns | ||
+ | socket-dir=/var/run | ||
+ | webserver=yes | ||
+ | webserver-address=0.0.0.0 | ||
+ | webserver-password=<pass> | ||
+ | webserver-port=8080 | ||
+ | version-string=powerdns | ||
+ | launch=gmysql,geo | ||
+ | include=/etc/powerdns/pdns.d | ||
+ | </pre> | ||
+ | |||
+ | === MySQL === | ||
+ | |||
+ | Create the base MySQL tables (and samples): | ||
<pre> | <pre> | ||
DROP TABLE IF EXISTS `domains`; | DROP TABLE IF EXISTS `domains`; | ||
− | |||
− | |||
CREATE TABLE `domains` ( | CREATE TABLE `domains` ( | ||
`id` int(11) NOT NULL AUTO_INCREMENT, | `id` int(11) NOT NULL AUTO_INCREMENT, | ||
Line 17: | Line 229: | ||
UNIQUE KEY `name_index` (`name`) | UNIQUE KEY `name_index` (`name`) | ||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; | ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; | ||
− | |||
− | |||
− | |||
DROP TABLE IF EXISTS `records`; | DROP TABLE IF EXISTS `records`; | ||
− | |||
− | |||
CREATE TABLE `records` ( | CREATE TABLE `records` ( | ||
`id` int(11) NOT NULL AUTO_INCREMENT, | `id` int(11) NOT NULL AUTO_INCREMENT, | ||
Line 38: | Line 245: | ||
KEY `domain_id` (`domain_id`) | KEY `domain_id` (`domain_id`) | ||
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; | ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; | ||
− | |||
− | |||
− | |||
DROP TABLE IF EXISTS `supermasters`; | DROP TABLE IF EXISTS `supermasters`; | ||
− | |||
− | |||
CREATE TABLE `supermasters` ( | CREATE TABLE `supermasters` ( | ||
`ip` varchar(25) NOT NULL, | `ip` varchar(25) NOT NULL, | ||
Line 52: | Line 254: | ||
</pre> | </pre> | ||
+ | Grant access to a specific user: | ||
+ | <pre> | ||
+ | GRANT ALL ON pdns.* TO pdns@localhost IDENTIFIED BY '<pass>'; | ||
+ | </pre> | ||
− | + | You can also insert some records for tests: | |
<pre> | <pre> | ||
− | + | INSERT INTO `domains` VALUES (1,'lunasys.fr',NULL,NULL,'NATIVE',NULL,NULL); | |
− | + | INSERT INTO `records` VALUES (3,1,'as.www.lunasys.fr','A','3.1.1.1',600,NULL,NULL), | |
− | + | (4,1,'us.www.lunasys.fr','A','2.1.1.1',600,NULL,NULL), | |
− | + | (5,1,'eu.www.lunasys.fr','A','4.1.1.1',600,NULL,NULL); | |
− | + | </pre> | |
− | + | ||
− | + | Then, in '''pdns.d/pdns.local''', add: | |
− | + | ||
− | + | <pre> | |
− | + | gmysql-host=127.0.0.1 | |
− | + | gmysql-user=pdns | |
− | + | gmysql-password=<pass> | |
− | + | gmysql-dbname=pdns | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</pre> | </pre> | ||
− | pdns.d/pdns.local | + | === Geo === |
+ | |||
+ | In '''pdns.d/pdns.local''', add: | ||
<pre> | <pre> | ||
Line 84: | Line 285: | ||
geo-ip-map-zonefile=/etc/powerdns/zz.countries.nerd.dk.rbldnsd | geo-ip-map-zonefile=/etc/powerdns/zz.countries.nerd.dk.rbldnsd | ||
geo-maps=/etc/powerdns/geo-maps | geo-maps=/etc/powerdns/geo-maps | ||
− | |||
− | |||
− | |||
− | |||
− | |||
</pre> | </pre> | ||
− | geo-maps/lunasys | + | Write '''geo-maps/lunasys''': |
<pre> | <pre> | ||
Line 103: | Line 299: | ||
0 eu.www | 0 eu.www | ||
</pre> | </pre> | ||
+ | |||
+ | Finally retrieve countries zone file with the following rsync command: | ||
+ | |||
+ | rsync -avz rsync://countries-ns.mdc.dk/zone . | ||
+ | |||
+ | And copy the '''zz.countries.nerd.dk.rbldnsd''' in '''/etc/powerdns/''' |
Latest revision as of 13:44, 24 June 2012
Contents
Bind
Configuration
Keep only the following 2 lines in named.conf:
include "/etc/bind/named.conf.options"; include "/etc/bind/named.conf.local";
Replace the content of named.conf.local by:
include "/etc/bind/geoip/GeoIP.acl"; include "/etc/bind/geoip/GeoIPv6.acl"; logging { channel simple_log { file "/var/log/named/bind.log" versions 3 size 5m; //severity client; print-time yes; print-severity yes; print-category yes; }; category default{ simple_log; }; }; view "America" { match-clients { US; CA; }; recursion no; include "/etc/bind/named.conf.default-zones"; //include "/etc/bind/named.conf.zones"; zone "lunasys.fr" { type master; file "/etc/bind/geoip/us.lunasys.fr.hosts"; }; }; view "Asia" { match-clients { HK; CN; }; recursion no; include "/etc/bind/named.conf.default-zones"; //include "/etc/bind/named.conf.zones"; zone "lunasys.fr" { type master; file "/etc/bind/geoip/as.lunasys.fr.hosts"; }; }; view "Europe" { match-clients { FR; }; recursion no; include "/etc/bind/named.conf.default-zones"; //include "/etc/bind/named.conf.zones"; zone "lunasys.fr" { type master; file "/etc/bind/geoip/eu.lunasys.fr.hosts"; }; }; view "Default" { match-clients { any; }; recursion no; include "/etc/bind/named.conf.default-zones"; //include “/etc/bind/named.conf.zones"; zone "lunasys.fr" { type master; file "/etc/bind/geoip/us.lunasys.fr.hosts"; }; };
Create the log directory:
mkdir /var/log/named chown bind /var/log/named
Setup all the zone files, with for example the file geoip/us.lunasys.fr.hosts for the US zone:
$TTL 86400 ; 24 hours could have been written as 24h or 1d $ORIGIN lunasys.fr. @ 1D IN SOA ns1.lunasys.fr. hostmaster.lunasys.fr. ( 2002022401 ; serial 3H ; refresh 15 ; retry 1w ; expire 3h ; minimum ) IN NS ns1.lunasys.fr. ; in the domain IN MX 10 mail.google.com. ; server host definitions ns1 IN A 198.245.55.128 yuki IN A 103.5.15.123 yuko IN A 198.245.55.128
GeoIP database
Then write the GeoIP.acl and GeoIPv6.acl files with the following scripts.
These scripts are from here.
geoip.sh:
#!/bin/bash [ -f GeoIPCountryCSV.zip ] || wget -T 5 -t 1 http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip echo -n "Creating CBE (Country,Begin,End) CSV file..." unzip -p GeoIPCountryCSV.zip GeoIPCountryWhois.csv | awk -F \" '{print $10","$6","$8}' > cbe.csv echo -ne "DONE\nGenerating BIND GeoIP.acl file..." (for c in $(awk -F , '{print $1}' cbe.csv | sort -u) do echo "acl \"$c\" {" grep "^$c," cbe.csv | awk -F , 'function s(b,e,l,m,n) {l = int(log(e-b+1)/log(2)); m = 2^32-2^l; n = and(m,e); if (n == and(m,b)) printf "\t%u.%u.%u.%u/%u;\n",b/2^24%256,b/2^16%256,b/2^8%256,b%256,32-l; else {s(b,n-1); s(n,e)}} s($2,$3)' echo -e "};\n" done) > GeoIP.acl rm -f cbe.csv echo "DONE" exit 0
geoip_v6.py:
#!/usr/bin/python from sys import stdin from mpmath import mag def s(b,e): l = mag(e-b+1)-1 m = 2**128-2**l n = m & e if n == m & b: print '\t%x:%x:%x:%x:%x:%x:%x:%x/%u;' % tuple([b/2**p%65536 for p in xrange(112,-1,-16)]+[128-l]) else: s(b,n-1) s(n,e)
geoip_v6.sh:
for r in (map(int,l.split(',')[1:3]) for l in stdin): s(*r) #!/bin/bash d=http://geolite.maxmind.com/download/geoip/database/ f=$(wget -qT 5 -t 1 -O- $d | egrep -o 'GeoIPv6-[0-9]{8}\.csv\.gz' | sort -r | head -1) [ -z "$f" ] && exit 1; [ -f $f ] || wget -T 5 -t 1 $d$f || exit 1 echo -n "Creating CBE (Country,Begin,End) CSV file..." gunzip -c $f | awk -F \" '{print $10","$6","$8}' > cbe.csv echo -e "DONE\nGenerating BIND GeoIPv6.acl file..." (for c in $(awk -F , '{print $1}' cbe.csv | sort -u) do echo "$c" >&2 echo "acl \"${c}v6\" {" grep "^$c," cbe.csv | ./geoip_v6.py | sed 's \(:0\)\+/ ::/ ' echo -e "};\n" done) > GeoIPv6.acl rm -f cbe.csv echo "DONE" exit 0
Move into /etc/bind/geoip in which the 3 scripts above must be present, and run both geoip_v6.sh and geoip_v6.sh. This will generate GeoIP.acl and GeoIPv6.acl.
PowerDNS
Installation (Debian)
Install the package (tested in squeeze):
apt-get install pdns-server pdns-backend-geo pdns-backend-mysql mysql-server
General Configuration
Setup basic configuration in /etc/powerdns/pdns.conf:
allow-recursion=127.0.0.1 config-dir=/etc/powerdns daemon=yes disable-axfr=yes guardian=yes lazy-recursion=yes local-address=0.0.0.0 local-port=53 loglevel=8 module-dir=/usr/lib/powerdns setgid=pdns setuid=pdns socket-dir=/var/run webserver=yes webserver-address=0.0.0.0 webserver-password=<pass> webserver-port=8080 version-string=powerdns launch=gmysql,geo include=/etc/powerdns/pdns.d
MySQL
Create the base MySQL tables (and samples):
DROP TABLE IF EXISTS `domains`; CREATE TABLE `domains` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `master` varchar(128) DEFAULT NULL, `last_check` int(11) DEFAULT NULL, `type` varchar(6) NOT NULL, `notified_serial` int(11) DEFAULT NULL, `account` varchar(40) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name_index` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; DROP TABLE IF EXISTS `records`; CREATE TABLE `records` ( `id` int(11) NOT NULL AUTO_INCREMENT, `domain_id` int(11) DEFAULT NULL, `name` varchar(255) DEFAULT NULL, `type` varchar(10) DEFAULT NULL, `content` varchar(64000) DEFAULT NULL, `ttl` int(11) DEFAULT NULL, `prio` int(11) DEFAULT NULL, `change_date` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `rec_name_index` (`name`), KEY `nametype_index` (`name`,`type`), KEY `domain_id` (`domain_id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; DROP TABLE IF EXISTS `supermasters`; CREATE TABLE `supermasters` ( `ip` varchar(25) NOT NULL, `nameserver` varchar(255) NOT NULL, `account` varchar(40) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Grant access to a specific user:
GRANT ALL ON pdns.* TO pdns@localhost IDENTIFIED BY '<pass>';
You can also insert some records for tests:
INSERT INTO `domains` VALUES (1,'lunasys.fr',NULL,NULL,'NATIVE',NULL,NULL); INSERT INTO `records` VALUES (3,1,'as.www.lunasys.fr','A','3.1.1.1',600,NULL,NULL), (4,1,'us.www.lunasys.fr','A','2.1.1.1',600,NULL,NULL), (5,1,'eu.www.lunasys.fr','A','4.1.1.1',600,NULL,NULL);
Then, in pdns.d/pdns.local, add:
gmysql-host=127.0.0.1 gmysql-user=pdns gmysql-password=<pass> gmysql-dbname=pdns
Geo
In pdns.d/pdns.local, add:
geo-zone=lunasys.fr #geo-ns-records=ns0.lunasys.fr geo-ip-map-zonefile=/etc/powerdns/zz.countries.nerd.dk.rbldnsd geo-maps=/etc/powerdns/geo-maps
Write geo-maps/lunasys:
$RECORD www $ORIGIN lunasys.fr. 56 eu.www 344 as.www 250 eu.www 840 us.www 124 us.www 0 eu.www
Finally retrieve countries zone file with the following rsync command:
rsync -avz rsync://countries-ns.mdc.dk/zone .
And copy the zz.countries.nerd.dk.rbldnsd in /etc/powerdns/