Funkensturm: a versatile DNS proxy
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:
- A setup function for the initial setup.
- Match/Modify function(s) — This function checks the packet for configured
properties. If there is match
true
is returned. - 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.
- A packet comes in (
IN
gets set), you can modify it at your heart’s content. In the exampleconfig_delay
the delaying happens here; - 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;
- 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 exampleconfig_sign
shows how to do that; - 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.