24 Commits
v0.1 ... v0.2

Author SHA1 Message Date
473671a4d0 Dockerfile: Shallow clone EasyRSA v3
* Do a shallow clone for a smaller checkout
* Condense multiple run lines to a single RUN line for a flatter image.
2014-12-05 14:07:00 -08:00
19f4c5cde4 Dockerfile: Clean-up after apt operations
* Delete old files to keep the image lean.
2014-12-05 13:55:53 -08:00
17ef8cebfc docs: advanced: Fix typo
* ... and feed the grammar Nazi
2014-11-16 10:06:04 -08:00
f07e4ad531 README: Remove mention of only UDP support
* This was fixed a while ago
  * 9951ca6ca2
* Closes #15
2014-11-16 10:01:59 -08:00
656be240b6 README: Add Digital Ocean reference
* Include promo code, because why not?
2014-10-29 08:06:31 -07:00
b06631099f Merge pull request #12 from compressed/dup_iptables
avoid dup iptables rules
2014-10-23 09:55:08 -07:00
be22048a2b avoid dup iptables rules 2014-10-23 09:16:51 -04:00
f05de3eb84 README: Fix Markdown indent
* Indent to get pre-formatted code box.
2014-10-06 22:34:27 -07:00
543292e124 Merge pull request #10 from adrianolek/patch-1
Use --cap-add=NET_ADMIN instead of --privileged
2014-10-06 22:22:30 -07:00
8c7d020074 Use --cap-add=NET_ADMIN instead of --privileged
Ovpn doesn't need all the capabilities.
https://docs.docker.com/reference/run/#runtime-privilege-linux-capabilities-and-lxc-configuration says:
For interacting with the network stack, instead of using --privileged they should use --cap-add=NET_ADMIN to modify the network interfaces.
2014-10-06 20:09:23 +02:00
a69ca8d65e Merge pull request #8 from disassembler/master
fixing regexp to allow dashes in OVPN_SERVER_URL
2014-08-17 12:53:31 -07:00
f1616f7196 fixing regexp to allow dashes in OVPN_SERVER_URL 2014-08-16 22:32:16 -04:00
d36bb7ecba getclient: Do not autogenerate key
* Do not autogenerate a key if it does not exist.  Instead fail.
* Requires users to explicitly generate keys and prevents generating
  erroneous keys in the event of a typo.
2014-07-10 09:55:06 -07:00
76a230b3be Merge branch 'docs' 2014-07-09 12:24:30 -07:00
5fd47763d7 README: Add --rm to init steps
* Don't need these containers to stick around polluting docker.
2014-07-09 12:23:48 -07:00
37f86037d8 advanced: Add advanced configs
* Copy paste stuff for using host mounted volumes
2014-07-09 12:21:50 -07:00
e9c5108a8f debug: Add mention of shells
* Very useful for getting in a running container or fix a data volume.
2014-07-09 12:21:38 -07:00
816eff9af6 docs: openvpn-data -> $OVPN_DATA
* Easier to work with.
2014-07-09 12:09:27 -07:00
c38b412dc6 Merge branch 'private_subnet'
Closes #5
2014-07-09 11:10:54 -07:00
b9cc5b347a genconfig: Convert OVPN_ROUTES to array
* Convert to an array to simplify the code.
* This breaks running `ovpn_genconfig` multiple times with the same
  route argument as the array will just grow.  This needs to be fixed in
  the future.
* Recommended way to work around this is to remove ovpn_env.sh.
2014-07-09 11:06:02 -07:00
20be0f90a5 genconfig: Add push support
* Add ability to specify push commands with `-p` argument.
2014-07-09 10:55:02 -07:00
0c873ab4cf genconfig: Print success
* Print success message to console. Provides positive feedback.
2014-07-09 10:53:41 -07:00
f263eb9a61 genconfig: Add client-to-client support 2014-07-09 10:53:25 -07:00
d5979915cf README: Use variable for volume container name
* Use a variable for the volume container name to simplify my life.
* I can set the variable and then copy/paste from the README.
2014-07-09 00:07:35 -07:00
9 changed files with 91 additions and 45 deletions

View File

@ -5,12 +5,13 @@ FROM debian:jessie
MAINTAINER Kyle Manna <kyle@kylemanna.com>
RUN apt-get update && apt-get install -y openvpn iptables git-core
RUN apt-get update && \
apt-get install -y openvpn iptables git-core && \
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Update checkout to use tags when v3.0 is finally released
RUN git clone https://github.com/OpenVPN/easy-rsa.git /usr/local/share/easy-rsa
RUN cd /usr/local/share/easy-rsa && git checkout -b tested 89f369c5bbd13fbf0da2ea6361632c244e8af532
RUN ln -s /usr/local/share/easy-rsa/easyrsa3/easyrsa /usr/local/bin
RUN git clone --depth 1 --branch v3.0.0-rc2 https://github.com/OpenVPN/easy-rsa.git /usr/local/share/easy-rsa && \
ln -s /usr/local/share/easy-rsa/easyrsa3/easyrsa /usr/local/bin
# Needed by scripts
ENV OPENVPN /etc/openvpn

View File

@ -2,28 +2,36 @@
OpenVPN server in a Docker container complete with an EasyRSA PKI CA.
Extensively tested on [Digital Ocean](https://www.digitalocean.com/?refcode=d19f7fe88c94).
## Quick Start
* Create the `openvpn-data` volume container
* Create the `$OVPN_DATA` volume container, i.e. `OVPN_DATA="ovpn-data"`
docker run --name openvpn-data -v /etc/openvpn busybox
docker run --name $OVPN_DATA -v /etc/openvpn busybox
* Initalize the `openvpn-data` container that will hold the configuration files and certificates
* Initalize the `$OVPN_DATA` container that will hold the configuration files and certificates
docker run --volumes-from openvpn-data kylemanna/openvpn ovpn_genconfig -u udp://VPN.SERVERNAME.COM:1194
docker run --volumes-from openvpn-data -it kylemanna/openvpn ovpn_initpki
docker run --volumes-from $OVPN_DATA --rm kylemanna/openvpn ovpn_genconfig -u udp://VPN.SERVERNAME.COM:1194
docker run --volumes-from $OVPN_DATA --rm -it kylemanna/openvpn ovpn_initpki
* Start OpenVPN server process
docker run --volumes-from openvpn-data -d -p 1194:1194/udp --privileged kylemanna/openvpn
- On Docker [version 1.2](http://blog.docker.com/2014/08/announcing-docker-1-2-0/) and newer
docker run --volumes-from $OVPN_DATA -d -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn
- On Docker older than 1.2 version
docker run --volumes-from $OVPN_DATA -d -p 1194:1194/udp --privileged kylemanna/openvpn
* Generate a client certificate without a passphrase
docker run --volumes-from openvpn-data --rm -it kylemanna/openvpn easyrsa build-client-full CLIENTNAME nopass
docker run --volumes-from $OVPN_DATA --rm -it kylemanna/openvpn easyrsa build-client-full CLIENTNAME nopass
* Retrieve the client configuration with embedded certificates
docker run --volumes-from openvpn-data --rm kylemanna/openvpn ovpn_getclient CLIENTNAME > CLIENTNAME.ovpn
docker run --volumes-from $OVPN_DATA --rm kylemanna/openvpn ovpn_getclient CLIENTNAME > CLIENTNAME.ovpn
## How Does It Work?
@ -106,13 +114,12 @@ packets, etc).
* Proper PKI support integrated into image
* OpenVPN config files, PKI keys and certs are stored on a storage
volume for re-use across containers
* Only offer UDP support for now, I don't have a good use case for TCP
* Addition of tls-auth for HMAC security
## Tested On
* Docker hosts:
* server a Digitial Ocean Droplet with 512 MB RAM running Ubuntu 14.04
* server a [Digital Ocean](https://www.digitalocean.com/?refcode=d19f7fe88c94) Droplet with 512 MB RAM running Ubuntu 14.04
* Clients
* Android App OpenVPN Connect 1.1.14 (built 56)
* OpenVPN core 3.0 android armv7a thumb2 32-bit

View File

@ -36,9 +36,11 @@ usage() {
echo " -u SERVER_PUBLIC_URL"
echo " [-s SERVER_SUBNET]"
echo " [-r ROUTE ...]"
echo " [-p PUSH ...]"
echo
echo "optional arguments:"
echo " -d Disable NAT routing and default route"
echo " -c Enable client-to-client option"
}
set -ex
@ -46,22 +48,17 @@ set -ex
OVPN_ENV=$OPENVPN/ovpn_env.sh
OVPN_SERVER=192.168.255.0/24
OVPN_DEFROUTE=1
OVPN_ROUTES=()
OVPN_PUSH=()
# Import defaults if present
[ -r "$OVPN_ENV" ] && source "$OVPN_ENV"
ORIG_OVPN_ROUTES=$OVPN_ROUTES
OVPN_ROUTES=""
# Parse arguments
while getopts ":r:s:du:" opt; do
while getopts ":r:s:du:cp:" opt; do
case $opt in
r)
if [ -n "$OVPN_ROUTES" ]; then
OVPN_ROUTES+=" $OPTARG"
else
OVPN_ROUTES+="$OPTARG"
fi
OVPN_ROUTES+=("$OPTARG")
;;
s)
OVPN_SERVER=$OPTARG
@ -72,6 +69,12 @@ while getopts ":r:s:du:" opt; do
u)
OVPN_SERVER_URL=$OPTARG
;;
c)
OVPN_CLIENT_TO_CLIENT=1
;;
p)
OVPN_PUSH+=("$OPTARG")
;;
\?)
set +x
echo "Invalid option: -$OPTARG" >&2
@ -89,7 +92,7 @@ done
# Server name is in the form "udp://vpn.example.com:1194"
if [[ "$OVPN_SERVER_URL" =~ ^((udp|tcp)://)?([0-9a-zA-Z\.]+)(:([0-9]+))?$ ]]; then
if [[ "$OVPN_SERVER_URL" =~ ^((udp|tcp)://)?([0-9a-zA-Z\.\-]+)(:([0-9]+))?$ ]]; then
OVPN_PROTO=${BASH_REMATCH[2]};
OVPN_CN=${BASH_REMATCH[3]};
OVPN_PORT=${BASH_REMATCH[5]};
@ -103,17 +106,11 @@ fi
# Apply defaults
[ -z "$OVPN_PROTO" ] && OVPN_PROTO=udp
[ -z "$OVPN_PORT" ] && OVPN_PORT=1194
if [ -z "$OVPN_ROUTES" ]; then
if [ -n "$ORIG_OVPN_ROUTES" ]; then
OVPN_ROUTES=$ORIG_OVPN_ROUTES
else
OVPN_ROUTES=192.168.254.0/24
fi
fi
[ ${#OVPN_ROUTES[@]} -eq 0 ] && OVPN_ROUTES=("192.168.254.0/24")
export OVPN_SERVER OVPN_ROUTES OVPN_DEFROUTE
export OVPN_SERVER_URL OVPN_ENV OVPN_PROTO OVPN_CN OVPN_PORT
export OVPN_CLIENT_TO_CLIENT OVPN_PUSH
# Preserve config
if [ -f "$OVPN_ENV" ]; then
@ -155,13 +152,22 @@ status /tmp/openvpn-status.log
client-config-dir $OPENVPN/ccd
EOF
[ -n "$OVPN_CLIENT_TO_CLIENT" ] && echo "client-to-client" >> "$conf"
# Append Routes
for i in ${OVPN_ROUTES[@]}; do
for i in "${OVPN_ROUTES[@]}"; do
# If user passed "0" skip this, assume no extra routes
[ "$i" = "0" ] && break;
echo route $(getroute $i) >> "$conf"
echo route $(getroute "$i") >> "$conf"
done
# Append push commands
for i in "${OVPN_PUSH[@]}"; do
echo push \"$i\" >> "$conf"
done
# Clean-up duplicate configs (always return success)
diff -q "$bak_env" "$OVPN_ENV" 2> /dev/null && rm "$bak_env" || true
diff -q "$bak" "$conf" 2> /dev/null && rm "$bak" || true
echo "Successfully generated config"

View File

@ -10,7 +10,8 @@ source "$OPENVPN/ovpn_env.sh"
cn=$1
if [ ! -f "$EASYRSA_PKI/private/${cn}.key" ]; then
easyrsa build-server-full $cn nopass
echo "Unable to find ${cn}, please try again or generate the key first"
exit 1
fi
cat <<EOF

View File

@ -19,10 +19,13 @@ fi
# Setup NAT forwarding if requested
if [ "$OVPN_DEFROUTE" != "0" ];then
iptables -t nat -A POSTROUTING -s $OVPN_SERVER -o eth0 -j MASQUERADE
for i in ${OVPN_ROUTES[@]}; do
iptables -t nat -A POSTROUTING -s $i -o eth0 -j MASQUERADE
iptables -t nat -C POSTROUTING -s $OVPN_SERVER -o eth0 -j MASQUERADE || {
iptables -t nat -A POSTROUTING -s $OVPN_SERVER -o eth0 -j MASQUERADE
}
for i in "${OVPN_ROUTES[@]}"; do
iptables -t nat -C POSTROUTING -s "$i" -o eth0 -j MASQUERADE || {
iptables -t nat -A POSTROUTING -s "$i" -o eth0 -j MASQUERADE
}
done
fi

21
docs/advanced.md Normal file
View File

@ -0,0 +1,21 @@
# Advanced Configurations
The ovpn_genconfig script is intended for simple configurations that apply to the majority of the users. If your use case isn't general, it likely won't be supported. This document aims to explain how to work around that.
## Create host volume mounts rather than data volumes
* Refer to the Quick Start document, and substitute `--volumes-from $OVPN_DATA` with `-v /path/on/host/openvpn0:/etc/openvpn`
* Quick example that is likely to be out of date, but here's how to get started:
mkdir openvpn0
cd openvpn0
docker run --rm -v $PWD:/etc/openvpn kylemanna/openvpn ovpn_genconfig -u udp://VPN.SERVERNAME.COM:1194
docker run --rm -v $PWD:/etc/openvpn -it kylemanna/openvpn ovpn_initpki
vim openvpn.conf
docker run --rm -v $PWD:/etc/openvpn -it kylemanna/openvpn easyrsa build-client-full CLIENTNAME nopass
docker run --rm -v $PWD:/etc/openvpn kylemanna/openvpn ovpn_getclient CLIENTNAME > CLIENTNAME.ovpn
* Start the server with:
docker run -v $PWD:/etc/openvpn -d -p 1194:1194/udp --privileged kylemanna/openvpn

View File

@ -11,8 +11,8 @@ TL;DR Protect the resulting archive file, by ensure there is very limited access
## Backup to Archive
docker run --volumes-from openvpn-data --rm busybox tar -cvf - -C /etc openvpn | xz > openvpn-backup.tar.xz
docker run --volumes-from $OVPN_DATA --rm busybox tar -cvf - -C /etc openvpn | xz > openvpn-backup.tar.xz
## Retore to New Image
xzcat openvpn-backup.tar.xz | docker run --name openvpn-data -v /etc/openvpn -i busybox tar -xvf - -C /etc
xzcat openvpn-backup.tar.xz | docker run --name $OVPN_DATA -v /etc/openvpn -i busybox tar -xvf - -C /etc

View File

@ -2,6 +2,13 @@
Random things I do to debug the containers.
## Login Shells
* Create a shell in the running docker container (aka namespace) with [nsenter](https://github.com/jpetazzo/nsenter)
* If you don't have nsenter/docker-enter, you can mount the data container and modify it with
docker run --rm -it --volumes-from $OVPN_DATA kylemanna/openvpn bash -l
## Stream OpenVPN Logs
1. Get the container's name or container ID:

View File

@ -6,19 +6,19 @@ The docker image is setup for static client configuration on the 192.168.254.0/2
1. Create a client specific configuration:
$ echo "ifconfig-push 192.168.254.1 192.168.254.2" | docker run --volumes-from openvpn-data -i --rm kylemanna/openvpn tee /etc/openvpn/ccd/CERT_COMMON_NAME
$ echo "ifconfig-push 192.168.254.1 192.168.254.2" | docker run --volumes-from $OVPN_DATA -i --rm kylemanna/openvpn tee /etc/openvpn/ccd/CERT_COMMON_NAME
ifconfig-push 192.168.254.1 192.168.254.2
2. Wait for client to reconnect if necessary
## Advanced Admin
Login to the openvpn-data volume with a `bash` container, note only changes in /etc/openvpn will persist:
Login to the data volume with a `bash` container, note only changes in /etc/openvpn will persist:
docker run --volumes-from openvpn-data -it --rm kylemanna/openvpn bash -l
docker run --volumes-from $OVPN_DATA -it --rm kylemanna/openvpn bash -l
## Upgrading from Old OpenVPN Configurations
If you're running an old configuration and need to upgrade it to pull in the ccd directory run the following:
docker run --volumes-from openvpn-data --rm kylemanna/openvpn ovpn_genconfig
docker run --volumes-from $OVPN_DATA --rm kylemanna/openvpn ovpn_genconfig