Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
473671a4d0 | |||
19f4c5cde4 | |||
17ef8cebfc | |||
f07e4ad531 | |||
656be240b6 | |||
b06631099f | |||
be22048a2b | |||
f05de3eb84 | |||
543292e124 | |||
8c7d020074 | |||
a69ca8d65e | |||
f1616f7196 | |||
d36bb7ecba | |||
76a230b3be | |||
5fd47763d7 | |||
37f86037d8 | |||
e9c5108a8f | |||
816eff9af6 | |||
c38b412dc6 | |||
b9cc5b347a | |||
20be0f90a5 | |||
0c873ab4cf | |||
f263eb9a61 | |||
d5979915cf |
@ -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
|
||||
|
27
README.md
27
README.md
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
11
bin/ovpn_run
11
bin/ovpn_run
@ -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
21
docs/advanced.md
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user