diff --git a/README.md b/README.md index 51e2d77..2d6df2e 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,6 @@ Spin up an OpenVPN Server ## 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 @@ -20,6 +19,13 @@ Spin up an OpenVPN Server $ vagrant up $ vagrant ssh +You can then perform a sanity test with a connection from a VPN client with: + + $ sudo su - + $ /vagrant/add-client.sh test-client + $ cp ~/client-configs/files/test-client.ovpn /vagrant + On the host, double click `test-client.ovpn` to load it into Tunnelblick + Use Tunnelblick to connect to the VPN server # Add a route to a subnet @@ -39,7 +45,7 @@ Then restart the VPN Server: 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 su - - $ /vagrant/add-config.sh client-name + $ /vagrant/add-client.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. This ovpn file can then be used with Tunnelblick (OS X), OpenVPN (Linux, iOS, Android and Windows). @@ -57,4 +63,4 @@ If you ever need to revoke access, simply execute: ## Extra Info * See [Using a VPN Server to Connect to Your AWS VPC for Just the Cost of an EC2 Nano Instance](https://redgeoff.com/posts/running-a-free-vpn-server-on-aws/) -* 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) +* See [How To Set Up and Configure an OpenVPN Server on Ubuntu 20.04](https://www.digitalocean.com/community/tutorials/how-to-set-up-and-configure-an-openvpn-server-on-ubuntu-20-04) diff --git a/Vagrantfile b/Vagrantfile index f127bcc..fd9dc0d 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -1,9 +1,9 @@ Vagrant.configure("2") do |config| - config.vm.box = "https://cloud-images.ubuntu.com/xenial/current/xenial-server-cloudimg-amd64-vagrant.box" + config.vm.box = "bento/ubuntu-22.04" # 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.network "private_network", ip: "192.168.56.11" config.vm.provider "virtualbox" do |v| v.memory = 1024 diff --git a/build-key-server.sh b/build-key-server.sh deleted file mode 100755 index 47b27f7..0000000 --- a/build-key-server.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/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/build-key.sh b/build-key.sh deleted file mode 100755 index aa937a1..0000000 --- a/build-key.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/expect - -# Usage: build-key.sh name - -# The following command doesn't work so we need to use expect -# yes "" | ./build-key ${name} - -set name [lindex $argv 0]; - -spawn ./build-key $name -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 index 9c8c45e..d4e9376 100755 --- a/config-default.sh +++ b/config-default.sh @@ -7,4 +7,4 @@ KEY_ORG="Fort-Funston" KEY_EMAIL="me@myhost.mydomain" KEY_OU="MyOrganizationalUnit" -PUBLIC_IP="192.168.50.11" +PUBLIC_IP="192.168.56.11" diff --git a/generate-client-certificate.sh b/generate-client-certificate.sh index ec40682..eee5dc2 100755 --- a/generate-client-certificate.sh +++ b/generate-client-certificate.sh @@ -13,5 +13,9 @@ if [ "$name" = "" ]; then fi cd ~/openvpn-ca -source vars -$sd/build-key.sh $name +yes "" | ./easyrsa gen-req ${name} nopass +cp pki/private/${name}.key ~/client-configs/keys/ +yes "yes" | ./easyrsa sign-req client ${name} +cp /root/openvpn-ca/pki/issued/${name}.crt ~/client-configs/keys/ +cp /etc/openvpn/server/ta.key ~/client-configs/keys/ +cp /etc/openvpn/server/ca.crt ~/client-configs/keys/ \ No newline at end of file diff --git a/make-config.sh b/make-config.sh index de50c95..c686c12 100755 --- a/make-config.sh +++ b/make-config.sh @@ -7,7 +7,7 @@ if [ "$name" = "" ]; then exit; fi -KEY_DIR=~/openvpn-ca/keys +KEY_DIR=~/client-configs/keys OUTPUT_DIR=~/client-configs/files BASE_CONFIG=~/client-configs/base.conf @@ -18,9 +18,9 @@ cat ${BASE_CONFIG} \ ${KEY_DIR}/${name}.crt \ <(echo -e '\n') \ ${KEY_DIR}/${name}.key \ - <(echo -e '\n') \ + <(echo -e '\n') \ ${KEY_DIR}/ta.key \ - <(echo -e '') \ + <(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 index b70835d..760a385 100755 --- a/openvpn.sh +++ b/openvpn.sh @@ -1,5 +1,8 @@ #!/usr/bin/env bash +# For details on why certain options have been chosen, see +# https://www.digitalocean.com/community/tutorials/how-to-set-up-and-configure-an-openvpn-server-on-ubuntu-20-04 + # Change to script directory sd=`dirname $0` cd $sd @@ -13,81 +16,91 @@ if [ ! -f ./config.sh ]; then exit; fi +# Install OpenVPN and net-tools (ifconfig) +apt-get -y install openvpn easy-rsa net-tools + # Load config source ./config.sh source ./interfaces.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 +echo "set_var EASYRSA_REQ_COUNTRY \"${KEY_COUNTRY}\"" >> vars +echo "set_var EASYRSA_REQ_PROVINCE \"${KEY_PROVINCE}\"" >> vars +echo "set_var EASYRSA_REQ_CITY \"${KEY_CITY}\"" >> vars +echo "set_var EASYRSA_REQ_ORG \"${KEY_ORG}\"" >> vars +echo "set_var EASYRSA_REQ_EMAIL \"${KEY_EMAIL}\"" >> vars +echo "set_var EASYRSA_REQ_OU \"${KEY_OU}\"" >> vars +echo "set_var EASYRSA_ALGO \"ec\"" >> vars +echo "set_var EASYRSA_DIGEST \"sha512\"" >> vars # Build the Certificate Authority -source vars -./clean-all -yes "" | ./build-ca +./easyrsa init-pki +yes "" | ./easyrsa build-ca nopass + +# Create the server certificate +yes "" | ./easyrsa gen-req server nopass +cp pki/private/server.key /etc/openvpn/server/ +cp pki/private/ca.key /etc/openvpn/server/ +cp pki/ca.crt /etc/openvpn/server/ -# Create the server certificate, key, and encryption files -$sd/build-key-server.sh -./build-dh -openvpn --genkey --secret keys/ta.key +# Sign the certificate request +yes "yes" | ./easyrsa sign-req server server +yes "yes" | cp pki/issued/server.crt /etc/openvpn/server/ -# 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 +# Generate an extra shared secret key +openvpn --genkey secret pki/ta.key +cp pki/ta.key /etc/openvpn/server/ + +# Copy the sample config to the OpenVPN directory +cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/server/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 +sed -i "s/tls-auth ta.key 0/tls-crypt ta.key/" /etc/openvpn/server/server.conf +sed -i "s/cipher AES-256-CBC/cipher AES-256-GCM\nauth SHA256/" /etc/openvpn/server/server.conf +sed -i "s/dh dh2048.pem/;dh dh2048.pem\ndh none/" /etc/openvpn/server/server.conf +sed -i "s/;user nobody/user nobody/" /etc/openvpn/server/server.conf +sed -i "s/;group nobody/group nogroup/" /etc/openvpn/server/server.conf # Allow IP forwarding sed -i "s/#net.ipv4.ip_forward/net.ipv4.ip_forward/" /etc/sysctl.conf sysctl -p -# Install iptables-persistent so that rules can persist across reboots -echo iptables-persistent iptables-persistent/autosave_v4 boolean true | sudo debconf-set-selections -echo iptables-persistent iptables-persistent/autosave_v6 boolean true | sudo debconf-set-selections -apt-get install -y iptables-persistent - -# Edit iptables rules to allow for forwarding -iptables -t nat -A POSTROUTING -o tun+ -j MASQUERADE -iptables -t nat -A POSTROUTING -o $VPNDEVICE -j MASQUERADE - -# Make iptables rules persistent across reboots -iptables-save > /etc/iptables/rules.v4 +# Firewall configuration +sed -i "s/# rules.before/# rules.before\n# START OPENVPN RULES\n# NAT table rules\n*nat\n:POSTROUTING ACCEPT [0:0]\n-A POSTROUTING -s 10.8.0.0\/8 -o ${VPNDEVICE} -j MASQUERADE\nCOMMIT\n# END OPENVPN RULES/" /etc/ufw/before.rules +sed -i "s/DEFAULT_FORWARD_POLICY=\"DROP\"/DEFAULT_FORWARD_POLICY=\"ACCEPT\"/" /etc/default/ufw +ufw allow 1194/udp +ufw allow OpenSSH +ufw disable +yes "y" | ufw enable # Start and enable the OpenVPN service -systemctl start openvpn@server -systemctl enable openvpn@server +systemctl -f enable openvpn-server@server.service +systemctl start openvpn-server@server.service -# Create the client config directory structure +# Creating the Client Configuration Infrastructure +mkdir -p ~/client-configs/keys +chmod -R 700 ~/client-configs 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 +sed -i "s/;group nobody/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 +sed -i "s/tls-auth ta.key 1/;tls-auth ta.key 1/" ~/client-configs/base.conf +sed -i "s/cipher AES-256-CBC/cipher AES-256-GCM/" ~/client-configs/base.conf echo "auth SHA256" >> ~/client-configs/base.conf echo "key-direction 1" >> ~/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 +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 +echo ";script-security 2" >> ~/client-configs/base.conf +echo ";up /etc/openvpn/update-systemd-resolved" >> ~/client-configs/base.conf +echo ";down /etc/openvpn/update-systemd-resolved" >> ~/client-configs/base.conf +echo ";down-pre" >> ~/client-configs/base.conf +echo ";dhcp-option DOMAIN-ROUTE ." >> ~/client-configs/base.conf diff --git a/revoke-full.sh b/revoke-full.sh index ee1919a..677baf9 100755 --- a/revoke-full.sh +++ b/revoke-full.sh @@ -3,21 +3,21 @@ name=$1 if [ "$name" = "" ]; then - echo "Usage: make-config.sh name" + echo "Usage: revoke-full.sh name" exit; fi cd ~/openvpn-ca -source vars -# And error ending in "ending in error 23" is expected -./revoke-full $name +yes "yes" | ./easyrsa revoke $name + +./easyrsa gen-crl # Install the revocation files -cp ~/openvpn-ca/keys/crl.pem /etc/openvpn +cp pki/crl.pem /etc/openvpn/server # Configure the server to check the client revocation list. This should only be done once -if [ $(grep -R 'crl-verify crl.pem' /etc/openvpn/server.conf | wc -l) -eq 0 ]; then - echo "crl-verify crl.pem" >> /etc/openvpn/server.conf - systemctl restart openvpn@server +if [ $(grep -R 'crl-verify crl.pem' /etc/openvpn/server/server.conf | wc -l) -eq 0 ]; then + echo -e "\ncrl-verify crl.pem" >> /etc/openvpn/server/server.conf + systemctl restart openvpn-server@server.service fi diff --git a/ubuntu.sh b/ubuntu.sh index 271ff9d..b21d9c7 100755 --- a/ubuntu.sh +++ b/ubuntu.sh @@ -5,4 +5,4 @@ apt-get -y update # Update Ubuntu apt-get -y upgrade -apt-get -y dist-upgrade +apt-get -y dist-upgrade \ No newline at end of file