|
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
|
|
# Secure OpenVPN server installer for Debian, Ubuntu, CentOS, Fedora and Arch Linux
|
|
|
|
|
# https://github.com/angristan/openvpn-install
|
|
|
|
|
|
|
|
|
|
function isRoot () {
|
|
|
|
|
if [ "$EUID" -ne 0 ]; then
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function tunAvailable () {
|
|
|
|
|
if [ ! -e /dev/net/tun ]; then
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkOS () {
|
|
|
|
|
if [[ -e /etc/debian_version ]]; then
|
|
|
|
|
source /etc/os-release
|
|
|
|
|
|
|
|
|
|
if [[ "$ID" == "debian" ]]; then
|
|
|
|
|
if [[ ! $VERSION_ID =~ (8|9) ]]; then
|
|
|
|
|
echo "⚠️ Your version of Debian is not supported."
|
|
|
|
|
echo ""
|
|
|
|
|
echo "However, if you're using Debian >= 9 or unstable/testing then you can continue."
|
|
|
|
|
echo "Keep in mind they are not supported, though."
|
|
|
|
|
echo ""
|
|
|
|
|
until [[ $CONTINUE =~ (y|n) ]]; do
|
|
|
|
|
read -rp "Continue? [y/n]: " -e CONTINUE
|
|
|
|
|
done
|
|
|
|
|
if [[ "$CONTINUE" = "n" ]]; then
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
else
|
|
|
|
|
echo "Looks like you aren't running this installer on a Debian Linux system"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function initialCheck () {
|
|
|
|
|
if ! isRoot; then
|
|
|
|
|
echo "Sorry, you need to run this as root"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
if ! tunAvailable; then
|
|
|
|
|
echo "TUN is not available"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
checkOS
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function newClient () {
|
|
|
|
|
echo ""
|
|
|
|
|
echo "Tell me a name for the client."
|
|
|
|
|
echo "Use one word only, no special characters."
|
|
|
|
|
|
|
|
|
|
until [[ "$CLIENT" =~ ^[a-zA-Z0-9_]+$ ]]; do
|
|
|
|
|
read -rp "Client name: " -e CLIENT
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
echo "Do you want to protect the configuration file with a password?"
|
|
|
|
|
echo "(e.g. encrypt the private key with a password)"
|
|
|
|
|
echo " 1) Add a passwordless client"
|
|
|
|
|
echo " 2) Use a password for the client"
|
|
|
|
|
|
|
|
|
|
until [[ "$PASS" =~ ^[1-2]$ ]]; do
|
|
|
|
|
read -rp "Select an option [1-2]: " -e -i 1 PASS
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
cd /etc/openvpn/easy-rsa/ || return
|
|
|
|
|
case $PASS in
|
|
|
|
|
1)
|
|
|
|
|
./easyrsa build-client-full "$CLIENT" nopass
|
|
|
|
|
;;
|
|
|
|
|
2)
|
|
|
|
|
echo "⚠️ You will be asked for the client password below ⚠️"
|
|
|
|
|
./easyrsa build-client-full "$CLIENT"
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
|
|
|
|
|
# Home directory of the user, where the client configuration (.ovpn) will be written
|
|
|
|
|
if [ -e "/home/$CLIENT" ]; then # if $1 is a user name
|
|
|
|
|
homeDir="/home/$CLIENT"
|
|
|
|
|
elif [ "${SUDO_USER}" ]; then # if not, use SUDO_USER
|
|
|
|
|
homeDir="/home/${SUDO_USER}"
|
|
|
|
|
else # if not SUDO_USER, use /root
|
|
|
|
|
homeDir="/root"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Determine if we use tls-auth or tls-crypt
|
|
|
|
|
if grep -qs "^tls-crypt" /etc/openvpn/server.conf; then
|
|
|
|
|
TLS_SIG="1"
|
|
|
|
|
elif grep -qs "^tls-auth" /etc/openvpn/server.conf; then
|
|
|
|
|
TLS_SIG="2"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Generates the custom client.ovpn
|
|
|
|
|
cp /etc/openvpn/client-template.txt "$homeDir/$CLIENT.ovpn"
|
|
|
|
|
{
|
|
|
|
|
echo "<ca>"
|
|
|
|
|
cat "/etc/openvpn/easy-rsa/pki/ca.crt"
|
|
|
|
|
echo "</ca>"
|
|
|
|
|
|
|
|
|
|
echo "<cert>"
|
|
|
|
|
awk '/BEGIN/,/END/' "/etc/openvpn/easy-rsa/pki/issued/$CLIENT.crt"
|
|
|
|
|
echo "</cert>"
|
|
|
|
|
|
|
|
|
|
echo "<key>"
|
|
|
|
|
cat "/etc/openvpn/easy-rsa/pki/private/$CLIENT.key"
|
|
|
|
|
echo "</key>"
|
|
|
|
|
|
|
|
|
|
case $TLS_SIG in
|
|
|
|
|
1)
|
|
|
|
|
echo "<tls-crypt>"
|
|
|
|
|
cat /etc/openvpn/tls-crypt.key
|
|
|
|
|
echo "</tls-crypt>"
|
|
|
|
|
;;
|
|
|
|
|
2)
|
|
|
|
|
echo "key-direction 1"
|
|
|
|
|
echo "<tls-auth>"
|
|
|
|
|
cat /etc/openvpn/tls-auth.key
|
|
|
|
|
echo "</tls-auth>"
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
} >> "$homeDir/$CLIENT.ovpn"
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
echo "Client $CLIENT added, the configuration file is available at $homeDir/$CLIENT.ovpn."
|
|
|
|
|
echo "Download the .ovpn file and import it in your OpenVPN client."
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function revokeClient () {
|
|
|
|
|
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!"
|
|
|
|
|
exit 1
|
|
|
|
|
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 -rp "Select one client [1]: " CLIENTNUMBER
|
|
|
|
|
else
|
|
|
|
|
read -rp "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_CRL_DAYS=3650 ./easyrsa gen-crl
|
|
|
|
|
# Cleanup
|
|
|
|
|
rm -f "pki/reqs/$CLIENT.req"
|
|
|
|
|
rm -f "pki/private/$CLIENT.key"
|
|
|
|
|
rm -f "pki/issued/$CLIENT.crt"
|
|
|
|
|
rm -f /etc/openvpn/crl.pem
|
|
|
|
|
cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem
|
|
|
|
|
chmod 644 /etc/openvpn/crl.pem
|
|
|
|
|
find /home/ -maxdepth 2 -name "$CLIENT.ovpn" -delete
|
|
|
|
|
rm -f "/root/$CLIENT.ovpn"
|
|
|
|
|
sed -i "s|^$CLIENT,.*||" /etc/openvpn/ipp.txt
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
echo "Certificate for client $CLIENT revoked."
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function manageMenu () {
|
|
|
|
|
clear
|
|
|
|
|
echo "Welcome to OpenVPN-install!"
|
|
|
|
|
echo "The git repository is available at: https://github.com/angristan/openvpn-install"
|
|
|
|
|
echo ""
|
|
|
|
|
echo "It looks like OpenVPN is already installed."
|
|
|
|
|
echo ""
|
|
|
|
|
echo "What do you want to do?"
|
|
|
|
|
echo " 1) Add a new user"
|
|
|
|
|
echo " 2) Revoke existing user"
|
|
|
|
|
echo " 3) Exit"
|
|
|
|
|
until [[ "$MENU_OPTION" =~ ^[1-4]$ ]]; do
|
|
|
|
|
read -rp "Select an option [1-4]: " MENU_OPTION
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
case $MENU_OPTION in
|
|
|
|
|
1)
|
|
|
|
|
newClient
|
|
|
|
|
;;
|
|
|
|
|
2)
|
|
|
|
|
revokeClient
|
|
|
|
|
;;
|
|
|
|
|
3)
|
|
|
|
|
exit 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Check for root, TUN, OS...
|
|
|
|
|
initialCheck
|
|
|
|
|
|
|
|
|
|
# Check if OpenVPN is already installed
|
|
|
|
|
if [[ -e /etc/openvpn/server.conf ]]; then
|
|
|
|
|
manageMenu
|
|
|
|
|
else
|
|
|
|
|
echo 'No configuration file detected!'
|
|
|
|
|
fi
|