Powerdns no answer on A records and others

Observed:

mother ~ # dig mother.titify.com

; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> mother.titify.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12227
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;mother.titify.com. IN A

;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Sep 28 18:08:19 2013
;; MSG SIZE rcvd: 35

As you can see, there is a QUESTION section, but no ANSWER. This is an example with a CNAME:

airgul ~ $ dig netly.io

; <<>> DiG 9.8.5-P1 <<>> netly.io
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2513
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;netly.io. IN A

;; ANSWER SECTION:
netly.io. 21600 IN CNAME mother.netly.io.
mother.netly.io. 21600 IN CNAME mother.titify.com.

;; Query time: 277 msec
;; SERVER: 10.60.111.1#53(10.60.111.1)
;; WHEN: Sat Sep 28 20:06:00 CEST 2013
;; MSG SIZE rcvd: 78

Solution:

mother # /etc/init.d/pdns stop
mother # /etc/init.d/pdns monitor

Will probably give an error message such as:

Sep 28 18:08:02 Should not get here (ns1.titify.com|1): 
please run pdnssec rectify-zone titify.com
Sep 28 18:08:02 Should not get here (ns2.titify.com|1): 
please run pdnssec rectify-zone titify.com
Sep 28 18:08:02 Should not get here (ns1.netly.io|1): 
please run pdnssec rectify-zone titify.com
Sep 28 18:08:02 Should not get here (ns2.netly.io|1): 
please run pdnssec rectify-zone titify.com
Sep 28 18:08:10 Should not get here (mother.titify.com|1): 
please run pdnssec rectify-zone titify.com
Sep 28 18:08:19 Should not get here (mother.titify.com|1): 
please run pdnssec rectify-zone titify.com

Execute that command:

pdnssec rectify-zone titify.com

and it’s magically fixed.

Raspberry Pi + ad blocking + nginx

There’s this howto that explains how to set up the RPi as ad blocker.

I’ve two RPi’s acting a router and was already running dnsmasq. I decided to give it a try. Note that this howto can actually be used on any DNS serving Linux server.

First of all, don’t go with the pixelserv as it crashes after a few minutes.

Apache is an option that worked fine. A general hint: if you’re already running Apache or whatever on port 80, just add a 2nd static IP and make Apache listen to that.

For example (/etc/network/interfaces) — be sure it’s in the same subnet:

auto eth0:0
iface eth0:0 inet static
 address 10.100.200.254
 netmask 255.255.255.0
 broadcast 10.100.200.255

10.100.200.254 is the Apache IP that just serves a HTTP 200 (or 204).

Here’s the relevant config part (note the HTTP 204 code, more info on that later):

<VirtualHost adblock:80>
 ServerAdmin webmaster@domain.net
 DocumentRoot /var/www
 <Directory />
 Options FollowSymLinks
 AllowOverride All
 </Directory>
 <Directory /var/www/>
 Options Indexes FollowSymLinks MultiViews
 AllowOverride None
 Order allow,deny
 allow from all
 RewriteEngine on
 RedirectMatch 204 (.*)$
 ErrorDocument 204 " "
 </Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
 LogLevel warn
 CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

And edit /etc/hosts to add “adblock”:

10.100.200.254 adblock.local adblock

If I had used the IP instead of adblock I would have had this error:

# apache2ctl configtest
[Mon Sep 16 20:27:21 2013] [error] (EAI 2)Name or service not known: 
Failed to resolve server name for 10.100.200.254 (check DNS) 
-- or specify an explicit ServerName
Syntax OK

With the HTTP 200 code, some browsers expect some content/file in return. So it’s generally safer to use HTTP 204 “No Content“; which basically means “all good but I have nothing to serve you.”

Now, I call myself an nginx fan. Running Apache on a RPi is a no go (at least for me). I could’ve ran nginx on the RPi, but decided to run it on a remote server with an additional IP. At least for now. To preserve resources on the RPi.

Here’s the relevant config to run it on nginx (and be sure this config is the first file nginx parses; or it might redirect all the domains to some other site):

server {
 listen 80;
 server_name pixel.0x04.com 10.100.200.254 _;
 access_log /var/log/nginx/pixel.access.log;
 error_log /var/log/nginx/pixel.error.log;
 expires max;
 autoindex off; 
 rewrite ^(.*)$ /;
 location / {
  return 204 'pixel';
 }
}

And if we test it, this is what we get:

HTTP/1.1 204 No Content
Server: nginx/1.4.0
Date: Mon, 16 Sep 2013 18:36:52 GMT
Connection: close
Expires: Thu, 31 Dec 2037 23:55:55 GMT
Cache-Control: max-age=315360000

And that’s it.

<3 nginx

The only downside is that this won’t work with HTTPS. You can run your webbrowser with a self signed certificate, but this will throw errors…

The result:

adblock

Fuck you, internet.

For a few years I ran my own public DNS server. I liked it, great experience, I could easily connect all my host to a central and fast DNS, I avoided all those nasty ISPs who filter their DNS, and it was fast (not Google fast, but fast — I actually think Google DNS didn’t even launch when I set it up).

A good year or so, they started using the DNS server to DDoS others (spoofed UDP DNS requests). That’s annoying… It hit like 5k or so requests per minute… That wasn’t really fine, but I didn’t care much until I saw the traffic it ended up generating… Then I started to null route most IPs sending bogus DNS requests (spamming ripe.net or isc.org)… That usually worked, and for a whole time I didn’t get any more DDoS… Until, apparently, recently.

And 5 to 10k I can accept… But 120k is over the limit.

So, as of today I’m sunsetting my public DNS. Goodbye and thank you for all the fish.

bind9_rndc

I log the queries:

df

vm1 /etc/bind # vnstat -m

eth0 / monthly

month rx | tx | total | avg. rate
 ------------------------+-------------+-------------+---------------
 Apr '12 44.04 GiB | 40.75 GiB | 84.79 GiB | 274.41 kbit/s
 May '12 108.58 GiB | 55.41 GiB | 163.99 GiB | 513.60 kbit/s
 Jun '12 150.30 GiB | 83.51 GiB | 233.81 GiB | 756.69 kbit/s
 Jul '12 240.42 GiB | 958.60 GiB | 1.17 TiB | 3.76 Mbit/s
 Aug '12 197.44 GiB | 745.38 GiB | 942.82 GiB | 2.95 Mbit/s
 Sep '12 182.99 GiB | 627.62 GiB | 810.61 GiB | 2.62 Mbit/s
 Oct '12 135.67 GiB | 431.33 GiB | 567.00 GiB | 1.78 Mbit/s
 Nov '12 93.75 GiB | 592.49 GiB | 686.24 GiB | 2.22 Mbit/s
 Dec '12 118.53 GiB | 68.36 GiB | 186.90 GiB | 585.35 kbit/s
 Jan '13 83.30 GiB | 159.82 GiB | 243.12 GiB | 761.43 kbit/s
 Feb '13 44.15 GiB | 187.99 GiB | 232.13 GiB | 804.93 kbit/s
 Mar '13 51.60 GiB | 532.81 GiB | 584.41 GiB | 4.04 Mbit/s
 ------------------------+-------------+-------------+---------------
 estimated 113.87 GiB | 1.15 TiB | 1.26 TiB |

Bind mrtg stats

Because I couldn’t find any that worked.

(Dark blue: incoming queries, light blue: outgoing/recursive lookups)

mrtg.cfg sample:

# Bind
Title[bind]: Bind Queries
Target[bind]: `/etc/mrtg/bind-stats.sh`
PageTop[bind]: <H1> Bind queries per minute on vm1 </H1>
Options[bind]: growright,pngdate,nobanner,gauge,nopercent,noinfo
MaxBytes[bind]: 50000
Ylegend[bind]: Queries/min
ShortLegend[bind]:  queries/min
LegendO[bind]: Incoming Bind queries per minute
LegendI[bind]: Outcoing Bind queries per minute
Legend2[bind]: Incoming Bind queries per minute
Legend1[bind]: Outcoing Bind queries per minute

bind-stats.sh:

#!/bin/bash
# Bind MRTG stats
# by Yeri Tiete (Tuinslak) - 10/02/2011
# http://yeri.be
#
# mrtg.cfg sample:
################################################################################
#	#
#	# Bind
#	#
#	Title[bind]: Bind Queries
#	Target[bind]: `/etc/mrtg/bind-stats.sh`
#	PageTop[bind]: <H1> Bind queries per minute on vm1 </H1>
#	Options[bind]: growright,pngdate,nobanner,gauge,nopercent,noinfo
#	MaxBytes[bind]: 50000
#	Ylegend[bind]: Queries/min
#	ShortLegend[bind]:  queries/min
#	LegendO[bind]: Incoming Bind queries per minute
#	LegendI[bind]: Outcoing Bind queries per minute
#	Legend2[bind]: Incoming Bind queries per minute
#	Legend1[bind]: Outcoing Bind queries per minute
################################################################################

# file path of named.stats
FILE=/var/log/named.stats
TMPFILE=/tmp/__dnsstats.txt

# how often does mrtg run? for me it's every 10 mins
TIME=10

# make file empty
echo /dev/null > /var/log/named.stats

# generate file
/usr/sbin/rndc stats

# save number of queries
INNOW=`egrep "[^I]QUERY" $FILE | awk '{print $1 }'`
OUTNOW=`grep Outgoing $FILE -A 9 | sed '1,2d' | awk '{ SUM += $1} END { print SUM }'`

# check if tmp file exists and insert data in it if it doesnt
# this prevents a peak
[ ! -e $TMPFILE ] && echo $INNOW > $TMPFILE && echo $OUTNOW >> $TMPFILE

# get old data
INOLD=`cat $TMPFILE | sed -n 1p`
OUTOLD=`cat $TMPFILE | sed -n 2p`

# overwrite old
echo $INNOW > $TMPFILE
echo $OUTNOW >> $TMPFILE

# calculate (to get difference)
INDIFF=$[ $INNOW-$INOLD ]
OUTDIFF=$[ $OUTNOW-$OUTOLD ]

# as mrtg runs */10 > divide by 10 to get per minute
INPERMIN=$[ $INDIFF/$TIME ]
OUTPERMIN=$[ $OUTDIFF/$TIME ]

# print !
echo $OUTPERMIN
echo $INPERMIN
echo
echo

Or download the file riiiiiight here.

Be sure the named.stats file gives this kind of output:

# grep Outgoing /var/log/named.stats -A 9
++ Outgoing Queries ++
[View: default]
               64316 A
                   2 NS
                  22 SOA
                6945 PTR
                 892 MX
                1104 TXT
                3117 AAAA
                  22 SRV

… for the outgoing queries, and …

# grep QUERY /var/log/named.stats | awk '{print $1 }'
163143

for the incoming queries.

Don’t forget to

chmod +x bind-stats.sh

Live sample: vm1.rootspirit.com/mrtg/bind.html