Reverse DNS proxy

Have a slow nameserver and want to spice things up? How about a reverse DNS proxy? For lack of a cool name I chose the name FunkenShield. It’s (of course) in the early stages, but it works quite nicely already.

This is done with the framework of FunkenSturm. Which is part of GoDNS.

How it works:

You place FunkenShield in front of your nameserver and it will cache the binary packets coming from your server in a local cache.

Read more →

On programming languages and programmers

Very well written email message from Geoff Teale on the golang mailing list on programmers and progamming languages (thread).

To summarise a long presentation I gave to non-programmers:

  • There are 12 million programmers in the world
  • The majority of those programmers are scarcely qualified
  • Most technology decisions are made by a combination of following the crowd and a false understanding of risk.
  • The high cost and failure rate in software development is no coincidence.

Remember the Stevie Wonder rule - “When you believe in something you don’t understand then you suffer”. In this case that means “Perhaps making programming language decisions based on what 12 million powerless idiots are doing isn’t the golden road to glory and great hacks.”

Read more →

Go DNS (update)

I’m finally back to coding Go DNS and making it work with the latest Go releases. Also the API has changed quite significantly since the last time I blogged about it.

So this I will detail key2ds which is small utility that queries a zone and print any DNSKEY records as DS records on the fly, to show the new API and some sample usage.

% ./key2ds sidn.nl
sidn.nl.    0   IN  DS  42033 8 1 343F74674D36C9B5BE2CEB2C401AC4EDEB2A05B2
sidn.nl.    0   IN  DS  42033 8 2 BF985EC0738FACC89EE0B12FBD9261827C59191D9EA6A9BDFF55F9BDF3DBBFF3
sidn.nl.    0   IN  DS  39274 8 1 E79E031DFDE8E68EF1E2C6CA0943C2CC0DED1889
sidn.nl.    0   IN  DS  39274 8 2 8E8A8CFB40FD0C30BFA82E53752E1C257DAFB7B6206D12B9EDA43AF3EAB2157D

This util uses synchronous queries. I will explain the main-function:

Read more →

DNS reflector server in GO

I’m (again) rewriting the API of godns. I’ve now taking a cue from the http package in Go, the result seems very nice. A reflector (returns your query in the answer) in Go becomes:

package main

import (
        "dns"
        "log"
)

func ReflectServer(w dns.ResponseWriter, req *dns.Msg) {
        m := new(dns.Msg)
        m.SetReply(req)

        m.Extra = make([]dns.RR, 1)
        m.Extra[0] = &dns.RR_TXT{Hdr: dns.RR_Header{Name: m.Question[0].Name, Rrtype: dns.TypeTXT, 
                Class: dns.ClassINET, Ttl: 0}, Txt: "Hello world"}
        buf, _ := m.Pack()
        w.Write(buf)
}

func main() {
        dns.HandleFunc(".", ReflectServer)
        err := dns.ListenAndServe(":8053", "udp", nil)
        if err != nil {
                log.Fatal("ListenAndServe: ", err.String())
        }
}
Read more →

Learning Go - version 0.3

I’ve tagged a new version of “Learning Go”, version 0.3. It’s more of a snapshot of the current development, than an actual “release” release.

There are lots of fixes, code updates and tweaks. Numerous people send in fixes. Thank you all for the contributions!

Get it:

Feedback is welcome.

To see the development version you can use:

Major stuff coming in 0.4:

Read more →

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 →

Precise float placement

If you know LaTeX, you know that precise float placement (I want this figure to positioned right here) is almost impossible. But what nobody told you is that there exists a float package (only since 2001 - maybe even earlier). With this package you get a new placement modifier: [H], which means: “Put this damn figure right here!”.

LateX users everywhere cheer.

Specifics are described in the pdf in the package. Using it on Ubuntu/Debian

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 →

Computer Languages

I have done programming in (or at least looked at) the following computer languages during my live. Of course the world is not a perfect place, but some languages out there are just plain awful.

  • BASIC - with line numbers! At the time (I was 11) didn’t know there was something else out there. Fun and easy language, although I never programmed in it ever again.

  • Pascal - After BASIC, there is no going back to Pascal. Only briefly looked at it in my youth and discarded it in favor for BASIC…

Read more →

Go Book Building

I’m still “writing a Go Book” which boils down to playing with LaTeX, Go and Vim.

Building the whole document might be a bit tricky, because of all the packages you may need.

Assuming you already installed TexLive on your system, you will further need to apt-get install:

  • texlive-xetex
  • ttf-droid
  • latex-cjk-common
  • latex-cjk-japanese-wadalab
  • latex-cjk-xcjk
  • latex-xft-fonts
  • latex-fonts-recommended
  • ttf-sazanami-gothic
  • inkscape (for .svg to .pdf conversion)

Which should make it build. If not, please let me know.

Read more →

Remember text in LaTeX

After reading the Android Book from O’Reilly I saw some nice use of bullets alongside source code which allowed for extra explanation to be given after the code. I thought only one thing: I want to use that too, but then in LaTeX. After fiddling around for an evening it finally looked like this:

Nice bullets in LaTeX

There are two ways you can do this. The easy way is to write a few macros which create numbered bullets in the code and then use these numbers manually after the code to add your explanation. There are however problems with this approach; You need to manually keep the numbers in sync and thus it distracts you from focussing on the text.

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 →

LaTeX Nirvana

I’m no fan of Word or OpenOffice for that matter, all that WYSIWYG stuff is not for me. For years now I’m using LaTeX for my editing needs. An added bonus for using LaTeX is that the output is stunning.

But for really nice looking output I wanted the following:

  • Fonts in images/graphics should match the font of the main document
  • TrueType fonts, instead of the standard TeX fonts. To avoid the “Heeh, that looks like a LaTeX document”-reactions;
  • UTF-8 support and international character support;
  • Easy integration of images (SVG based);
  • Automatic building.

I’m using the following tools for 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 →

Prime sieve (in Go ofcourse)

After reading up on the prime sieve, and playing with Go for the past week I thought needed to implement this algorithm in Go and make it parallel.

I want to create a set (n in 2..N) goroutines. Each of these routines will check if it can divide a number (i) by n (integer division). If so the number i is not prime, otherwise it is given to the next goroutine. Communication between the goroutines is done via channels as in this example.

Read more →

More Go

Still learning and playing with Go, I’ve rewritten my cat experiment, to use a *bufio.Reader, which is more correct I think. I’m also slowly wrapping my mind around the concept of Interfaces. As a non-OO programmer (C and non-OO Perl) is starting to see why this is useful.

So today’s exercises:

  1. Write a cat implementation in Go. See below.
  2. Write a grep implementation in Go. See below.

Cat in go

package main

// A implementation of cat in Go

import (
    "os";
    "fmt";
    "bufio";
    "flag";
)

var numberFlag = flag.Bool("n", false, "number each line")

func cat(r *bufio.Reader) bool {
    i := 1;
    for {
	    buf, e := r.ReadBytes('\n');
	    if e == os.EOF {
		    break
	    }
	    if *numberFlag {
		    fmt.Fprintf(os.Stdout, "%5d  %s", i, buf);
		    i++
	    } else {
		    fmt.Fprintf(os.Stdout, "%s", buf)
	    }
    }
    return true;
}

func main() {
    flag.Parse();
    if flag.NArg() == 0 {
	    cat(bufio.NewReader(os.Stdin))
    }
    for i := 0; i < flag.NArg(); i++ {
	    f, e := os.Open(flag.Arg(i), os.O_RDONLY, 0);
	    if e != nil {
		    fmt.Fprintf(os.Stderr, "%s: error reading from %s: %s\n",
			    os.Args[0], flag.Arg(i), e.String());
		    continue;
	    }
	    if !cat(bufio.NewReader(f)) {
		    os.Exit(1)
	    }
    }
}

Grep in go

package main

// A implementation of Unix grep in Go
// TODO(mg) better error handling

import (
    "os";
    "fmt";
    "bufio";
    "regexp";
    "flag";
)

var numberFlag = flag.Bool("n", false, "number each line")
var filenameFlag = flag.Bool("l", false, "print names of matching files")

func grep(r *bufio.Reader, reg string) (match bool) {
    i := 0;
    for {
	    buf, e := r.ReadBytes('\n');
	    i++;
	    if e == os.EOF {
		    break
	    }
	    if m, _ := regexp.Match(reg, buf); m == true {
		    match = true;
		    if *filenameFlag {
			    return match
		    }
		    if *numberFlag {
			    fmt.Fprintf(os.Stdout, "%5.d:  %s", i, buf)
		    } else {
			    fmt.Fprintf(os.Stdout, "%s", buf)
		    }
	    }
    }
    return match;
}

func main() {
    flag.Parse();
    if flag.NArg() < 1 {
	    fmt.Fprintf(os.Stderr, "%s: missing regexp\n", os.Args[0]);
	    os.Exit(1);
    }
    if flag.NArg() == 1 {
	    if grep(bufio.NewReader(os.Stdin), flag.Arg(0)) {
		    if *filenameFlag {
			    fmt.Fprintf(os.Stdout, "(standard input)\n");
		    }
	    }
    }
    for i := 1; i < flag.NArg(); i++ {
	    f, e := os.Open(flag.Arg(i), os.O_RDONLY, 0);
	    if e != nil {
		    fmt.Fprintf(os.Stderr, "%s: error reading from %s: %s\n",
			    os.Args[0], flag.Arg(i), e.String());
		    continue;
	    }
	    if grep(bufio.NewReader(f), flag.Arg(0)) {
		    if *filenameFlag {
			    fmt.Fprintf(os.Stdout, "%s\n", flag.Arg(i))
		    }
	    }
    }
}
Read more →

cat in Go

After spending every free minute to Go I’m starting to get a feel for the language. Every one has to start somewhere, so I decided to “port” Unix utils to Go. I’m starting with cat, and thanks to the Go tutorial this is the result.

package main

// An implementation of Unix cat in Go

import (
    "os";
    "fmt";
    "flag";
)

func cat(filename string) bool {
    const NBUF = 512;
    var buf [NBUF]byte;
    if f, e := os.Open(filename, os.O_RDONLY, 0); e != nil {
	    fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n",
		    filename, e.String());
	    return true;
    } else {
	    for {
		    switch nr, _ := f.Read(&buf); true {
		    case nr < 0:
			    os.Exit(1)
		    case nr == 0:	// EOF
			    return true
		    case nr > 0:
			    if nw, ew := os.Stdout.Write(buf[0:nr]); nw != nr {
				    fmt.Fprintf(os.Stderr,
					    "cat: error writing from %s: %s\n",
					    filename, ew.String());
				    return false;
			    }
		    }
	    }
    }
    return true;
}

func main() {
    flag.Parse();	// implement -n TODO
    if flag.NArg() == 0 {
	    cat("/dev/stdin")
    }
    for i := 0; i < flag.NArg(); i++ {
	    if !cat(flag.Arg(i)) {
		    os.Exit(1)
	    }
    }
}

In something like 50 lines you have a cat program. I’m really starting to like Go. Next up: extra features and a grep command.

Read more →