Iked/c (VPN) in a Docker container

Setting up an IKE VPN in privileged Docker container.

This is a bit of a personal project however I felt it highlighted the power of Docker, specifically around the fact you can ship your application with underlying OS level dependencies in a container, even if your target host has a different version. I'm sure you can realise the power there of being able to ship OS dependencies with your app, thus guaranteeing compatibility with any host that can run a Docker container.

In this particular example I am needing to connect to an IKE VPN which was presenting itself with a rather old 1024bit certificate. Now it's widely accepted that 2048bit should be the minimum, and all of a sudden after a recent openssl and IKE update on my machine I was no longer able to connect to IKE VPNs where the servers CA certificate was 1024bit. Unfortunately the end point I was connecting to had no intention of updating their certificates and time soon, and I wasn't going to downgrade my openssl version just to support their outdated endpoint - and herein lies the power of containers.


Docker is effectively Chroot on steroids, but fundamentally we create a filesystem which we executed programs within, and they can only access the filesystem within that "chrooted" jail. In means we can definitively control which versions of libraries our applications use. In this case, we're wanting to create a chroot jail which contains a version of openssl which allows us to connect to 1024bit endpoints.

When I say, "Chroot on steroids", it wraps all the aspects of creating the jail in a nice little Dockerfile syntax. Below is the Dockerfile I use to basically use centos 6 as a base, I downgrade openssl to 1.0.1e-30, I install the dependencies for iked/c, and then set the entrypoint of the container (what to run when the container starts):

FROM centos:6
MAINTAINER Karl Stoney <[email protected]> 

RUN yum -y install openssl-devel
RUN yum -y downgrade openssl-1.0.1e-30.el6_6.4 openssl-devel-1.0.1e-30.el6_6.4
RUN yum -y install wget tar cmake gcc gcc-c++ libedit-devel flex bison 

RUN cd /tmp && \ 
    wget https://www.shrew.net/download/ike/ike-2.2.1-release.tgz && \
    tar -xzf ike-* && \
    cd ike* && \
    make && \
    make install && \
    make install && \
    rm -rf /tmp/ike*

RUN mv /etc/iked.conf.sample /etc/iked.conf

VOLUME /sites
WORKDIR /sites

COPY start-iked.sh /usr/local/bin/start-iked.sh
ENTRYPOINT ["/usr/local/bin/start-iked.sh"]

You can see the full project on my github at https://github.com/Stono/ike

Using the container

If you actually have a use for this container, I've already published it to the Docker Registry so you simply type:

docker run --rm -it --privileged --net=host -v ~/.ike/sites:/sites stono/ike SiteName Username Password

What we're doing here is mounting in our local ~/.ike/sites directory into /sites in the container, starting the site SiteName with the user Username and the password Password. What you should get when you run the command, is a successful VPN connection:

IKEd started.
Starting IKEc for SiteName...
ii : ## : VPN Connect, ver 2.2.1
## : Copyright 2013 Shrew Soft Inc.
## : press the <h> key for help
>> : config loaded for site 'EMEA'
>> : attached to key daemon ...
ii : created ike socket
ii : created natt socket
## : IKE Daemon, ver 2.2.1
## : Copyright 2013 Shrew Soft Inc.
## : This product linked OpenSSL 1.0.1e-fips 11 Feb 2013
>> : peer configured
>> : iskamp proposal configured
>> : esp proposal configured
>> : client configured
>> : local id configured
>> : remote id configured
>> : server cert configured
K! : recv X_SPDDUMP message failure ( errno = 2 )
ii : bringing up tunnel ...
!! : peer violates RFC, transform number mismatch ( 1 != 14 )
!! : phase1 packet ignored, resending last packet ( phase1 already mature )
!! : phase1 packet ignored, resending last packet ( phase1 already mature )
>> : network device configured
!! : config packet ignored ( config already mature )
ii : tunnel enabled
!! : config packet ignored ( config already mature )
!! : peer violates RFC, transform number mismatch ( 1 != 32 )
^CDetected SIGTERM, shuting down...
Stopping ikec...
Stopping iked...