diff --git a/openvpn-install.sh b/openvpn-install.sh index bbf9227..9e66f84 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -3,21 +3,22 @@ # Secure OpenVPN server installer for Debian, Ubuntu, CentOS, Fedora and Arch Linux # https://github.com/angristan/openvpn-install -function isRoot () { +function isRoot() { if [ "$EUID" -ne 0 ]; then return 1 fi } -function tunAvailable () { +function tunAvailable() { if [ ! -e /dev/net/tun ]; then return 1 fi } -function checkOS () { +function checkOS() { if [[ -e /etc/debian_version ]]; then OS="debian" + # shellcheck disable=1091 source /etc/os-release if [[ "$ID" == "debian" ]]; then @@ -30,11 +31,11 @@ function checkOS () { until [[ $CONTINUE =~ (y|n) ]]; do read -rp "Continue? [y/n]: " -e CONTINUE done - if [[ "$CONTINUE" = "n" ]]; then + if [[ "$CONTINUE" == "n" ]]; then exit 1 fi fi - elif [[ "$ID" == "ubuntu" ]];then + elif [[ "$ID" == "ubuntu" ]]; then OS="ubuntu" if [[ ! $VERSION_ID =~ (16.04|18.04) ]]; then echo "⚠️ Your version of Ubuntu is not supported." @@ -45,7 +46,7 @@ function checkOS () { until [[ $CONTINUE =~ (y|n) ]]; do read -rp "Continue? [y/n]: " -e CONTINUE done - if [[ "$CONTINUE" = "n" ]]; then + if [[ "$CONTINUE" == "n" ]]; then exit 1 fi fi @@ -61,7 +62,7 @@ function checkOS () { until [[ $CONTINUE =~ (y|n) ]]; do read -rp "Continue anyway? [y/n]: " -e CONTINUE done - if [[ "$CONTINUE" = "n" ]]; then + if [[ "$CONTINUE" == "n" ]]; then echo "Ok, bye!" exit 1 fi @@ -75,7 +76,7 @@ function checkOS () { fi } -function initialCheck () { +function initialCheck() { if ! isRoot; then echo "Sorry, you need to run this as root" exit 1 @@ -87,7 +88,7 @@ function initialCheck () { checkOS } -function installUnbound () { +function installUnbound() { if [[ ! -e /etc/unbound/unbound.conf ]]; then if [[ "$OS" =~ (debian|ubuntu) ]]; then @@ -99,9 +100,9 @@ access-control: 10.8.0.1/24 allow hide-identity: yes hide-version: yes use-caps-for-id: yes -prefetch: yes' >> /etc/unbound/unbound.conf +prefetch: yes' >>/etc/unbound/unbound.conf - elif [[ "$OS" = "centos" ]]; then + elif [[ "$OS" == "centos" ]]; then yum install -y unbound # Configuration @@ -111,7 +112,7 @@ prefetch: yes' >> /etc/unbound/unbound.conf sed -i 's|# hide-version: no|hide-version: yes|' /etc/unbound/unbound.conf sed -i 's|use-caps-for-id: no|use-caps-for-id: yes|' /etc/unbound/unbound.conf - elif [[ "$OS" = "fedora" ]]; then + elif [[ "$OS" == "fedora" ]]; then dnf install -y unbound # Configuration @@ -121,14 +122,14 @@ prefetch: yes' >> /etc/unbound/unbound.conf sed -i 's|# hide-version: no|hide-version: yes|' /etc/unbound/unbound.conf sed -i 's|# use-caps-for-id: no|use-caps-for-id: yes|' /etc/unbound/unbound.conf - elif [[ "$OS" = "arch" ]]; then + elif [[ "$OS" == "arch" ]]; then pacman -Syu --noconfirm unbound # Get root servers list curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache mv /etc/unbound/unbound.conf /etc/unbound/unbound.conf.old - + echo 'server: use-syslog: yes do-daemonize: no @@ -145,10 +146,10 @@ prefetch: yes' >> /etc/unbound/unbound.conf hide-identity: yes hide-version: yes qname-minimisation: yes - prefetch: yes' > /etc/unbound/unbound.conf + prefetch: yes' >/etc/unbound/unbound.conf fi - if [[ ! "$OS" =~ (fedora|centos) ]];then + if [[ ! "$OS" =~ (fedora|centos) ]]; then # DNS Rebinding fix echo "private-address: 10.0.0.0/8 private-address: 172.16.0.0/12 @@ -157,10 +158,10 @@ private-address: 169.254.0.0/16 private-address: fd00::/8 private-address: fe80::/10 private-address: 127.0.0.0/8 -private-address: ::ffff:0:0/96" >> /etc/unbound/unbound.conf +private-address: ::ffff:0:0/96" >>/etc/unbound/unbound.conf fi else # Unbound is already installed - echo 'include: /etc/unbound/openvpn.conf' >> /etc/unbound/unbound.conf + echo 'include: /etc/unbound/openvpn.conf' >>/etc/unbound/unbound.conf # Add Unbound 'server' for the OpenVPN subnet echo 'server: @@ -177,14 +178,14 @@ private-address: 169.254.0.0/16 private-address: fd00::/8 private-address: fe80::/10 private-address: 127.0.0.0/8 -private-address: ::ffff:0:0/96' > /etc/unbound/openvpn.conf +private-address: ::ffff:0:0/96' >/etc/unbound/openvpn.conf fi - systemctl enable unbound - systemctl restart unbound + systemctl enable unbound + systemctl restart unbound } -function installQuestions () { +function installQuestions() { echo "Welcome to the OpenVPN installer!" echo "The git repository is available at: https://github.com/angristan/openvpn-install" echo "" @@ -212,7 +213,7 @@ function installQuestions () { echo "Checking for IPv6 connectivity..." echo "" # "ping6" and "ping -6" availability varies depending on the distribution - if type ping6 > /dev/null 2>&1; then + if type ping6 >/dev/null 2>&1; then PING6="ping6 -c3 ipv6.google.com > /dev/null 2>&1" else PING6="ping -6 -c3 ipv6.google.com > /dev/null 2>&1" @@ -238,18 +239,18 @@ function installQuestions () { read -rp "Port choice [1-3]: " -e -i 1 PORT_CHOICE done case $PORT_CHOICE in - 1) - PORT="1194" + 1) + PORT="1194" ;; - 2) - until [[ "$PORT" =~ ^[0-9]+$ ]] && [ "$PORT" -ge 1 ] && [ "$PORT" -le 65535 ]; do - read -rp "Custom port [1-65535]: " -e -i 1194 PORT - done + 2) + until [[ "$PORT" =~ ^[0-9]+$ ]] && [ "$PORT" -ge 1 ] && [ "$PORT" -le 65535 ]; do + read -rp "Custom port [1-65535]: " -e -i 1194 PORT + done ;; - 3) - # Generate random number within private ports range - PORT=$(shuf -i49152-65535 -n1) - echo "Random Port: $PORT" + 3) + # Generate random number within private ports range + PORT=$(shuf -i49152-65535 -n1) + echo "Random Port: $PORT" ;; esac echo "" @@ -261,11 +262,11 @@ function installQuestions () { read -rp "Protocol [1-2]: " -e -i 1 PROTOCOL_CHOICE done case $PROTOCOL_CHOICE in - 1) - PROTOCOL="udp" + 1) + PROTOCOL="udp" ;; - 2) - PROTOCOL="tcp" + 2) + PROTOCOL="tcp" ;; esac echo "" @@ -283,30 +284,30 @@ function installQuestions () { echo " 11) AdGuard DNS (Russia)" until [[ "$DNS" =~ ^[0-9]+$ ]] && [ "$DNS" -ge 1 ] && [ "$DNS" -le 11 ]; do read -rp "DNS [1-10]: " -e -i 3 DNS - if [[ $DNS == 2 ]] && [[ -e /etc/unbound/unbound.conf ]]; then - echo "" - echo "Unbound is already installed." - echo "You can allow the script to configure it in order to use it from your OpenVPN clients" - echo "We will simply add a second server to /etc/unbound/unbound.conf for the OpenVPN subnet." - echo "No changes are made to the current configuration." - echo "" + if [[ $DNS == 2 ]] && [[ -e /etc/unbound/unbound.conf ]]; then + echo "" + echo "Unbound is already installed." + echo "You can allow the script to configure it in order to use it from your OpenVPN clients" + echo "We will simply add a second server to /etc/unbound/unbound.conf for the OpenVPN subnet." + echo "No changes are made to the current configuration." + echo "" - until [[ $CONTINUE =~ (y|n) ]]; do - read -rp "Apply configuration changes to Unbound? [y/n]: " -e CONTINUE - done - if [[ $CONTINUE = "n" ]];then - # Break the loop and cleanup - unset DNS - unset CONTINUE - fi + until [[ $CONTINUE =~ (y|n) ]]; do + read -rp "Apply configuration changes to Unbound? [y/n]: " -e CONTINUE + done + if [[ $CONTINUE == "n" ]]; then + # Break the loop and cleanup + unset DNS + unset CONTINUE fi + fi done echo "" echo "Do you want to use compression? It is not recommended since the VORACLE attack make use of it." until [[ $COMPRESSION_ENABLED =~ (y|n) ]]; do - read -rp"Enable compression? [y/n]: " -e -i n COMPRESSION_ENABLED + read -rp"Enable compression? [y/n]: " -e -in COMPRESSION_ENABLED done - if [[ $COMPRESSION_ENABLED == "y" ]];then + if [[ $COMPRESSION_ENABLED == "y" ]]; then echo "Choose which compression algorithm you want to use:" echo " 1) LZ4 (more efficient)" echo " 2) LZ0" @@ -314,10 +315,10 @@ function installQuestions () { read -rp"Compression algorithm [1-2]: " -e -i 1 COMPRESSION_CHOICE done case $COMPRESSION_CHOICE in - 1) + 1) COMPRESSION_ALG="lz4" ;; - 2) + 2) COMPRESSION_ALG="lzo" ;; esac @@ -329,9 +330,9 @@ function installQuestions () { echo "See https://github.com/angristan/openvpn-install#security-and-encryption to learn more." echo "" until [[ $CUSTOMIZE_ENC =~ (y|n) ]]; do - read -rp "Customize encryption settings? [y/n]: " -e -i n CUSTOMIZE_ENC + read -rp "Customize encryption settings? [y/n]: " -e -in CUSTOMIZE_ENC done - if [[ $CUSTOMIZE_ENC == "n" ]];then + if [[ $CUSTOMIZE_ENC == "n" ]]; then # Use default, sane and fast parameters CIPHER="AES-128-GCM" CERT_TYPE="1" # ECDSA @@ -354,23 +355,23 @@ function installQuestions () { read -rp "Cipher [1-6]: " -e -i 1 CIPHER_CHOICE done case $CIPHER_CHOICE in - 1) - CIPHER="AES-128-GCM" + 1) + CIPHER="AES-128-GCM" ;; - 2) - CIPHER="AES-192-GCM" + 2) + CIPHER="AES-192-GCM" ;; - 3) - CIPHER="AES-256-GCM" + 3) + CIPHER="AES-256-GCM" ;; - 4) - CIPHER="AES-128-CBC" + 4) + CIPHER="AES-128-CBC" ;; - 5) - CIPHER="AES-192-CBC" + 5) + CIPHER="AES-192-CBC" ;; - 6) - CIPHER="AES-256-CBC" + 6) + CIPHER="AES-256-CBC" ;; esac echo "" @@ -381,81 +382,81 @@ function installQuestions () { read -rp"Certificate key 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 certificate's key:" + echo " 1) prime256v1 (recommended)" + echo " 2) secp384r1" + echo " 3) secp521r1" + until [[ $CERT_CURVE_CHOICE =~ ^[1-3]$ ]]; do + read -rp"Curve [1-3]: " -e -i 1 CERT_CURVE_CHOICE + done + case $CERT_CURVE_CHOICE in 1) - echo "" - echo "Choose which curve you want to use for the certificate's key:" - echo " 1) prime256v1 (recommended)" - echo " 2) secp384r1" - echo " 3) secp521r1" - until [[ $CERT_CURVE_CHOICE =~ ^[1-3]$ ]]; do - read -rp"Curve [1-3]: " -e -i 1 CERT_CURVE_CHOICE - done - case $CERT_CURVE_CHOICE in - 1) - CERT_CURVE="prime256v1" - ;; - 2) - CERT_CURVE="secp384r1" - ;; - 3) - CERT_CURVE="secp521r1" - ;; - esac - ;; + CERT_CURVE="prime256v1" + ;; 2) - echo "" - echo "Choose which size you want to use for the certificate's RSA key:" - echo " 1) 2048 bits (recommended)" - echo " 2) 3072 bits" - echo " 3) 4096 bits" - until [[ "$RSA_KEY_SIZE_CHOICE" =~ ^[1-3]$ ]]; do - read -rp "RSA key size [1-3]: " -e -i 1 RSA_KEY_SIZE_CHOICE - done - case $RSA_KEY_SIZE_CHOICE in - 1) - RSA_KEY_SIZE="2048" - ;; - 2) - RSA_KEY_SIZE="3072" - ;; - 3) - RSA_KEY_SIZE="4096" - ;; - esac + CERT_CURVE="secp384r1" + ;; + 3) + CERT_CURVE="secp521r1" + ;; + esac + ;; + 2) + echo "" + echo "Choose which size you want to use for the certificate's RSA key:" + echo " 1) 2048 bits (recommended)" + echo " 2) 3072 bits" + echo " 3) 4096 bits" + until [[ "$RSA_KEY_SIZE_CHOICE" =~ ^[1-3]$ ]]; do + read -rp "RSA key size [1-3]: " -e -i 1 RSA_KEY_SIZE_CHOICE + done + case $RSA_KEY_SIZE_CHOICE in + 1) + RSA_KEY_SIZE="2048" + ;; + 2) + RSA_KEY_SIZE="3072" + ;; + 3) + RSA_KEY_SIZE="4096" + ;; + esac ;; esac echo "" echo "Choose which cipher you want to use for the control channel:" case $CERT_TYPE in + 1) + echo " 1) ECDHE-ECDSA-AES-128-GCM-SHA256 (recommended)" + echo " 2) ECDHE-ECDSA-AES-256-GCM-SHA384" + until [[ $CC_CIPHER_CHOICE =~ ^[1-2]$ ]]; do + read -rp"Control channel cipher [1-2]: " -e -i 1 CC_CIPHER_CHOICE + done + case $CC_CIPHER_CHOICE in 1) - echo " 1) ECDHE-ECDSA-AES-128-GCM-SHA256 (recommended)" - echo " 2) ECDHE-ECDSA-AES-256-GCM-SHA384" - until [[ $CC_CIPHER_CHOICE =~ ^[1-2]$ ]]; do - read -rp"Control channel cipher [1-2]: " -e -i 1 CC_CIPHER_CHOICE - done - case $CC_CIPHER_CHOICE in - 1) - CC_CIPHER="TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256" - ;; - 2) - CC_CIPHER="TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384" - ;; - esac - ;; + CC_CIPHER="TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256" + ;; 2) - echo " 1) ECDHE-RSA-AES-128-GCM-SHA256 (recommended)" - echo " 2) ECDHE-RSA-AES-256-GCM-SHA384" - until [[ $CC_CIPHER_CHOICE =~ ^[1-2]$ ]]; do - read -rp"Control channel cipher [1-2]: " -e -i 1 CC_CIPHER_CHOICE - done - case $CC_CIPHER_CHOICE in - 1) - CC_CIPHER="TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256" - ;; - 2) - CC_CIPHER="TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384" - ;; - esac + CC_CIPHER="TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384" + ;; + esac + ;; + 2) + echo " 1) ECDHE-RSA-AES-128-GCM-SHA256 (recommended)" + echo " 2) ECDHE-RSA-AES-256-GCM-SHA384" + until [[ $CC_CIPHER_CHOICE =~ ^[1-2]$ ]]; do + read -rp"Control channel cipher [1-2]: " -e -i 1 CC_CIPHER_CHOICE + done + case $CC_CIPHER_CHOICE in + 1) + CC_CIPHER="TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256" + ;; + 2) + CC_CIPHER="TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384" + ;; + esac ;; esac echo "" @@ -466,47 +467,47 @@ function installQuestions () { read -rp"DH key type [1-2]: " -e -i 1 DH_TYPE done case $DH_TYPE in + 1) + echo "" + echo "Choose which curve you want to use for the ECDH key:" + echo " 1) prime256v1 (recommended)" + echo " 2) secp384r1" + echo " 3) secp521r1" + while [[ $DH_CURVE_CHOICE != "1" && $DH_CURVE_CHOICE != "2" && $DH_CURVE_CHOICE != "3" ]]; do + read -rp"Curve [1-3]: " -e -i 1 DH_CURVE_CHOICE + done + case $DH_CURVE_CHOICE in 1) - echo "" - echo "Choose which curve you want to use for the ECDH key:" - echo " 1) prime256v1 (recommended)" - echo " 2) secp384r1" - echo " 3) secp521r1" - while [[ $DH_CURVE_CHOICE != "1" && $DH_CURVE_CHOICE != "2" && $DH_CURVE_CHOICE != "3" ]]; do - read -rp"Curve [1-3]: " -e -i 1 DH_CURVE_CHOICE - done - case $DH_CURVE_CHOICE in - 1) - DH_CURVE="prime256v1" - ;; - 2) - DH_CURVE="secp384r1" - ;; - 3) - DH_CURVE="secp521r1" - ;; - esac - ;; + DH_CURVE="prime256v1" + ;; 2) - echo "" - echo "Choose what size of Diffie-Hellman key you want to use:" - echo " 1) 2048 bits (recommended)" - echo " 2) 3072 bits" - echo " 3) 4096 bits" - until [[ "$DH_KEY_SIZE_CHOICE" =~ ^[1-3]$ ]]; do - read -rp "DH key size [1-3]: " -e -i 1 DH_KEY_SIZE_CHOICE - done - case $DH_KEY_SIZE_CHOICE in - 1) - DH_KEY_SIZE="2048" - ;; - 2) - DH_KEY_SIZE="3072" - ;; - 3) - DH_KEY_SIZE="4096" - ;; - esac + DH_CURVE="secp384r1" + ;; + 3) + DH_CURVE="secp521r1" + ;; + esac + ;; + 2) + echo "" + echo "Choose what size of Diffie-Hellman key you want to use:" + echo " 1) 2048 bits (recommended)" + echo " 2) 3072 bits" + echo " 3) 4096 bits" + until [[ "$DH_KEY_SIZE_CHOICE" =~ ^[1-3]$ ]]; do + read -rp "DH key size [1-3]: " -e -i 1 DH_KEY_SIZE_CHOICE + done + case $DH_KEY_SIZE_CHOICE in + 1) + DH_KEY_SIZE="2048" + ;; + 2) + DH_KEY_SIZE="3072" + ;; + 3) + DH_KEY_SIZE="4096" + ;; + esac ;; esac echo "" @@ -524,14 +525,14 @@ function installQuestions () { read -rp "Digest algorithm [1-3]: " -e -i 1 HMAC_ALG_CHOICE done case $HMAC_ALG_CHOICE in - 1) - HMAC_ALG="SHA256" + 1) + HMAC_ALG="SHA256" ;; - 2) - HMAC_ALG="SHA384" + 2) + HMAC_ALG="SHA384" ;; - 3) - HMAC_ALG="SHA512" + 3) + HMAC_ALG="SHA512" ;; esac echo "" @@ -540,7 +541,7 @@ function installQuestions () { echo " 1) tls-crypt (recommended)" echo " 2) tls-auth" until [[ $TLS_SIG =~ [1-2] ]]; do - read -rp "Control channel additional security mechanism [1-2]: " -e -i 1 TLS_SIG + read -rp "Control channel additional security mechanism [1-2]: " -e -i 1 TLS_SIG done fi echo "" @@ -549,7 +550,7 @@ function installQuestions () { read -n1 -r -p "Press any key to continue..." } -function installOpenVPN () { +function installOpenVPN() { # Run setup questions first installQuestions @@ -560,24 +561,24 @@ function installOpenVPN () { apt-get update apt-get -y install ca-certificates gnupg # We add the OpenVPN repo to get the latest version. - if [[ "$VERSION_ID" = "8" ]]; then - echo "deb http://build.openvpn.net/debian/openvpn/stable jessie main" > /etc/apt/sources.list.d/openvpn.list + if [[ "$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 - apt-get update fi - if [[ "$VERSION_ID" = "16.04" ]]; then - echo "deb http://build.openvpn.net/debian/openvpn/stable trusty main" > /etc/apt/sources.list.d/openvpn.list + if [[ "$VERSION_ID" == "16.04" ]]; then + 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 - apt-get update fi # Ubuntu > 16.04 and Debian > 8 have OpenVPN >= 2.4 without the need of a third party repository. apt-get install -y openvpn iptables openssl wget ca-certificates curl - elif [[ "$OS" = 'centos' ]]; then + elif [[ "$OS" == 'centos' ]]; then yum install -y epel-release yum install -y openvpn iptables openssl wget ca-certificates curl - elif [[ "$OS" = 'fedora' ]]; then + elif [[ "$OS" == 'fedora' ]]; then dnf install -y openvpn iptables openssl wget ca-certificates curl - elif [[ "$OS" = 'arch' ]]; then + elif [[ "$OS" == 'arch' ]]; then echo "" echo "WARNING: 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 (Arch Linux does not support partial upgrades)." @@ -586,9 +587,9 @@ function installOpenVPN () { echo "" unset CONTINUE until [[ $CONTINUE =~ (y|n) ]]; do - read -rp "Continue? [y/n]: " -e -i y CONTINUE + read -rp "Continue? [y/n]: " -e -iy CONTINUE done - if [[ "$CONTINUE" = "n" ]]; then + if [[ "$CONTINUE" == "n" ]]; then echo "Exiting because user did not permit updating the system." exit 4 fi @@ -618,21 +619,21 @@ function installOpenVPN () { chown -R root:root /etc/openvpn/easy-rsa/ rm -f ~/EasyRSA-nix-${version}.tgz - cd /etc/openvpn/easy-rsa/ + cd /etc/openvpn/easy-rsa/ || exit case $CERT_TYPE in - 1) - echo "set_var EASYRSA_ALGO ec" > vars - echo "set_var EASYRSA_CURVE $CERT_CURVE" >> vars + 1) + echo "set_var EASYRSA_ALGO ec" >vars + echo "set_var EASYRSA_CURVE $CERT_CURVE" >>vars ;; - 2) - echo "set_var EASYRSA_KEY_SIZE $RSA_KEY_SIZE" > vars + 2) + echo "set_var EASYRSA_KEY_SIZE $RSA_KEY_SIZE" >vars ;; esac # Generate a random, alphanumeric identifier of 16 characters for CN and one for server name SERVER_CN="cn_$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)" SERVER_NAME="server_$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)" - echo "set_var EASYRSA_REQ_CN $SERVER_CN" >> vars + echo "set_var EASYRSA_REQ_CN $SERVER_CN" >>vars # Create the PKI, set up the CA, the DH params and the server certificate ./easyrsa init-pki ./easyrsa --batch build-ca nopass @@ -641,36 +642,36 @@ function installOpenVPN () { # ECDH keys are generated on-the-fly so we don't need to generate them beforehand openssl dhparam -out dh.pem $DH_KEY_SIZE fi - + ./easyrsa build-server-full "$SERVER_NAME" nopass EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl - + case $TLS_SIG in - 1) - # Generate tls-crypt key - openvpn --genkey --secret /etc/openvpn/tls-crypt.key + 1) + # Generate tls-crypt key + openvpn --genkey --secret /etc/openvpn/tls-crypt.key ;; - 2) - # Generate tls-auth key - openvpn --genkey --secret /etc/openvpn/tls-auth.key + 2) + # Generate tls-auth key + openvpn --genkey --secret /etc/openvpn/tls-auth.key ;; esac - + # Move all the generated files cp pki/ca.crt pki/private/ca.key "pki/issued/$SERVER_NAME.crt" "pki/private/$SERVER_NAME.key" /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn if [[ $DH_TYPE == "2" ]]; then cp dh.pem /etc/openvpn fi - + # Make cert revocation list readable for non-root chmod 644 /etc/openvpn/crl.pem # Generate server.conf - echo "port $PORT" > /etc/openvpn/server.conf - if [[ "$IPV6_SUPPORT" = 'n' ]]; then - echo "proto $PROTOCOL" >> /etc/openvpn/server.conf - elif [[ "$IPV6_SUPPORT" = 'y' ]]; then - echo "proto ${PROTOCOL}6" >> /etc/openvpn/server.conf + echo "port $PORT" >/etc/openvpn/server.conf + if [[ "$IPV6_SUPPORT" == 'n' ]]; then + echo "proto $PROTOCOL" >>/etc/openvpn/server.conf + elif [[ "$IPV6_SUPPORT" == 'y' ]]; then + echo "proto ${PROTOCOL}6" >>/etc/openvpn/server.conf fi echo "dev tun @@ -681,91 +682,91 @@ persist-tun keepalive 10 120 topology subnet server 10.8.0.0 255.255.255.0 -ifconfig-pool-persist ipp.txt" >> /etc/openvpn/server.conf +ifconfig-pool-persist ipp.txt" >>/etc/openvpn/server.conf # DNS resolvers case $DNS in - 1) - # Locate the proper resolv.conf - # Needed for systems running systemd-resolved - if grep -q "127.0.0.53" "/etc/resolv.conf"; then - RESOLVCONF='/run/systemd/resolve/resolv.conf' - else - RESOLVCONF='/etc/resolv.conf' - fi - # Obtain the resolvers from resolv.conf and use them for OpenVPN - grep -v '#' $RESOLVCONF | grep 'nameserver' | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | while read -r line; do - echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server.conf - done + 1) + # Locate the proper resolv.conf + # Needed for systems running systemd-resolved + if grep -q "127.0.0.53" "/etc/resolv.conf"; then + RESOLVCONF='/run/systemd/resolve/resolv.conf' + else + RESOLVCONF='/etc/resolv.conf' + fi + # Obtain the resolvers from resolv.conf and use them for OpenVPN + grep -v '#' $RESOLVCONF | grep 'nameserver' | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | while read -r line; do + echo "push \"dhcp-option DNS $line\"" >>/etc/openvpn/server.conf + done ;; - 2) - echo 'push "dhcp-option DNS 10.8.0.1"' >> /etc/openvpn/server.conf + 2) + echo 'push "dhcp-option DNS 10.8.0.1"' >>/etc/openvpn/server.conf ;; - 3) # Cloudflare - echo 'push "dhcp-option DNS 1.0.0.1"' >> /etc/openvpn/server.conf - echo 'push "dhcp-option DNS 1.1.1.1"' >> /etc/openvpn/server.conf + 3) # Cloudflare + echo 'push "dhcp-option DNS 1.0.0.1"' >>/etc/openvpn/server.conf + echo 'push "dhcp-option DNS 1.1.1.1"' >>/etc/openvpn/server.conf ;; - 4) # Quad9 - echo 'push "dhcp-option DNS 9.9.9.9"' >> /etc/openvpn/server.conf - echo 'push "dhcp-option DNS 149.112.112.112"' >> /etc/openvpn/server.conf + 4) # Quad9 + echo 'push "dhcp-option DNS 9.9.9.9"' >>/etc/openvpn/server.conf + echo 'push "dhcp-option DNS 149.112.112.112"' >>/etc/openvpn/server.conf ;; - 5) # Quad9 uncensored - echo 'push "dhcp-option DNS 9.9.9.10"' >> /etc/openvpn/server.conf - echo 'push "dhcp-option DNS 149.112.112.10"' >> /etc/openvpn/server.conf + 5) # Quad9 uncensored + echo 'push "dhcp-option DNS 9.9.9.10"' >>/etc/openvpn/server.conf + echo 'push "dhcp-option DNS 149.112.112.10"' >>/etc/openvpn/server.conf ;; - 6) # FDN - echo 'push "dhcp-option DNS 80.67.169.40"' >> /etc/openvpn/server.conf - echo 'push "dhcp-option DNS 80.67.169.12"' >> /etc/openvpn/server.conf + 6) # FDN + echo 'push "dhcp-option DNS 80.67.169.40"' >>/etc/openvpn/server.conf + echo 'push "dhcp-option DNS 80.67.169.12"' >>/etc/openvpn/server.conf ;; - 7) # 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 + 7) # 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 ;; - 8) # OpenDNS - 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 + 8) # OpenDNS + 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 ;; - 9) # 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 + 9) # 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 ;; - 10) # 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 + 10) # 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 ;; - 11) # AdGuard DNS - echo 'push "dhcp-option DNS 176.103.130.130"' >> /etc/openvpn/server.conf - echo 'push "dhcp-option DNS 176.103.130.131"' >> /etc/openvpn/server.conf + 11) # AdGuard DNS + echo 'push "dhcp-option DNS 176.103.130.130"' >>/etc/openvpn/server.conf + echo 'push "dhcp-option DNS 176.103.130.131"' >>/etc/openvpn/server.conf ;; esac - echo 'push "redirect-gateway def1 bypass-dhcp" '>> /etc/openvpn/server.conf + echo 'push "redirect-gateway def1 bypass-dhcp" ' >>/etc/openvpn/server.conf # IPv6 network settings if needed - if [[ "$IPV6_SUPPORT" = 'y' ]]; then + if [[ "$IPV6_SUPPORT" == 'y' ]]; then echo 'server-ipv6 fd42:42:42:42::/112 tun-ipv6 push tun-ipv6 push "route-ipv6 2000::/3" -push "redirect-gateway ipv6"' >> /etc/openvpn/server.conf +push "redirect-gateway ipv6"' >>/etc/openvpn/server.conf fi - if [[ $COMPRESSION_ENABLED == "y" ]]; then - echo "compress $COMPRESSION_ALG" >> /etc/openvpn/server.conf + if [[ $COMPRESSION_ENABLED == "y" ]]; then + echo "compress $COMPRESSION_ALG" >>/etc/openvpn/server.conf fi if [[ $DH_TYPE == "1" ]]; then - echo "dh none" >> /etc/openvpn/server.conf - echo "ecdh-curve $DH_CURVE" >> /etc/openvpn/server.conf + echo "dh none" >>/etc/openvpn/server.conf + echo "ecdh-curve $DH_CURVE" >>/etc/openvpn/server.conf elif [[ $DH_TYPE == "2" ]]; then - echo "dh dh.pem" >> /etc/openvpn/server.conf + echo "dh dh.pem" >>/etc/openvpn/server.conf fi case $TLS_SIG in - 1) - echo "tls-crypt tls-crypt.key 0" >> /etc/openvpn/server.conf + 1) + echo "tls-crypt tls-crypt.key 0" >>/etc/openvpn/server.conf ;; - 2) - echo "tls-auth tls-auth.key 0" >> /etc/openvpn/server.conf + 2) + echo "tls-auth tls-auth.key 0" >>/etc/openvpn/server.conf ;; esac @@ -780,15 +781,15 @@ tls-server tls-version-min 1.2 tls-cipher $CC_CIPHER status /var/log/openvpn/status.log -verb 3" >> /etc/openvpn/server.conf +verb 3" >>/etc/openvpn/server.conf # Create log dir mkdir -p /var/log/openvpn # Enable routing - echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.d/20-openvpn.conf - if [[ "$IPV6_SUPPORT" = 'y' ]]; then - echo 'net.ipv6.conf.all.forwarding=1' >> /etc/sysctl.d/20-openvpn.conf + echo 'net.ipv4.ip_forward=1' >>/etc/sysctl.d/20-openvpn.conf + if [[ "$IPV6_SUPPORT" == 'y' ]]; then + echo 'net.ipv6.conf.all.forwarding=1' >>/etc/sysctl.d/20-openvpn.conf fi # Avoid an unneeded reboot sysctl --system @@ -803,16 +804,16 @@ verb 3" >> /etc/openvpn/server.conf fi # Finally, restart and enable OpenVPN - if [[ "$OS" = 'arch' || "$OS" = 'fedora' ]]; then + if [[ "$OS" == 'arch' || "$OS" == 'fedora' ]]; then # Don't modify package-provided service cp /usr/lib/systemd/system/openvpn-server@.service /etc/systemd/system/openvpn-server@.service - + # Workaround to fix OpenVPN service on OpenVZ sed -i 's|LimitNPROC|#LimitNPROC|' /etc/systemd/system/openvpn-server@.service # Another workaround to keep using /etc/openvpn/ sed -i 's|/etc/openvpn/server|/etc/openvpn|' /etc/systemd/system/openvpn-server@.service # On fedora, the service hardcodes the ciphers. We want to manage the cipher ourselves, so we remove it from the service - if [[ "$OS" == "fedora" ]];then + if [[ "$OS" == "fedora" ]]; then sed -i 's|--cipher AES-256-GCM --ncp-ciphers AES-256-GCM:AES-128-GCM:AES-256-CBC:AES-128-CBC:BF-CBC||' /etc/systemd/system/openvpn-server@.service fi @@ -827,18 +828,18 @@ verb 3" >> /etc/openvpn/server.conf else # Don't modify package-provided service cp /lib/systemd/system/openvpn\@.service /etc/systemd/system/openvpn\@.service - + # Workaround to fix OpenVPN service on OpenVZ sed -i 's|LimitNPROC|#LimitNPROC|' /etc/systemd/system/openvpn\@.service # Another workaround to keep using /etc/openvpn/ sed -i 's|/etc/openvpn/server|/etc/openvpn|' /etc/systemd/system/openvpn\@.service - + systemctl daemon-reload systemctl restart openvpn@server systemctl enable openvpn@server fi - if [[ $DNS == 2 ]];then + if [[ $DNS == 2 ]]; then installUnbound fi @@ -851,13 +852,13 @@ iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o $NIC -j MASQUERADE iptables -A INPUT -i tun0 -j ACCEPT iptables -A FORWARD -i $NIC -o tun0 -j ACCEPT iptables -A FORWARD -i tun0 -o $NIC -j ACCEPT -iptables -A INPUT -i $NIC -p $PROTOCOL --dport $PORT -j ACCEPT" > /etc/iptables/add-openvpn-rules.sh +iptables -A INPUT -i $NIC -p $PROTOCOL --dport $PORT -j ACCEPT" >/etc/iptables/add-openvpn-rules.sh - if [[ "$IPV6_SUPPORT" = 'y' ]]; then + if [[ "$IPV6_SUPPORT" == 'y' ]]; then echo "ip6tables -t nat -A POSTROUTING -s fd42:42:42:42::/112 -o $NIC -j MASQUERADE ip6tables -A INPUT -i tun0 -j ACCEPT ip6tables -A FORWARD -i $NIC -o tun0 -j ACCEPT -ip6tables -A FORWARD -i tun0 -o $NIC -j ACCEPT" >> /etc/iptables/add-openvpn-rules.sh +ip6tables -A FORWARD -i tun0 -o $NIC -j ACCEPT" >>/etc/iptables/add-openvpn-rules.sh fi # Script to remove rules @@ -866,13 +867,13 @@ iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o $NIC -j MASQUERADE iptables -D INPUT -i tun0 -j ACCEPT iptables -D FORWARD -i $NIC -o tun0 -j ACCEPT iptables -D FORWARD -i tun0 -o $NIC -j ACCEPT -iptables -D INPUT -i $NIC -p $PROTOCOL --dport $PORT -j ACCEPT" > /etc/iptables/rm-openvpn-rules.sh +iptables -D INPUT -i $NIC -p $PROTOCOL --dport $PORT -j ACCEPT" >/etc/iptables/rm-openvpn-rules.sh - if [[ "$IPV6_SUPPORT" = 'y' ]]; then + if [[ "$IPV6_SUPPORT" == 'y' ]]; then echo "ip6tables -t nat -D POSTROUTING -s fd42:42:42:42::/112 -o $NIC -j MASQUERADE ip6tables -D INPUT -i tun0 -j ACCEPT ip6tables -D FORWARD -i $NIC -o tun0 -j ACCEPT -ip6tables -D FORWARD -i tun0 -o $NIC -j ACCEPT" >> /etc/iptables/rm-openvpn-rules.sh +ip6tables -D FORWARD -i tun0 -o $NIC -j ACCEPT" >>/etc/iptables/rm-openvpn-rules.sh fi chmod +x /etc/iptables/add-openvpn-rules.sh @@ -891,7 +892,7 @@ ExecStop=/etc/iptables/rm-openvpn-rules.sh RemainAfterExit=yes [Install] -WantedBy=multi-user.target" > /etc/systemd/system/iptables-openvpn.service +WantedBy=multi-user.target" >/etc/systemd/system/iptables-openvpn.service # Enable service and apply rules systemctl daemon-reload @@ -904,11 +905,11 @@ WantedBy=multi-user.target" > /etc/systemd/system/iptables-openvpn.service fi # client-template.txt is created so we have a template to add further users later - echo "client" > /etc/openvpn/client-template.txt - if [[ "$PROTOCOL" = 'udp' ]]; then - echo "proto udp" >> /etc/openvpn/client-template.txt - elif [[ "$PROTOCOL" = 'tcp' ]]; then - echo "proto tcp-client" >> /etc/openvpn/client-template.txt + echo "client" >/etc/openvpn/client-template.txt + if [[ "$PROTOCOL" == 'udp' ]]; then + echo "proto udp" >>/etc/openvpn/client-template.txt + elif [[ "$PROTOCOL" == 'tcp' ]]; then + echo "proto tcp-client" >>/etc/openvpn/client-template.txt fi echo "remote $IP $PORT dev tun @@ -925,18 +926,18 @@ tls-client tls-version-min 1.2 tls-cipher $CC_CIPHER setenv opt block-outside-dns # Prevent Windows 10 DNS leak -verb 3" >> /etc/openvpn/client-template.txt +verb 3" >>/etc/openvpn/client-template.txt -if [[ $COMPRESSION_ENABLED == "y" ]]; then - echo "compress $COMPRESSION_ALG" >> /etc/openvpn/client-template.txt -fi + if [[ $COMPRESSION_ENABLED == "y" ]]; then + echo "compress $COMPRESSION_ALG" >>/etc/openvpn/client-template.txt + fi # Generate the custom client.ovpn newClient echo "If you want to add more clients, you simply need to run this script another time!" } -function newClient () { +function newClient() { echo "" echo "Tell me a name for the client." echo "Use one word only, no special characters." @@ -957,21 +958,21 @@ function newClient () { cd /etc/openvpn/easy-rsa/ || return case $PASS in - 1) - ./easyrsa build-client-full "$CLIENT" nopass + 1) + ./easyrsa build-client-full "$CLIENT" nopass ;; - 2) + 2) echo "⚠️ You will be asked for the client password below ⚠️" - ./easyrsa build-client-full "$CLIENT" + ./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 + if [ -e "/home/$CLIENT" ]; then # if $1 is a user name homeDir="/home/$CLIENT" - elif [ "${SUDO_USER}" ]; then # if not, use SUDO_USER + elif [ "${SUDO_USER}" ]; then # if not, use SUDO_USER homeDir="/home/${SUDO_USER}" - else # if not SUDO_USER, use /root + else # if not SUDO_USER, use /root homeDir="/root" fi @@ -998,28 +999,28 @@ function newClient () { echo "" case $TLS_SIG in - 1) - echo "" - cat /etc/openvpn/tls-crypt.key - echo "" + 1) + echo "" + cat /etc/openvpn/tls-crypt.key + echo "" ;; - 2) - echo "key-direction 1" - echo "" - cat /etc/openvpn/tls-auth.key - echo "" + 2) + echo "key-direction 1" + echo "" + cat /etc/openvpn/tls-auth.key + echo "" ;; esac - } >> "$homeDir/$CLIENT.ovpn" + } >>"$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 () { +function revokeClient() { NUMBEROFCLIENTS=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep -c "^V") - if [[ "$NUMBEROFCLIENTS" = '0' ]]; then + if [[ "$NUMBEROFCLIENTS" == '0' ]]; then echo "" echo "You have no existing clients!" exit 1 @@ -1028,14 +1029,14 @@ function revokeClient () { 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 + 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/ + cd /etc/openvpn/easy-rsa/ || exit ./easyrsa --batch revoke "$CLIENT" EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl # Cleanup @@ -1053,7 +1054,7 @@ function revokeClient () { echo "Certificate for client $CLIENT revoked." } -function removeUnbound () { +function removeUnbound() { # Remove OpenVPN-related config sed -i 's|include: \/etc\/unbound\/openvpn.conf||' /etc/unbound/unbound.conf rm /etc/unbound/openvpn.conf @@ -1065,17 +1066,17 @@ function removeUnbound () { read -rp "Do you want to completely remove Unbound? [y/n]: " -e REMOVE_UNBOUND done - if [[ "$REMOVE_UNBOUND" = 'y' ]]; then + if [[ "$REMOVE_UNBOUND" == 'y' ]]; then # Stop Unbound systemctl stop unbound if [[ "$OS" =~ (debian|ubuntu) ]]; then apt-get autoremove --purge -y unbound - elif [[ "$OS" = 'arch' ]]; then + elif [[ "$OS" == 'arch' ]]; then pacman --noconfirm -R unbound - elif [[ "$OS" = 'centos' ]]; then + elif [[ "$OS" == 'centos' ]]; then yum remove -y unbound - elif [[ "$OS" = 'fedora' ]]; then + elif [[ "$OS" == 'fedora' ]]; then dnf remove -y unbound fi @@ -1089,10 +1090,10 @@ function removeUnbound () { fi } -function removeOpenVPN () { +function removeOpenVPN() { echo "" - read -rp "Do you really want to remove OpenVPN? [y/n]: " -e -i n REMOVE - if [[ "$REMOVE" = 'y' ]]; then + read -rp "Do you really want to remove OpenVPN? [y/n]: " -e -in REMOVE + if [[ "$REMOVE" == 'y' ]]; then # Get OpenVPN port from the configuration PORT=$(grep '^port ' /etc/openvpn/server.conf | cut -d " " -f 2) @@ -1132,15 +1133,15 @@ function removeOpenVPN () { if [[ "$OS" =~ (debian|ubuntu) ]]; then apt-get autoremove --purge -y openvpn - if [[ -e /etc/apt/sources.list.d/openvpn.list ]];then + if [[ -e /etc/apt/sources.list.d/openvpn.list ]]; then rm /etc/apt/sources.list.d/openvpn.list apt-get update fi - elif [[ "$OS" = 'arch' ]]; then + elif [[ "$OS" == 'arch' ]]; then pacman --noconfirm -R openvpn - elif [[ "$OS" = 'centos' ]]; then + elif [[ "$OS" == 'centos' ]]; then yum remove -y openvpn - elif [[ "$OS" = 'fedora' ]]; then + elif [[ "$OS" == 'fedora' ]]; then dnf remove -y openvpn fi @@ -1163,7 +1164,7 @@ function removeOpenVPN () { fi } -function manageMenu () { +function manageMenu() { clear echo "Welcome to OpenVPN-install!" echo "The git repository is available at: https://github.com/angristan/openvpn-install" @@ -1180,17 +1181,17 @@ function manageMenu () { done case $MENU_OPTION in - 1) - newClient + 1) + newClient ;; - 2) - revokeClient + 2) + revokeClient ;; - 3) - removeOpenVPN + 3) + removeOpenVPN ;; - 4) - exit 0 + 4) + exit 0 ;; esac }