Certificates for GRPC with TLS posted on 20 March 2016

I haven’t blogged anything for the past few months because I have been busy working on a few projects using new shiny toys. One of them is gRPC, a high performance, open source, general RPC framework, which is based on Google’s internal Stubby RPC system.

This post is mostly about using TLS with gRPC in Golang, but if you are wondering what gRPC brings that HTTP/JSON does not, here are a few reasons on top of my head:

  • Better performance in respect to network compression, serialization etc.
  • Structured RPC.
  • Error tracing.

Anyway, if you want to use TLS with gRPC, you need to create a few certificates first. This script does it for you. Usage is gen.sh <host> <prefix> where host is the host on which your gRPC server is listening. The parameter prefix is just used to prefix the output files such that you can create prod and dev certificates.

PASSWORD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1`
HOST=$1
if [ -z $HOST ]; then HOST="localhost"; fi
PREFIX=$2
if [ -z $PREFIX ]; then PREFIX="dev"; fi

openssl genrsa -passout pass:$PASSWORD -des3 -out $PREFIX'server.key' 4096
openssl req -passin pass:$PASSWORD -new -x509 -days 3650 -key $PREFIX'server.key' -out $PREFIX'server.crt' -subj '/C=US/ST=CA/L=Sunnyvale/O=MyApp/CN='$HOST[email protected]'
openssl rsa -passin pass:$PASSWORD -in $PREFIX'server.key' -out $PREFIX'server.key'

Two files are created, a .crt and .key one. You can then create create a connection with:

creds, err := credentials.NewClientTLSFromFile(grpcCrtFile, host)
if err != nil {
  log.Fatalf("Failed to create TLS credentials %v", err)
}
opts := grpc.WithTransportCredentials(creds)
connection, err := grpc.Dial(g.address, g.opts)

Create your server with:

lis, err := net.Listen("tcp", *grpcHost+":"+strconv.Itoa(*grpcPort))
if err != nil {
  log.Fatalf("failed to listen: %v", err)
}

creds, err := credentials.NewServerTLSFromFile(grpcCrtFile, grpcKeyFile)
if err != nil {
  log.Fatalf("Failed to generate credentials %v", err)
}

s := grpc.NewServer(grpc.Creds(creds))
// Register your services here
s.Serve(lis)

Using Travis'container architecture posted on 02 December 2015

Last year, Travis announced faster builds with container-based infrastructure and Docker.

One requirement to use such infrastructure is to disable sudo with sudo: false at the top of your .travis.yml file.

If you were installing third party software using apt-get and sudo, you can just download the .deb package, and unpack it. For RethinkDB, you can run these commands:

wget http://download.rethinkdb.com/apt/pool/precise/main/r/rethinkdb/rethinkdb_2.2.1
ar x *.deb
ar xvzf data.tar.gz

You can then find your binary in ./usr/bin. For example, this is reqlite .travis.yml:

language: node_js
sudo: false
node_js:
  - "node"
before_install:
  - wget http://download.rethinkdb.com/apt/pool/precise/main/r/rethinkdb/rethinkdb_2.2.1~0precise_amd64.deb
  - ar x *.deb
  - tar xvzf data.tar.gz
before_script:
  - ./usr/bin/rethinkdb --daemon
  - npm install
  - ./bin/reqlite --port-offset 1 &
  - sleep 10
after_script:
  - rethinkdb
notifications:
  email: false

Docker without sudo, network issues posted on 05 September 2015

If you want to run docker without using sudo, you can add yourself to the docker group.

sudo usermod -aG docker <user>

In my case (Archlinux), this was not quite enough. Starting a container would work but without internet access. The main problem was that I was not part of the network groop.

sudo usermod -aG network <user>

Then things went smoothly.

Losing connectivity after a Chrome request posted on 30 August 2015

When I upgraded my kernel from 4.0.7-2 to 4.1.4.1 (and more recently to 4.1.6-1) I had a really annoying bug and since it wasted some of my time, I hope that this post may help someone.

After my 4.1 kernel update, I would start connected to the internet. I could ping any server, use wget, but as soon as I would make a request on Chromium or Firefox, I would “lose connectivity” after a few seconds. By loosing connectivity, the pings would timeout or fail with “Destination Host Unreachable”. Once of the reason I had a hard time finding the reason is that I had no errors reported by the kernel or the driver. The only way to get back a connectivity was to take down the interface and bring it back up.

Eventually, everything boiled down to my Qualcomm Atheros AR8161 driver. Increasing the MTU to 9000 fixed my problem as described on this archlinux bug