Funkensign

How about on-the-fly signing? In this example we add a signature to any packet dealing with www.example.org. Again it is a matter of defining the matching, action and setup functions.

Matching

We don’t have to match anything coming in, we only need to sign pkts on their way out. So the function becomes:

func match(m *dns.Msg, d int) (*dns.Msg, bool) {
        // Matching criteria
        switch d { 
        case IN: 
                // nothing
        case OUT:
                // nothing
        }   
        // Packet Mangling
        switch d { 
        case IN: 
                // nothing
        case OUT:
                if m.Question[0].Name == "www.example.org." {
                        // On the way out sign the packet
                        m = sign(m) // keys are global
                }   
        }   
        return m, true
}

As you can see, it calls the sign() function where the actual signing takes place. We just sign the first RR in the answer section — if there is one.

Read more →

Funkensturm: delaying proxy example

Another application for Funkensturm is: delaying packets. Here we only delay packets with the recursion desired bit (RD) set, but it can be easily be changed to check for other properties of a packet, see godoc dns for all elements of DNS packets.

The configuration is similar as described here.

Matching pkts with RD bit set

The matching function becomes:

// the only matching we do is on the RD bit
// for incoming packets.
func match(m *dns.Msg, d int) (*dns.Msg, bool) {
        // Matching criteria
        var ok bool
        switch d {
        case IN:
                // only delay pkts with RD bit 
                ok = m.MsgHdr.RecursionDesired == true
        case OUT:
                // nothing
        }

        // Packet Mangling
        switch d {
        case IN:
                // nothing
        case OUT:
                // nothing
        }
        return m, ok
}

Action function

First a delay helper function. As shown here it returns true if the delay time isn’t reached, and false if a something should be delayed.

Read more →

Funkensturm: transparent proxy example

A transparent proxy is a proxy that does nothing, but it serves as a nice introduction into Funkensturm.

See this post for an architectural overview of Funkensturm.

Currently a configuration is compiled into the Funkensturm binary. As such it must look like a normal Go program.

Matching function

The matching function checks a packet for features and can optionally modify it.

This is the prototype of a matching function:

func match(m *dns.Msg, d int) (*dns.Msg, bool)

It receives a *dns.Msg which is a packet in Go DNS and a direction d which can be IN (first incoming packet) or OUT when the packet is on its way back to the client. It returns a DNS packet and a boolean value signaling a match.

Read more →

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:

  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.

Read more →

DNSSEC validation in Go for fun and profit

Doing cryptography is hard, luckily there are enough libraries out there that help you with it. OpenSSL is probably one of the best (known). Go has its own crypto library, which is written in pure Go.

Now with these aids crypto becomes doable for mere mortals, but all these libraries work with buffers which hold the data, the signature and sometimes the key also. Off-by-one errors in composing these buffers leads to a “Bogus signature” error (in DNSSEC). The problem here is that you don’t get any other clue on what went wrong. For me as a programmer an error such as “Shift buffer A one byte to the left and you’re OK”, would be much better. But due to the nature of crypto these kind of errors are not possible, nor desirable.

Read more →

Go DNS and AXFR

I’ve implemented axfr in my Go DNS library in nice and Go-like way (at least that’s what I like to think). Starting an axfr results in a channel which can then be used with the range keyword to loop over it, until the entire axfr is received.

Using it

First the normal begin of a Go program:

package main
import (
    "fmt"
    "dns"           // DNS package
)

Then we start the main function in which we define a new resolver and a channel for receiving the axfr messages. The channels will send dns.xfr messages which is defined as:

Read more →

(Re)announcing GoDNS

[ post updated to reflect changes in the library ]

This library takes a new, innovative and enterprise ready approach sends and receives queries to and from the DNS.

The library was forked from the official DNS code in Go (in the net package). Since that time Go team has thrown out this code and started to use the system’s C library via a wrapper. I was however struck by the elegance of the code (esp. the pack and unpack functions), so I forked it and added new record types (AAAA, DS, RRSIG, etc.) and turned into a more general DNS API.

Read more →

Learning Go - version 0.2

This morning I’ve tagged version 0.2 of “Learning Go”. Among the larger changes is that “Interfaces” is now a separate chapter.

I have also removed/added/updated the text. Fixed mistakes in the text and code (and probably added new ones).

To get it:

Feedback is welcome.

Of course a lot of work still needs to be done:

  • (Finally) fix all the exercises;
  • Test/Retest if all the Go code works with the latest compiler;
  • Finish the last chapters (chapter 6,7 and 8);
Read more →

Go book update

I’m preparing a 0.2 version of the Go book I’m writing. There are lots of small tweaks in the text and in the layout. I still need to extend the number exercises (and enhance the answers a bit), but it is slowly coming together.

There is a new chapter on how to write programs that communicate with the outside world (via files, sockets, etc.).

Some infrastructure work includes an automatic code checker — sadly written in Perl.

Read more →

Go number cruncher

Write a number cruncher that works as follows:

  • Pick six (6) random numbers from this list:

    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25, 50, 75, 100
    

    Numbers may be picked multiple times.

  • Pick one (1) random number (i) in the range:

    1 . . . 1000
    

  • Tell how, by combining the first 6 numbers or or subset with the operators +,-,* and /, you can make i;

Read more →

Learning Go - version 0.1

I’ve tagged an 0.1 version of the book I’m writing: “Learning Go”. It currently has 7 chapters. The first five are finished. Chapter 6 and 7 still need work. The exercises can also use some (more) love. The current chapter list of “Learning Go” is:

  1. Introduction
  2. Basics
  3. Functions
  4. Packages
  5. Beyond the basics
  6. Concurrency
  7. Communication

To get it:

If you have comments, text or exercises feel free to drop an email.

Read more →

Formatting Go code with Vim

There are no formatting rules when writing Go code, but there is an official style. If you pipe your code through gofmt, its output is the official style. So while writing you need to occasionally execute: %!~/bin/gofmt (which I’ve wrapped in a command, so I only need to type :Fmt).

But the trouble is that executing this code resets the cursor to the first line and you then have to jump back to whatever line number you were on.

Read more →

Go DNS online

The last couple of days I’ve been working on (better) DNS support in Go. I think it would be very nice to get something like ldns in Go, but then in less lines of code.

I’ve just published the first code on godns @github. This is heavily based on the DNS implementation currently in Go, in the net-package. Current additions consist of:

  • AAAA support;
  • Parsing rdata to hex or base64;
  • Groundwork for DNSSEC types (DS, DNSKEY, RRSIG);
  • Groundwork for EDNS0.

More info (well not a lot at the moment) can be found here.

Read more →

Go Book

I’m writing a book about Go. It is very much a work-in-progress, but I just wanted to mention this work and publish a snapshot. The aim is to explain Go and to provide many (many) exercises (and answers) so people may learn this wonderful language.

It is written using LaTeX (of course), see gitweb for the code.

Help is appreciated. The pdf of today (aka daily build) can be found here.

The title page looks like this:

Read more →

Go tutorial in Dutch

During the last few weeks I’ve attempted to translate the Go tutorial to Dutch. This was a lot more work than anticipated and I’m still not finished, but I just wanted to share what I’ve got up to now.

You can get the text version here.

Things do

  • Finish translating the last few paragraphs;
  • Proof read;
  • Spell check;
  • Update it to the latest Go release;
  • Get this included in Go?
Read more →

map function in Go

There is better stuff in the standard Go release but I wanted to try something for myself. In Go, this function is also called Map(), but is (of course) nicer. Anyhow, I’m liking this Go stuff more and more. Next I want to rewrite the DNS stuff in Go.

package main

import (
    "fmt"
)

type e interface{}

func mult2(f e) e { 
    switch f.(type) {
    case int:
	    return f.(int) * 2 
    case string:
	    return f.(string) + f.(string)
    }   
    return f
}

func Map(n []e, f func(e) e) {
    for k, v := range n { 
	    n[k] = f(v)
    }   
}

func main() {
    m := [...]e{1, 2, 3, 4}
    s := [...]e{"a", "b", "c", "d"}
    Map(&m, mult2)
    Map(&s, mult2)
    fmt.Printf("%v\n", m)
    fmt.Printf("%v\n", s)
}
Read more →