Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker-compose local development setup #3

Merged
merged 1 commit into from
Jan 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
strong-duckling
strong-duckling-linux
.vscode
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
# strong-duckling
Strongswan sidecar and VPN tooling

## Local development setup
To use the test setup start a linux build watcher (requires nodemon) like this:

```bash
./build-linux.sh
```

In a separate terminal start the docker-compose configuration:

```bash
docker-compose up -d
```

This will start 2 linked docker containers each running:

* StrongSwan VPN
* A small nodejs HTTP server on :8080
* strong-duckling

The setup is configured to automatically connect the 2 containers using StrongSwan through an IKE v2 tunnel. The machines have added internal IPs `10.101.0.1` and `10.102.0.1`.
3 changes: 3 additions & 0 deletions build-linux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

GOOS=linux GOARCH=amd64 nodemon --ext go -x "(go build -v -o strong-duckling-linux || exit 1)"
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/bash

nodemon --ext go -x "go build -v || exit 1"
nodemon --ext go -x "(go build -v -o strong-duckling || exit 1)"
35 changes: 35 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
version: "3.7"
services:
strongswan1:
build:
context: strongswan
dockerfile: Dockerfile
privileged: true
environment:
STRONGSWAN_VERSION: 5.8.1
VPN_LOCAL_PEER: strongswan1
VPN_LOCAL_NETWORK: 10.101.0.1
VPN_REMOTE_PEER: strongswan2
VPN_REMOTE_NETWORK: 10.102.0.1
STRONG_DUCKLING_ARGS: "--listen :8000"
volumes:
- type: bind
source: ./strong-duckling-linux
target: /strong-duckling

strongswan2:
build:
context: strongswan
dockerfile: Dockerfile
privileged: true
environment:
STRONGSWAN_VERSION: 5.8.1
VPN_LOCAL_PEER: strongswan2
VPN_LOCAL_NETWORK: 10.102.0.1
VPN_REMOTE_PEER: strongswan1
VPN_REMOTE_NETWORK: 10.101.0.1
STRONG_DUCKLING_ARGS: "--listen :8000"
volumes:
- type: bind
source: ./strong-duckling-linux
target: /strong-duckling
54 changes: 54 additions & 0 deletions strongswan/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
FROM docker.io/library/ubuntu:16.04
ARG STRONGSWAN_VERSION=5.8.1

RUN \
apt-get update &&\
apt-get install -y \
build-essential \
libgmp-dev \
libunbound-dev \
libldns-dev \
pkg-config \
libsystemd-dev \
wget \
curl \
supervisor

RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - &&\
apt-get install -y nodejs
RUN npm install nodemon -g

RUN \
wget https://download.strongswan.org/strongswan-$STRONGSWAN_VERSION.tar.gz &&\
wget https://download.strongswan.org/strongswan-$STRONGSWAN_VERSION.tar.gz.md5 &&\
md5sum -c strongswan-$STRONGSWAN_VERSION.tar.gz.md5
RUN \
tar xvzf strongswan-$STRONGSWAN_VERSION.tar.gz &&\
cd strongswan-$STRONGSWAN_VERSION &&\
./configure \
--prefix=/usr \
--sysconfdir=/etc \
--enable-eap-mschapv2 \
--enable-kernel-libipsec \
--enable-swanctl \
--enable-unity \
--enable-unbound \
--enable-vici \
--enable-xauth-eap \
--enable-xauth-noauth \
--enable-eap-identity \
--enable-md4 \
--enable-pem \
--enable-openssl \
--enable-pubkey \
--enable-farp \
--enable-systemd \
--disable-charon \
--disable-stroke \
--disable-scepclient &&\
make &&\
make install

ADD . /

CMD ["/start.sh"]
9 changes: 9 additions & 0 deletions strongswan/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const http = require('http');

const requestListener = function (req, res) {
res.writeHead(200);
res.end('Hello from ' + process.env.VPN_LOCAL_PEER + "\n");
}

const server = http.createServer(requestListener);
server.listen(8080);
88 changes: 88 additions & 0 deletions strongswan/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/bin/bash

# turn on bash's job control
set -m
ip=$(hostname -I)

# Add internal IP
ip address add $VPN_LOCAL_NETWORK/32 dev eth0
# Add route for remote network over internal IP
ip route add $VPN_REMOTE_NETWORK/32 via $VPN_LOCAL_NETWORK

cat <<EOF >/etc/swanctl/swanctl.conf
connections {
gw-gw {
local_addrs = $ip,$VPN_LOCAL_PEER
remote_addrs = $VPN_REMOTE_PEER

local {
auth = psk
id = $VPN_LOCAL_PEER
}
remote {
auth = psk
id = $VPN_REMOTE_PEER
}
children {
net-net-0 {
local_ts = $VPN_LOCAL_NETWORK/32
remote_ts = $VPN_REMOTE_NETWORK/32
updown = /usr/libexec/ipsec/_updown iptables

rekey_time = 5400
rekey_bytes = 500000000
rekey_packets = 1000000
esp_proposals = aes256-sha256-ecp384

start_action = start
close_action = start
dpd_action = start
}
}
version = 2
mobike = no
reauth_time = 10800
proposals = aes256-sha256-ecp384
}
}

secrets {
ike-1 {
id-local = $VPN_LOCAL_PEER
id-remote = $VPN_REMOTE_PEER
secret = "123456"
}
}
EOF

mkdir -p /etc/supervisor/conf.d/
cat <<EOF >/supervisord.conf
[supervisord]
nodaemon=true

[program:charon]
command=/usr/sbin/charon-systemd
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
stderr_logfile=/dev/fd/2
stderr_logfile_maxbytes=0

[program:http-server]
command=node /server.js
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
stderr_logfile=/dev/fd/2
stderr_logfile_maxbytes=0

[program:strong-duckling]
command=nodemon --signal SIGTERM --watch /strong-duckling -x "/strong-duckling $STRONG_DUCKLING_ARGS || exit 1"
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
stderr_logfile=/dev/fd/2
stderr_logfile_maxbytes=0
EOF

/usr/bin/supervisord -c /supervisord.conf &
sleep 2
/usr/sbin/swanctl --load-all --noprompt
fg %1