Facebook
From Mustard Leopard, 3 Months ago, written in Bash.
Embed
Download Paste or View Raw
Hits: 96
  1. #!/bin/bash
  2.  
  3. # Secure OpenVPN server installer for Debian, Ubuntu, CentOS, Amazon Linux 2, Fedora and Arch Linux
  4. # https://github.com/angristan/openvpn-install
  5.  
  6. function isRoot () {
  7.         if [ "$EUID" -ne 0 ]; then
  8.                 return 1
  9.         fi
  10. }
  11.  
  12. function tunAvailable () {
  13.         if [ ! -e /dev/net/tun ]; then
  14.                 return 1
  15.         fi
  16. }
  17.  
  18. function checkOS () {
  19.         if [[ -e /etc/debian_version ]]; then
  20.                 OS="debian"
  21.                 # shellcheck disable=SC1091
  22.                 source /etc/os-release
  23.  
  24.                 if [[ "$ID" == "debian" || "$ID" == "raspbian" ]]; then
  25.                         if [[ ! $VERSION_ID =~ (8|9|10) ]]; then
  26.                                 echo "⚠️ Your version of Debian is not supported."
  27.                                 echo ""
  28.                                 echo "However, if you're using Debian >= 9 or unstable/testing then you can continue."
  29.                                 echo "Keep in mind they are not supported, though."
  30.                                 echo ""
  31.                                 until [[ $CONTINUE =~ (y|n) ]]; do
  32.                                         read -rp "Continue? [y/n]: " -e CONTINUE
  33.                                 done
  34.                                 if [[ "$CONTINUE" == "n" ]]; then
  35.                                         exit 1
  36.                                 fi
  37.                         fi
  38.                 elif [[ "$ID" == "ubuntu" ]];then
  39.                         OS="ubuntu"
  40.                         if [[ ! $VERSION_ID =~ (16.04|18.04|19.04) ]]; then
  41.                                 echo "⚠️ Your version of Ubuntu is not supported."
  42.                                 echo ""
  43.                                 echo "However, if you're using Ubuntu > 17 or beta, then you can continue."
  44.                                 echo "Keep in mind they are not supported, though."
  45.                                 echo ""
  46.                                 until [[ $CONTINUE =~ (y|n) ]]; do
  47.                                         read -rp "Continue? [y/n]: " -e CONTINUE
  48.                                 done
  49.                                 if [[ "$CONTINUE" == "n" ]]; then
  50.                                         exit 1
  51.                                 fi
  52.                         fi
  53.                 fi
  54.         elif [[ -e /etc/system-release ]]; then
  55.                 # shellcheck disable=SC1091
  56.                 source /etc/os-release
  57.                 if [[ "$ID" == "fedora" ]]; then
  58.                         OS="fedora"
  59.                 fi
  60.                 if [[ "$ID" == "centos" ]]; then
  61.                         OS="centos"
  62.                         if [[ ! $VERSION_ID =~ (7|8) ]]; then
  63.                                 echo "⚠️ Your version of CentOS is not supported."
  64.                                 echo ""
  65.                                 echo "The script only support CentOS 7."
  66.                                 echo ""
  67.                                 exit 1
  68.                         fi
  69.                 fi
  70.                 if [[ "$ID" == "amzn" ]]; then
  71.                         OS="amzn"
  72.                         if [[ ! $VERSION_ID == "2" ]]; then
  73.                                 echo "⚠️ Your version of Amazon Linux is not supported."
  74.                                 echo ""
  75.                                 echo "The script only support Amazon Linux 2."
  76.                                 echo ""
  77.                                 exit 1
  78.                         fi
  79.                 fi
  80.         elif [[ -e /etc/arch-release ]]; then
  81.                 OS=arch
  82.         else
  83.                 echo "Looks like you aren't running this installer on a Debian, Ubuntu, Fedora, CentOS, Amazon Linux 2 or Arch Linux system"
  84.                 exit 1
  85.         fi
  86. }
  87.  
  88. function initialCheck () {
  89.         if ! isRoot; then
  90.                 echo "Sorry, you need to run this as root"
  91.                 exit 1
  92.         fi
  93.         if ! tunAvailable; then
  94.                 echo "TUN is not available"
  95.                 exit 1
  96.         fi
  97.         checkOS
  98. }
  99.  
  100. function installUnbound () {
  101.         if [[ ! -e /etc/unbound/unbound.conf ]]; then
  102.  
  103.                 if [[ "$OS" =~ (debian|ubuntu) ]]; then
  104.                         apt-get install -y unbound
  105.  
  106.                         # Configuration
  107.                         echo 'interface: 10.8.0.1
  108. access-control: 10.8.0.1/16 allow
  109. hide-identity: yes
  110. hide-version: yes
  111. use-caps-for-id: yes
  112. prefetch: yes' >> /etc/unbound/unbound.conf
  113.  
  114.                 elif [[ "$OS" =~ (centos|amzn) ]]; then
  115.                         yum install -y unbound
  116.  
  117.                         # Configuration
  118.                         sed -i 's|# interface: 0.0.0.0$|interface: 10.8.0.1|' /etc/unbound/unbound.conf
  119.                         sed -i 's|# access-control: 127.0.0.0/8 allow|access-control: 10.8.0.1/16 allow|' /etc/unbound/unbound.conf
  120.                         sed -i 's|# hide-identity: no|hide-identity: yes|' /etc/unbound/unbound.conf
  121.                         sed -i 's|# hide-version: no|hide-version: yes|' /etc/unbound/unbound.conf
  122.                         sed -i 's|use-caps-for-id: no|use-caps-for-id: yes|' /etc/unbound/unbound.conf
  123.  
  124.                 elif [[ "$OS" == "fedora" ]]; then
  125.                         dnf install -y unbound
  126.  
  127.                         # Configuration
  128.                         sed -i 's|# interface: 0.0.0.0$|interface: 10.8.0.1|' /etc/unbound/unbound.conf
  129.                         sed -i 's|# access-control: 127.0.0.0/8 allow|access-control: 10.8.0.1/16 allow|' /etc/unbound/unbound.conf
  130.                         sed -i 's|# hide-identity: no|hide-identity: yes|' /etc/unbound/unbound.conf
  131.                         sed -i 's|# hide-version: no|hide-version: yes|' /etc/unbound/unbound.conf
  132.                         sed -i 's|# use-caps-for-id: no|use-caps-for-id: yes|' /etc/unbound/unbound.conf
  133.  
  134.                 elif [[ "$OS" == "arch" ]]; then
  135.                         pacman -Syu --noconfirm unbound
  136.  
  137.                         # Get root servers list
  138.                         curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache
  139.  
  140.                         mv /etc/unbound/unbound.conf /etc/unbound/unbound.conf.old
  141.  
  142.                         echo 'server:
  143.         use-syslog: yes
  144.         do-daemonize: no
  145.         username: "unbound"
  146.         directory: "/etc/unbound"
  147.         trust-anchor-file: trusted-key.key
  148.         root-hints: root.hints
  149.         interface: 10.8.0.1
  150.         access-control: 10.8.0.1/16 allow
  151.         port: 53
  152.         num-threads: 2
  153.         use-caps-for-id: yes
  154.         harden-glue: yes
  155.         hide-identity: yes
  156.         hide-version: yes
  157.         qname-minimisation: yes
  158.         prefetch: yes' > /etc/unbound/unbound.conf
  159.                 fi
  160.  
  161.                 if [[ ! "$OS" =~ (fedora|centos|amzn) ]];then
  162.                         # DNS Rebinding fix
  163.                         echo "private-address: 10.0.0.0/8
  164. private-address: 172.16.0.0/12
  165. private-address: 192.168.0.0/16
  166. private-address: 169.254.0.0/16
  167. private-address: fd00::/8
  168. private-address: fe80::/10
  169. private-address: 127.0.0.0/8
  170. private-address: ::ffff:0:0/96" >> /etc/unbound/unbound.conf
  171.                 fi
  172.         else # Unbound is already installed
  173.                 echo 'include: /etc/unbound/openvpn.conf' >> /etc/unbound/unbound.conf
  174.  
  175.                 # Add Unbound 'server' for the OpenVPN subnet
  176.                 echo 'server:
  177. interface: 10.8.0.1
  178. access-control: 10.8.0.1/16 allow
  179. hide-identity: yes
  180. hide-version: yes
  181. use-caps-for-id: yes
  182. prefetch: yes
  183. private-address: 10.0.0.0/8
  184. private-address: 172.16.0.0/12
  185. private-address: 192.168.0.0/16
  186. private-address: 169.254.0.0/16
  187. private-address: fd00::/8
  188. private-address: fe80::/10
  189. private-address: 127.0.0.0/8
  190. private-address: ::ffff:0:0/96' > /etc/unbound/openvpn.conf
  191.         fi
  192.  
  193.                 systemctl enable unbound
  194.                 systemctl restart unbound
  195. }
  196.  
  197. function installQuestions () {
  198.         echo "Welcome to the OpenVPN installer!"
  199.         echo "The git repository is available at: https://github.com/angristan/openvpn-install"
  200.         echo ""
  201.  
  202.         echo "I need to ask you a few questions before starting the setup."
  203.         echo "You can leave the default options and just press enter if you are ok with them."
  204.         echo ""
  205.         echo "I need to know the IPv4 address of the network interface you want OpenVPN listening to."
  206.         echo "Unless your server is behind NAT, it should be your public IPv4 address."
  207.  
  208.         # Detect public IPv4 address and pre-fill for the user
  209.         IP=$(ip addr | grep 'inet' | grep -v inet6 | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1)
  210.         APPROVE_IP=${APPROVE_IP:-n}
  211.         if [[ $APPROVE_IP =~ n ]]; then
  212.                 read -rp "IP address: " -e -i "$IP" IP
  213.         fi
  214.         # If $IP is a private IP address, the server must be behind NAT
  215.         if echo "$IP" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then
  216.                 echo ""
  217.                 echo "It seems this server is behind NAT. What is its public IPv4 address or hostname?"
  218.                 echo "We need it for the clients to connect to the server."
  219.                 until [[ "$ENDPOINT" != "" ]]; do
  220.                         read -rp "Public IPv4 address or hostname: " -e ENDPOINT
  221.                 done
  222.         fi
  223.  
  224.         echo ""
  225.         echo "Checking for IPv6 connectivity..."
  226.         echo ""
  227.         # "ping6" and "ping -6" availability varies depending on the distribution
  228.         if type ping6 > /dev/null 2>&1; then
  229.                 PING6="ping6 -c3 ipv6.google.com > /dev/null 2>&1"
  230.         else
  231.                 PING6="ping -6 -c3 ipv6.google.com > /dev/null 2>&1"
  232.         fi
  233.         if eval "$PING6"; then
  234.                 echo "Your host appears to have IPv6 connectivity."
  235.                 SUGGESTION="y"
  236.         else
  237.                 echo "Your host does not appear to have IPv6 connectivity."
  238.                 SUGGESTION="n"
  239.         fi
  240.         echo ""
  241.         # Ask the user if they want to enable IPv6 regardless its availability.
  242.         until [[ $IPV6_SUPPORT =~ (y|n) ]]; do
  243.                 read -rp "Do you want to enable IPv6 support (NAT)? [y/n]: " -e -i $SUGGESTION IPV6_SUPPORT
  244.         done
  245.         echo ""
  246.         echo "What port do you want OpenVPN to listen to?"
  247.         echo "   1) Default: 1194"
  248.         echo "   2) Custom"
  249.         echo "   3) Random [49152-65535]"
  250.         until [[ "$PORT_CHOICE" =~ ^[1-3]$ ]]; do
  251.                 read -rp "Port choice [1-3]: " -e -i 1 PORT_CHOICE
  252.         done
  253.         case $PORT_CHOICE in
  254.                 1)
  255.                         PORT="1194"
  256.                 ;;
  257.                 2)
  258.                         until [[ "$PORT" =~ ^[0-9]+$ ]] && [ "$PORT" -ge 1 ] && [ "$PORT" -le 65535 ]; do
  259.                                 read -rp "Custom port [1-65535]: " -e -i 1194 PORT
  260.                         done
  261.                 ;;
  262.                 3)
  263.                         # Generate random number within private ports range
  264.                         PORT=$(shuf -i49152-65535 -n1)
  265.                         echo "Random Port: $PORT"
  266.                 ;;
  267.         esac
  268.         echo ""
  269.         echo "What protocol do you want OpenVPN to use?"
  270.         echo "UDP is faster. Unless it is not available, you shouldn't use TCP."
  271.         echo "   1) UDP"
  272.         echo "   2) TCP"
  273.         until [[ "$PROTOCOL_CHOICE" =~ ^[1-2]$ ]]; do
  274.                 read -rp "Protocol [1-2]: " -e -i 1 PROTOCOL_CHOICE
  275.         done
  276.         case $PROTOCOL_CHOICE in
  277.                 1)
  278.                         PROTOCOL="udp"
  279.                 ;;
  280.                 2)
  281.                         PROTOCOL="tcp"
  282.                 ;;
  283.         esac
  284.         echo ""
  285.         echo "What DNS resolvers do you want to use with the VPN?"
  286.         echo "   1) Current system resolvers (from /etc/resolv.conf)"
  287.         echo "   2) Self-hosted DNS Resolver (Unbound)"
  288.         echo "   3) Cloudflare (Anycast: worldwide)"
  289.         echo "   4) Quad9 (Anycast: worldwide)"
  290.         echo "   5) Quad9 uncensored (Anycast: worldwide)"
  291.         echo "   6) FDN (France)"
  292.         echo "   7) DNS.WATCH (Germany)"
  293.         echo "   8) OpenDNS (Anycast: worldwide)"
  294.         echo "   9) Google (Anycast: worldwide)"
  295.         echo "   10) Yandex Basic (Russia)"
  296.         echo "   11) AdGuard DNS (Anycast: worldwide)"
  297.         echo "   12) NextDNS (Anycast: worldwide)"
  298.         echo "   13) Custom"
  299.         until [[ "$DNS" =~ ^[0-9]+$ ]] && [ "$DNS" -ge 1 ] && [ "$DNS" -le 13 ]; do
  300.                 read -rp "DNS [1-12]: " -e -i 3 DNS
  301.                         if [[ $DNS == 2 ]] && [[ -e /etc/unbound/unbound.conf ]]; then
  302.                                 echo ""
  303.                                 echo "Unbound is already installed."
  304.                                 echo "You can allow the script to configure it in order to use it from your OpenVPN clients"
  305.                                 echo "We will simply add a second server to /etc/unbound/unbound.conf for the OpenVPN subnet."
  306.                                 echo "No changes are made to the current configuration."
  307.                                 echo ""
  308.  
  309.                                 until [[ $CONTINUE =~ (y|n) ]]; do
  310.                                         read -rp "Apply configuration changes to Unbound? [y/n]: " -e CONTINUE
  311.                                 done
  312.                                 if [[ $CONTINUE == "n" ]];then
  313.                                         # Break the loop and cleanup
  314.                                         unset DNS
  315.                                         unset CONTINUE
  316.                                 fi
  317.                         elif [[ $DNS == "13" ]]; then
  318.                                 until [[ "$DNS1" =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ ]]; do
  319.                                         read -rp "Primary DNS: " -e DNS1
  320.                                 done
  321.                                 until [[ "$DNS2" =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ ]]; do
  322.                                         read -rp "Secondary DNS (optional): " -e DNS2
  323.                                         if [[ "$DNS2" == "" ]]; then
  324.                                                 break
  325.                                         fi
  326.                                 done
  327.                         fi
  328.         done
  329.         echo ""
  330.         echo "Do you want to use compression? It is not recommended since the VORACLE attack make use of it."
  331.         until [[ $COMPRESSION_ENABLED =~ (y|n) ]]; do
  332.                 read -rp"Enable compression? [y/n]: " -e -i n COMPRESSION_ENABLED
  333.         done
  334.         if [[ $COMPRESSION_ENABLED == "y" ]];then
  335.                 echo "Choose which compression algorithm you want to use: (they are ordered by efficiency)"
  336.                 echo "   1) LZ4-v2"
  337.                 echo "   2) LZ4"
  338.                 echo "   3) LZ0"
  339.                 until [[ $COMPRESSION_CHOICE =~ ^[1-3]$ ]]; do
  340.                         read -rp"Compression algorithm [1-3]: " -e -i 1 COMPRESSION_CHOICE
  341.                 done
  342.                 case $COMPRESSION_CHOICE in
  343.                         1)
  344.                         COMPRESSION_ALG="lz4-v2"
  345.                         ;;
  346.                         2)
  347.                         COMPRESSION_ALG="lz4"
  348.                         ;;
  349.                         3)
  350.                         COMPRESSION_ALG="lzo"
  351.                         ;;
  352.                 esac
  353.         fi
  354.         echo ""
  355.         echo "Do you want to customize encryption settings?"
  356.         echo "Unless you know what you're doing, you should stick with the default parameters provided by the script."
  357.         echo "Note that whatever you choose, all the choices presented in the script are safe. (Unlike OpenVPN's defaults)"
  358.         echo "See https://github.com/angristan/openvpn-install#security-and-encryption to learn more."
  359.         echo ""
  360.         until [[ $CUSTOMIZE_ENC =~ (y|n) ]]; do
  361.                 read -rp "Customize encryption settings? [y/n]: " -e -i n CUSTOMIZE_ENC
  362.         done
  363.         if [[ $CUSTOMIZE_ENC == "n" ]];then
  364.                 # Use default, sane and fast parameters
  365.                 CIPHER="AES-128-GCM"
  366.                 CERT_TYPE="1" # ECDSA
  367.                 CERT_CURVE="prime256v1"
  368.                 CC_CIPHER="TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256"
  369.                 DH_TYPE="1" # ECDH
  370.                 DH_CURVE="prime256v1"
  371.                 HMAC_ALG="SHA256"
  372.                 TLS_SIG="1" # tls-crypt
  373.         else
  374.                 echo ""
  375.                 echo "Choose which cipher you want to use for the data channel:"
  376.                 echo "   1) AES-128-GCM (recommended)"
  377.                 echo "   2) AES-192-GCM"
  378.                 echo "   3) AES-256-GCM"
  379.                 echo "   4) AES-128-CBC"
  380.                 echo "   5) AES-192-CBC"
  381.                 echo "   6) AES-256-CBC"
  382.                 until [[ "$CIPHER_CHOICE" =~ ^[1-6]$ ]]; do
  383.                         read -rp "Cipher [1-6]: " -e -i 1 CIPHER_CHOICE
  384.                 done
  385.                 case $CIPHER_CHOICE in
  386.                         1)
  387.                                 CIPHER="AES-128-GCM"
  388.                         ;;
  389.                         2)
  390.                                 CIPHER="AES-192-GCM"
  391.                         ;;
  392.                         3)
  393.                                 CIPHER="AES-256-GCM"
  394.                         ;;
  395.                         4)
  396.                                 CIPHER="AES-128-CBC"
  397.                         ;;
  398.                         5)
  399.                                 CIPHER="AES-192-CBC"
  400.                         ;;
  401.                         6)
  402.                                 CIPHER="AES-256-CBC"
  403.                         ;;
  404.                 esac
  405.                 echo ""
  406.                 echo "Choose what kind of certificate you want to use:"
  407.                 echo "   1) ECDSA (recommended)"
  408.                 echo "   2) RSA"
  409.                 until [[ $CERT_TYPE =~ ^[1-2]$ ]]; do
  410.                         read -rp"Certificate key type [1-2]: " -e -i 1 CERT_TYPE
  411.                 done
  412.                 case $CERT_TYPE in
  413.                         1)
  414.                                 echo ""
  415.                                 echo "Choose which curve you want to use for the certificate's key:"
  416.                                 echo "   1) prime256v1 (recommended)"
  417.                                 echo "   2) secp384r1"
  418.                                 echo "   3) secp521r1"
  419.                                 until [[ $CERT_CURVE_CHOICE =~ ^[1-3]$ ]]; do
  420.                                         read -rp"Curve [1-3]: " -e -i 1 CERT_CURVE_CHOICE
  421.                                 done
  422.                                 case $CERT_CURVE_CHOICE in
  423.                                         1)
  424.                                                 CERT_CURVE="prime256v1"
  425.                                         ;;
  426.                                         2)
  427.                                                 CERT_CURVE="secp384r1"
  428.                                         ;;
  429.                                         3)
  430.                                                 CERT_CURVE="secp521r1"
  431.                                         ;;
  432.                                 esac
  433.                         ;;
  434.                         2)
  435.                                 echo ""
  436.                                 echo "Choose which size you want to use for the certificate's RSA key:"
  437.                                 echo "   1) 2048 bits (recommended)"
  438.                                 echo "   2) 3072 bits"
  439.                                 echo "   3) 4096 bits"
  440.                                 until [[ "$RSA_KEY_SIZE_CHOICE" =~ ^[1-3]$ ]]; do
  441.                                         read -rp "RSA key size [1-3]: " -e -i 1 RSA_KEY_SIZE_CHOICE
  442.                                 done
  443.                                 case $RSA_KEY_SIZE_CHOICE in
  444.                                         1)
  445.                                                 RSA_KEY_SIZE="2048"
  446.                                         ;;
  447.                                         2)
  448.                                                 RSA_KEY_SIZE="3072"
  449.                                         ;;
  450.                                         3)
  451.                                                 RSA_KEY_SIZE="4096"
  452.                                         ;;
  453.                                 esac
  454.                         ;;
  455.                 esac
  456.                 echo ""
  457.                 echo "Choose which cipher you want to use for the control channel:"
  458.                 case $CERT_TYPE in
  459.                         1)
  460.                                 echo "   1) ECDHE-ECDSA-AES-128-GCM-SHA256 (recommended)"
  461.                                 echo "   2) ECDHE-ECDSA-AES-256-GCM-SHA384"
  462.                                 until [[ $CC_CIPHER_CHOICE =~ ^[1-2]$ ]]; do
  463.                                         read -rp"Control channel cipher [1-2]: " -e -i 1 CC_CIPHER_CHOICE
  464.                                 done
  465.                                 case $CC_CIPHER_CHOICE in
  466.                                         1)
  467.                                                 CC_CIPHER="TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256"
  468.                                         ;;
  469.                                         2)
  470.                                                 CC_CIPHER="TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384"
  471.                                         ;;
  472.                                 esac
  473.                         ;;
  474.                         2)
  475.                                 echo "   1) ECDHE-RSA-AES-128-GCM-SHA256 (recommended)"
  476.                                 echo "   2) ECDHE-RSA-AES-256-GCM-SHA384"
  477.                                 until [[ $CC_CIPHER_CHOICE =~ ^[1-2]$ ]]; do
  478.                                         read -rp"Control channel cipher [1-2]: " -e -i 1 CC_CIPHER_CHOICE
  479.                                 done
  480.                                 case $CC_CIPHER_CHOICE in
  481.                                         1)
  482.                                                 CC_CIPHER="TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256"
  483.                                         ;;
  484.                                         2)
  485.                                                 CC_CIPHER="TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384"
  486.                                         ;;
  487.                                 esac
  488.                         ;;
  489.                 esac
  490.                 echo ""
  491.                 echo "Choose what kind of Diffie-Hellman key you want to use:"
  492.                 echo "   1) ECDH (recommended)"
  493.                 echo "   2) DH"
  494.                 until [[ $DH_TYPE =~ [1-2] ]]; do
  495.                         read -rp"DH key type [1-2]: " -e -i 1 DH_TYPE
  496.                 done
  497.                 case $DH_TYPE in
  498.                         1)
  499.                                 echo ""
  500.                                 echo "Choose which curve you want to use for the ECDH key:"
  501.                                 echo "   1) prime256v1 (recommended)"
  502.                                 echo "   2) secp384r1"
  503.                                 echo "   3) secp521r1"
  504.                                 while [[ $DH_CURVE_CHOICE != "1" && $DH_CURVE_CHOICE != "2" && $DH_CURVE_CHOICE != "3" ]]; do
  505.                                         read -rp"Curve [1-3]: " -e -i 1 DH_CURVE_CHOICE
  506.                                 done
  507.                                 case $DH_CURVE_CHOICE in
  508.                                         1)
  509.                                                 DH_CURVE="prime256v1"
  510.                                         ;;
  511.                                         2)
  512.                                                 DH_CURVE="secp384r1"
  513.                                         ;;
  514.                                         3)
  515.                                                 DH_CURVE="secp521r1"
  516.                                         ;;
  517.                                 esac
  518.                         ;;
  519.                         2)
  520.                                 echo ""
  521.                                 echo "Choose what size of Diffie-Hellman key you want to use:"
  522.                                 echo "   1) 2048 bits (recommended)"
  523.                                 echo "   2) 3072 bits"
  524.                                 echo "   3) 4096 bits"
  525.                                 until [[ "$DH_KEY_SIZE_CHOICE" =~ ^[1-3]$ ]]; do
  526.                                         read -rp "DH key size [1-3]: " -e -i 1 DH_KEY_SIZE_CHOICE
  527.                                 done
  528.                                 case $DH_KEY_SIZE_CHOICE in
  529.                                         1)
  530.                                                 DH_KEY_SIZE="2048"
  531.                                         ;;
  532.                                         2)
  533.                                                 DH_KEY_SIZE="3072"
  534.                                         ;;
  535.                                         3)
  536.                                                 DH_KEY_SIZE="4096"
  537.                                         ;;
  538.                                 esac
  539.                         ;;
  540.                 esac
  541.                 echo ""
  542.                 # The "auth" options behaves differently with AEAD ciphers
  543.                 if [[ "$CIPHER" =~ CBC$ ]]; then
  544.                         echo "The digest algorithm authenticates data channel packets and tls-auth packets from the control channel."
  545.                 elif [[ "$CIPHER" =~ GCM$ ]]; then
  546.                         echo "The digest algorithm authenticates tls-auth packets from the control channel."
  547.                 fi
  548.                 echo "Which digest algorithm do you want to use for HMAC?"
  549.                 echo "   1) SHA-256 (recommended)"
  550.                 echo "   2) SHA-384"
  551.                 echo "   3) SHA-512"
  552.                 until [[ $HMAC_ALG_CHOICE =~ ^[1-3]$ ]]; do
  553.                         read -rp "Digest algorithm [1-3]: " -e -i 1 HMAC_ALG_CHOICE
  554.                 done
  555.                 case $HMAC_ALG_CHOICE in
  556.                         1)
  557.                                 HMAC_ALG="SHA256"
  558.                         ;;
  559.                         2)
  560.                                 HMAC_ALG="SHA384"
  561.                         ;;
  562.                         3)
  563.                                 HMAC_ALG="SHA512"
  564.                         ;;
  565.                 esac
  566.                 echo ""
  567.                 echo "You can add an additional layer of security to the control channel with tls-auth and tls-crypt"
  568.                 echo "tls-auth authenticates the packets, while tls-crypt authenticate and encrypt them."
  569.                 echo "   1) tls-crypt (recommended)"
  570.                 echo "   2) tls-auth"
  571.                 until [[ $TLS_SIG =~ [1-2] ]]; do
  572.                                 read -rp "Control channel additional security mechanism [1-2]: " -e -i 1 TLS_SIG
  573.                 done
  574.         fi
  575.         echo ""
  576.         echo "Okay, that was all I needed. We are ready to setup your OpenVPN server now."
  577.         echo "You will be able to generate a client at the end of the installation."
  578.         APPROVE_INSTALL=${APPROVE_INSTALL:-n}
  579.         if [[ $APPROVE_INSTALL =~ n ]]; then
  580.                 read -n1 -r -p "Press any key to continue..."
  581.         fi
  582. }
  583.  
  584. function installOpenVPN () {
  585.         if [[ $AUTO_INSTALL == "y" ]]; then
  586.                 # Set default choices so that no questions will be asked.
  587.                 APPROVE_INSTALL=${APPROVE_INSTALL:-y}
  588.                 APPROVE_IP=${APPROVE_IP:-y}
  589.                 IPV6_SUPPORT=${IPV6_SUPPORT:-n}
  590.                 PORT_CHOICE=${PORT_CHOICE:-1}
  591.                 PROTOCOL_CHOICE=${PROTOCOL_CHOICE:-1}
  592.                 DNS=${DNS:-1}
  593.                 COMPRESSION_ENABLED=${COMPRESSION_ENABLED:-n}
  594.                 CUSTOMIZE_ENC=${CUSTOMIZE_ENC:-n}
  595.                 CLIENT=${CLIENT:-client}
  596.                 PASS=${PASS:-1}
  597.                 CONTINUE=${CONTINUE:-y}
  598.  
  599.                 # Behind NAT, we'll default to the publicly reachable IPv4.
  600.                 PUBLIC_IPV4=$(curl ifconfig.co)
  601.                 ENDPOINT=${ENDPOINT:-$PUBLIC_IPV4}
  602.         fi
  603.  
  604.         # Run setup questions first, and set other variales if auto-install
  605.         installQuestions
  606.  
  607.         # Get the "public" interface from the default route
  608.         NIC=$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)' | head -1)
  609.         if [[ -z "$NIC" ]] && [[ "$IPV6_SUPPORT" == 'y' ]]; then
  610.                 NIC=$(ip -6 route show default | sed -ne 's/^default .* dev \([^ ]*\) .*$/\1/p')
  611.         fi
  612.  
  613.         # $NIC can not be empty for script rm-openvpn-rules.sh
  614.         if [[ -z "$NIC" ]]; then
  615.                 echo
  616.                 echo "Can not detect public interface."
  617.                 echo "This needs for setup MASQUERADE."
  618.                 until [[ $CONTINUE =~ (y|n) ]]; do
  619.                         read -rp "Continue? [y/n]: " -e CONTINUE
  620.                 done
  621.                 if [[ "$CONTINUE" == "n" ]]; then
  622.                         exit 1
  623.                 fi
  624.         fi
  625.  
  626.         if [[ "$OS" =~ (debian|ubuntu) ]]; then
  627.                 apt-get update
  628.                 apt-get -y install ca-certificates gnupg
  629.                 # We add the OpenVPN repo to get the latest version.
  630.                 if [[ "$VERSION_ID" == "8" ]]; then
  631.                         echo "deb http://build.openvpn.net/debian/openvpn/stable jessie main" > /etc/apt/sources.list.d/openvpn.list
  632.                         wget -O - https://swupdate.openvpn.net/repos/repo-public.gpg | apt-key add -
  633.                         apt-get update
  634.                 fi
  635.                 if [[ "$VERSION_ID" == "16.04" ]]; then
  636.                         echo "deb http://build.openvpn.net/debian/openvpn/stable xenial main" > /etc/apt/sources.list.d/openvpn.list
  637.                         wget -O - https://swupdate.openvpn.net/repos/repo-public.gpg | apt-key add -
  638.                         apt-get update
  639.                 fi
  640.                 # Ubuntu > 16.04 and Debian > 8 have OpenVPN >= 2.4 without the need of a third party repository.
  641.                 apt-get install -y openvpn iptables openssl wget ca-certificates curl
  642.         elif [[ "$OS" == 'centos' ]]; then
  643.                 yum install -y epel-release
  644.                 yum install -y openvpn iptables openssl wget ca-certificates curl tar 'policycoreutils-python*'
  645.         elif [[ "$OS" == 'amzn' ]]; then
  646.                 amazon-linux-extras install -y epel
  647.                 yum install -y openvpn iptables openssl wget ca-certificates curl
  648.         elif [[ "$OS" == 'fedora' ]]; then
  649.                 dnf install -y openvpn iptables openssl wget ca-certificates curl
  650.         elif [[ "$OS" == 'arch' ]]; then
  651.                 # Install required dependencies and upgrade the system
  652.                 pacman --needed --noconfirm -Syu openvpn iptables openssl wget ca-certificates curl
  653.         fi
  654.  
  655.         # Find out if the machine uses nogroup or nobody for the permissionless group
  656.         if grep -qs "^nogroup:" /etc/group; then
  657.                 NOGROUP=nogroup
  658.         else
  659.                 NOGROUP=nobody
  660.         fi
  661.  
  662.         # An old version of easy-rsa was available by default in some openvpn packages
  663.         if [[ -d /etc/openvpn/easy-rsa/ ]]; then
  664.                 rm -rf /etc/openvpn/easy-rsa/
  665.         fi
  666.  
  667.         # Install the latest version of easy-rsa from source
  668.         local version="3.0.6"
  669.         wget -O ~/EasyRSA-unix-v${version}.tgz https://github.com/OpenVPN/easy-rsa/releases/download/v${version}/EasyRSA-unix-v${version}.tgz
  670.         tar xzf ~/EasyRSA-unix-v${version}.tgz -C ~/
  671.         mv ~/EasyRSA-v${version} /etc/openvpn/easy-rsa
  672.         chown -R root:root /etc/openvpn/easy-rsa/
  673.         rm -f ~/EasyRSA-unix-v${version}.tgz
  674.  
  675.         cd /etc/openvpn/easy-rsa/ || return
  676.         case $CERT_TYPE in
  677.                 1)
  678.                         echo "set_var EASYRSA_ALGO ec" > vars
  679.                         echo "set_var EASYRSA_CURVE $CERT_CURVE" >> vars
  680.                 ;;
  681.                 2)
  682.                         echo "set_var EASYRSA_KEY_SIZE $RSA_KEY_SIZE" > vars
  683.                 ;;
  684.         esac
  685.  
  686.         # Generate a random, alphanumeric identifier of 16 characters for CN and one for server name
  687.         SERVER_CN="cn_$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)"
  688.         SERVER_NAME="server_$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)"
  689.         echo "set_var EASYRSA_REQ_CN $SERVER_CN" >> vars
  690.  
  691.         # Create the PKI, set up the CA, the DH params and the server certificate
  692.         ./easyrsa init-pki
  693.  
  694.         # Workaround to remove unharmful error until easy-rsa 3.0.7
  695.         # https://github.com/OpenVPN/easy-rsa/issues/261
  696.         sed -i 's/^RANDFILE/#RANDFILE/g' pki/openssl-easyrsa.cnf
  697.  
  698.         ./easyrsa --batch build-ca nopass
  699.  
  700.         if [[ $DH_TYPE == "2" ]]; then
  701.                 # ECDH keys are generated on-the-fly so we don't need to generate them beforehand
  702.                 openssl dhparam -out dh.pem $DH_KEY_SIZE
  703.         fi
  704.  
  705.         ./easyrsa build-server-full "$SERVER_NAME" nopass
  706.         EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
  707.  
  708.         case $TLS_SIG in
  709.                 1)
  710.                         # Generate tls-crypt key
  711.                         openvpn --genkey --secret /etc/openvpn/tls-crypt.key
  712.                 ;;
  713.                 2)
  714.                         # Generate tls-auth key
  715.                         openvpn --genkey --secret /etc/openvpn/tls-auth.key
  716.                 ;;
  717.         esac
  718.  
  719.         # Move all the generated files
  720.         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
  721.         if [[ $DH_TYPE == "2" ]]; then
  722.                 cp dh.pem /etc/openvpn
  723.         fi
  724.  
  725.         # Make cert revocation list readable for non-root
  726.         chmod 644 /etc/openvpn/crl.pem
  727.  
  728.         # Generate server.conf
  729.         echo "port $PORT" > /etc/openvpn/server.conf
  730.         if [[ "$IPV6_SUPPORT" == 'n' ]]; then
  731.                 echo "proto $PROTOCOL" >> /etc/openvpn/server.conf
  732.         elif [[ "$IPV6_SUPPORT" == 'y' ]]; then
  733.                 echo "proto ${PROTOCOL}6" >> /etc/openvpn/server.conf
  734.         fi
  735.  
  736.         echo "dev tun
  737. user nobody
  738. group $NOGROUP
  739. persist-key
  740. persist-tun
  741. keepalive 10 120
  742. topology subnet
  743. server 10.8.0.0 255.255.255.0
  744. ifconfig-pool-persist ipp.txt" >> /etc/openvpn/server.conf
  745.  
  746.         # DNS resolvers
  747.         case $DNS in
  748.                 1) # Current system resolvers
  749.                         # Locate the proper resolv.conf
  750.                         # Needed for systems running systemd-resolved
  751.                         if grep -q "127.0.0.53" "/etc/resolv.conf"; then
  752.                                 RESOLVCONF='/run/systemd/resolve/resolv.conf'
  753.                         else
  754.                                 RESOLVCONF='/etc/resolv.conf'
  755.                         fi
  756.                         # Obtain the resolvers from resolv.conf and use them for OpenVPN
  757.                         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
  758.                                 echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server.conf
  759.                         done
  760.                 ;;
  761.                 2) # Self-hosted DNS resolver (Unbound)
  762.                         echo 'push "dhcp-option DNS 10.8.0.1"' >> /etc/openvpn/server.conf
  763.                 ;;
  764.                 3) # Cloudflare
  765.                         echo 'push "dhcp-option DNS 1.0.0.1"' >> /etc/openvpn/server.conf
  766.                         echo 'push "dhcp-option DNS 1.1.1.1"' >> /etc/openvpn/server.conf
  767.                 ;;
  768.                 4) # Quad9
  769.                         echo 'push "dhcp-option DNS 9.9.9.9"' >> /etc/openvpn/server.conf
  770.                         echo 'push "dhcp-option DNS 149.112.112.112"' >> /etc/openvpn/server.conf
  771.                 ;;
  772.                 5) # Quad9 uncensored
  773.                         echo 'push "dhcp-option DNS 9.9.9.10"' >> /etc/openvpn/server.conf
  774.                         echo 'push "dhcp-option DNS 149.112.112.10"' >> /etc/openvpn/server.conf
  775.                 ;;
  776.                 6) # FDN
  777.                         echo 'push "dhcp-option DNS 80.67.169.40"' >> /etc/openvpn/server.conf
  778.                         echo 'push "dhcp-option DNS 80.67.169.12"' >> /etc/openvpn/server.conf
  779.                 ;;
  780.                 7) # DNS.WATCH
  781.                         echo 'push "dhcp-option DNS 84.200.69.80"' >> /etc/openvpn/server.conf
  782.                         echo 'push "dhcp-option DNS 84.200.70.40"' >> /etc/openvpn/server.conf
  783.                 ;;
  784.                 8) # OpenDNS
  785.                         echo 'push "dhcp-option DNS 208.67.222.222"' >> /etc/openvpn/server.conf
  786.                         echo 'push "dhcp-option DNS 208.67.220.220"' >> /etc/openvpn/server.conf
  787.                 ;;
  788.                 9) # Google
  789.                         echo 'push "dhcp-option DNS 8.8.8.8"' >> /etc/openvpn/server.conf
  790.                         echo 'push "dhcp-option DNS 8.8.4.4"' >> /etc/openvpn/server.conf
  791.                 ;;
  792.                 10) # Yandex Basic
  793.                         echo 'push "dhcp-option DNS 77.88.8.8"' >> /etc/openvpn/server.conf
  794.                         echo 'push "dhcp-option DNS 77.88.8.1"' >> /etc/openvpn/server.conf
  795.                 ;;
  796.                 11) # AdGuard DNS
  797.                         echo 'push "dhcp-option DNS 176.103.130.130"' >> /etc/openvpn/server.conf
  798.                         echo 'push "dhcp-option DNS 176.103.130.131"' >> /etc/openvpn/server.conf
  799.                 ;;
  800.                 12) # NextDNS
  801.                         echo 'push "dhcp-option DNS 45.90.28.167"' >> /etc/openvpn/server.conf
  802.                         echo 'push "dhcp-option DNS 45.90.30.167"' >> /etc/openvpn/server.conf
  803.                 ;;
  804.                 13) # Custom DNS
  805.                 echo "push \"dhcp-option DNS $DNS1\"" >> /etc/openvpn/server.conf
  806.                 if [[ "$DNS2" != "" ]]; then
  807.                         echo "push \"dhcp-option DNS $DNS2\"" >> /etc/openvpn/server.conf
  808.                 fi
  809.                 ;;
  810.         esac
  811.         echo 'push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server.conf
  812.  
  813.         # IPv6 network settings if needed
  814.         if [[ "$IPV6_SUPPORT" == 'y' ]]; then
  815.                 echo 'server-ipv6 fd42:42:42:42::/112
  816. tun-ipv6
  817. push tun-ipv6
  818. push "route-ipv6 2000::/3"
  819. push "redirect-gateway ipv6"' >> /etc/openvpn/server.conf
  820.         fi
  821.  
  822.         if [[ $COMPRESSION_ENABLED == "y"  ]]; then
  823.                 echo "compress $COMPRESSION_ALG" >> /etc/openvpn/server.conf
  824.         fi
  825.  
  826.         if [[ $DH_TYPE == "1" ]]; then
  827.                 echo "dh none" >> /etc/openvpn/server.conf
  828.                 echo "ecdh-curve $DH_CURVE" >> /etc/openvpn/server.conf
  829.         elif [[ $DH_TYPE == "2" ]]; then
  830.                 echo "dh dh.pem" >> /etc/openvpn/server.conf
  831.         fi
  832.  
  833.         case $TLS_SIG in
  834.                 1)
  835.                         echo "tls-crypt tls-crypt.key 0" >> /etc/openvpn/server.conf
  836.                 ;;
  837.                 2)
  838.                         echo "tls-auth tls-auth.key 0" >> /etc/openvpn/server.conf
  839.                 ;;
  840.         esac
  841.  
  842.         echo "crl-verify crl.pem
  843. ca ca.crt
  844. cert $SERVER_NAME.crt
  845. key $SERVER_NAME.key
  846. auth $HMAC_ALG
  847. cipher $CIPHER
  848. ncp-ciphers $CIPHER
  849. tls-server
  850. tls-version-min 1.2
  851. tls-cipher $CC_CIPHER
  852. client-config-dir /etc/openvpn/ccd
  853. status /var/log/openvpn/status.log
  854. verb 3" >> /etc/openvpn/server.conf
  855.  
  856.         # Create client-config-dir dir
  857.         mkdir -p /etc/openvpn/ccd
  858.         # Create log dir
  859.         mkdir -p /var/log/openvpn
  860.  
  861.         # Enable routing
  862.         echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.d/20-openvpn.conf
  863.         if [[ "$IPV6_SUPPORT" == 'y' ]]; then
  864.                 echo 'net.ipv6.conf.all.forwarding=1' >> /etc/sysctl.d/20-openvpn.conf
  865.         fi
  866.         # Apply sysctl rules
  867.         sysctl --system
  868.  
  869.         # If SELinux is enabled and a custom port was selected, we need this
  870.         if hash sestatus 2>/dev/null; then
  871.                 if sestatus | grep "Current mode" | grep -qs "enforcing"; then
  872.                         if [[ "$PORT" != '1194' ]]; then
  873.                                 semanage port -a -t openvpn_port_t -p "$PROTOCOL" "$PORT"
  874.                         fi
  875.                 fi
  876.         fi
  877.  
  878.         # Finally, restart and enable OpenVPN
  879.         if [[ "$OS" == 'arch' || "$OS" == 'fedora' || "$OS" == 'centos' ]]; then
  880.                 # Don't modify package-provided service
  881.                 cp /usr/lib/systemd/system/openvpn-server@.service /etc/systemd/system/openvpn-server@.service
  882.  
  883.                 # Workaround to fix OpenVPN service on OpenVZ
  884.                 sed -i 's|LimitNPROC|#LimitNPROC|' /etc/systemd/system/openvpn-server@.service
  885.                 # Another workaround to keep using /etc/openvpn/
  886.                 sed -i 's|/etc/openvpn/server|/etc/openvpn|' /etc/systemd/system/openvpn-server@.service
  887.                 # On fedora, the service hardcodes the ciphers. We want to manage the cipher ourselves, so we remove it from the service
  888.                 if [[ "$OS" == "fedora" ]];then
  889.                         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
  890.                 fi
  891.  
  892.                 systemctl daemon-reload
  893.                 systemctl enable openvpn-server@server
  894.                 systemctl restart openvpn-server@server
  895.         elif [[ "$OS" == "ubuntu" ]] && [[ "$VERSION_ID" == "16.04" ]]; then
  896.                 # On Ubuntu 16.04, we use the package from the OpenVPN repo
  897.                 # This package uses a sysvinit service
  898.                 systemctl enable openvpn
  899.                 systemctl start openvpn
  900.         else
  901.                 # Don't modify package-provided service
  902.                 cp /lib/systemd/system/openvpn\@.service /etc/systemd/system/openvpn\@.service
  903.  
  904.                 # Workaround to fix OpenVPN service on OpenVZ
  905.                 sed -i 's|LimitNPROC|#LimitNPROC|' /etc/systemd/system/openvpn\@.service
  906.                 # Another workaround to keep using /etc/openvpn/
  907.                 sed -i 's|/etc/openvpn/server|/etc/openvpn|' /etc/systemd/system/openvpn\@.service
  908.  
  909.                 systemctl daemon-reload
  910.                 systemctl enable openvpn@server
  911.                 systemctl restart openvpn@server
  912.         fi
  913.  
  914.         if [[ $DNS == 2 ]];then
  915.                 installUnbound
  916.         fi
  917.  
  918.         # Add iptables rules in two scripts
  919.         mkdir -p /etc/iptables
  920.  
  921.         # Script to add rules
  922.         echo "#!/bin/sh
  923. iptables -t nat -I POSTROUTING 1 -s 10.8.0.0/16 -o $NIC -j MASQUERADE
  924. iptables -I INPUT 1 -i tun0 -j ACCEPT
  925. iptables -I FORWARD 1 -i $NIC -o tun0 -j ACCEPT
  926. iptables -I FORWARD 1 -i tun0 -o $NIC -j ACCEPT
  927. iptables -I INPUT 1 -i $NIC -p $PROTOCOL --dport $PORT -j ACCEPT" > /etc/iptables/add-openvpn-rules.sh
  928.  
  929.         if [[ "$IPV6_SUPPORT" == 'y' ]]; then
  930.                 echo "ip6tables -t nat -I POSTROUTING 1 -s fd42:42:42:42::/112 -o $NIC -j MASQUERADE
  931. ip6tables -I INPUT 1 -i tun0 -j ACCEPT
  932. ip6tables -I FORWARD 1 -i $NIC -o tun0 -j ACCEPT
  933. ip6tables -I FORWARD 1 -i tun0 -o $NIC -j ACCEPT" >> /etc/iptables/add-openvpn-rules.sh
  934.         fi
  935.  
  936.         # Script to remove rules
  937.         echo "#!/bin/sh
  938. iptables -t nat -D POSTROUTING -s 10.8.0.0/16 -o $NIC -j MASQUERADE
  939. iptables -D INPUT -i tun0 -j ACCEPT
  940. iptables -D FORWARD -i $NIC -o tun0 -j ACCEPT
  941. iptables -D FORWARD -i tun0 -o $NIC -j ACCEPT
  942. iptables -D INPUT -i $NIC -p $PROTOCOL --dport $PORT -j ACCEPT" > /etc/iptables/rm-openvpn-rules.sh
  943.  
  944.         if [[ "$IPV6_SUPPORT" == 'y' ]]; then
  945.                 echo "ip6tables -t nat -D POSTROUTING -s fd42:42:42:42::/112 -o $NIC -j MASQUERADE
  946. ip6tables -D INPUT -i tun0 -j ACCEPT
  947. ip6tables -D FORWARD -i $NIC -o tun0 -j ACCEPT
  948. ip6tables -D FORWARD -i tun0 -o $NIC -j ACCEPT" >> /etc/iptables/rm-openvpn-rules.sh
  949.         fi
  950.  
  951.         chmod +x /etc/iptables/add-openvpn-rules.sh
  952.         chmod +x /etc/iptables/rm-openvpn-rules.sh
  953.  
  954.         # Handle the rules via a systemd script
  955.         echo "[Unit]
  956. Description=iptables rules for OpenVPN
  957. Before=network-online.target
  958. Wants=network-online.target
  959.  
  960. [Service]
  961. Type=oneshot
  962. ExecStart=/etc/iptables/add-openvpn-rules.sh
  963. ExecStop=/etc/iptables/rm-openvpn-rules.sh
  964. RemainAfterExit=yes
  965.  
  966. [Install]
  967. WantedBy=multi-user.target" > /etc/systemd/system/iptables-openvpn.service
  968.  
  969.         # Enable service and apply rules
  970.         systemctl daemon-reload
  971.         systemctl enable iptables-openvpn
  972.         systemctl start iptables-openvpn
  973.  
  974.         # If the server is behind a NAT, use the correct IP address for the clients to connect to
  975.         if [[ "$ENDPOINT" != "" ]]; then
  976.                 IP=$ENDPOINT
  977.         fi
  978.  
  979.         # client-template.txt is created so we have a template to add further users later
  980.         echo "client" > /etc/openvpn/client-template.txt
  981.         if [[ "$PROTOCOL" == 'udp' ]]; then
  982.                 echo "proto udp" >> /etc/openvpn/client-template.txt
  983.                 echo "explicit-exit-notify" >> /etc/openvpn/client-template.txt
  984.         elif [[ "$PROTOCOL" == 'tcp' ]]; then
  985.                 echo "proto tcp-client" >> /etc/openvpn/client-template.txt
  986.         fi
  987.         echo "remote $IP $PORT
  988. dev tun
  989. resolv-retry infinite
  990. nobind
  991. persist-key
  992. persist-tun
  993. remote-cert-tls server
  994. verify-x509-name $SERVER_NAME name
  995. auth $HMAC_ALG
  996. auth-nocache
  997. cipher $CIPHER
  998. tls-client
  999. tls-version-min 1.2
  1000. tls-cipher $CC_CIPHER
  1001. setenv opt block-outside-dns # Prevent Windows 10 DNS leak
  1002. verb 3" >> /etc/openvpn/client-template.txt
  1003.  
  1004. if [[ $COMPRESSION_ENABLED == "y"  ]]; then
  1005.         echo "compress $COMPRESSION_ALG" >> /etc/openvpn/client-template.txt
  1006. fi
  1007.  
  1008.         # Generate the custom client.ovpn
  1009.         newClient
  1010.         echo "If you want to add more clients, you simply need to run this script another time!"
  1011. }
  1012.  
  1013. function newClient () {
  1014.         echo ""
  1015.         echo "Tell me a name for the client."
  1016.         echo "Use one word only, no special characters."
  1017.  
  1018.         until [[ "$CLIENT" =~ ^[a-zA-Z0-9_]+$ ]]; do
  1019.                 read -rp "Client name: " -e CLIENT
  1020.         done
  1021.  
  1022.         echo ""
  1023.         echo "Do you want to protect the configuration file with a password?"
  1024.         echo "(e.g. encrypt the private key with a password)"
  1025.         echo "   1) Add a passwordless client"
  1026.         echo "   2) Use a password for the client"
  1027.  
  1028.         until [[ "$PASS" =~ ^[1-2]$ ]]; do
  1029.                 read -rp "Select an option [1-2]: " -e -i 1 PASS
  1030.         done
  1031.  
  1032.         cd /etc/openvpn/easy-rsa/ || return
  1033.         case $PASS in
  1034.                 1)
  1035.                         ./easyrsa build-client-full "$CLIENT" nopass
  1036.                 ;;
  1037.                 2)
  1038.                 echo "⚠️ You will be asked for the client password below ⚠️"
  1039.                         ./easyrsa build-client-full "$CLIENT"
  1040.                 ;;
  1041.         esac
  1042.  
  1043.         # Home directory of the user, where the client configuration (.ovpn) will be written
  1044.         if [ -e "/home/$CLIENT" ]; then  # if $1 is a user name
  1045.                 homeDir="/home/$CLIENT"
  1046.         elif [ "${SUDO_USER}" ]; then # if not, use SUDO_USER
  1047.                 homeDir="/home/${SUDO_USER}"
  1048.         else # if not SUDO_USER, use /root
  1049.                 homeDir="/root"
  1050.         fi
  1051.  
  1052.         # Determine if we use tls-auth or tls-crypt
  1053.         if grep -qs "^tls-crypt" /etc/openvpn/server.conf; then
  1054.                 TLS_SIG="1"
  1055.         elif grep -qs "^tls-auth" /etc/openvpn/server.conf; then
  1056.                 TLS_SIG="2"
  1057.         fi
  1058.  
  1059.         # Generates the custom client.ovpn
  1060.         cp /etc/openvpn/client-template.txt "$homeDir/$CLIENT.ovpn"
  1061.         {
  1062.                 echo "<ca>"
  1063.                 cat "/etc/openvpn/easy-rsa/pki/ca.crt"
  1064.                 echo "</ca>"
  1065.  
  1066.                 echo "<cert>"
  1067.                 awk '/BEGIN/,/END/' "/etc/openvpn/easy-rsa/pki/issued/$CLIENT.crt"
  1068.                 echo "</cert>"
  1069.  
  1070.                 echo "<key>"
  1071.                 cat "/etc/openvpn/easy-rsa/pki/private/$CLIENT.key"
  1072.                 echo "</key>"
  1073.  
  1074.                 case $TLS_SIG in
  1075.                         1)
  1076.                                 echo "<tls-crypt>"
  1077.                                 cat /etc/openvpn/tls-crypt.key
  1078.                                 echo "</tls-crypt>"
  1079.                         ;;
  1080.                         2)
  1081.                                 echo "key-direction 1"
  1082.                                 echo "<tls-auth>"
  1083.                                 cat /etc/openvpn/tls-auth.key
  1084.                                 echo "</tls-auth>"
  1085.                         ;;
  1086.                 esac
  1087.         } >> "$homeDir/$CLIENT.ovpn"
  1088.  
  1089.         echo ""
  1090.         echo "Client $CLIENT added, the configuration file is available at $homeDir/$CLIENT.ovpn."
  1091.         echo "Download the .ovpn file and import it in your OpenVPN client."
  1092.  
  1093.         exit 0
  1094. }
  1095.  
  1096. function revokeClient () {
  1097.         NUMBEROFCLIENTS=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep -c "^V")
  1098.         if [[ "$NUMBEROFCLIENTS" == '0' ]]; then
  1099.                 echo ""
  1100.                 echo "You have no existing clients!"
  1101.                 exit 1
  1102.         fi
  1103.  
  1104.         echo ""
  1105.         echo "Select the existing client certificate you want to revoke"
  1106.         tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
  1107.         if [[ "$NUMBEROFCLIENTS" == '1' ]]; then
  1108.                 read -rp "Select one client [1]: " CLIENTNUMBER
  1109.         else
  1110.                 read -rp "Select one client [1-$NUMBEROFCLIENTS]: " CLIENTNUMBER
  1111.         fi
  1112.  
  1113.         CLIENT=$(tail -n +2 /etc/openvpn/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$CLIENTNUMBER"p)
  1114.         cd /etc/openvpn/easy-rsa/ || return
  1115.         ./easyrsa --batch revoke "$CLIENT"
  1116.         EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
  1117.         # Cleanup
  1118.         rm -f "pki/reqs/$CLIENT.req"
  1119.         rm -f "pki/private/$CLIENT.key"
  1120.         rm -f "pki/issued/$CLIENT.crt"
  1121.         rm -f /etc/openvpn/crl.pem
  1122.         cp /etc/openvpn/easy-rsa/pki/crl.pem /etc/openvpn/crl.pem
  1123.         chmod 644 /etc/openvpn/crl.pem
  1124.         find /home/ -maxdepth 2 -name "$CLIENT.ovpn" -delete
  1125.         rm -f "/root/$CLIENT.ovpn"
  1126.         sed -i "/^$CLIENT,.*/d" /etc/openvpn/ipp.txt
  1127.  
  1128.         echo ""
  1129.         echo "Certificate for client $CLIENT revoked."
  1130. }
  1131.  
  1132. function removeUnbound () {
  1133.         # Remove OpenVPN-related config
  1134.         sed -i '/include: \/etc\/unbound\/openvpn.conf/d' /etc/unbound/unbound.conf
  1135.         rm /etc/unbound/openvpn.conf
  1136.  
  1137.         until [[ $REMOVE_UNBOUND =~ (y|n) ]]; do
  1138.                 echo ""
  1139.                 echo "If you were already using Unbound before installing OpenVPN, I removed the configuration related to OpenVPN."
  1140.                 read -rp "Do you want to completely remove Unbound? [y/n]: " -e REMOVE_UNBOUND
  1141.         done
  1142.  
  1143.         if [[ "$REMOVE_UNBOUND" == 'y' ]]; then
  1144.                 # Stop Unbound
  1145.                 systemctl stop unbound
  1146.  
  1147.                 if [[ "$OS" =~ (debian|ubuntu) ]]; then
  1148.                         apt-get autoremove --purge -y unbound
  1149.                 elif [[ "$OS" == 'arch' ]]; then
  1150.                         pacman --noconfirm -R unbound
  1151.                 elif [[ "$OS" =~ (centos|amzn) ]]; then
  1152.                         yum remove -y unbound
  1153.                 elif [[ "$OS" == 'fedora' ]]; then
  1154.                         dnf remove -y unbound
  1155.                 fi
  1156.  
  1157.                 rm -rf /etc/unbound/
  1158.  
  1159.                 echo ""
  1160.                 echo "Unbound removed!"
  1161.         else
  1162.                 systemctl restart unbound
  1163.                 echo ""
  1164.                 echo "Unbound wasn't removed."
  1165.         fi
  1166. }
  1167.  
  1168. function removeOpenVPN () {
  1169.         echo ""
  1170.         # shellcheck disable=SC2034
  1171.         read -rp "Do you really want to remove OpenVPN? [y/n]: " -e -i n REMOVE
  1172.         if [[ "$REMOVE" == 'y' ]]; then
  1173.                 # Get OpenVPN port from the configuration
  1174.                 PORT=$(grep '^port ' /etc/openvpn/server.conf | cut -d " " -f 2)
  1175.  
  1176.                 # Stop OpenVPN
  1177.                 if [[ "$OS" =~ (fedora|arch|centos) ]]; then
  1178.                         systemctl disable openvpn-server@server
  1179.                         systemctl stop openvpn-server@server
  1180.                         # Remove customised service
  1181.                         rm /etc/systemd/system/openvpn-server@.service
  1182.                 elif [[ "$OS" == "ubuntu" ]] && [[ "$VERSION_ID" == "16.04" ]]; then
  1183.                         systemctl disable openvpn
  1184.                         systemctl stop openvpn
  1185.                 else
  1186.                         systemctl disable openvpn@server
  1187.                         systemctl stop openvpn@server
  1188.                         # Remove customised service
  1189.                         rm /etc/systemd/system/openvpn\@.service
  1190.                 fi
  1191.  
  1192.                 # Remove the iptables rules related to the script
  1193.                 systemctl stop iptables-openvpn
  1194.                 # Cleanup
  1195.                 systemctl disable iptables-openvpn
  1196.                 rm /etc/systemd/system/iptables-openvpn.service
  1197.                 systemctl daemon-reload
  1198.                 rm /etc/iptables/add-openvpn-rules.sh
  1199.                 rm /etc/iptables/rm-openvpn-rules.sh
  1200.  
  1201.                 # SELinux
  1202.                 if hash sestatus 2>/dev/null; then
  1203.                         if sestatus | grep "Current mode" | grep -qs "enforcing"; then
  1204.                                 if [[ "$PORT" != '1194' ]]; then
  1205.                                         semanage port -d -t openvpn_port_t -p udp "$PORT"
  1206.                                 fi
  1207.                         fi
  1208.                 fi
  1209.  
  1210.                 if [[ "$OS" =~ (debian|ubuntu) ]]; then
  1211.                         apt-get autoremove --purge -y openvpn
  1212.                         if [[ -e /etc/apt/sources.list.d/openvpn.list ]];then
  1213.                                 rm /etc/apt/sources.list.d/openvpn.list
  1214.                                 apt-get update
  1215.                         fi
  1216.                 elif [[ "$OS" == 'arch' ]]; then
  1217.                         pacman --noconfirm -R openvpn
  1218.                 elif [[ "$OS" =~ (centos|amzn) ]]; then
  1219.                         yum remove -y openvpn
  1220.                 elif [[ "$OS" == 'fedora' ]]; then
  1221.                         dnf remove -y openvpn
  1222.                 fi
  1223.  
  1224.                 # Cleanup
  1225.                 find /home/ -maxdepth 2 -name "*.ovpn" -delete
  1226.                 find /root/ -maxdepth 1 -name "*.ovpn" -delete
  1227.                 rm -rf /etc/openvpn
  1228.                 rm -rf /usr/share/doc/openvpn*
  1229.                 rm -f /etc/sysctl.d/20-openvpn.conf
  1230.                 rm -rf /var/log/openvpn
  1231.  
  1232.                 # Unbound
  1233.                 if [[ -e /etc/unbound/openvpn.conf ]]; then
  1234.                         removeUnbound
  1235.                 fi
  1236.                 echo ""
  1237.                 echo "OpenVPN removed!"
  1238.         else
  1239.                 echo ""
  1240.                 echo "Removal aborted!"
  1241.         fi
  1242. }
  1243.  
  1244. function manageMenu () {
  1245.         clear
  1246.         echo "Welcome to OpenVPN-install!"
  1247.         echo "The git repository is available at: https://github.com/angristan/openvpn-install"
  1248.         echo ""
  1249.         echo "It looks like OpenVPN is already installed."
  1250.         echo ""
  1251.         echo "What do you want to do?"
  1252.         echo "   1) Add a new user"
  1253.         echo "   2) Revoke existing user"
  1254.         echo "   3) Remove OpenVPN"
  1255.         echo "   4) Exit"
  1256.         until [[ "$MENU_OPTION" =~ ^[1-4]$ ]]; do
  1257.                 read -rp "Select an option [1-4]: " MENU_OPTION
  1258.         done
  1259.  
  1260.         case $MENU_OPTION in
  1261.                 1)
  1262.                         newClient
  1263.                 ;;
  1264.                 2)
  1265.                         revokeClient
  1266.                 ;;
  1267.                 3)
  1268.                         removeOpenVPN
  1269.                 ;;
  1270.                 4)
  1271.                         exit 0
  1272.                 ;;
  1273.         esac
  1274. }
  1275.  
  1276. # Check for root, TUN, OS...
  1277. initialCheck
  1278.  
  1279. # Check if OpenVPN is already installed
  1280. if [[ -e /etc/openvpn/server.conf ]]; then
  1281.         manageMenu
  1282. else
  1283.         installOpenVPN
  1284. fi