From TCP to TLS in Go

In this post we will have a look at a simple TCP example in Go and how it can be changed to use secure TLS instead.

Plain TCP server

First let's have a look at a simple TCP server. It listens on port 8088 and prints everything it receives to stdout.

Plain TCP client

Next we have a client that will send a message to the above server.

clienttcp/client.go

If you start the server and then execute the client you should see a "Hello Server" message printed by the server.

Until now everything is written in cleartext over the wire so let's see if we can make it more secure by using TLS.

Going TLS

The TLS certificates in the code are created using the following OpenSSL commands:

We start by adding TLS support to our server and client manually and then improve the code by using the shortcuts provided by the Go standard library.

TLS server v1

To enable TLS in the server we need to setup the configuration to do, this add the private key serverKey and the server certificate serverCert and pass it as certificates to tls.Config.

After this we start a normal server like before and enter our loop that is accepting new connections. However after a connection is accepted we wrap the connection connp with a tls.Server. This effectively makes the connection a TLS connection. After this the connection conn can be used as before.

Now that we have our Server TLS enabled we need to do the same for our client to make it able to talk to the server.

TLS client v1

Again we need to add a root certificate rootCert the client uses to verify the server certificate and pass this to tls.Config.
After this we connect to the server as before but before reading or writing any date we wrap the connection in a tls.Client which converts it to a TLS connection. Please note that we need to pass the server name "localhost" to tls.Config so it is able to verify the server certificate is correct. This is because tls.Client doesn't know the value passwd to net.Dial. We will improve on this later.

Improving TLS

No we added TLS support "manually". This is not ideal and also is not very good to handle errors. Go provides some better methods to setup a TLS server and client.

TLS server v2

In version 1 of the server we were wrapping every connection using tls.Server. In this new improved version we directly wrap the listener returned by net.Listen. This way if we call the listeners Accept method we directly get a TLS connection.

This is already better but we can improve even more.

TLS server v3

In version 3 instead of wrapping the connection (v1) or the listener (v2) we directly use the tls.Listen method, this replaces net.Listen and takes care of all the TLS stuff for use.
Now the server looks again quite similar to the plain TCP version, the only overhead comes from the certificate and key handling.

Now that we optimized the server let's see if we can do the same with the client.

TLS client v2

Here we don't wrap the connection but instead of using net.Dial we are directly using tls.Dial.
This is everything, the client is now almost as simple as the plain TCP one.
It's woth noting that we no longer need to explicitly pass the address of the server as we had to do with version 1 as the tls.Dial function takes care of this for us.

New Unison (2.40.102) builds available

I recently updated the Unison version in my PPA.

https://launchpad.net/~pascal-bach/+archive/unison

The current version is 2.40.102. This version is taken from the Debian git sources and build without modifications.

The package is available for the following Ubuntu versions:

  • 10.04 LTS (lucid)
  • 12.04 LTS (precise)
  • 12.10 (quantal)
  • 13.04 (raring)

If you encounter any problems please let me know.

Using Cygwin SSH with Putty Pageant

On windows I mostly use Putty as my SSH client. But in some cases for example when I use unison or rsync I use the ssh client from cygwin.

Following good practice I use public key authentication and Putty's Pageant to manage my password protected keys. This works great with Putty and Plink. I thought this would be great if I could use the same agent for cygwin too. As often the solution already existed in the form of ssh-pageant.

Here is a small tutorial how to set it up:

  1. Download the prebuilt version of ssh-pageant from github (direct link).
  2. Upack it and copy the ssh-pageant.exe to your cygwin's /usr/local/bin directory
  3. You need to edit your .bash_profile file in order to start the ssh-pageant on opening a shell
    The method I use is different form the one described in ssh-pageant's readme as it only starts one instance of ssh-pageant and reuses this in subsequent sessions. It is based on the Github Help about ssh keys.

Update: In never versions the --reuse
makes things a lot easier. (Thanks sun for pointing this out)

Add this at the end of your .bashrc

See https://github.com/cuviper/ssh-pageant/pull/19

Now you should be able to login using cygwin's ssh.exe with the same comfort of putty.

Use Zentyal Zarafa z-push with an N900

Today I had the problem that my Nokia N900 Mail for Exchange could not sync with my Zentyal server via Active Sync. After some research I found a solution in the Zarafa forum.

It consists of activating LOOSE_PROVISIONING in your z-push config.php.
If you are using Zentyal 2.0 this is located at /usr/share/z-push/config.php and you have to change the line:

to

now it should work.
Unfortunately I'm not sure if this gets overwritten during the next update!

Build Ubuntu/Debian packages from source (and apply a patch)

Sometimes there is a bug in a package from ubuntu that is not yet fixed, or you just want to modify something in the source of a software. Here is an easy way to build your own package from the ubuntu sources.

First you need to install the required tools for building software from source

Let's assume you want to build a package called foo and apply a patch bar.patch to it.

First you have to download the necessary build dependencies for foo

Now you are ready to download the actual sources of the package (Don't use sudo here!!)

This gives you a directory called foo-<version> you can now cd into it apply the patch and build the package

Now you have a package called foo-<version>.deb in the same directory where you have run apt-get source. You can install it using dpkg.

Automatically start SCREEN on SSH login

I just found a nice method to invoke screen automatically if after login via SSH. So you don't have to manually start it first.

Put the following at the end of your ~/.bashrc

If you want more details and some additional tricks just go to http://taint.org/wk/RemoteLoginAutoScreen.

Wuala rc.d Script for Archlinux

Recently I published an init.d script for debian/ubuntu to start wuala in headless mode. Since some time now I have a mediacenter running on Archlinux so the debian init.d script needed some change to run properly. I'm currently putting together a package to install wuala on archlinux with via pacman. In the meantime I will publish the rc.d script  in case someone wants to install wuala manually following the instructions found here.

/etc/rc.d/wuala (download)

Upadte: Use wualacmd instead of wuala. (Thanks to http://www.synergeek.fr/2010/06/wuala-sous-linux/ for the hint)

HP Printer drivers (hpijs) for Mac OS X

Since I switched to Snow Leopard I was not satisfied with the printing drivers for my old HP OfficeJet 95. I used the included Gutenprint drivers. For text they worked ok, but images looked terrible.

Today I decided to do something about it. From Linux I know that HPLIP has some pretty good driver (hpijs) for most HP Devices. Fortunately I can use the same drivers for Mac OS X to. You need three packages to do this. More information can be found on the website of the Linux Foundation.

http://www.linuxfoundation.org/collaborate/workgroups/openprinting/macosx/hpijs

This should help you get your old HP Printer working.

How to enable ALSA Analog 5.1 Sound on Nvidia ION

I recently had the problem to enable 5.1 Sound with 3 click outputs on an Nvidia ION board. By default Linux configures it with only one plug configured as output. After some research I found a solution in the OpenSUSE Wiki you have to set during module loading to get it working.
Basically you have to add

to your modeprobe.conf to tell the driver to use all its 3 plugs as output. After you loaded the modules like this, alsamixer will show you all the 6 channels, so you can unmute them.