diff --git a/functions.sh b/functions.sh index a12d510db187faca4eb84c85fc3b6471209ce748..a4f3b5c9cf3860c6772393f1ee9c77189d65e2a0 100644 --- a/functions.sh +++ b/functions.sh @@ -79,6 +79,190 @@ done function ask_server_questions { +#copied over from init + + # READ the config from here - you need to have init'ed first - ideally ovs init-ca + . /etc/openvpn-server/config.sh + +DEFAULT_PORT=1194 #Default OpenVPN Port +DEFAULT_PROTOCOL_SELECTION=1 #Default OpenVPN Protocol to use, set 1 for UDP and 2 for TCP + +if [ -f /var/lib/openvpn-server/ca-store ] +then +# /usr/lib/openvpn-server/ovs-commands/mount-ca-store +# if [ $? = 1 ] +# then + if grep -q ca-store /proc/mounts + then + echo "ca-store mounted" + else + echo "ca-store not mounted, or your session has expired." + echo "Use ovs mount-ca-store to mount your ca-store" + exit 1 + fi + +fi + +#TODO - setup an init-ca function - so the steps will be init-ca build-server and then build clients. server certs and config gets copied to server. +# KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORGANISATION are all CA related info. $OVPN_ORGNICK, read from config.sh +# ORG_EMAIL read from config.sh + + +#Ask for any subnets to push to clients +## TODO subnet input validation. A shell case statement might be enough +## since it provides pattern matching. +echo "" +echo "" +read -p "Specify the subnet you want VPN clients to be able to access. +If you provide a value here, this subnet range will be pushed to +clients as one which can be accessed via this VPN server. + +You must specify the subnet in the format nnn.nnn.nnn.nnn/sss.sss.sss.sss, +where nnn.nnn.nnn.nnn is the network and sss.sss.sss.sss is the subnet mask. +For example, to tell clients to use this VPN to access the 192.168.10.0/24 +network, enter 192.168.10.0/255.255.255.0 + +You may also specify multiple subnets to route by providing them all here, +separated by spaces. For example to tell clients to use this VPN to access +the 192.168.10.0/24 and 192.168.20.0/24 networks enter +192.168.10.0/255.255.255.0 192.168.11.0/255.255.255.0 + +If you wish this server to be standalone, and not provide access to any +other networks, leave this option blank. +: " SUBNETSTRING + +#Turn the SUBNETSTRING variable into an array +SUBNETS=($SUBNETSTRING) + + + +#TODO: Use this text as a base for subnet validation message when I wrote that check +#The subnet specification you provided was incorrect. +# The set of subnets you gave was incorrect. Please go back and try again. + + +#TODO: Add some validation so we don't have an empty hostname variable +#Ask for the server hostname to be used by ovs for client file generation +echo "" +echo "" +read -p "What is the generally-accessible name or IP address of the server? +For clients to be able to connect to the server, it must have a consistent +DNS name or IP address. Please enter this name or address here: " SERVERADDR + + + +#Ask port to be used by this server +#TODO Port number validation +echo "" +echo "" +read -p "What port number do you want this server to use? +For most uses the standard OpenVPN port of $DEFAULT_PORT +is fine, however if you need to use a non standard port you +can specify a port number here [$DEFAULT_PORT]: " SERVER_PORT + +#Count the number of characters entered +COUNT=($(echo -n $SERVER_PORT | wc -m)) + +#If enter was pressed then lets just set the default OpenVPN Port here +if [ $COUNT -eq 0 ] +then + SERVER_PORT=$DEFAULT_PORT +fi + + + +#Ask for the transport protocol to be used by this server +if [[ $DEFAULT_PROTOCOL_SELECTION =~ ^[2]+$ ]]; then + DEFAULT_PROTOCOL=TCP +else + DEFAULT_PROTOCOL=UDP +fi + +echo "" +echo "" +read -p "What transport protocol is this server to use? +For most uses the standard protocol of UDP +is fine, however if you need to use TCP you can select +that here by entering the protocol number +1 UDP +2 TCP +[$DEFAULT_PROTOCOL]: " PROTOCOL_SELECTION + +#Count the number of characters entered +COUNT=($(echo -n $PROTOCOL_SELECTION | wc -m)) + +#If enter was pressed then lets just set the default OpenVPN Protocol here +if [ $COUNT -eq 0 ] +then + PROTOCOL_SELECTION=$DEFAULT_PROTOCOL_SELECTION + VALID_PROTOCOL=1 +else + #There was something entered so lets validate PROTOCOL_SELECTION + if [[ $PROTOCOL_SELECTION =~ ^[1]+$ ]] || [[ $PROTOCOL_SELECTION =~ ^[2]+$ ]]; then + #We have a 1 or 2 so the selection is valid + VALID_PROTOCOL=1 + else + #We don't have a 1 or 2 so selection is invalid + VALID_PROTOCOL=0 + fi + +fi + +echo "" +echo "Passed the first loop and variable is $PROTOCOL_SELECTION" +echo "" + +#Check to make sure it was 1 or 2 entered, and if not then head into this loop +while [[ $VALID_PROTOCOL != 1 ]]; do + + echo "" + echo "You entered [$PROTOCOL_SELECTION]. Please only enter 1 or 2 " + echo "1 UDP" + echo "2 TCP" + read -p "[$DEFAULT_PROTOCOL]:" PROTOCOL_SELECTION + COUNT=($(echo -n $PROTOCOL_SELECTION | wc -m)) + + if [ $COUNT -eq 0 ]; then + #This lets us get out of the loop if you just press enter and it also sets PROTOCOL_SELECTION to the default + PROTOCOL_SELECTION=$DEFAULT_PROTOCOL_SELECTION + VALID_PROTOCOL=1 + else + #There was something entered so lets validate the selection + if [[ $PROTOCOL_SELECTION =~ ^[1-2]+$ ]]; then + #We have a valid selection so lets set VALID_PROTOCOL to 1 and get out of this loop + VALID_PROTOCOL=1 + fi + fi +done + +#Finally lets read the PROTOCOL_SELECTION variable and set the SERVER_PROTOCOL variable + +if [[ $PROTOCOL_SELECTION =~ ^[2]+$ ]]; then + SERVER_PROTOCOL=tcp +else + SERVER_PROTOCOL=udp +fi + + + +#Lets show the user all the values entered and allow a verification before proceeding +echo "Subnets:" +for subnet in "${SUBNETS[@]}" +do + echo $subnet +done +echo "Server address: $SERVERADDR" +echo "Server port: $SERVER_PORT" +echo "Server protocol: $SERVER_PROTOCOL" + + +#Asking the user a final yes or no question if the values are correct before proceeding +echo "" +read -p "Press y to proceed or any other key to abort: " CORRECTVALUES + + + +#old questions echo "This step creates a server certificate for using on an OpenVPN server" read -p "Common Name of Server certificate, this should be unique, using 4 to 30 upper or lowercase letters or numbers and _ ONLY: " OVPN_COMMONNAME @@ -262,23 +446,23 @@ y" | \ function make_server_bundle { - . /etc/openvpn-server/config.sh - local email="$1" - local commonname="$2" - local parentworkdir="$3" + . /etc/openvpn-server/config.sh + local email="$1" + local commonname="$2" + local parentworkdir="$3" - local WORKDIR=$(mktemp -d) + local WORKDIR=$(mktemp -d) - pushd $WORKDIR >/dev/null + pushd $WORKDIR >/dev/null echo "------------------------------------------" echo -n "Generating server key..." - KEY_NAME="$KEY_ORGANISATION OpenVPN server on $(hostname)" \ - KEY_EMAIL="$ORG_EMAIL" \ + KEY_NAME=$commonname \ + KEY_EMAIL=$email \ openssl req -nodes -new \ - -keyout $WORKDIR/$ORGNICK-$commonname-server.key \ - -out $WORKDIR/$ORGNICK-$commonname-server.csr \ + -keyout $WORKDIR/$OVPN_ORGNICK-$commonname-server.key \ + -out $WORKDIR/$OVPN_ORGNICK-$commonname-server.csr \ -extensions server \ -config /etc/openvpn-server/openssl/openssl.cnf echo " done." @@ -292,8 +476,8 @@ y KEY_NAME="$KEY_ORGANISATION OpenVPN server on $(hostname)" \ KEY_EMAIL="$ORG_EMAIL" \ openssl ca -days 3650 \ - -out $WORKDIR/$ORGNICK-$commonname-server.crt \ - -in $WORKDIR/$ORGNICK-$commonname-server.csr \ + -out $WORKDIR/$OVPN_ORGNICK-$commonname-server.crt \ + -in $WORKDIR/$OVPN_ORGNICK-$commonname-server.csr \ -extensions server \ -config /etc/openvpn-server/openssl/openssl.cnf echo " done." @@ -301,20 +485,20 @@ y echo "------------------------------------------" echo -n "Converting key to pkcs12 format..." openssl pkcs12 -export \ - -inkey $WORKDIR/$ORGNICK-$commonname-server.key \ - -in $WORKDIR/$ORGNICK-$commonname-server.crt \ + -inkey $WORKDIR/$OVPN_ORGNICK-$commonname-server.key \ + -in $WORKDIR/$OVPN_ORGNICK-$commonname-server.crt \ -password pass: \ -certfile /var/lib/openvpn-server/openssl/ca.crt \ - -out /etc/openvpn-server/$ORGNICK-$commonname-server.p12 + -out /var/lib/openvpn-server/openssl/$OVPN_ORGNICK-$commonname-server.p12 echo " done." - chmod 0600 /etc/openvpn-server/$ORGNICK-$commonname-server.p12 + chmod 0600 /var/lib/openvpn-server/openssl/$OVPN_ORGNICK-$commonname-server.p12 - popd >/dev/null + popd >/dev/null - cp $WORKDIR/* $parentworkdir/ + cp $WORKDIR/* $parentworkdir/ - rm -rf $WORKDIR + rm -rf $WORKDIR } diff --git a/scripts/build-server-cert b/scripts/build-server-cert index fe4970f36a202ae808d7b0ee030d438133506383..6f8ad76185091af674ae9e070c174dde21824cab 100755 --- a/scripts/build-server-cert +++ b/scripts/build-server-cert @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash set -e @@ -36,15 +36,29 @@ FILEBASE="${OVPN_ORGNICK}-${OVPN_COMMONNAME}" make_server_bundle "$OVPN_EMAIL" "$OVPN_COMMONNAME" "$WORKDIR" -CA=`cat "$OVPN_ORGNAME"-ca.crt` -CERT=`sed -n "/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p" $OVPN_COMMONNAME-server.crt` -KEY=`cat $OVPN_COMMONNAME-server.key` +CA=`cat /var/lib/openvpn-server/openssl/ca.crt` +CERT=`sed -n "/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p" $FILEBASE-server.crt` +KEY=`cat $FILEBASE-server.key` + +OCTET2=$(($RANDOM % 16 + 16)) +OCTET3=$(($RANDOM % 256 / 4 * 4)) +SERVERLINE="server 172.$OCTET2.$OCTET3.0 255.255.252.0" + +#Assemble the array containing the local networks to route into +#the correct push statements for the OpenVPN config file +for subnet in "${SUBNETS[@]}"; do + NET=${subnet/\/*/} + MASK=${subnet/*\//} + SUBNET_ARRAY+=("push \"route $NET $MASK\"") +done + +sed "s/%%SERVER_PORT%%/$SERVER_PORT/; + s/%%SERVER_PROTOCOL%%/$SERVER_PROTOCOL/; + s/%%ORGNICK%%/$ORGNICK/; + s/%%SERVERLINE%%/$SERVERLINE/;" \ + < /usr/share/openvpn-server/config-templates/server.conf \ + > $WORKDIR/${FILEBASE}-server.conf -sed "s/%%PORT%%/$OVPN_PORT/; - s/%%PROTOCOL%%/$OVPN_PROTO/; - s/%%REMOTE%%/$OVPN_REMOTE/" \ - /usr/share/openvpn-server/config-templates/server.conf \ - > ${FILEBASE}-server.conf echo " <ca> @@ -59,17 +73,16 @@ $KEY popd >/dev/null -OVPNFILE="openvpn-${FILEBASE}-server.conf" -cp ${WORKDIR}/${FILEBASE}-server.conf ./$OVPNFILE if [ -z "$CACHE_BUILDS" ]; then cp ${WORKDIR}/${FILEBASE}-server.conf ./$OVPNFILE - echo "Your OpenVPN generic client has been built in ${OVPNFILE}" + echo "Your OpenVPN generic client has been built in ${OVPNFILE}" else make_cache - cp ${WORKDIR}/${FILEBASE}-server.conf "${CACHE_BUILDS}/${OVPNFILE}" - echo "Your OpenVPN generic client has been built in ${CACHE_BUILDS}/${OVPNFILE}" + cp ${WORKDIR}/${FILEBASE}-server.conf "${CACHE_BUILDS}/" + echo "Your OpenVPN generic client has been built in ${CACHE_BUILDS}/${OVPNFILE}" fi rm -rf $WORKDIR echo "install this config file in /etc/openvpn on the target server" +