summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--images/obfsvpn/Dockerfile40
-rw-r--r--images/obfsvpn/README.md31
-rw-r--r--images/obfsvpn/config/client.ovpn18
-rw-r--r--images/obfsvpn/config/server.conf26
-rw-r--r--images/obfsvpn/scripts/functions.sh45
-rwxr-xr-ximages/obfsvpn/scripts/start.sh101
-rwxr-xr-ximages/obfsvpn/scripts/start_obfs4.sh10
8 files changed, 278 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 8a356d1..da7027d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,7 @@
OBFS4_ENDPOINT ?=
OBFS4_CERT ?=
+TAG ?= 0.1
+OBFSVPN_IMAGE_NAME ?= leap/obfsvpn-test-server
certs:
curl -k https://black.riseup.net/ca.crt > /tmp/ca.crt
@@ -45,3 +47,8 @@ test:
check-yawning-obfs4:
./scripts/check-go-modules.sh
+
+obfsvpn-server-container:
+ docker build -t ${OBFSVPN_IMAGE_NAME}:${TAG} -f images/obfsvpn/Dockerfile \
+ . --no-cache
+
diff --git a/images/obfsvpn/Dockerfile b/images/obfsvpn/Dockerfile
new file mode 100644
index 0000000..9a779a3
--- /dev/null
+++ b/images/obfsvpn/Dockerfile
@@ -0,0 +1,40 @@
+FROM golang:1.17 AS build
+
+ENV SOURCE_PATH ${GOPATH}/src/0xacab.org/leap/obfsvpn
+COPY . ${SOURCE_PATH}/
+WORKDIR ${SOURCE_PATH}
+RUN cd server && make build && cp server /obfsvpn-server
+
+
+FROM alpine:3.14.1
+
+ENV APP_NAME Dockovpn
+ENV APP_INSTALL_PATH /opt/${APP_NAME}
+ENV APP_PERSIST_DIR /opt/${APP_NAME}_data
+ENV OBFS4_DATA_DIR /opt/obfsvpn-server-data
+ENV PROTO tcp
+ENV PORT 5540
+
+ENV OBFS4_HOST 0.0.0.0
+ENV OBFS4_PORT 4430
+
+WORKDIR ${APP_INSTALL_PATH}
+
+RUN apk add --no-cache openvpn easy-rsa bash netcat-openbsd zip dumb-init
+
+COPY --from=build /obfsvpn-server .
+
+COPY images/obfsvpn/scripts .
+COPY images/obfsvpn/config ./config
+COPY server/test_data ./obfsvpn-server-data
+
+RUN mkdir -p ${APP_PERSIST_DIR} && \
+ cd ${APP_INSTALL_PATH} && \
+ cp config/server.conf /etc/openvpn/server.conf
+
+EXPOSE 5540/tcp
+
+VOLUME [ "/opt/Dockovpn_data" ]
+
+ENTRYPOINT [ "dumb-init", "./start.sh" ]
+CMD [ "" ]
diff --git a/images/obfsvpn/README.md b/images/obfsvpn/README.md
new file mode 100644
index 0000000..5338513
--- /dev/null
+++ b/images/obfsvpn/README.md
@@ -0,0 +1,31 @@
+## Dockerized obfs4 and openvpn in a single container
+
+This is based on the [dockovpn/docker-openvpn](https://github.com/dockovpn/docker-openvpn) repository, it adds the `obfsvpn-server`
+binary and the required config files to start an instance of the server targetting the
+`openvpn` server running at port 5540 (default)
+
+A directory can be bind mounted to `/opt/Dockovpn_data` to persist the configurations of the
+`openvpn` server and additionally to copy out the `client.ovpn` file created at `/opt/Dockovpn/client/<client-id>/client.ovpn`
+
+The container recognises the following environment variables and can be used to override the
+default values:
+
+```
+OBFS4_HOST = 0.0.0.0 (default) # This is the OBFS4 server endpoint
+OBFS4_PORT = 4430
+HOST_ADDR = localhost # openvpn gateway ip
+PORT = 5540 # openvpn GW port
+PROTO = tcp # openvpn proto
+```
+
+### To test locally
+
+```
+$ make obfsvpn-server-container
+```
+
+Then run the container using the following command:
+
+```
+$ docker run -it --rm --privileged -p 4430:4430/tcp leap/obfsvpn:0.1
+```
diff --git a/images/obfsvpn/config/client.ovpn b/images/obfsvpn/config/client.ovpn
new file mode 100644
index 0000000..ae5db3a
--- /dev/null
+++ b/images/obfsvpn/config/client.ovpn
@@ -0,0 +1,18 @@
+client
+dev tun
+proto __PROTO__
+resolv-retry infinite
+nobind
+persist-key
+persist-tun
+cipher AES-256-GCM
+auth SHA512
+verb 3
+tls-client
+tls-version-min 1.2
+key-direction 1
+remote-cert-tls server
+;remote localhost 1194
+;ca ca.crt
+;cert client.crt
+;key client.key
diff --git a/images/obfsvpn/config/server.conf b/images/obfsvpn/config/server.conf
new file mode 100644
index 0000000..cbafe6c
--- /dev/null
+++ b/images/obfsvpn/config/server.conf
@@ -0,0 +1,26 @@
+port __PORT__
+proto __PROTO__
+dev tun
+ca /etc/openvpn/ca.crt
+cert /etc/openvpn/MyReq.crt
+key /etc/openvpn/MyReq.key
+dh /etc/openvpn/dh.pem
+server 10.8.0.0 255.255.255.0
+ifconfig-pool-persist ipp.txt
+push "redirect-gateway def1 bypass-dhcp"
+push "dhcp-option DNS 208.67.222.222"
+push "dhcp-option DNS 208.67.220.220"
+duplicate-cn
+keepalive 10 120
+cipher AES-256-GCM
+ncp-ciphers AES-256-GCM:AES-256-CBC
+auth SHA512
+user nobody
+group nobody
+persist-key
+persist-tun
+status openvpn-status.log
+verb 1
+tls-server
+tls-version-min 1.2
+tls-auth /etc/openvpn/ta.key 0
diff --git a/images/obfsvpn/scripts/functions.sh b/images/obfsvpn/scripts/functions.sh
new file mode 100644
index 0000000..f00ac38
--- /dev/null
+++ b/images/obfsvpn/scripts/functions.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+function datef() {
+ # Output:
+ # Sat Jun 8 20:29:08 2019
+ date "+%a %b %-d %T %Y"
+}
+
+function createConfig() {
+ cd "$APP_PERSIST_DIR"
+ CLIENT_ID="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)"
+ CLIENT_PATH="$APP_PERSIST_DIR/clients/$CLIENT_ID"
+
+ # Redirect stderr to the black hole
+ /usr/share/easy-rsa/easyrsa build-client-full "$CLIENT_ID" nopass &> /dev/null
+ # Writing new private key to '/usr/share/easy-rsa/pki/private/client.key
+ # Client sertificate /usr/share/easy-rsa/pki/issued/client.crt
+ # CA is by the path /usr/share/easy-rsa/pki/ca.crt
+
+ mkdir -p $CLIENT_PATH
+
+ cp "pki/private/$CLIENT_ID.key" "pki/issued/$CLIENT_ID.crt" pki/ca.crt /etc/openvpn/ta.key $CLIENT_PATH
+
+ # Set default value to HOST_ADDR if it was not set from environment
+ if [ -z "$HOST_ADDR" ]
+ then
+ HOST_ADDR='localhost'
+ fi
+
+ cd "$APP_INSTALL_PATH"
+ cp config/client.ovpn $CLIENT_PATH
+
+ echo -e "\nremote $HOST_ADDR $PORT" >> "$CLIENT_PATH/client.ovpn"
+
+ # Embed client authentication files into config file
+ cat <(echo -e '<ca>') \
+ "$CLIENT_PATH/ca.crt" <(echo -e '</ca>\n<cert>') \
+ "$CLIENT_PATH/$CLIENT_ID.crt" <(echo -e '</cert>\n<key>') \
+ "$CLIENT_PATH/$CLIENT_ID.key" <(echo -e '</key>\n<tls-auth>') \
+ "$CLIENT_PATH/ta.key" <(echo -e '</tls-auth>') \
+ >> "$CLIENT_PATH/client.ovpn"
+
+ echo $CLIENT_PATH
+}
+
diff --git a/images/obfsvpn/scripts/start.sh b/images/obfsvpn/scripts/start.sh
new file mode 100755
index 0000000..3a3bce5
--- /dev/null
+++ b/images/obfsvpn/scripts/start.sh
@@ -0,0 +1,101 @@
+#!/bin/bash
+
+source ./functions.sh
+
+mkdir -p /dev/net
+
+if ! [ -c /dev/net/tun ]; then
+ echo "$(datef) Creating tun/tap device."
+ mknod /dev/net/tun c 10 200
+fi
+
+# Following firewall configurations will be needed later on
+# for a functional deployment of obfsvpn
+ # Allow UDP traffic on port 1194.
+ #iptables -A INPUT -i eth0 -p udp -m state --state NEW,ESTABLISHED --dport 1194 -j ACCEPT
+ #iptables -A OUTPUT -o eth0 -p udp -m state --state ESTABLISHED --sport 1194 -j ACCEPT
+
+ # Allow traffic on the TUN interface.
+ #iptables -A INPUT -i tun0 -j ACCEPT
+ #iptables -A FORWARD -i tun0 -j ACCEPT
+ #iptables -A OUTPUT -o tun0 -j ACCEPT
+
+ # Allow forwarding traffic only from the VPN.
+ #iptables -A FORWARD -i tun0 -o eth0 -s 10.8.0.0/24 -j ACCEPT
+ #iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
+
+ #iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
+
+cd "$APP_PERSIST_DIR"
+
+LOCKFILE=.gen
+
+# Regenerate certs only on the first start
+if ! [ -f $LOCKFILE ]; then
+ IS_INITIAL="1"
+
+ /usr/share/easy-rsa/easyrsa init-pki
+
+ # DH parameters of size 2048 created at APP_PERSIST_DIR/pki
+ /usr/share/easy-rsa/easyrsa gen-dh
+
+ /usr/share/easy-rsa/easyrsa build-ca nopass << EOF
+
+EOF
+ # CA creation complete and you may now import and sign cert requests.
+ # Your new CA certificate file for publishing is at:
+ # /opt/Dockovpn_data/pki/ca.crt
+
+ /usr/share/easy-rsa/easyrsa gen-req MyReq nopass << EOF2
+
+EOF2
+ # Keypair and certificate request completed. Your files are:
+ # req: /opt/Dockovpn_data/pki/reqs/MyReq.req
+ # key: /opt/Dockovpn_data/pki/private/MyReq.key
+
+ /usr/share/easy-rsa/easyrsa sign-req server MyReq << EOF3
+yes
+EOF3
+ # Certificate created at: /opt/Dockovpn_data/pki/issued/MyReq.crt
+
+ openvpn --genkey secret ta.key << EOF4
+yes
+EOF4
+
+ touch $LOCKFILE
+fi
+
+# Copy server keys, dh file and certificates
+cp pki/dh.pem pki/ca.crt pki/issued/MyReq.crt pki/private/MyReq.key ta.key /etc/openvpn
+
+# Update proto and port in /etc/openvpn/server.conf
+sed -i -e "s/__PROTO__/${PROTO}/g" \
+ -e "s/__PORT__/${PORT}/g" /etc/openvpn/server.conf
+
+# Need to feed key password
+openvpn --config /etc/openvpn/server.conf &
+
+# By some strange reason we need to do echo command to get to the next command
+echo " "
+
+# backoff for openvpn to start
+sleep 20
+
+# Generate client config
+if [[ -n $IS_INITIAL ]]; then
+ CLIENT_PATH="$(createConfig)"
+ FILE_NAME=client.ovpn
+ FILE_PATH="$CLIENT_PATH/$FILE_NAME"
+ sed -i -e "s/__PROTO__/${PROTO}/g" "${FILE_PATH}"
+
+ echo "$(datef) Created ${FILE_PATH}."
+ # dirty hack: copy client config to root of APP_PERSIST_DIR
+ # for reusing in the obfsvpn-client container
+ cp "${FILE_PATH}" "$APP_PERSIST_DIR/"
+fi
+
+cd "${APP_INSTALL_PATH}"
+./start_obfs4.sh &
+
+tail -f /dev/null
+
diff --git a/images/obfsvpn/scripts/start_obfs4.sh b/images/obfsvpn/scripts/start_obfs4.sh
new file mode 100755
index 0000000..c73f604
--- /dev/null
+++ b/images/obfsvpn/scripts/start_obfs4.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+if [ -z "$HOST_ADDR" ]
+then
+ HOST_ADDR='localhost'
+fi
+
+cd "${APP_INSTALL_PATH}"
+./obfsvpn-server -addr ${OBFS4_HOST}:${OBFS4_PORT} -vpn ${HOST_ADDR}:${PORT} \
+ -state ./obfsvpn-server-data -c ./obfsvpn-server-data/obfs4.json -v