shell-scripte-code/openvpn-install.sh

847 lines
28 KiB
Bash
Raw Normal View History

2017-06-14 14:27:28 +02:00
#!/bin/bash
2017-10-01 16:45:01 +02:00
set -ex
2017-09-26 22:27:59 +02:00
# Secure OpenVPN server installer for Debian, Ubuntu, CentOS and Arch Linux
# https://github.com/Angristan/OpenVPN-install
2017-06-14 14:27:28 +02:00
if [[ "$EUID" -ne 0 ]]; then
echo "Sorry, you need to run this as root"
2017-09-26 22:27:59 +02:00
exit 1
2017-06-14 14:27:28 +02:00
fi
if [[ ! -e /dev/net/tun ]]; then
2017-09-26 22:27:59 +02:00
echo "TUN is not available"
exit 2
2017-06-14 14:27:28 +02:00
fi
if grep -qs "CentOS release 5" "/etc/redhat-release"; then
echo "CentOS 5 is too old and not supported"
2017-09-26 22:27:59 +02:00
exit 3
2017-06-14 14:27:28 +02:00
fi
2017-09-26 22:27:59 +02:00
2017-06-14 14:27:28 +02:00
if [[ -e /etc/debian_version ]]; then
2017-09-26 22:27:59 +02:00
OS="debian"
# Getting the version number, to verify that a recent version of OpenVPN is available
VERSION_ID=$(cat /etc/os-release | grep "VERSION_ID")
2017-06-14 14:27:28 +02:00
RCLOCAL='/etc/rc.local'
2017-09-26 22:27:59 +02:00
SYSCTL='/etc/sysctl.conf'
2017-10-01 15:03:40 +02:00
if [[ "$VERSION_ID" != 'VERSION_ID="8"' ]] && [[ "$VERSION_ID" != 'VERSION_ID="9"' ]] && [[ "$VERSION_ID" != 'VERSION_ID="14.04"' ]] && [[ "$VERSION_ID" != 'VERSION_ID="16.04"' ]] && [[ "$VERSION_ID" != 'VERSION_ID="17.04"' ]]; then
2017-09-26 22:27:59 +02:00
echo "Your version of Debian/Ubuntu is not supported."
echo "I can't install a recent version of OpenVPN on your system."
echo ""
echo "However, if you're using Debian unstable/testing, or Ubuntu beta,"
echo "then you can continue, a recent version of OpenVPN is available on these."
echo "Keep in mind they are not supported, though."
while [[ $CONTINUE != "y" && $CONTINUE != "n" ]]; do
read -p "Continue ? [y/n]: " -e CONTINUE
done
if [[ "$CONTINUE" = "n" ]]; then
echo "Ok, bye !"
exit 4
fi
fi
2017-06-14 14:27:28 +02:00
elif [[ -e /etc/centos-release || -e /etc/redhat-release ]]; then
OS=centos
RCLOCAL='/etc/rc.d/rc.local'
2017-09-26 22:27:59 +02:00
SYSCTL='/etc/sysctl.conf'
# Needed for CentOS 7
chmod +x /etc/rc.d/rc.local
elif [[ -e /etc/arch-release ]]; then
OS=arch
RCLOCAL='/etc/rc.local'
SYSCTL='/etc/sysctl.d/openvpn.conf'
2017-06-14 14:27:28 +02:00
else
2017-09-26 22:27:59 +02:00
echo "Looks like you aren't running this installer on a Debian, Ubuntu, CentOS or ArchLinux system"
exit 4
2017-06-14 14:27:28 +02:00
fi
newclient () {
2017-09-26 22:27:59 +02:00
# Where to write the custom client.ovpn?
2017-10-01 15:03:40 +02:00
if [ ${SUDO_USER} ]; then # if not, use SUDO_USER
2017-09-26 22:27:59 +02:00
homeDir="/home/${SUDO_USER}"
else # if not SUDO_USER, use /root
homeDir="/root"
fi
2017-06-14 14:27:28 +02:00
# Generates the custom client.ovpn
2017-09-26 22:27:59 +02:00
cp /etc/openvpn/client-template.txt $homeDir/$1.ovpn
echo "<ca>" >> $homeDir/$1.ovpn
cat /etc/openvpn/easy-rsa/pki/ca.crt >> $homeDir/$1.ovpn
echo "</ca>" >> $homeDir/$1.ovpn
echo "<cert>" >> $homeDir/$1.ovpn
cat /etc/openvpn/easy-rsa/pki/issued/$1.crt >> $homeDir/$1.ovpn
echo "</cert>" >> $homeDir/$1.ovpn
echo "<key>" >> $homeDir/$1.ovpn
cat /etc/openvpn/easy-rsa/pki/private/$1.key >> $homeDir/$1.ovpn
echo "</key>" >> $homeDir/$1.ovpn
2017-10-01 15:03:40 +02:00
#We verify if we used tls-crypt or tls-auth during the installation
TLS_SIG=$(cat /etc/openvpn/TLS_SIG)
if [[ $TLS_SIG == "1" ]]; then
echo "<tls-crypt>" >> ~/$1.ovpn
cat /etc/openvpn/tls-crypt.key >> ~/$1.ovpn
echo "</tls-crypt>" >> ~/$1.ovpn
elif [[ $TLS_SIG == "2" ]]; then
echo "key-direction 1" >> $homeDir/$1.ovpn
echo "<tls-auth>" >> $homeDir/$1.ovpn
cat /etc/openvpn/tls-auth.key >> $homeDir/$1.ovpn
echo "</tls-auth>" >> $homeDir/$1.ovpn
fi
2017-06-14 14:27:28 +02:00
}
# Try to get our IP from the system and fallback to the Internet.
2017-09-26 22:27:59 +02:00
# I do this to make the script compatible with NATed servers (LowEndSpirit/Scaleway)
2017-06-14 14:27:28 +02:00
# and to avoid getting an IPv6.
IP=$(ip addr | grep 'inet' | grep -v inet6 | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -o -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1)
if [[ "$IP" = "" ]]; then
2017-09-26 22:27:59 +02:00
IP=$(wget -qO- ipv4.icanhazip.com)
2017-06-14 14:27:28 +02:00
fi
2017-09-26 22:27:59 +02:00
# Get Internet network interface with default route
2017-10-01 16:45:01 +02:00
NIC=$(ip -4 route ls | grep default -m 1 | grep -Po '(?<=dev )(\S+)')
2017-06-14 14:27:28 +02:00
if [[ -e /etc/openvpn/server.conf ]]; then
while :
do
clear
2017-09-26 22:27:59 +02:00
echo "OpenVPN-install (github.com/Angristan/OpenVPN-install)"
echo ""
2017-06-14 14:27:28 +02:00
echo "Looks like OpenVPN is already installed"
echo ""
echo "What do you want to do?"
2017-09-26 22:27:59 +02:00
echo " 1) Add a cert for a new user"
echo " 2) Revoke existing user cert"
2017-06-14 14:27:28 +02:00
echo " 3) Remove OpenVPN"
echo " 4) Exit"
read -p "Select an option [1-4]: " option
case $option in
2017-09-26 22:27:59 +02:00
1)
2017-06-14 14:27:28 +02:00
echo ""
2017-09-26 22:27:59 +02:00
echo "Tell me a name for the client cert"
2017-06-14 14:27:28 +02:00
echo "Please, use one word only, no special characters"
read -p "Client name: " -e -i client CLIENT
cd /etc/openvpn/easy-rsa/
./easyrsa build-client-full $CLIENT nopass
# Generates the custom client.ovpn
newclient "$CLIENT"
echo ""
2017-09-26 22:27:59 +02:00
echo "Client $CLIENT added, certs available at $homeDir/$CLIENT.ovpn"
2017-06-14 14:27:28 +02:00
exit
;;
2)
NUMBEROFCLIENTS=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep -c "^V")
if [[ "$NUMBEROFCLIENTS" = '0' ]]; then
echo ""
echo "You have no existing clients!"
2017-09-26 22:27:59 +02:00
exit 5
2017-06-14 14:27:28 +02:00
fi
echo ""
echo "Select the existing client certificate you want to revoke"
tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
if [[ "$NUMBEROFCLIENTS" = '1' ]]; then
read -p "Select one client [1]: " CLIENTNUMBER
else
read -p "Select one client [1-$NUMBEROFCLIENTS]: " CLIENTNUMBER
fi
CLIENT=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$CLIENTNUMBER"p)
cd /etc/openvpn/easy-rsa/
./easyrsa --batch revoke $CLIENT
./easyrsa gen-crl
rm -rf pki/reqs/$CLIENT.req
rm -rf pki/private/$CLIENT.key
rm -rf pki/issued/$CLIENT.crt
rm -rf /etc/openvpn/crl.pem
cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem
2017-09-26 22:27:59 +02:00
chmod 644 /etc/openvpn/crl.pem
2017-06-14 14:27:28 +02:00
echo ""
echo "Certificate for client $CLIENT revoked"
2017-09-26 22:27:59 +02:00
echo "Exiting..."
2017-06-14 14:27:28 +02:00
exit
;;
2017-09-26 22:27:59 +02:00
3)
2017-06-14 14:27:28 +02:00
echo ""
read -p "Do you really want to remove OpenVPN? [y/n]: " -e -i n REMOVE
if [[ "$REMOVE" = 'y' ]]; then
PORT=$(grep '^port ' /etc/openvpn/server.conf | cut -d " " -f 2)
if pgrep firewalld; then
# Using both permanent and not permanent rules to avoid a firewalld reload.
2017-09-26 22:27:59 +02:00
firewall-cmd --zone=public --remove-port=$PORT/udp
2017-06-14 14:27:28 +02:00
firewall-cmd --zone=trusted --remove-source=10.8.0.0/24
2017-09-26 22:27:59 +02:00
firewall-cmd --permanent --zone=public --remove-port=$PORT/udp
2017-06-14 14:27:28 +02:00
firewall-cmd --permanent --zone=trusted --remove-source=10.8.0.0/24
fi
2017-09-26 22:27:59 +02:00
if iptables -L -n | grep -qE 'REJECT|DROP'; then
sed -i "/iptables -I INPUT -p udp --dport $PORT -j ACCEPT/d" $RCLOCAL
sed -i "/iptables -I FORWARD -s 10.8.0.0\/24 -j ACCEPT/d" $RCLOCAL
sed -i "/iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT/d" $RCLOCAL
fi
sed -i '/iptables -t nat -A POSTROUTING -s 10.8.0.0\/24 -j SNAT --to /d' $RCLOCAL
2017-06-14 14:27:28 +02:00
if hash sestatus 2>/dev/null; then
if sestatus | grep "Current mode" | grep -qs "enforcing"; then
2017-09-26 22:27:59 +02:00
if [[ "$PORT" != '1194' ]]; then
semanage port -d -t openvpn_port_t -p udp $PORT
2017-06-14 14:27:28 +02:00
fi
fi
fi
if [[ "$OS" = 'debian' ]]; then
2017-09-26 22:27:59 +02:00
apt-get autoremove --purge -y openvpn
elif [[ "$OS" = 'arch' ]]; then
pacman -R openvpn --noconfirm
2017-06-14 14:27:28 +02:00
else
yum remove openvpn -y
fi
rm -rf /etc/openvpn
2017-09-26 22:27:59 +02:00
rm -rf /usr/share/doc/openvpn*
2017-10-01 15:03:40 +02:00
# Where are the client files?
if [ ${SUDO_USER} ]; then # if not, use SUDO_USER
homeDir="/home/${SUDO_USER}"
else # if not SUDO_USER, use /root
homeDir="/root"
fi
2017-10-01 16:45:01 +02:00
rm $homeDir/*.ovpn
2017-06-14 14:27:28 +02:00
echo ""
echo "OpenVPN removed!"
else
echo ""
echo "Removal aborted!"
fi
exit
;;
4) exit;;
esac
done
else
clear
2017-09-26 22:27:59 +02:00
echo "Welcome to the secure OpenVPN installer (github.com/Angristan/OpenVPN-install)"
2017-06-14 14:27:28 +02:00
echo ""
# OpenVPN setup and first user creation
echo "I need to ask you a few questions before starting the setup"
echo "You can leave the default options and just press enter if you are ok with them"
echo ""
2017-09-26 22:27:59 +02:00
echo "I need to know the IPv4 address of the network interface you want OpenVPN listening to."
echo "If your server is running behind a NAT, (e.g. LowEndSpirit, Scaleway) leave the IP address as it is. (local/private IP)"
echo "Otherwise, it should be your public IPv4 address."
2017-06-14 14:27:28 +02:00
read -p "IP address: " -e -i $IP IP
echo ""
2017-09-26 22:27:59 +02:00
echo "What port do you want for OpenVPN?"
read -p "Port: " -e -i 1194 PORT
echo ""
echo "What protocol do you want for OpenVPN?"
echo "Unless UDP is blocked, you should not use TCP (unnecessarily slower)"
2017-10-01 15:03:40 +02:00
echo " 1) UDP (recommended)"
echo " 2) TCP"
while [[ $PROTOCOL != "1" && $PROTOCOL != "2" ]]; do
read -p "Protocol [1-2]: " -e -i 1 PROTOCOL
2017-09-26 22:27:59 +02:00
done
echo ""
echo "What DNS do you want to use with the VPN?"
echo " 1) Current system resolvers (in /etc/resolv.conf)"
echo " 2) FDN (France)"
echo " 3) DNS.WATCH (Germany)"
echo " 4) OpenDNS (Anycast: worldwide)"
echo " 5) Google (Anycast: worldwide)"
echo " 6) Yandex Basic (Russia)"
while [[ $DNS != "1" && $DNS != "2" && $DNS != "3" && $DNS != "4" && $DNS != "5" && $DNS != "6" ]]; do
read -p "DNS [1-6]: " -e -i 1 DNS
done
echo ""
2017-10-01 15:03:40 +02:00
echo "Choose which compression algorithm you want to use:"
echo " 1) LZ4 (faster)"
echo " 2) LZ0 (use for OpenVPN 2.3 compatibility"
while [[ $COMPRESSION != "1" && $COMPRESSION != "2" ]]; do
read -p "Compression algorithm [1-2]: " -e -i 1 COMPRESSION
done
case $COMPRESSION in
1)
COMPRESSION="lz4"
;;
2)
COMPRESSION="lzo"
;;
esac
echo ""
2017-09-26 22:27:59 +02:00
echo "See https://github.com/Angristan/OpenVPN-install#encryption to learn more about "
2017-10-01 15:03:40 +02:00
echo "the encryption in OpenVPN and the choices proposed in this script."
echo "Please note that all the choices proposed are secure enough considering today's strandards, unlike some default OpenVPN options"
echo "You can just type "enter" if you don't know what to choose."
echo "Note that if you want to use an OpenVPN 2.3 client, You'll have to choose OpenVPN 2.3-compatible options."
echo "All OpenVPN 2.3-compatible choices are specified for each following option."
echo ""
2017-09-26 22:27:59 +02:00
echo "Choose which cipher you want to use for the data channel:"
2017-10-01 15:03:40 +02:00
echo " 1) AES-128-GCM (recommended)"
echo " 2) AES-192-GCM"
echo " 3) AES-256-GCM"
echo "Only use AES-CBC for OpenVPN 2.3 compatibilty"
echo " 4) AES-128-CBC"
echo " 5) AES-192-CBC"
echo " 6) AES-256-CBC"
while [[ $CIPHER != "1" && $CIPHER != "2" && $CIPHER != "3" && $CIPHER != "4" && $CIPHER != "5" && $CIPHER != "6" ]]; do
read -p "Data channel cipher [1-6]: " -e -i 1 CIPHER
2017-09-26 22:27:59 +02:00
done
case $CIPHER in
1)
2017-10-01 15:03:40 +02:00
CIPHER="cipher AES-128-GCM"
2017-06-14 14:27:28 +02:00
;;
2017-09-26 22:27:59 +02:00
2)
2017-10-01 15:03:40 +02:00
CIPHER="cipher AES-192-GCM"
2017-09-26 22:27:59 +02:00
;;
3)
2017-10-01 15:03:40 +02:00
CIPHER="cipher AES-256-GCM"
2017-09-26 22:27:59 +02:00
;;
4)
2017-10-01 15:03:40 +02:00
CIPHER="cipher AES-128-CBC"
2017-09-26 22:27:59 +02:00
;;
5)
2017-10-01 15:03:40 +02:00
CIPHER="cipher AES-192-CBC"
2017-09-26 22:27:59 +02:00
;;
6)
2017-10-01 15:03:40 +02:00
CIPHER="cipher AES-256-CBC"
2017-09-26 22:27:59 +02:00
;;
2017-10-01 15:03:40 +02:00
esac
echo ""
echo "Choose what kind of certificate you want to use:"
echo "Elleptic Curves keys (EC) are recommended, they're faster, lighter and more secure."
echo "Use RSA for OpenVPN 2.3 compatibilty"
echo " 1) ECDSA (recommended)"
echo " 2) RSA"
while [[ $CERT_TYPE != "1" && $CERT_TYPE != "2" ]]; do
read -p "Certificate type [1-2]: " -e -i 1 CERT_TYPE
done
case $CERT_TYPE in
1)
echo ""
echo "Choose which curve you want to use for the EC key:"
echo " 1) secp256r1"
echo " 2) secp384r1 (recommended)"
echo " 3) secp521r1"
while [[ $CERT_CURVE != "1" && $CERT_CURVE != "2" && $CERT_CURVE != "3" ]]; do
read -p "Curve [1-3]: " -e -i 2 CERT_CURVE
done
case $CERT_CURVE in
1)
CERT_CURVE="secp256r1"
;;
2)
CERT_CURVE="secp384r1"
;;
3)
CERT_CURVE="secp521r1"
;;
esac
;;
2)
echo ""
echo "Choose which RSA key size you want to use:"
echo " 1) 2048 bits"
echo " 2) 3072 bits (recommended)"
echo " 3) 4096 bits"
while [[ $RSA_SIZE != "1" && $RSA_SIZE != "2" && $RSA_SIZE != "3" ]]; do
read -p "DH key size [1-3]: " -e -i 2 RSA_SIZE
done
case $RSA_SIZE in
1)
RSA_SIZE="2048"
;;
2)
RSA_SIZE="3072"
;;
3)
RSA_SIZE="4096"
;;
esac
2017-06-14 14:27:28 +02:00
;;
esac
echo ""
2017-10-01 15:03:40 +02:00
echo "Choose which hash algorithm you want to use for the certificate:"
echo " 1) SHA-256"
echo " 2) SHA-384 (recommended)"
echo " 3) SHA-512"
while [[ $CERT_HASH != "1" && $CERT_HASH != "2" && $CERT_HASH != "3" ]]; do
read -p "Hash algorithm [1-3]: " -e -i 2 CERT_HASH
2017-09-26 22:27:59 +02:00
done
2017-10-01 15:03:40 +02:00
case $CERT_HASH in
2017-09-26 22:27:59 +02:00
1)
2017-10-01 15:03:40 +02:00
CERT_HASH="sha256"
2017-09-26 22:27:59 +02:00
;;
2)
2017-10-01 15:03:40 +02:00
CERT_HASH="sha384"
2017-09-26 22:27:59 +02:00
;;
3)
2017-10-01 15:03:40 +02:00
CERT_HASH="sha512"
2017-09-26 22:27:59 +02:00
;;
esac
2017-06-14 14:27:28 +02:00
echo ""
2017-10-01 15:03:40 +02:00
echo "Choose what kind of Diffie-Hellman key you want to use."
echo "Elleptic Curves (EC) are recommended, they're faster, lighter and more secure."
echo "Use DH for OpenVPN 2.3 compatibilty"
echo " 1) ECDH (recommended)"
echo " 2) DH"
while [[ $DH_TYPE != "1" && $DH_TYPE != "2" ]]; do
read -p "DH key type [1-2]: " -e -i 1 DH_TYPE
2017-09-26 22:27:59 +02:00
done
2017-10-01 15:03:40 +02:00
case $DH_TYPE in
2017-09-26 22:27:59 +02:00
1)
2017-10-01 15:03:40 +02:00
echo ""
echo "Choose which curve you want to use for the ECDH key"
echo " 1) secp256r1"
echo " 2) secp384r1 (recommended)"
echo " 3) secp521r1"
while [[ $DH_CURVE != "1" && $DH_CURVE != "2" && $DH_CURVE != "3" ]]; do
read -p "Curve [1-3]: " -e -i 2 DH_CURVE
done
case $DH_CURVE in
1)
DH_CURVE="secp256r1"
;;
2)
DH_CURVE="secp384r1"
;;
3)
DH_CURVE="secp521r1"
;;
esac
2017-09-26 22:27:59 +02:00
;;
2)
2017-10-01 15:03:40 +02:00
echo""
echo "Choose which DH key size you want to use"
echo " 1) 2048 bits"
echo " 2) 3072 bits (recommended)"
echo " 3) 4096 bits"
while [[ $DH_SIZE != "1" && $DH_SIZE != "2" && $DH_SIZE != "3" ]]; do
read -p "DH key size [1-3]: " -e -i 2 DH_SIZE
done
case $DH_SIZE in
1)
DH_SIZE="2048"
;;
2)
DH_SIZE="3072"
;;
3)
DH_SIZE="4096"
;;
esac
;;
esac
echo ""
echo "Choose which cipher you want to use for the control channel:"
if [[ "$CERT_TYPE" = '1' ]]; then
echo " 1) ECDHE-ECDSA-AES-256-GCM-SHA384 (recommended)"
echo " 2) ECDHE-ECDSA-AES-128-GCM-SHA256"
while [[ $CC_ENC != "1" && $CC_ENC != "2" ]]; do
read -p "Control channel cipher [1-2]: " -e -i 1 CC_ENC
done
case $CC_ENC in
1)
CC_ENC="TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384"
;;
2)
CC_ENC="TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256"
;;
esac
elif [[ "$CERT_TYPE" = '2' ]]; then
echo " 1) ECDHE-RSA-AES-256-GCM-SHA384 (recommended)"
echo " 2) ECDHE-RSA-AES-128-GCM-SHA256"
while [[ $CC_ENC != "1" && $CC_ENC != "2" ]]; do
read -p "Control channel cipher [1-2]: " -e -i 1 CC_ENC
done
case $CC_ENC in
1)
CC_ENC="TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384"
;;
2)
CC_ENC="TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256"
;;
esac
fi
echo ""
echo "Do you want to use tls-crypt or tls-auth?"
echo "They both encrypt and authenticate all control channel packets with a key."
echo "tls-crypt is more advanced and secure than tls-auth, but it's an OpenVPN 2.4 feature."
echo " 1) tls-crypt (recommended)"
echo " 2) tls-auth (use only for OpenVPN 2.3 client compatibility)"
while [[ $TLS_SIG != "1" && $TLS_SIG != "2" ]]; do
read -p "Crontrol channel additional security layer [1-2]: " -e -i 1 TLS_SIG
done
echo""
if [[ $CIPHER = "cipher AES-256-GCM" ]] || [[ $CIPHER = "cipher AES-192-GCM" ]] || [[ $CIPHER = "cipher AES-128-GCM" ]]; then
echo "Choose which message digest algorithm you want to use for the tls-auth/tls-crypt control channel packets:"
elif [[ $CIPHER = "cipher AES-256-CBC" ]] || [[ $CIPHER = "cipher AES-192-CBC" ]] || [[ $CIPHER = "cipher AES-128-CBC" ]]; then
echo "Choose which message digest algorithm you want to use for the data channel packets"
echo "and the tls-auth/tls-crypt control channel packets:"
fi
echo " 1) SHA-256"
echo " 2) SHA-384 (recommended)"
echo " 3) SHA-512"
while [[ $HMAC_AUTH != "1" && $HMAC_AUTH != "2" && $HMAC_AUTH != "3" ]]; do
read -p "HMAC authentication algorithm [1-3]: " -e -i 2 HMAC_AUTH
done
case $HMAC_AUTH in
1)
HMAC_AUTH="SHA256"
;;
2)
HMAC_AUTH="SHA384"
2017-09-26 22:27:59 +02:00
;;
3)
2017-10-01 15:03:40 +02:00
HMAC_AUTH="SHA512"
2017-09-26 22:27:59 +02:00
;;
esac
2017-06-14 14:27:28 +02:00
echo ""
2017-09-26 22:27:59 +02:00
echo "Finally, tell me a name for the client certificate and configuration"
while [[ $CLIENT = "" ]]; do
echo "Please, use one word only, no special characters"
read -p "Client name: " -e -i client CLIENT
done
2017-06-14 14:27:28 +02:00
echo ""
echo "Okay, that was all I needed. We are ready to setup your OpenVPN server now"
read -n1 -r -p "Press any key to continue..."
2017-09-26 22:27:59 +02:00
2017-06-14 14:27:28 +02:00
if [[ "$OS" = 'debian' ]]; then
2017-09-26 22:27:59 +02:00
apt-get install ca-certificates -y
# We add the OpenVPN repo to get the latest version.
# Debian 8
if [[ "$VERSION_ID" = 'VERSION_ID="8"' ]]; then
echo "deb http://build.openvpn.net/debian/openvpn/stable jessie main" > /etc/apt/sources.list.d/openvpn.list
wget -O - https://swupdate.openvpn.net/repos/repo-public.gpg | apt-key add -
# Ubuntu 14.04
2017-10-01 15:03:40 +02:00
elif [[ "$VERSION_ID" = 'VERSION_ID="14.04"' ]]; then
2017-09-26 22:27:59 +02:00
echo "deb http://build.openvpn.net/debian/openvpn/stable trusty main" > /etc/apt/sources.list.d/openvpn.list
wget -O - https://swupdate.openvpn.net/repos/repo-public.gpg | apt-key add -
2017-10-01 15:03:40 +02:00
# Ubuntu 16.04
elif [[ "$VERSION_ID" = 'VERSION_ID="16.04"' ]]; then
echo "deb http://build.openvpn.net/debian/openvpn/stable xenial main" > /etc/apt/sources.list.d/openvpn.list
wget -O - https://swupdate.openvpn.net/repos/repo-public.gpg | apt-key add -
2017-09-26 22:27:59 +02:00
fi
2017-10-01 15:03:40 +02:00
# Ubuntu >= 17.04 and Debian > 9 have OpenVPN 2.4 without the need of a third party repository.
2017-09-26 22:27:59 +02:00
# The we install OpenVPN
2017-10-01 15:03:40 +02:00
apt-get update
2017-09-26 22:27:59 +02:00
apt-get install openvpn iptables openssl wget ca-certificates curl -y
elif [[ "$OS" = 'centos' ]]; then
2017-06-14 14:27:28 +02:00
yum install epel-release -y
2017-09-26 22:27:59 +02:00
yum install openvpn iptables openssl wget ca-certificates curl -y
else
# Else, the distro is ArchLinux
echo ""
echo ""
echo "As you're using ArchLinux, I need to update the packages on your system to install those I need."
echo "Not doing that could cause problems between dependencies, or missing files in repositories."
echo ""
echo "Continuing will update your installed packages and install needed ones."
while [[ $CONTINUE != "y" && $CONTINUE != "n" ]]; do
read -p "Continue ? [y/n]: " -e -i y CONTINUE
done
if [[ "$CONTINUE" = "n" ]]; then
echo "Ok, bye !"
exit 4
fi
if [[ "$OS" = 'arch' ]]; then
# Install rc.local
echo "[Unit]
Description=/etc/rc.local compatibility
[Service]
Type=oneshot
ExecStart=/etc/rc.local
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target" > /etc/systemd/system/rc-local.service
chmod +x /etc/rc.local
systemctl enable rc-local.service
if ! grep '#!' $RCLOCAL; then
echo "#!/bin/bash" > $RCLOCAL
fi
fi
# Install dependencies
pacman -Syu openvpn iptables openssl wget ca-certificates curl --needed --noconfirm
if [[ "$OS" = 'arch' ]]; then
touch /etc/iptables/iptables.rules # iptables won't start if this file does not exist
systemctl enable iptables
systemctl start iptables
fi
2017-06-14 14:27:28 +02:00
fi
2017-10-01 15:03:40 +02:00
#To remember if we use tls-crypt or tls-auth when generating a new client conf
echo $TLS_SIG > /etc/openvpn/TLS_SIG
2017-09-26 22:27:59 +02:00
# Find out if the machine uses nogroup or nobody for the permissionless group
if grep -qs "^nogroup:" /etc/group; then
NOGROUP=nogroup
else
NOGROUP=nobody
fi
2017-06-14 14:27:28 +02:00
# An old version of easy-rsa was available by default in some openvpn packages
if [[ -d /etc/openvpn/easy-rsa/ ]]; then
rm -rf /etc/openvpn/easy-rsa/
fi
# Get easy-rsa
2017-09-26 22:27:59 +02:00
wget -O ~/EasyRSA-3.0.3.tgz https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.3/EasyRSA-3.0.3.tgz
tar xzf ~/EasyRSA-3.0.3.tgz -C ~/
mv ~/EasyRSA-3.0.3/ /etc/openvpn/
mv /etc/openvpn/EasyRSA-3.0.3/ /etc/openvpn/easy-rsa/
2017-06-14 14:27:28 +02:00
chown -R root:root /etc/openvpn/easy-rsa/
2017-09-26 22:27:59 +02:00
rm -rf ~/EasyRSA-3.0.3.tgz
2017-06-14 14:27:28 +02:00
cd /etc/openvpn/easy-rsa/
2017-10-01 15:03:40 +02:00
if [[ $CERT_TYPE == "1" ]]; then
echo "set_var EASYRSA_ALGO ec
set_var EASYRSA_CURVE $CERT_CURVE" > vars
elif [[ $CERT_TYPE == "2" ]]; then
echo "set_var EASYRSA_KEY_SIZE $RSA_SIZE" > vars
fi
echo 'set_var EASYRSA_DIGEST "'$CERT_HASH'"' >> vars
2017-06-14 14:27:28 +02:00
# Create the PKI, set up the CA, the DH params and the server + client certificates
./easyrsa init-pki
./easyrsa --batch build-ca nopass
2017-10-01 15:03:40 +02:00
if [[ $DH_TYPE == "2" ]]; then
openssl dhparam -out dh.pem $DH_SIZE
fi
2017-06-14 14:27:28 +02:00
./easyrsa build-server-full server nopass
./easyrsa build-client-full $CLIENT nopass
./easyrsa gen-crl
2017-10-01 15:03:40 +02:00
if [[ $TLS_SIG == "1" ]]; then
# Generate tls-crypt key
openvpn --genkey --secret /etc/openvpn/tls-crypt.key
elif [[ $TLS_SIG == "2" ]]; then
# Generate tls-auth key
openvpn --genkey --secret /etc/openvpn/tls-auth.key
fi
2017-09-26 22:27:59 +02:00
# Move all the generated files
2017-10-01 15:03:40 +02:00
cp pki/ca.crt pki/private/ca.key pki/issued/server.crt pki/private/server.key /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn
if [[ $DH_TYPE == "2" ]]; then
cp dh.pem /etc/openvpn
fi
2017-09-26 22:27:59 +02:00
# Make cert revocation list readable for non-root
chmod 644 /etc/openvpn/crl.pem
2017-06-14 14:27:28 +02:00
# Generate server.conf
2017-10-01 15:03:40 +02:00
echo "port $PORT" > /etc/openvpn/server.conf
if [[ "$PROTOCOL" = '1' ]]; then
2017-09-26 22:27:59 +02:00
echo "proto udp" >> /etc/openvpn/server.conf
2017-10-01 15:03:40 +02:00
elif [[ "$PROTOCOL" = '2' ]]; then
2017-09-26 22:27:59 +02:00
echo "proto tcp" >> /etc/openvpn/server.conf
fi
echo "dev tun
user nobody
group $NOGROUP
persist-key
persist-tun
keepalive 10 120
2017-06-14 14:27:28 +02:00
topology subnet
server 10.8.0.0 255.255.255.0
2017-09-26 22:27:59 +02:00
ifconfig-pool-persist ipp.txt" >> /etc/openvpn/server.conf
# DNS resolvers
2017-06-14 14:27:28 +02:00
case $DNS in
2017-09-26 22:27:59 +02:00
1)
2017-06-14 14:27:28 +02:00
# Obtain the resolvers from resolv.conf and use them for OpenVPN
grep -v '#' /etc/resolv.conf | grep 'nameserver' | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | while read line; do
echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server.conf
done
;;
2017-09-26 22:27:59 +02:00
2) #FDN
echo 'push "dhcp-option DNS 80.67.169.12"' >> /etc/openvpn/server.conf
echo 'push "dhcp-option DNS 80.67.169.40"' >> /etc/openvpn/server.conf
2017-06-14 14:27:28 +02:00
;;
2017-09-26 22:27:59 +02:00
3) #DNS.WATCH
echo 'push "dhcp-option DNS 84.200.69.80"' >> /etc/openvpn/server.conf
echo 'push "dhcp-option DNS 84.200.70.40"' >> /etc/openvpn/server.conf
;;
4) #OpenDNS
2017-06-14 14:27:28 +02:00
echo 'push "dhcp-option DNS 208.67.222.222"' >> /etc/openvpn/server.conf
echo 'push "dhcp-option DNS 208.67.220.220"' >> /etc/openvpn/server.conf
;;
2017-09-26 22:27:59 +02:00
5) #Google
echo 'push "dhcp-option DNS 8.8.8.8"' >> /etc/openvpn/server.conf
echo 'push "dhcp-option DNS 8.8.4.4"' >> /etc/openvpn/server.conf
2017-06-14 14:27:28 +02:00
;;
2017-09-26 22:27:59 +02:00
6) #Yandex Basic
echo 'push "dhcp-option DNS 77.88.8.8"' >> /etc/openvpn/server.conf
echo 'push "dhcp-option DNS 77.88.8.1"' >> /etc/openvpn/server.conf
2017-06-14 14:27:28 +02:00
;;
esac
2017-09-26 22:27:59 +02:00
echo 'push "redirect-gateway def1 bypass-dhcp" '>> /etc/openvpn/server.conf
echo "crl-verify crl.pem
ca ca.crt
cert server.crt
2017-10-01 15:03:40 +02:00
key server.key" >> /etc/openvpn/server.conf
if [[ $TLS_SIG == "1" ]]; then
echo "tls-crypt tls-crypt.key 0" >> /etc/openvpn/server.conf
elif [[ $TLS_SIG == "2" ]]; then
echo "tls-auth tls-auth.key 0" >> /etc/openvpn/server.conf
fi
if [[ $DH_TYPE == "1" ]]; then
echo "dh none
ecdh-curve $DH_CURVE" >> /etc/openvpn/server.conf
elif [[ $DH_TYPE == "2" ]]; then
echo "dh dh.pem" >> /etc/openvpn/server.conf
fi
echo "auth $HMAC_AUTH
2017-09-26 22:27:59 +02:00
$CIPHER
2017-10-01 15:03:40 +02:00
ncp-disable
2017-09-26 22:27:59 +02:00
tls-server
tls-version-min 1.2
2017-10-01 15:03:40 +02:00
tls-cipher $CC_ENC
compress $COMPRESSION
2017-09-26 22:27:59 +02:00
status openvpn.log
verb 3" >> /etc/openvpn/server.conf
# Create the sysctl configuration file if needed (mainly for Arch Linux)
if [[ ! -e $SYSCTL ]]; then
touch $SYSCTL
fi
2017-06-14 14:27:28 +02:00
# Enable net.ipv4.ip_forward for the system
2017-09-26 22:27:59 +02:00
sed -i '/\<net.ipv4.ip_forward\>/c\net.ipv4.ip_forward=1' $SYSCTL
if ! grep -q "\<net.ipv4.ip_forward\>" $SYSCTL; then
echo 'net.ipv4.ip_forward=1' >> $SYSCTL
2017-06-14 14:27:28 +02:00
fi
# Avoid an unneeded reboot
echo 1 > /proc/sys/net/ipv4/ip_forward
2017-09-26 22:27:59 +02:00
# Needed to use rc.local with some systemd distros
if [[ "$OS" = 'debian' && ! -e $RCLOCAL ]]; then
echo '#!/bin/sh -e
exit 0' > $RCLOCAL
fi
chmod +x $RCLOCAL
# Set NAT for the VPN subnet
iptables -t nat -A POSTROUTING -o $NIC -s 10.8.0.0/24 -j MASQUERADE
sed -i "1 a\iptables -t nat -A POSTROUTING -o $NIC -s 10.8.0.0/24 -j MASQUERADE" $RCLOCAL
2017-06-14 14:27:28 +02:00
if pgrep firewalld; then
# We don't use --add-service=openvpn because that would only work with
2017-09-26 22:27:59 +02:00
# the default port. Using both permanent and not permanent rules to
# avoid a firewalld reload.
2017-10-01 15:03:40 +02:00
if [[ "$PROTOCOL" = '1' ]]; then
2017-09-26 22:27:59 +02:00
firewall-cmd --zone=public --add-port=$PORT/udp
firewall-cmd --permanent --zone=public --add-port=$PORT/udp
2017-10-01 15:03:40 +02:00
elif [[ "$PROTOCOL" = '2' ]]; then
2017-09-26 22:27:59 +02:00
firewall-cmd --zone=public --add-port=$PORT/tcp
firewall-cmd --permanent --zone=public --add-port=$PORT/tcp
fi
2017-06-14 14:27:28 +02:00
firewall-cmd --zone=trusted --add-source=10.8.0.0/24
firewall-cmd --permanent --zone=trusted --add-source=10.8.0.0/24
2017-09-26 22:27:59 +02:00
fi
if iptables -L -n | grep -qE 'REJECT|DROP'; then
# If iptables has at least one REJECT rule, we asume this is needed.
# Not the best approach but I can't think of other and this shouldn't
# cause problems.
2017-10-01 15:03:40 +02:00
if [[ "$PROTOCOL" = '1' ]]; then
2017-09-26 22:27:59 +02:00
iptables -I INPUT -p udp --dport $PORT -j ACCEPT
2017-10-01 15:03:40 +02:00
elif [[ "$PROTOCOL" = '2' ]]; then
2017-09-26 22:27:59 +02:00
iptables -I INPUT -p tcp --dport $PORT -j ACCEPT
2017-06-14 14:27:28 +02:00
fi
2017-09-26 22:27:59 +02:00
iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT
iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
2017-10-01 15:03:40 +02:00
if [[ "$PROTOCOL" = '1' ]]; then
2017-09-26 22:27:59 +02:00
sed -i "1 a\iptables -I INPUT -p udp --dport $PORT -j ACCEPT" $RCLOCAL
2017-10-01 15:03:40 +02:00
elif [[ "$PROTOCOL" = '2' ]]; then
2017-09-26 22:27:59 +02:00
sed -i "1 a\iptables -I INPUT -p tcp --dport $PORT -j ACCEPT" $RCLOCAL
2017-06-14 14:27:28 +02:00
fi
2017-09-26 22:27:59 +02:00
sed -i "1 a\iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT" $RCLOCAL
sed -i "1 a\iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" $RCLOCAL
2017-06-14 14:27:28 +02:00
fi
2017-09-26 22:27:59 +02:00
# If SELinux is enabled and a custom port was selected, we need this
2017-06-14 14:27:28 +02:00
if hash sestatus 2>/dev/null; then
if sestatus | grep "Current mode" | grep -qs "enforcing"; then
2017-09-26 22:27:59 +02:00
if [[ "$PORT" != '1194' ]]; then
2017-06-14 14:27:28 +02:00
# semanage isn't available in CentOS 6 by default
if ! hash semanage 2>/dev/null; then
yum install policycoreutils-python -y
fi
2017-10-01 15:03:40 +02:00
if [[ "$PROTOCOL" = '1' ]]; then
2017-09-26 22:27:59 +02:00
semanage port -a -t openvpn_port_t -p udp $PORT
2017-10-01 15:03:40 +02:00
elif [[ "$PROTOCOL" = '2' ]]; then
2017-09-26 22:27:59 +02:00
semanage port -a -t openvpn_port_t -p tcp $PORT
fi
2017-06-14 14:27:28 +02:00
fi
fi
fi
# And finally, restart OpenVPN
if [[ "$OS" = 'debian' ]]; then
# Little hack to check for systemd
if pgrep systemd-journal; then
2017-09-26 22:27:59 +02:00
if [[ "$VERSION_ID" = 'VERSION_ID="9"' ]]; then
#Workaround to fix OpenVPN service on Debian 9 OpenVZ
sed -i 's|LimitNPROC|#LimitNPROC|' /lib/systemd/system/openvpn-server\@.service
sed -i 's|/etc/openvpn/server|/etc/openvpn|' /lib/systemd/system/openvpn-server\@.service
sed -i 's|%i.conf|server.conf|' /lib/systemd/system/openvpn-server\@.service
systemctl daemon-reload
systemctl restart openvpn-server@openvpn.service
systemctl enable openvpn-server@openvpn.service
else
systemctl restart openvpn@server.service
fi
2017-06-14 14:27:28 +02:00
else
/etc/init.d/openvpn restart
fi
else
if pgrep systemd-journal; then
2017-09-26 22:27:59 +02:00
if [[ "$OS" = 'arch' ]]; then
#Workaround to avoid rewriting the entire script for Arch
sed -i 's|/etc/openvpn/server|/etc/openvpn|' /usr/lib/systemd/system/openvpn-server@.service
sed -i 's|%i.conf|server.conf|' /usr/lib/systemd/system/openvpn-server@.service
systemctl daemon-reload
systemctl restart openvpn-server@openvpn.service
systemctl enable openvpn-server@openvpn.service
else
systemctl restart openvpn@server.service
systemctl enable openvpn@server.service
fi
2017-06-14 14:27:28 +02:00
else
service openvpn restart
chkconfig openvpn on
fi
fi
2017-09-26 22:27:59 +02:00
# Try to detect a NATed connection and ask about it to potential LowEndSpirit/Scaleway users
EXTERNALIP=$(wget -qO- ipv4.icanhazip.com)
2017-06-14 14:27:28 +02:00
if [[ "$IP" != "$EXTERNALIP" ]]; then
echo ""
echo "Looks like your server is behind a NAT!"
echo ""
2017-09-26 22:27:59 +02:00
echo "If your server is NATed (e.g. LowEndSpirit, Scaleway, or behind a router),"
echo "then I need to know the address that can be used to access it from outside."
echo "If that's not the case, just ignore this and leave the next field blank"
read -p "External IP or domain name: " -e USEREXTERNALIP
2017-06-14 14:27:28 +02:00
if [[ "$USEREXTERNALIP" != "" ]]; then
IP=$USEREXTERNALIP
fi
fi
2017-09-26 22:27:59 +02:00
# client-template.txt is created so we have a template to add further users later
echo "client" > /etc/openvpn/client-template.txt
2017-10-01 15:03:40 +02:00
if [[ "$PROTOCOL" = '1' ]]; then
2017-09-26 22:27:59 +02:00
echo "proto udp" >> /etc/openvpn/client-template.txt
2017-10-01 15:03:40 +02:00
elif [[ "$PROTOCOL" = '2' ]]; then
2017-09-26 22:27:59 +02:00
echo "proto tcp-client" >> /etc/openvpn/client-template.txt
fi
echo "remote $IP $PORT
2017-06-14 14:27:28 +02:00
dev tun
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
2017-10-01 15:03:40 +02:00
auth $HMAC_AUTH
2017-09-26 22:27:59 +02:00
$CIPHER
tls-client
tls-version-min 1.2
2017-10-01 15:03:40 +02:00
tls-cipher $CC_ENC
2017-06-14 14:27:28 +02:00
setenv opt block-outside-dns
2017-09-26 22:27:59 +02:00
verb 3" >> /etc/openvpn/client-template.txt
# Generate the custom client.ovpn
2017-06-14 14:27:28 +02:00
newclient "$CLIENT"
echo ""
echo "Finished!"
echo ""
2017-09-26 22:27:59 +02:00
echo "Your client config is available at $homeDir/$CLIENT.ovpn"
echo "If you want to add more clients, you simply need to run this script another time!"
fi
exit 0;
2017-10-01 16:45:01 +02:00
# internet-routing
iptables -t nat -F POSTROUTING
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -s 10.8.0.0/24 -j MASQUERADE