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

EasyRSA Generation including environment variables to set parameters #8

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
efafd81
change image to my debian-armel:jessie
ClashTheBunny Jun 4, 2014
86a6817
add ability to configure server quite a bit
ClashTheBunny Jun 4, 2014
4421748
export the variables so as to be accessable
ClashTheBunny Jun 4, 2014
cb2b215
just give path to correct openssl.cnf
ClashTheBunny Jun 4, 2014
131fecf
make keydir
ClashTheBunny Jun 4, 2014
d0c8489
clean-all creates the keydir and does other beneficial things
ClashTheBunny Jun 4, 2014
f2a2f77
check for existance of files before re-creating them
ClashTheBunny Jun 4, 2014
c7c2eae
add zip for both TunnelBlick and Ubuntu Configurations
ClashTheBunny Jun 4, 2014
809e722
fix problem with parens and add easy-rsa for ubuntu
ClashTheBunny Jun 4, 2014
5bd3568
replace dh1024 with dh2048, check for tblk directory and skip if exis…
ClashTheBunny Jun 4, 2014
910a6ea
fix ta.key path
ClashTheBunny Jun 4, 2014
3ed3e69
reference actual number of bits in dh .pem
ClashTheBunny Jun 4, 2014
ce7a1eb
don't build android's key, seems to delete files
ClashTheBunny Jun 5, 2014
67f67f1
add scripts to start and configure
ClashTheBunny Jun 6, 2014
326395c
wait, we really do want those export statements
ClashTheBunny Jun 6, 2014
5170005
autodetect hostname and arch
ClashTheBunny Jun 6, 2014
53dbeda
fix runDockVPN.sh so it tags images better, use non python detection …
ClashTheBunny Jun 6, 2014
6ec2a30
update README.md
ClashTheBunny Jun 6, 2014
6efebc0
More options for getting config files out in README
ClashTheBunny Jun 6, 2014
fbce001
make the server stateless besides the CA and Keys, open ports on the …
ClashTheBunny Jun 10, 2014
b04768b
add import script, run after creation of OpenVPN-Config container, fi…
ClashTheBunny Jun 13, 2014
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
12 changes: 6 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
FROM ubuntu:precise
RUN echo deb http://archive.ubuntu.com/ubuntu/ precise main universe > /etc/apt/sources.list.d/precise.list
FROM ubuntu:trusty
MAINTAINER randall@mason.ch

RUN apt-get update -q
RUN apt-get install -qy openvpn iptables socat curl
RUN apt-get install -qy openvpn iptables socat zip easy-rsa curl gettext-base miniupnpc
ADD ./bin /usr/local/sbin
VOLUME /etc/openvpn
EXPOSE 443/tcp 1194/udp 8080/tcp
CMD run

CMD ["/usr/local/sbin/run"]
103 changes: 20 additions & 83 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,96 +2,33 @@

Quick instructions:

Edit the environment variables half way down runDockVPN.sh and then run it:
```bash
CID=$(docker run -d --privileged -p 1194:1194/udp -p 443:443/tcp jpetazzo/openvpn)
docker run -t -i -p 8080:8080 --volumes-from $CID jpetazzo/openvpn serveconfig
vim runDockVPN.sh
./runDockVPN.sh
```
it will print out the directory where your OpenVPN configuration files
are stored and you should get those (SECURELY!!!) to your local directory:
```bash
rsync -avH --rsync-path="sudo rsync" userWithSudo@dockerHost:<directoryFromScript>/ OpenVPN-Config/
```
or
```bash
docker run --rm --volumes-from OpenVPN-Config busybox tar cvf - /etc/openvpn/ \
| ssh mobile@jailBrokeniPhone "mkdir OpenVPN-Config; tar -xvf - -C OpenVPN-Config/"
```

Now download the file located at the indicated URL. You will get a
certificate warning, since the connection is done over SSL, but we are
using a self-signed certificate. After downloading the configuration,
stop the `serveconfig` container. You can restart it later if you need
to re-download the configuration, or to download it to multiple devices.

The file can be used immediately as an OpenVPN profile. It embeds all the
required configuration and credentials. It has been tested successfully on
Linux, Windows, and Android clients. If you can test it on OS X and iPhone,
let me know!

**Note:** there is a [bug in the Android Download Manager](
http://code.google.com/p/android/issues/detail?id=3492) which prevents
downloading files from untrusted SSL servers; and in that case, our
self-signed certificate means that our server is untrusted. If you
try to download with the default browser on your Android device,
it will show the download as "in progress" but it will remain stuck.
You can download it with Firefox; or you can transfer it with another
way: Dropbox, USB, micro-SD card...

If you reboot the server (or stop the container) and you `docker run`
again, you will create a new service (with a new configuration) and
you will have to re-download the configuration file. However, you can
use `docker start` to restart the service without touching the configuration.


## How does it work?

When the `jpetazzo/openvpn` image is started, it generates:

- Diffie-Hellman parameters,
- a private key,
- a self-certificate matching the private key,
- two OpenVPN server configurations (for UDP and TCP),
- an OpenVPN client profile.

Then, it starts two OpenVPN server processes (one on 1194/udp, another
on 443/tcp).

The configuration is located in `/etc/openvpn`, and the Dockerfile
declares that directory as a volume. It means that you can start another
container with the `--volumes-from` flag, and access the configuration.
Conveniently, `jpetazzo/openvpn` comes with a script called `serveconfig`,
which starts a pseudo HTTPS server on `8080/tcp`. The pseudo server
does not even check the HTTP request; it just sends the HTTP status line,
headers, and body right away.
then you can directly import those files into Ubuntu's Network Manager,
TunnelBlick, iPhone or Android's OpenVPN Connect, or pretty much anywhere.

Since the configuration files are in a seperate volume only container named OpenVPN-Config,
any reboots or restarts will start you back off where you were. Just re-run the script.
If you need to add hosts to your server, just edit and re-run the script. It will restart
OpenVPN, but it will re-create the needed files. A new script to add hosts without a restart
is easy to create, and will hopefully be added later.

## OpenVPN details

We use `tun` mode, because it works on the widest range of devices.
`tap` mode, for instance, does not work on Android, except if the device
is rooted.

The topology used is `net30`, because it works on the widest range of OS.
`p2p`, for instance, does not work on Windows.

The TCP server uses `192.168.255.0/25` and the UDP server uses
`192.168.255.128/25`.

The client profile specifies `redirect-gateway def1`, meaning that after
establishing the VPN connection, all traffic will go through the VPN.
This might cause problems if you use local DNS recursors which are not
directly reachable, since you will try to reach them through the VPN
and they might not answer to you. If that happens, use public DNS
resolvers like those of Google (8.8.4.4 and 8.8.8.8) or OpenDNS
(208.67.222.222 and 208.67.220.220).


## Security discussion

For simplicity, the client and the server use the same private key and
certificate. This is certainly a terrible idea. If someone can get their
hands on the configuration on one of your clients, they will be able to
connect to your VPN, and you will have to generate new keys. Which is,
by the way, extremely easy, since each time you `docker run` the OpenVPN
image, a new key is created. If someone steals your configuration file
(and key), they will also be able to impersonate the VPN server (if they
can also somehow hijack your connection).

It would probably be a good idea to generate two sets of keys.

It would probably be even better to generate the server key when
running the container for the first time (as it is done now), but
generate a new client key each time the `serveconfig` command is
called. The command could even take the client CN as argument, and
another `revoke` command could be used to revoke previously issued
keys.
32 changes: 32 additions & 0 deletions bin/client.combined.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
client
dev tun
nobind
resolv-retry infinite
persist-key
persist-tun

cipher BF-CBC
comp-lzo
passtos
mssfix
verb 3

redirect-gateway def1

<key>
$CLIENT_KEY
</key>
<cert>
$CLIENT_CRT
</cert>
<ca>
$CA_CRT
</ca>
<dh>
$DH_PARAMS
</dh>
key-direction 1
<tls-auth>
$TA_KEY
</tls-auth>

19 changes: 19 additions & 0 deletions bin/client.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
client
dev tun
nobind
resolv-retry infinite
persist-key
persist-tun

cipher BF-CBC
comp-lzo
passtos
mssfix
verb 3

redirect-gateway def1

ca ca.crt
cert ${CLIENTNAME}.crt
key ${CLIENTNAME}.key
tls-auth ta.key 1
7 changes: 7 additions & 0 deletions bin/printconfig.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

while read line
do
grep -q GET "$line" | sed -e 's#GET /\([a-z]\).ovpn HTTP.*#\1#g' | grep -q . && \
cat client.$(grep -q GET "$line" | sed -e 's#GET /\([a-z]\).ovpn HTTP.*#\1#g').combined.ovpn
done
Loading