Sunday, March 4, 2012

Easiest DNSSEC ever when running PowerDNS in BIND mode

Without further comment, except to note that this is really all there is to this. Signatures will autorotate, 'pdnssec' allows for complete key management. No cronjobs or further configuration.

# apt-get install bind9
The following NEW packages will be installed:
  bind9
..
 * Starting domain name service... bind9                     [OK]

# dig -x 127.0.0.1 +dnssec @127.0.0.1 +noall +answer
1.0.0.127.in-addr.arpa. 604800 IN PTR localhost.

# wget http://powerdnssec.org/downloads/packages/pdns-static_3.1-pre.20120304.2462-1_amd64.deb
# dpkg -i pdns-static_3.1-pre.20120304.2462-1_amd64.deb 
Restarting PowerDNS authoritative nameserver: not running, starting
Starting PowerDNS authoritative nameserver: started

# cat > /etc/powerdns/pdns.conf
local-port=5300
launch=bind
bind-config=/etc/bind/named.conf
bind-dnssec-db=/var/db/bind-dnssec-db  
^D

# pdnssec create-bind-db /var/db/bind-dnssec-db 
# /etc/init.d/pdns reload
Reloading PowerDNS authoritative nameserver: requested reload


# pdnssec secure-zone 127.in-addr.arpa
Zone 127.in-addr.arpa secured

# dig -x 127.0.0.1 +dnssec @127.0.0.1 +noall +answer -p 5300
1.0.0.127.in-addr.arpa. 604800 IN PTR localhost.
1.0.0.127.in-addr.arpa. 604800 IN RRSIG PTR 8 6 604800 20120315000000 20120301000000 44311 127.in-addr.arpa. EHjRegR...iN0 1iE=

# dig -t dnskey 127.in-addr.arpa @127.0.0.1 -p 5300  | grep ^127 | tee trust-anchor
127.in-addr.arpa. 604800 IN DNSKEY 257 3 8 AwEAAdT...M7S CbrksGuVtmc=
127.in-addr.arpa. 604800 IN DNSKEY 256 3 8 AwEAAax...A97L jkGHUdO3
127.in-addr.arpa. 604800 IN DNSKEY 256 3 8 AwEAAeNc0G...rZX rBZcGuWL

# drill -D  ptr 1.0.0.127.in-addr.arpa  @127.0.0.1 -p 5300 -k trust-anchor 
...
; 1.0.0.127.in-addr.arpa. 604800 IN PTR localhost.
; VALIDATED by id = 57268, owner = 127.in-addr.arpa.


Update: by popular demand:

# pdnssec show-zone 127.in-addr.arpa
Zone has NSEC semantics
Zone is not presigned
keys: 
ID = 1 (KSK), tag = 23402, algo = 8, bits = 2048 Active: 1
KSK DNSKEY = 127.in-addr.arpa IN DNSKEY 257 3 8 AwEAAdTtgIBwyzXNibY3FkHAKsTEZLHIsXVCFM0x+PAqCc8du3js3pDnmIscZBaG8kjaHmcOWwPMFZuisJW2gMKhTr1Dg7IEWpAD8SB+6qzcCmX2YTmQ5nbMZ9Bh8j7q3atcGVurxKJnnEblCzjZghR2vuTaebpCgxArTBeEgb3k8HeIydbiIdjUgcWw8zkBP8/10oy0BOyiWWEtNM0bjl3gtTbpMGKqrByMILHtDMzHFqsJ3L/84kiXrI/896Nv/p9Eo3+OKYTSsjQYEH2Pn3fuflHV7CwtS3wuBt9JzzO82863yjY0TK2XwCSrL8qQDpPSe398dOlpmM7SCbrksGuVtmc=
DS = 127.in-addr.arpa IN DS 23402 8 1 47d3b1aca6f1993422253c74a2768b6e01090136
DS = 127.in-addr.arpa IN DS 23402 8 2 d13f1ea3e1895c49982c6dfbbe3344e022d72027ca63cf5aebc65b1ab909936a
DS = 127.in-addr.arpa IN DS 23402 8 3 9f27adaac6930a0d4cfac56f192d518937e6007bd104d52452c861e843d4faae


ID = 2 (ZSK), tag = 57268, algo = 8, bits = 1024 Active: 1
ID = 3 (ZSK), tag = 61326, algo = 8, bits = 1024 Active: 0




Tuesday, February 7, 2012

On SRP - some implementation notes and a critical review

Some time ago, Dan Kaminsky mentioned the Secure Remote Password protocol (SRP) on Twitter. As I find certificates to be cumbersome, I'm always interested in solutions to setup trusted communications without them.

Update: this post has been updated based on suggestions by SRP designer, Tom Wu!

SRP is surprisingly unknown for what it offers, so I decided to do a writeup here to help spread the word on what SRP is and isn't, how to implement and what the caveats are.

SRP was designed by Tom Wu while he was at Stanford University. Details can be found from the page linked above, and the Wikipedia page is also informative.

This writeup assumes familiarity with hashes and Diffie-Hellman, but not a lot else.

What is the problem that SRP solves?

To do anything important on the public Internet, we need secure communication channels. Stricter definitions are available, but the core of this is that we have secrecy (other people on the Internet can't listen in) and that we know who we are talking to (other people can't impersonate the endpoint we think we are talking to).

Often we use SSL, in the form of https, to deliver both. The SSL protocol negotiates a session with privacy, and through the use of X509 certificates, makes sure that we are talking to someone with a certificate that matches who we think we are talking to (what this means in the year 2012 is anybody's guess, though).

In addition, once we have setup this secure channel, most of the time we will then log in to a remote system (think gmail, for example). We do so by providing a username and a password.

And here's the interesting thing. The server has provided proof of its identity to us in a way that doesn't allow us to subsequently impersonate that server. However, as users, we are then asked to give that same server our full username and password! If we share passwords, this mean the operator of the server can now try to log in elsewhere with our credentials.

Enter SRP.

Zero knowledge proof of identity with key establishment

SRP rolls up most of the things above. As a user, we can prove to the other side that we are who we say we are (or at least, that we know the password we enrolled earlier). We never have to send the remote our password, not even when we are enrolling. Simultaneously, we get proof that the other side is one that we enrolled with in the past. Finally, we also get a secure session key to encrypt our communications.

And all this without certificates!

Compare this to SSH, where we first setup a secure connection, and then send our full password over that same session. Or CRAM-MD5, which allows us to prove who we are without sending over our password, but which does demand that the server have a plaintext copy of our credentials.

All pretty impressive.

Practical details

With our username, the server stores a 'verifier' of our credentials, plus the salt used to generate this verifier. As is usual, we deal with hashes of the password, and not the password itself. The verifier however is even further away from the password, and consists of the result of a one-way cryptographic operation on the hash.

Password + Salt  -> Hash -> Verifier

We never need to tell the server our password if we don't want to, we can just send them a random salt and the verifier (which we can calculate) when we enroll. Quite often though, we'll provide the password just once, though, and have the server calculate the salt thence hash & verifier.

When we want to setup a secure authenticated session, we connect to the server and tell it our username. In return, it reminds us of the salt used in generating the hash.

The user now enters the password on his own computer, which subsequently calculates the hash based on the salt. This hash constitutes our secret key. The verifier stored on the other side performs the role of a public key.

Next, a modified Diffie-Hellman key exchange is performed, based on the public and private keys derived from our password. If the server verifier is indeed related to our client hash, both parties will end up with a shared secret which, once hashed, forms our session key.

A final message exchange based on the shared session key is then performed, and if the session key is in fact identical on client and server, this will prove that the verifier and user password match.

And we are logged in, and have an authenticated secure shared key!

Downsides

There are a few downsides to the above. For one, we have to send out our username in plaintext at the very beginning of the session. An eavesdropper can derive from this who we are claiming to be.

Secondly, while the server is 100% assured we know the password associated with the username, we are in turn not 100% sure if we are connected to the right server. We only know we are connected to someone who has access to our username and password (knowing only the verifier is not enough).

The last bit basically means that if someone knows our username and password, he'd be able to impersonate the server you connect to, and transparently send everything on. But then again, if he knows your username and password, he could just log in as well.

If an attacker only knows the verifier, he can wait for a user to connect, and pretend to be the intended server. However, the attacker can't setup a transparent connection to the authentic server, so you'd have an authenticated connection to a server that does not have the contents of the original server.

Patent situation

Update: this section has been updated after further research. The previously mentioned patent is predated by the publication of SRP by a wide margin, so it does not apply.
Various sources mention that there might be a patent issue with SRP, but there is nothing concrete to point to. There is a Stanford patent, but it has been licensed in such a way that it does not hinder SRP usage in any way. It might in fact protect it.

When the SRP RFC was initially written, two firms made IPR disclosures, but these have not been followed up on. When RFC 5054 was published, which also describes SRP, there were no further IPR disclosures.

SRP has by now seen quite some use, if there were any applicable patents out there that were still valid, we would probably have heard from them already. If anyone knows of specific patents that apply, please let me know. It would be good to put this to rest.

The balance

SRP is pretty cool, and delivers quite a lot of 'bang for the buck'. It is way better than many other solutions, which either require plaintext passwords on the server, or require us to hand over our password to the server every time we log in.

In particular, it appears SRP should have been used in WPA2 instead of what was used.

However, SRP falls short of having 'real' authentication. If an attacker knows the password, he can effectively pretend to be the remote server. And even though an attacker with the correct password was pretty powerful already, this is a downside.

The usecase for SRP is therefore for people who'd like to have better security than just passing around passwords, but don't want to go through the hassle of doing certificate administration.

Potential improvements

If we could keep the salt a secret, it could function as a poor man's authenticator. The server does not need to know the salt, as long as it has the verifier. The salt itself could then be used as the 'public' key of the remote.

Implementation notes

The best place to start reading is the SRP Design Page. There is a also  paper which describes the math, but not the practicalities. RFC 5054 meanwhile describes how to do SRP within SSL/TLS, and Tom Wu suggests using that if possible. If you do SRP outside of SSL/TLS, it appears wise to follow the practicalities in of SRP-TLS (mostly related to padding) anyhow, for interoperability's sake.

Sunday, January 15, 2012

Four million pings only - aka 1 dimensional DNS radar

Quick post as I have no time to work on this for now. Ages ago I read a book, I think by Arthur C. Clarke, where powerful atomic bombs were used to generate radar pulses so powerful, the return signal was used to map the entire solar system in one go. The grandeur of this vision impressed me a lot, and I hope that one day we can do it. (Btw, if anybody knows the name of the book, please share!).

If you send out one powerful 'ping' of radar signal, and only measure the strength of the return over time, you don't get a good picture - you learn how much reflection you get, and from how far away (based on the delay). But you don't get the angle. This is why 'real' radars rotate, so they can sweep the sky. (I know there are other reasons).

One of the 2012 goals for the PowerDNS Recursor is to become the DNS resolver with the best perceived experience for the end-users. This means not so much the highest performance (in terms of hundreds of thousands of queries/second, the usual metric), but in terms of getting the best answer to the user within the shortest amount of time.

In doing the math on this challenge, I needed to know how the response times of authoritative DNS servers are distributed, so I instrumented the PowerDNS Recursor to graph this while I sent it runs of 2,000,000 questions from a list of the most popular domain names. I was naively expecting some sort of Poisson distribution centered around 150ms.

But lo and behold, I got this graph. From this you can see that around 10% of answers came in beteen 1 and 2msec.  But this graph isn't any kind of nice smooth distribution at all, and I should have realised that.

(the graph contains two runs, called 'plot' and 'plot.1', plus the combination of both runs in Blue)

The speed of light within a fiberoptic cable is around 200,000km/s, and because the answer needs to come back too, this equals around 100km per msec. So if you multiply the y-axis by a hundred, you get a very rough measure of the distance of all authoritative servers queried. And servers are not distributed smoothly! They tend to cluster around hotspots.

So what are these peaks? Well.. the first one turns out to be mostly ANYcasted servers present very closely to xs.powerdns.com. A secondary peak (24ms) appears to be Milan (actual distance: 1000km, but we lose 20ms somewhere within Level3 for no apparent reason), hosting an instance of a.dns.it, plus an instance of b.gtld-servers.net in Stockholm (actual distance: 1500km).

The big void between 50ms and 75ms might correspond to the Atlantic Ocean.

The peak around 84-87ms matches closely with the East Coast of the US, whereas the somewhat broader peak beyond 158ms might well be California. Or Asia!

250ms is about what you'd expect from Australia, the peak from 350ms might again be Australia, but then 'the wrong way round'.

These analyses are very tentative, but I've now seen the same result on 4 different datasets, one of which was measured a few years ago and based on very different techniques, but gave the same result.

The dataset used to generate the graph above can be found on http://xs.powerdns.com/dns-radar, the format is "microseconds errorcode remote-server:port domain-name".

I might publish more details on how to reproduce later, but for now, I thought this was cool enough to share!

Tuesday, January 10, 2012

PowerDNS Authoritative Server Security Notification 2012-01

CVECVE-2012-0206
Date10th of January 2012
CreditRay Morris of BetterCGI.com.
AffectsMost PowerDNS Authoritative Server versions < 3.0.1 (with the exception of the just released 2.9.22.5)
Not affectedNo versions of the PowerDNS Recursor ('pdns_recursor') are affected.
SeverityHigh
ImpactUsing well crafted UDP packets, one or more PowerDNS servers could be made to enter a tight packet loop, causing temporary denial of service
ExploitProof of concept
Risk of system compromiseNo
SolutionUpgrade to PowerDNS Authoritative Server 2.9.22.5 or 3.0.1
WorkaroundSeveral, the easiest is setting: cache-ttl=0, which does have a performance impact. Please see below.

Affected versions of the PowerDNS Authoritative Server can be made to respond to DNS responses, thus enabling an attacker to setup a packet loop between two PowerDNS servers, perpetually answering each other's answers. In some scenarios, a server could also be made to talk to itself, achieving the same effect.
If enough bouncing traffic is generated, this will overwhelm the server or network and disrupt service.
As a workaround, if upgrading to a non-affected version is not possible, several options are available. The issue is caused by the packet-cache, which can be disabled by setting 'cache-ttl=0', although this does incur a performance penalty. This can be partially addressed by raising the query-cache-ttl to a (far) higher value.
Alternatively, on Linux systems with a working iptables setup, 'responses' sent to the PowerDNS Authoritative Server 'question' address can be blocked by issuing:
iptables -I INPUT -p udp --dst $AUTHIP --dport 53 \! -f -m u32 --u32 "0>>22&0x3C@8>>15&0x01=1" -j DROP 
 
If this command is used on a router or firewall, substitute FORWARD for INPUT.
To solve this issue, we recommend upgrading to the latest packages available for your system. Tarballs and new static builds (32/64bit, RPM/DEB) of 2.9.22.5 and 3.0.1 have been uploaded to our download site. Kees Monshouwer has provided updated CentOS/RHEL packages in his repository. Debian, Fedora and SuSE should have packages available shortly after this announcement.
For those running custom PowerDNS versions, just applying this patch may be easier:
--- pdns/common_startup.cc   (revision 2326)
+++ pdns/common_startup.cc   (working copy)
@@ -253,7 +253,9 @@
       numreceived4++;
     else
       numreceived6++;
-
+    if(P->d.qr)
+      continue;
+      
     S.ringAccount("queries", P->qdomain+"/"+P->qtype.getName());
     S.ringAccount("remotes",P->getRemote());
     if(logDNSQueries) {
It should apply cleanly to 3.0 and with little trouble to several older releases, including 2.9.22 and 2.9.21.
This bug resurfaced because over time, the check for 'not responding to responses' moved to the wrong place, allowing certain responses to be processed anyhow.
We would like to thank Ray Morris of BetterCGI.com for bringing this issue to our attention and Aki Tuomi for helping us reproduce the problem.

Sunday, November 20, 2011

Old blog posts back

Hi everybody,

More than a year ago my old server died, taking down my blog with it. It was a busy year so I only now got round to reviving the content.

It is back now, and you can find the old content here.

Some of my favorite old posts:


Friday, September 23, 2011

Neutrinos faster than light?

I'm really hoping it is true, that neutrinos are actually travelling faster than light! As is usually the case with potential breakthroughs in physics, the evidence is complicated.

It would be wonderful if it had been a simple race between light and neutrinos, and the neutrinos arriving first. Sadly, it is not as simple as this.

In reality, "trains" of millions and millions of neutrinos are generated in Switzerland, from where they travel straight through the earth, to be detected in an experiment in Italy. Over three years of measurements, 16111 neutrinos have been recorded and timed.

Each train of neutrinos is 10500 nanoseconds long, and the average neutrino is measured to appear 60 nanoseconds earlier than expected.  The problem is that of the millions of neutrinos sent, only a few get detected.

So when the arrival of a neutrino is measured, it is not certain if it is one from the beginning of the 10500 nanosecond long train, or one at the end.

If the train of neutrinos were exactly uniform, you could just take the average travel time, and be done with it. In the end the length of the train would average out. The problem is that the density of neutrinos being sent is absolutely not uniform.

Through crafty statistics however, and by measuring the precise density shape of the train in Switzerland, it is however possible to still generate an average travel time. And this is the number that is being reported, between 50 and 70 nanoseconds too fast (more or less).

This corresponds to around 180 18 meters at the speed of light. The distance to between where the beam starts and where it is measured is known to 20 centimeters precise, so that is not a problem. It also appears that the very best timekeeping people in the whole world have been involved in making sure the clocks are running correctly.

It is an impressive effort. It would have been a lot easier if we could just organize a race between a neutrino and a photon. The result now reported is statistical in nature, but the statistics are impressive. It should however be realized that a lot of calculations are needed to get the 60ns number, and a mistake could hide anywhere.

The result can be compared to trying to measure if a (real) train runs on schedule by timing when people walk out of the train station. If you keep that up long enough, you will be able to get results - but a lot of things could mess with your measurements!

On a final note, it might well turn out that neutrinos do not travel faster than light, but that there is another reason why we are getting these results. That might in itself be almost as interesting!

Saturday, July 23, 2011

A prior art post: wifi OR bluetooth for powersaving

While singing my lovely son to sleep just now, an idea popped up in my head which I'm hoping is not yet patented. If it isn't, this post should kill any chances of that ever happening. Here goes.

Bluetooth and Wifi on smartphones both draw power, even when there is no actual Wifi or Bluetooth connection active - the mere act of listening for a potential pairing costs energy.

However, when I'm on my home Wifi, I am never on Bluetooth. When I'm connected to Bluetooth, I'm never eager for a wireless connection.

Thus, wouldn't it be nice if there was a piece of software that shutdown the Bluetooth listener if connected to Wifi? And if that Wifi goes out of range, turn off the Bluetooth again. If that leads to a connection, shut down the Wifi listener.

I'm pretty sure that for many use cases (people with wifi at home and at the office, and bluetooth handsfree in the car), this would save like.. joules per day! ;-)

This post was of course inspired by my phone shutting down while I was reading the web while singing my son to sleep.

So - feel free to make this appear on the Android market or the appstore. And who knows, it might be there already.