From 24c60d799b9486769b13684642d6ec2a73dfe5f9 Mon Sep 17 00:00:00 2001 From: Geoff Cox Date: Fri, 21 Jul 2017 17:23:23 -0700 Subject: [PATCH] initial --- .gitignore | 4 ++ LICENSE | 5 ++- README.md | 44 ++++++++++++++++++- Vagrantfile | 22 ++++++++++ bootstrap.sh | 5 +++ build-key-server.sh | 31 +++++++++++++ config-default.sh | 10 +++++ generate-client-certificate.sh | 12 ++++++ make-config.sh | 23 ++++++++++ openvpn.sh | 79 ++++++++++++++++++++++++++++++++++ revoke-full.sh | 15 +++++++ ubuntu.sh | 8 ++++ 12 files changed, 255 insertions(+), 3 deletions(-) create mode 100644 .gitignore create mode 100644 Vagrantfile create mode 100755 bootstrap.sh create mode 100755 build-key-server.sh create mode 100755 config-default.sh create mode 100755 generate-client-certificate.sh create mode 100755 make-config.sh create mode 100755 openvpn.sh create mode 100755 revoke-full.sh create mode 100755 ubuntu.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1234fe0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.vagrant +.DS_Store +*.log +config.sh diff --git a/LICENSE b/LICENSE index fad18ec..20efd1b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ -MIT License +The MIT License (MIT) -Copyright (c) 2017 Geoff Cox +Copyright (c) 2015 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/README.md b/README.md index 07f2146..e87ab17 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,44 @@ # openvpn-server-vagrant -A VM that runs an OpenVPN Server + +Spin up an OpenVPN Server + + +## Install Vagrant, VirtualBox and git + + http://www.vagrantup.com + https://www.virtualbox.org (don't worry about setting up any VMs as the steps below will cover this) + http://git-scm.com + + +## Set up + + Edit /etc/hosts locally and add `192.168.50.11 vpn.dev` + $ git clone https://github.com/redgeoff/openvpn-server-vagrant.git + $ cd openvpn-server-vagrant + $ cp config-default.sh config.sh + Edit config.sh and fill in your config + $ vagrant up + $ vagrant ssh + + +# Generate a client config + +The following should be repeated for each new client/user for whom you wish to grant access to your VPN. Replace client-name with a unique name. + + $ sudo /vagrant/make-config.sh client-name + +You will then find a file like the following that you should provide to the individual who will be connecting to your VPN. + + ~client-configs/files/client-name.ovpn + + +# Revoke client certificate + +If you ever need to revoke access, simply execute: + + $ sudo /vagrant/revoke-full.sh client-name + + +## Extra Info + +See [How To Set Up an OpenVPN Server on Ubuntu 16.04](https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-16-04) diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..9240e79 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,22 @@ +Vagrant.configure("2") do |config| + + # The ubuntu/xenial64 box is unstable and randomly becomes unresponsive so we'll use an image + # directly from ubuntu instead + # + # config.vm.box = "ubuntu/xenial64" + config.vm.box = "https://cloud-images.ubuntu.com/xenial/current/xenial-server-cloudimg-amd64-vagrant.box" + + # Use a private network so that we don't have to worry about forwarding ports + config.vm.network "private_network", ip: "192.168.50.11" + + config.vm.provider "virtualbox" do |v| + v.memory = 1024 + + # Only allow drift of 1 sec, instead of 20 min default + v.customize [ "guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-set-threshold", 1000 ] + end + + # Bootstrap script for configuring VM + config.vm.provision :shell, path: "bootstrap.sh" + +end diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100755 index 0000000..7ae2a89 --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +/vagrant/ubuntu.sh + +# /vagrant/openvpn.sh diff --git a/build-key-server.sh b/build-key-server.sh new file mode 100755 index 0000000..47b27f7 --- /dev/null +++ b/build-key-server.sh @@ -0,0 +1,31 @@ +#!/usr/bin/expect + +# The following command doesn't work so we need to use expect +# yes "" | ./build-key-server server + +spawn ./build-key-server server +expect "Country Name" +send "\n" +expect "State or Province Name" +send "\n" +expect "Locality Name" +send "\n" +expect "Organization Name" +send "\n" +expect "Organizational Unit Name" +send "\n" +expect "Common Name" +send "\n" +expect "Name" +send "\n" +expect "Email Address" +send "\n" +expect "A challenge password" +send "\n" +expect "An optional company name" +send "\n" +expect "Sign the certificate" +send "y\n" +expect "1 out of 1 certificate" +send "y\n" +expect "$ " diff --git a/config-default.sh b/config-default.sh new file mode 100755 index 0000000..9c8c45e --- /dev/null +++ b/config-default.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +KEY_COUNTRY="US" +KEY_PROVINCE="CA" +KEY_CITY="SanFrancisco" +KEY_ORG="Fort-Funston" +KEY_EMAIL="me@myhost.mydomain" +KEY_OU="MyOrganizationalUnit" + +PUBLIC_IP="192.168.50.11" diff --git a/generate-client-certificate.sh b/generate-client-certificate.sh new file mode 100755 index 0000000..d68b2ca --- /dev/null +++ b/generate-client-certificate.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +name=$1 + +if [ "$name" = "" ]; then + echo "Usage: generate-client-certificate name" + exit; +fi + +cd ~/openvpn-ca +source vars +yes "" | ./build-key $name diff --git a/make-config.sh b/make-config.sh new file mode 100755 index 0000000..ac06841 --- /dev/null +++ b/make-config.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +# First argument: Client identifier + +name=$1 + +KEY_DIR=~/openvpn-ca/keys +OUTPUT_DIR=~/client-configs/files +BASE_CONFIG=~/client-configs/base.conf + +cat ${BASE_CONFIG} \ + <(echo -e '') \ + ${KEY_DIR}/ca.crt \ + <(echo -e '\n') \ + ${KEY_DIR}/${name}.crt \ + <(echo -e '\n') \ + ${KEY_DIR}/${name}.key \ + <(echo -e '\n') \ + ${KEY_DIR}/ta.key \ + <(echo -e '') \ + > ${OUTPUT_DIR}/${name}.ovpn + +# sed -i "s/group nogroup/group nobody/" ${OUTPUT_DIR}/${name}.ovpn diff --git a/openvpn.sh b/openvpn.sh new file mode 100755 index 0000000..4b2175e --- /dev/null +++ b/openvpn.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash + +# Change to script directory +sd=`dirname $0` +cd $sd + +# Make sure config file exists +if [ ! -f ./config.sh ]; then + echo "config.sh not found!" + exit; +fi + +# Load config +source ./config.sh + +# Install OpenVPN and expect +apt-get -y install openvpn easy-rsa expect + +# Set up the CA directory +make-cadir ~/openvpn-ca +cd ~/openvpn-ca + +# Update vars +sed -i "s/export KEY_COUNTRY=\"[^\"]*\"/export KEY_COUNTRY=\"${KEY_COUNTRY}\"/" vars +sed -i "s/export KEY_PROVINCE=\"[^\"]*\"/export KEY_PROVINCE=\"${KEY_PROVINCE}\"/" vars +sed -i "s/export KEY_CITY=\"[^\"]*\"/export KEY_CITY=\"${KEY_CITY}\"/" vars +sed -i "s/export KEY_ORG=\"[^\"]*\"/export KEY_ORG=\"${KEY_ORG}\"/" vars +sed -i "s/export KEY_EMAIL=\"[^\"]*\"/export KEY_EMAIL=\"${KEY_EMAIL}\"/" vars +sed -i "s/export KEY_OU=\"[^\"]*\"/export KEY_OU=\"${KEY_OU}\"/" vars +sed -i "s/export KEY_NAME=\"[^\"]*\"/export KEY_NAME=\"server\"/" vars + +# Build the Certificate Authority +source vars +./clean-all +yes "" | ./build-ca + +# Create the server certificate, key, and encryption files +$sd/build-key-server.sh +./build-dh +openvpn --genkey --secret keys/ta.key + +# Generate a client certificate and key pair +$sd/generate-client-certificate.sh client1 + +# Copy the files to the OpenVPN directory +cd ~/openvpn-ca/keys +cp ca.crt ca.key server.crt server.key ta.key dh2048.pem /etc/openvpn +gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf + +# Adjust the OpenVPN configuration +sed -i "s/;tls-auth ta.key 0/tls-auth ta.key 0\nkey-direction 0/" /etc/openvpn/server.conf +sed -i "s/;cipher AES-128-CBC/cipher AES-128-CBC\nauth SHA256/" /etc/openvpn/server.conf +sed -i "s/;user nobody/user nobody/" /etc/openvpn/server.conf +sed -i "s/;group nogroup/group nogroup/" /etc/openvpn/server.conf + +# Allow IP forwarding +sed -i "s/#net.ipv4.ip_forward/net.ipv4.ip_forward/" /etc/sysctl.conf +sysctl -p + +# Start and enable the OpenVPN service +systemctl start openvpn@server +systemctl enable openvpn@server + +# Create the client config directory structure +mkdir -p ~/client-configs/files + +# Create a base configuration +cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf +sed -i "s/remote my-server-1 1194/remote ${PUBLIC_IP} 1194/" ~/client-configs/base.conf +sed -i "s/;user nobody/user nobody/" ~/client-configs/base.conf +sed -i "s/;group nogroup/group nogroup/" ~/client-configs/base.conf +sed -i "s/ca ca.crt/#ca ca.crt/" ~/client-configs/base.conf +sed -i "s/cert client.crt/#cert client.crt/" ~/client-configs/base.conf +sed -i "s/key client.key/#key client.key/" ~/client-configs/base.conf +echo "cipher AES-128-CBC" >> ~/client-configs/base.conf +echo "auth SHA256" >> ~/client-configs/base.conf +echo "#script-security 2" >> ~/client-configs/base.conf +echo "#up /etc/openvpn/update-resolv-conf" >> ~/client-configs/base.conf +echo "#down /etc/openvpn/update-resolv-conf" >> ~/client-configs/base.conf diff --git a/revoke-full.sh b/revoke-full.sh new file mode 100755 index 0000000..38d04ef --- /dev/null +++ b/revoke-full.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +# Usage: revoke-full.sh client-name + +cd ~/openvpn-ca +source vars + +# And error ending in "ending in error 23" is expected +./revoke-full $1 + +# TODO: should this be done during the setup?? +# Install the revocation files +# cp ~/openvpn-ca/keys/crl.pem /etc/openvpn +# echo "crl-verify crl.pem" >> /etc/openvpn/server.conf +# systemctl restart openvpn@server diff --git a/ubuntu.sh b/ubuntu.sh new file mode 100755 index 0000000..271ff9d --- /dev/null +++ b/ubuntu.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +# Update apt-get +apt-get -y update + +# Update Ubuntu +apt-get -y upgrade +apt-get -y dist-upgrade