Funkensturm: a versatile DNS proxy

January 23, 2011

programming

What’s a DNS proxy?

A proxy is something this sits between a client and a server and does something with the data flowing through it. So a DNS proxy does this for DNS packets.

How does Funkensturm work?

Funkensturm consists out of 3 configuration parts:

  1. A setup function for the initial setup.
  2. Match/Modify function(s) — This function checks the packet for configured properties. If there is match true is returned.
  3. Action function(s) — Taking the truth value from 2. (and the packet) as input, it does something with it.

With this setup you can change incoming packets before they are send through to the server. And you can change packet coming from the server that are send back to the client.

The image above shows the architecture and the stages of Funkensturm. The number shows the stage were you can influence the packet.

  1. A packet comes in (IN gets set), you can modify it at your heart’s content. In the example config_delay the delaying happens here;
  2. Action function is called, often it will forward the packet to a server. You can for instance broadcast packets to multiple servers, that would typically happen here;
  3. Reply packets; they go through the match/modify function again (OUT gets set). Only the modification is important. On the fly signing happens here for instance. The example config_sign shows how to do that;
  4. The packet gets send back to the client. If any of the above functions returns a nil packet, nothing is send back.

The match/modify functions are chained (ala Unix pipes), the input packet to the function[N+1] is the output packet from function[N]. They are also chained in the logical sense of the word:

outcome = true AND funcion[N] AND/OR function[N+1]

outcome is given to the action function(s), so they can decide what to do to packets that match the criteria and those that don’t.

The match/modify functions are re-used on the way back, so you have a last change to change the packet before it is send to the client. If this stage is reached a packet is always send back, unless it is nil.

Configuring Funkensturm

I contemplated a “simple” configuration syntax, which would then be translated to Go code. But making a flexible and simple syntax is hard and there will always be stuff you can not express using this syntax. In the end this will lead to a complex language which still won’t fulfill all your needs.

Therefor I opted to configure Funkensturm directly with Go. I.e. you have to recompile Funkensturm for new configuration to take effect. Luckily with Go this takes about half a second. This has advantages (you don’t need to learn a complex config language) and disadvantages (you’ll have to learn Go syntax (your life will never be the same.)you’re millage may vary.

I’m playing with the idea of interpreted Go code (exp/eval package) to make this more dynamic, but this will not happen any time soon.

In upcoming posts I will detail some proxy configurations and show actual code.

Current status

Code works, but needs to be cleaned up. I expect this too happen in the coming days or weeks - at the most. The code is included as an example in the Go DNS package and can be compiled if you have the Go language installed. See the directory _example/funkensturm for the code and examples.

The name

Why Funkensturm? I just wanted a cool sounding German name for this project, like Stacheldraht, but different. Thanks to Twitter and @__sporkbomb it became the name.

Golang