From 1c79a9603b0eb54cea2248ee0005453655ae5fca Mon Sep 17 00:00:00 2001 From: Nyr Date: Fri, 6 Sep 2019 02:44:17 +0200 Subject: [PATCH 01/65] Fix LimitNPROC in containers See #206 for context. --- openvpn-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openvpn-install.sh b/openvpn-install.sh index 136e7d9f..38503284 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -145,6 +145,7 @@ if [[ -e /etc/openvpn/server/server.conf ]]; then fi systemctl disable --now openvpn-server@server.service rm -rf /etc/openvpn/server + rm -f /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf rm -f /etc/sysctl.d/30-openvpn-forward.conf if [[ "$OS" = 'debian' ]]; then apt-get remove --purge -y openvpn @@ -212,6 +213,12 @@ else echo echo "Okay, that was all I needed. We are ready to set up your OpenVPN server now." read -n1 -r -p "Press any key to continue..." + # If running inside a container, disable LimitNPROC to prevent conflicts + if systemd-detect-virt -cq; then + mkdir /etc/systemd/system/openvpn-server@server.service.d/ 2>/dev/null + echo '[Service] +LimitNPROC=infinity' > /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf + fi if [[ "$OS" = 'debian' ]]; then apt-get update apt-get install openvpn iptables openssl ca-certificates -y From 68e48d21b6859c26b04b4713e326d1cd2d40d214 Mon Sep 17 00:00:00 2001 From: Nyr Date: Sat, 21 Sep 2019 14:39:58 +0200 Subject: [PATCH 02/65] Check for unsupported distributions --- openvpn-install.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/openvpn-install.sh b/openvpn-install.sh index 38503284..646ff87f 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -5,6 +5,21 @@ # Copyright (c) 2013 Nyr. Released under the MIT License. +if grep -qs "14.04" "/etc/os-release"; then + echo "Ubuntu 14.04 is too old and not supported" + exit +fi + +if grep -qs "jessie" "/etc/os-release"; then + echo "Debian 8 is too old and not supported" + exit +fi + +if grep -qs "CentOS release 6" "/etc/redhat-release"; then + echo "CentOS 6 is too old and not supported" + exit +fi + if grep -qs "Ubuntu 16.04" "/etc/os-release"; then echo 'Ubuntu 16.04 is no longer supported in the current version of openvpn-install Use an older version if Ubuntu 16.04 support is needed: https://git.io/vpn1604' From 6a29a6babdb6e2d813c6c585800debc1558ead2d Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 26 Sep 2019 19:13:33 +0200 Subject: [PATCH 03/65] Miscellaneous improvements This commit contains lots changes which are not very significant on its own but provide important usability improvements and future proofing. It also includes changes which required OpenVPN v2.4+ and were pending until that version became widely available. - General cleanup - Improved IP address and NAT configuration - Added input validation and sanitization - Fix #603 - Remove "sndbuf" and "recvbuf" parameters - Add server-side "explicit-exit-notify" - Switch from "setenv opt" to "ignore-unknown-option" - Switch from "tls-auth" to "tls-crypt" - Other minor bugfixes and optimizations --- openvpn-install.sh | 291 ++++++++++++++++++++++++++------------------- 1 file changed, 168 insertions(+), 123 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 646ff87f..1216b50f 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -5,22 +5,22 @@ # Copyright (c) 2013 Nyr. Released under the MIT License. -if grep -qs "14.04" "/etc/os-release"; then +if grep -qs "14.04" /etc/os-release; then echo "Ubuntu 14.04 is too old and not supported" exit fi -if grep -qs "jessie" "/etc/os-release"; then +if grep -qs "jessie" /etc/os-release; then echo "Debian 8 is too old and not supported" exit fi -if grep -qs "CentOS release 6" "/etc/redhat-release"; then +if grep -qs "CentOS release 6" /etc/redhat-release; then echo "CentOS 6 is too old and not supported" exit fi -if grep -qs "Ubuntu 16.04" "/etc/os-release"; then +if grep -qs "Ubuntu 16.04" /etc/os-release; then echo 'Ubuntu 16.04 is no longer supported in the current version of openvpn-install Use an older version if Ubuntu 16.04 support is needed: https://git.io/vpn1604' exit @@ -44,31 +44,33 @@ You need to enable TUN before running this script" fi if [[ -e /etc/debian_version ]]; then - OS=debian - GROUPNAME=nogroup + os="debian" + group_name="nogroup" elif [[ -e /etc/centos-release || -e /etc/redhat-release ]]; then - OS=centos - GROUPNAME=nobody + os="centos" + group_name="nobody" else echo "Looks like you aren't running this installer on Debian, Ubuntu or CentOS" exit fi -newclient () { +new_client () { # Generates the custom client.ovpn - cp /etc/openvpn/server/client-common.txt ~/$1.ovpn - echo "" >> ~/$1.ovpn - cat /etc/openvpn/server/easy-rsa/pki/ca.crt >> ~/$1.ovpn - echo "" >> ~/$1.ovpn - echo "" >> ~/$1.ovpn - sed -ne '/BEGIN CERTIFICATE/,$ p' /etc/openvpn/server/easy-rsa/pki/issued/$1.crt >> ~/$1.ovpn - echo "" >> ~/$1.ovpn - echo "" >> ~/$1.ovpn - cat /etc/openvpn/server/easy-rsa/pki/private/$1.key >> ~/$1.ovpn - echo "" >> ~/$1.ovpn - echo "" >> ~/$1.ovpn - sed -ne '/BEGIN OpenVPN Static key/,$ p' /etc/openvpn/server/ta.key >> ~/$1.ovpn - echo "" >> ~/$1.ovpn + { + cat /etc/openvpn/server/client-common.txt + echo "" + cat /etc/openvpn/server/easy-rsa/pki/ca.crt + echo "" + echo "" + sed -ne '/BEGIN CERTIFICATE/,$ p' /etc/openvpn/server/easy-rsa/pki/issued/"$1".crt + echo "" + echo "" + cat /etc/openvpn/server/easy-rsa/pki/private/"$1".key + echo "" + echo "" + sed -ne '/BEGIN OpenVPN Static key/,$ p' /etc/openvpn/server/tc.key + echo "" + } > ~/"$1".ovpn } if [[ -e /etc/openvpn/server/server.conf ]]; then @@ -82,26 +84,35 @@ if [[ -e /etc/openvpn/server/server.conf ]]; then echo " 2) Revoke an existing user" echo " 3) Remove OpenVPN" echo " 4) Exit" - read -p "Select an option [1-4]: " option - case $option in + read -p "Select an option: " option + until [[ "$option" =~ ^[1-4]$ ]]; do + echo "$option: invalid selection." + read -p "Select an option: " option + done + case "$option" in 1) echo echo "Tell me a name for the client certificate." - echo "Please, use one word only, no special characters." - read -p "Client name: " -e CLIENT + read -p "Client name: " unsanitized_client + client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") + while [[ -z "$client" || -e /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt ]]; do + echo "$client: invalid client name." + read -p "Client name: " unsanitized_client + client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") + done cd /etc/openvpn/server/easy-rsa/ - EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full $CLIENT nopass + EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full "$client" nopass # Generates the custom client.ovpn - newclient "$CLIENT" + new_client "$client" echo - echo "Client $CLIENT added, configuration is available at:" ~/"$CLIENT.ovpn" + echo "Client $client added, configuration is available at:" ~/"$client.ovpn" exit ;; 2) # This option could be documented a bit better and maybe even be simplified # ...but what can I say, I want some sleep too - NUMBEROFCLIENTS=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep -c "^V") - if [[ "$NUMBEROFCLIENTS" = '0' ]]; then + number_of_clients=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep -c "^V") + if [[ "$number_of_clients" = 0 ]]; then echo echo "You have no existing clients!" exit @@ -109,60 +120,68 @@ if [[ -e /etc/openvpn/server/server.conf ]]; then echo echo "Select the existing client certificate you want to revoke:" tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') ' - if [[ "$NUMBEROFCLIENTS" = '1' ]]; then - read -p "Select one client [1]: " CLIENTNUMBER - else - read -p "Select one client [1-$NUMBEROFCLIENTS]: " CLIENTNUMBER - fi - CLIENT=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$CLIENTNUMBER"p) + read -p "Select one client: " client_number + until [[ "$client_number" =~ ^[0-9]+$ && "$client_number" -le "$number_of_clients" ]]; do + echo "$client_number: invalid selection." + read -p "Select one client: " client_number + done + client=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$client_number"p) echo - read -p "Do you really want to revoke access for client $CLIENT? [y/N]: " -e REVOKE - if [[ "$REVOKE" = 'y' || "$REVOKE" = 'Y' ]]; then + read -p "Do you really want to revoke access for client $client? [y/N]: " revoke + until [[ "$revoke" =~ ^[yYnN]*$ ]]; do + echo "$revoke: invalid selection." + read -p "Do you really want to revoke access for client $client? [y/N]: " revoke + done + if [[ "$revoke" =~ ^[yY]$ ]]; then cd /etc/openvpn/server/easy-rsa/ - ./easyrsa --batch revoke $CLIENT + ./easyrsa --batch revoke "$client" EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl - rm -f pki/reqs/$CLIENT.req - rm -f pki/private/$CLIENT.key - rm -f pki/issued/$CLIENT.crt + rm -f pki/reqs/"$client".req + rm -f pki/private/"$client".key + rm -f pki/issued/"$client".crt rm -f /etc/openvpn/server/crl.pem cp /etc/openvpn/server/easy-rsa/pki/crl.pem /etc/openvpn/server/crl.pem # CRL is read with each client connection, when OpenVPN is dropped to nobody - chown nobody:$GROUPNAME /etc/openvpn/server/crl.pem + chown nobody:"$group_name" /etc/openvpn/server/crl.pem echo - echo "Certificate for client $CLIENT revoked!" + echo "Certificate for client $client revoked!" else echo - echo "Certificate revocation for client $CLIENT aborted!" + echo "Certificate revocation for client $client aborted!" fi exit ;; 3) echo - read -p "Do you really want to remove OpenVPN? [y/N]: " -e REMOVE - if [[ "$REMOVE" = 'y' || "$REMOVE" = 'Y' ]]; then - PORT=$(grep '^port ' /etc/openvpn/server/server.conf | cut -d " " -f 2) - PROTOCOL=$(grep '^proto ' /etc/openvpn/server/server.conf | cut -d " " -f 2) + read -p "Do you really want to remove OpenVPN? [y/N]: " remove + until [[ "$remove" =~ ^[yYnN]*$ ]]; do + echo "$remove: invalid selection." + read -p "Do you really want to remove OpenVPN? [y/N]: " remove + done + if [[ "$remove" =~ ^[yY]$ ]]; then + port=$(grep '^port ' /etc/openvpn/server/server.conf | cut -d " " -f 2) + protocol=$(grep '^proto ' /etc/openvpn/server/server.conf | cut -d " " -f 2) if pgrep firewalld; then - IP=$(firewall-cmd --direct --get-rules ipv4 nat POSTROUTING | grep '\-s 10.8.0.0/24 '"'"'!'"'"' -d 10.8.0.0/24 -j SNAT --to ' | cut -d " " -f 10) + ip=$(firewall-cmd --direct --get-rules ipv4 nat POSTROUTING | grep '\-s 10.8.0.0/24 '"'"'!'"'"' -d 10.8.0.0/24 -j SNAT --to ' | cut -d " " -f 10) # Using both permanent and not permanent rules to avoid a firewalld reload. - firewall-cmd --remove-port=$PORT/$PROTOCOL + firewall-cmd --remove-port="$port"/"$protocol" firewall-cmd --zone=trusted --remove-source=10.8.0.0/24 - firewall-cmd --permanent --remove-port=$PORT/$PROTOCOL + firewall-cmd --permanent --remove-port="$port"/"$protocol" firewall-cmd --permanent --zone=trusted --remove-source=10.8.0.0/24 - firewall-cmd --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP - firewall-cmd --permanent --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP + firewall-cmd --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip" + firewall-cmd --permanent --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip" else systemctl disable --now openvpn-iptables.service rm -f /etc/systemd/system/openvpn-iptables.service fi - if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$PORT" != '1194' ]]; then - semanage port -d -t openvpn_port_t -p $PROTOCOL $PORT + if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then + semanage port -d -t openvpn_port_t -p "$protocol" "$port" fi systemctl disable --now openvpn-server@server.service rm -rf /etc/openvpn/server rm -f /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf rm -f /etc/sysctl.d/30-openvpn-forward.conf - if [[ "$OS" = 'debian' ]]; then + if [[ "$os" = "debian" ]]; then apt-get remove --purge -y openvpn else yum remove openvpn -y @@ -180,39 +199,59 @@ if [[ -e /etc/openvpn/server/server.conf ]]; then done else clear - echo 'Welcome to this OpenVPN "road warrior" installer!' - echo - # OpenVPN setup and first user creation - echo "I need to ask you a few questions before starting the setup." - echo "You can leave the default options and just press enter if you are ok with them." + echo "Welcome to this OpenVPN "road warrior" installer!" echo - echo "First, provide the IPv4 address of the network interface you want OpenVPN" - echo "listening to." - # Autodetect IP address and pre-fill for the user - 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) - read -p "IP address: " -e -i $IP IP + echo "I need to ask you a few questions before starting setup." + echo "You can use the default options and just press enter if you are ok with them." + # If system has a single IPv4, it is selected automatically. Else, ask the user + if [[ $(ip addr | grep inet | grep -v inet6 | grep -vEc '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') -eq 1 ]]; then + ip=$(ip addr | grep inet | grep -v inet6 | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') + else + number_of_ips=$(ip addr | grep inet | grep -v inet6 | grep -vEc '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') + echo + echo "What IPv4 address should the OpenVPN server bind to?" + ip addr | grep inet | grep -v inet6 | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | nl -s ') ' + read -p "IPv4 address [1]: " ip_number + until [[ -z "$ip_number" || "$ip_number" =~ ^[0-9]+$ && "$ip_number" -le "$number_of_ips" ]]; do + echo "$ip_number: invalid selection." + read -p "IPv4 address [1]: " ip_number + done + [[ -z "$ip_number" ]] && ip_number="1" + ip=$(ip addr | grep inet | grep -v inet6 | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sed -n "$ip_number"p) + fi # If $IP is a private IP address, the server must be behind NAT - if echo "$IP" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then + if echo "$ip" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then echo echo "This server is behind NAT. What is the public IPv4 address or hostname?" - read -p "Public IP address / hostname: " -e PUBLICIP + get_public_ip=$(wget -4qO- "http://whatismyip.akamai.com/" || curl -4Ls "http://whatismyip.akamai.com/") + read -p "Public IPv4 address / hostname [$get_public_ip]: " public_ip + [ -z "$public_ip" ] && public_ip="$get_public_ip" fi echo echo "Which protocol do you want for OpenVPN connections?" echo " 1) UDP (recommended)" echo " 2) TCP" - read -p "Protocol [1-2]: " -e -i 1 PROTOCOL - case $PROTOCOL in - 1) - PROTOCOL=udp + read -p "Protocol [1]: " protocol + until [[ -z "$protocol" || "$protocol" =~ ^[12]$ ]]; do + echo "$protocol: invalid selection." + read -p "Protocol [1]: " protocol + done + case "$protocol" in + 1|"") + protocol=udp ;; 2) - PROTOCOL=tcp + protocol=tcp ;; esac echo echo "What port do you want OpenVPN listening to?" - read -p "Port: " -e -i 1194 PORT + read -p "Port [1194]: " port + until [[ -z "$port" || "$port" =~ ^[0-9]+$ && "$port" -le 65535 ]]; do + echo "$port: invalid selection." + read -p "Port [1194]: " port + done + [[ -z "$port" ]] && port="1194" echo echo "Which DNS do you want to use with the VPN?" echo " 1) Current system resolvers" @@ -220,21 +259,27 @@ else echo " 3) Google" echo " 4) OpenDNS" echo " 5) Verisign" - read -p "DNS [1-5]: " -e -i 1 DNS + read -p "DNS [1]: " dns + until [[ -z "$dns" || "$dns" =~ ^[1-5]$ ]]; do + echo "$dns: invalid selection." + read -p "DNS [1]: " dns + done echo - echo "Finally, tell me your name for the client certificate." - echo "Please, use one word only, no special characters." - read -p "Client name: " -e -i client CLIENT + echo "Finally, tell me a name for the client certificate." + read -p "Client name [client]: " unsanitized_client + # Allow a limited set of characters to avoid conflicts + client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") + [[ -z "$client" ]] && client="client" echo echo "Okay, that was all I needed. We are ready to set up your OpenVPN server now." read -n1 -r -p "Press any key to continue..." # If running inside a container, disable LimitNPROC to prevent conflicts if systemd-detect-virt -cq; then mkdir /etc/systemd/system/openvpn-server@server.service.d/ 2>/dev/null - echo '[Service] -LimitNPROC=infinity' > /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf + echo "[Service] +LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf fi - if [[ "$OS" = 'debian' ]]; then + if [[ "$os" = "debian" ]]; then apt-get update apt-get install openvpn iptables openssl ca-certificates -y else @@ -243,8 +288,8 @@ LimitNPROC=infinity' > /etc/systemd/system/openvpn-server@server.service.d/disab yum install openvpn iptables openssl ca-certificates -y fi # Get easy-rsa - EASYRSAURL='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.5/EasyRSA-nix-3.0.5.tgz' - wget -O ~/easyrsa.tgz "$EASYRSAURL" 2>/dev/null || curl -Lo ~/easyrsa.tgz "$EASYRSAURL" + easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.5/EasyRSA-nix-3.0.5.tgz' + wget -O ~/easyrsa.tgz "$easy_rsa_url" 2>/dev/null || curl -Lo ~/easyrsa.tgz "$easy_rsa_url" tar xzf ~/easyrsa.tgz -C ~/ mv ~/EasyRSA-3.0.5/ /etc/openvpn/server/ mv /etc/openvpn/server/EasyRSA-3.0.5/ /etc/openvpn/server/easy-rsa/ @@ -255,14 +300,14 @@ LimitNPROC=infinity' > /etc/systemd/system/openvpn-server@server.service.d/disab ./easyrsa init-pki ./easyrsa --batch build-ca nopass EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-server-full server nopass - EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full $CLIENT nopass + EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full "$client" nopass EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl # Move the stuff we need cp pki/ca.crt pki/private/ca.key pki/issued/server.crt pki/private/server.key pki/crl.pem /etc/openvpn/server # CRL is read with each client connection, when OpenVPN is dropped to nobody - chown nobody:$GROUPNAME /etc/openvpn/server/crl.pem - # Generate key for tls-auth - openvpn --genkey --secret /etc/openvpn/server/ta.key + chown nobody:"$group_name" /etc/openvpn/server/crl.pem + # Generate key for tls-crypt + openvpn --genkey --secret /etc/openvpn/server/tc.key # Create the DH parameters file using the predefined ffdhe2048 group echo '-----BEGIN DH PARAMETERS----- MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz @@ -273,33 +318,32 @@ YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== -----END DH PARAMETERS-----' > /etc/openvpn/server/dh.pem # Generate server.conf - echo "port $PORT -proto $PROTOCOL + echo "local $ip +port $port +proto $protocol dev tun -sndbuf 0 -rcvbuf 0 ca ca.crt cert server.crt key server.key dh dh.pem auth SHA512 -tls-auth ta.key 0 +tls-crypt tc.key topology subnet server 10.8.0.0 255.255.255.0 ifconfig-pool-persist ipp.txt" > /etc/openvpn/server/server.conf echo 'push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server/server.conf # DNS - case $DNS in - 1) + 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' + resolv_conf="/run/systemd/resolve/resolv.conf" else - RESOLVCONF='/etc/resolv.conf' + resolv_conf="/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 line; do + grep -v '#' "$resolv_conf" | grep nameserver | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | while read line; do echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server/server.conf done ;; @@ -323,12 +367,15 @@ ifconfig-pool-persist ipp.txt" > /etc/openvpn/server/server.conf echo "keepalive 10 120 cipher AES-256-CBC user nobody -group $GROUPNAME +group $group_name persist-key persist-tun status openvpn-status.log verb 3 crl-verify crl.pem" >> /etc/openvpn/server/server.conf + if [[ "$protocol" = "udp" ]]; then + echo "explicit-exit-notify" >> /etc/openvpn/server/server.conf + fi # Enable net.ipv4.ip_forward for the system echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/30-openvpn-forward.conf # Enable without waiting for a reboot or service restart @@ -338,25 +385,25 @@ crl-verify crl.pem" >> /etc/openvpn/server/server.conf # reload. # We don't use --add-service=openvpn because that would only work with # the default port and protocol. - firewall-cmd --add-port=$PORT/$PROTOCOL + firewall-cmd --add-port="$port"/"$protocol" firewall-cmd --zone=trusted --add-source=10.8.0.0/24 - firewall-cmd --permanent --add-port=$PORT/$PROTOCOL + firewall-cmd --permanent --add-port="$port"/"$protocol" firewall-cmd --permanent --zone=trusted --add-source=10.8.0.0/24 # Set NAT for the VPN subnet - firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP - firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP + firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip" + firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip" else # Create a service to set up persistent iptables rules echo "[Unit] Before=network.target [Service] Type=oneshot -ExecStart=/sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP -ExecStart=/sbin/iptables -I INPUT -p $PROTOCOL --dport $PORT -j ACCEPT +ExecStart=/sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $ip +ExecStart=/sbin/iptables -I INPUT -p $protocol --dport $port -j ACCEPT ExecStart=/sbin/iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT ExecStart=/sbin/iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT -ExecStop=/sbin/iptables -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $IP -ExecStop=/sbin/iptables -D INPUT -p $PROTOCOL --dport $PORT -j ACCEPT +ExecStop=/sbin/iptables -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $ip +ExecStop=/sbin/iptables -D INPUT -p $protocol --dport $port -j ACCEPT ExecStop=/sbin/iptables -D FORWARD -s 10.8.0.0/24 -j ACCEPT ExecStop=/sbin/iptables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT RemainAfterExit=yes @@ -365,7 +412,7 @@ WantedBy=multi-user.target" > /etc/systemd/system/openvpn-iptables.service systemctl enable --now openvpn-iptables.service fi # If SELinux is enabled and a custom port was selected, we need this - if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$PORT" != '1194' ]]; then + if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then # Install semanage if not already present if ! hash semanage 2>/dev/null; then if grep -qs "CentOS Linux release 7" "/etc/centos-release"; then @@ -374,21 +421,17 @@ WantedBy=multi-user.target" > /etc/systemd/system/openvpn-iptables.service yum install policycoreutils-python-utils -y fi fi - semanage port -a -t openvpn_port_t -p $PROTOCOL $PORT + semanage port -a -t openvpn_port_t -p "$protocol" "$port" fi - # And finally, enable and start the OpenVPN service - systemctl enable --now openvpn-server@server.service # If the server is behind a NAT, use the correct IP address - if [[ "$PUBLICIP" != "" ]]; then - IP=$PUBLICIP + if [[ "$public_ip" != "" ]]; then + ip="$public_ip" fi # client-common.txt is created so we have a template to add further users later echo "client dev tun -proto $PROTOCOL -sndbuf 0 -rcvbuf 0 -remote $IP $PORT +proto $protocol +remote $ip $port resolv-retry infinite nobind persist-key @@ -396,14 +439,16 @@ persist-tun remote-cert-tls server auth SHA512 cipher AES-256-CBC -setenv opt block-outside-dns -key-direction 1 +ignore-unknown-option block-outside-dns +block-outside-dns verb 3" > /etc/openvpn/server/client-common.txt + # Enable and start the OpenVPN service + systemctl enable --now openvpn-server@server.service # Generates the custom client.ovpn - newclient "$CLIENT" + new_client "$client" echo echo "Finished!" echo - echo "Your client configuration is available at:" ~/"$CLIENT.ovpn" - echo "If you want to add more clients, you simply need to run this script again!" + echo "Your client configuration is available at:" ~/"$client.ovpn" + echo "If you want to add more clients, just run this script again!" fi From 71f5fcc023ad533c89b88e43381bba2d6bb9d281 Mon Sep 17 00:00:00 2001 From: Nyr Date: Wed, 16 Oct 2019 22:09:25 +0200 Subject: [PATCH 04/65] Resolves #664 --- openvpn-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openvpn-install.sh b/openvpn-install.sh index 1216b50f..6adaf40e 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -43,6 +43,13 @@ You need to enable TUN before running this script" exit fi +if ! iptables -t nat -nL &>/dev/null; then + echo "Unable to initialize the iptables/netfilter NAT table, setup can't continue. +If you are a LowEndSpirit customer, see here: https://git.io/nfLES +If you are getting this message on any other provider, ask them for support." + exit +fi + if [[ -e /etc/debian_version ]]; then os="debian" group_name="nogroup" From 92d90dac29596487306df0e1cca48f85b74221d3 Mon Sep 17 00:00:00 2001 From: Nyr Date: Mon, 23 Dec 2019 20:19:57 +0100 Subject: [PATCH 05/65] Update error message LowEndSpirit no longer requires that. --- openvpn-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 6adaf40e..39a9f42f 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -45,8 +45,8 @@ fi if ! iptables -t nat -nL &>/dev/null; then echo "Unable to initialize the iptables/netfilter NAT table, setup can't continue. -If you are a LowEndSpirit customer, see here: https://git.io/nfLES -If you are getting this message on any other provider, ask them for support." +Make sure that your system has iptables/netfilter available. +If using OpenVZ, ask your provider to enable full netfilter support." exit fi From 6c4a21b5b9f5350981e8b0ad26fab18d9d204de4 Mon Sep 17 00:00:00 2001 From: Nyr Date: Wed, 18 Mar 2020 19:38:35 +0100 Subject: [PATCH 06/65] Fix #727 --- openvpn-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 39a9f42f..d57c9181 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -292,7 +292,7 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab else # Else, the distro is CentOS yum install epel-release -y - yum install openvpn iptables openssl ca-certificates -y + yum install openvpn iptables openssl ca-certificates tar -y fi # Get easy-rsa easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.5/EasyRSA-nix-3.0.5.tgz' From 9ea14fcbfc3e8d4254bb19f6dab6c2dffdd04d69 Mon Sep 17 00:00:00 2001 From: Nyr Date: Tue, 31 Mar 2020 02:35:50 +0200 Subject: [PATCH 07/65] Update to easy-rsa v3.0.7 --- openvpn-install.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index d57c9181..062590b8 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -143,9 +143,6 @@ if [[ -e /etc/openvpn/server/server.conf ]]; then cd /etc/openvpn/server/easy-rsa/ ./easyrsa --batch revoke "$client" EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl - rm -f pki/reqs/"$client".req - rm -f pki/private/"$client".key - rm -f pki/issued/"$client".crt rm -f /etc/openvpn/server/crl.pem cp /etc/openvpn/server/easy-rsa/pki/crl.pem /etc/openvpn/server/crl.pem # CRL is read with each client connection, when OpenVPN is dropped to nobody @@ -295,11 +292,11 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab yum install openvpn iptables openssl ca-certificates tar -y fi # Get easy-rsa - easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.5/EasyRSA-nix-3.0.5.tgz' + easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.7/EasyRSA-3.0.7.tgz' wget -O ~/easyrsa.tgz "$easy_rsa_url" 2>/dev/null || curl -Lo ~/easyrsa.tgz "$easy_rsa_url" tar xzf ~/easyrsa.tgz -C ~/ - mv ~/EasyRSA-3.0.5/ /etc/openvpn/server/ - mv /etc/openvpn/server/EasyRSA-3.0.5/ /etc/openvpn/server/easy-rsa/ + mv ~/EasyRSA-3.0.7/ /etc/openvpn/server/ + mv /etc/openvpn/server/EasyRSA-3.0.7/ /etc/openvpn/server/easy-rsa/ chown -R root:root /etc/openvpn/server/easy-rsa/ rm -f ~/easyrsa.tgz cd /etc/openvpn/server/easy-rsa/ From 67e8427ba532eef211d08b3ae3afb98e24fa2806 Mon Sep 17 00:00:00 2001 From: Nyr Date: Wed, 1 Apr 2020 00:54:00 +0200 Subject: [PATCH 08/65] Remove the iptables NAT table check LowEndSpirit fixed the issue on their end, so this is longer needed. Additionally, the check causes unneeded trouble for users whose system doesn't have the iptables package installed. --- openvpn-install.sh | 7 ------- 1 file changed, 7 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 062590b8..5134b2f5 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -43,13 +43,6 @@ You need to enable TUN before running this script" exit fi -if ! iptables -t nat -nL &>/dev/null; then - echo "Unable to initialize the iptables/netfilter NAT table, setup can't continue. -Make sure that your system has iptables/netfilter available. -If using OpenVZ, ask your provider to enable full netfilter support." - exit -fi - if [[ -e /etc/debian_version ]]; then os="debian" group_name="nogroup" From 5229459f99c5204f59697f880508f05cbb6d3999 Mon Sep 17 00:00:00 2001 From: Nyr Date: Wed, 1 Apr 2020 01:17:17 +0200 Subject: [PATCH 09/65] IPv6 support Clients will be provided with IPv6 connectivity if the server has it. Other very small and unimportant improvements are also included in this commit. --- openvpn-install.sh | 81 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 15 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 5134b2f5..d3c3f003 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -159,7 +159,7 @@ if [[ -e /etc/openvpn/server/server.conf ]]; then port=$(grep '^port ' /etc/openvpn/server/server.conf | cut -d " " -f 2) protocol=$(grep '^proto ' /etc/openvpn/server/server.conf | cut -d " " -f 2) if pgrep firewalld; then - ip=$(firewall-cmd --direct --get-rules ipv4 nat POSTROUTING | grep '\-s 10.8.0.0/24 '"'"'!'"'"' -d 10.8.0.0/24 -j SNAT --to ' | cut -d " " -f 10) + ip=$(firewall-cmd --direct --get-rules ipv4 nat POSTROUTING | grep '\-s 10.8.0.0/24 '"'"'!'"'"' -d 10.8.0.0/24' | grep -oE '[^ ]+$') # Using both permanent and not permanent rules to avoid a firewalld reload. firewall-cmd --remove-port="$port"/"$protocol" firewall-cmd --zone=trusted --remove-source=10.8.0.0/24 @@ -167,6 +167,13 @@ if [[ -e /etc/openvpn/server/server.conf ]]; then firewall-cmd --permanent --zone=trusted --remove-source=10.8.0.0/24 firewall-cmd --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip" firewall-cmd --permanent --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip" + if grep -qs "server-ipv6" /etc/openvpn/server/server.conf; then + ip6=$(firewall-cmd --direct --get-rules ipv6 nat POSTROUTING | grep '\-s fddd:1194:1194:1194::/64 '"'"'!'"'"' -d fddd:1194:1194:1194::/64' | grep -oE '[^ ]+$') + firewall-cmd --zone=trusted --remove-source=fddd:1194:1194:1194::/64 + firewall-cmd --permanent --zone=trusted --remove-source=fddd:1194:1194:1194::/64 + firewall-cmd --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6" + firewall-cmd --permanent --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6" + fi else systemctl disable --now openvpn-iptables.service rm -f /etc/systemd/system/openvpn-iptables.service @@ -201,22 +208,22 @@ else echo "I need to ask you a few questions before starting setup." echo "You can use the default options and just press enter if you are ok with them." # If system has a single IPv4, it is selected automatically. Else, ask the user - if [[ $(ip addr | grep inet | grep -v inet6 | grep -vEc '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') -eq 1 ]]; then - ip=$(ip addr | grep inet | grep -v inet6 | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') + if [[ $(ip -4 addr | grep inet | grep -vEc '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') -eq 1 ]]; then + ip=$(ip -4 addr | grep inet | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') else - number_of_ips=$(ip addr | grep inet | grep -v inet6 | grep -vEc '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') + number_of_ip=$(ip -4 addr | grep inet | grep -vEc '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') echo - echo "What IPv4 address should the OpenVPN server bind to?" - ip addr | grep inet | grep -v inet6 | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | nl -s ') ' + echo "What IPv4 address should the OpenVPN server use?" + ip -4 addr | grep inet | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | nl -s ') ' read -p "IPv4 address [1]: " ip_number - until [[ -z "$ip_number" || "$ip_number" =~ ^[0-9]+$ && "$ip_number" -le "$number_of_ips" ]]; do + until [[ -z "$ip_number" || "$ip_number" =~ ^[0-9]+$ && "$ip_number" -le "$number_of_ip" ]]; do echo "$ip_number: invalid selection." read -p "IPv4 address [1]: " ip_number done [[ -z "$ip_number" ]] && ip_number="1" - ip=$(ip addr | grep inet | grep -v inet6 | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sed -n "$ip_number"p) + ip=$(ip -4 addr | grep inet | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sed -n "$ip_number"p) fi - # If $IP is a private IP address, the server must be behind NAT + # If $ip is a private IP address, the server must be behind NAT if echo "$ip" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then echo echo "This server is behind NAT. What is the public IPv4 address or hostname?" @@ -224,6 +231,24 @@ else read -p "Public IPv4 address / hostname [$get_public_ip]: " public_ip [ -z "$public_ip" ] && public_ip="$get_public_ip" fi + # If system has a single IPv6, it is selected automatically + if [[ $(ip -6 addr | grep -c 'inet6 [23]') -eq 1 ]]; then + ip6=$(ip -6 addr | grep 'inet6 [23]' | cut -d '/' -f 1 | grep -oE '([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}') + fi + # If system has multiple IPv6, ask the user to select one + if [[ $(ip -6 addr | grep -c 'inet6 [23]') -gt 1 ]]; then + number_of_ip6=$(ip -6 addr | grep -c 'inet6 [23]') + echo + echo "What IPv6 address should the OpenVPN server use?" + ip -6 addr | grep 'inet6 [23]' | cut -d '/' -f 1 | grep -oE '([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}' | nl -s ') ' + read -p "IPv6 address [1]: " ip6_number + until [[ -z "$ip6_number" || "$ip6_number" =~ ^[0-9]+$ && "$ip6_number" -le "$number_of_ip6" ]]; do + echo "$ip6_number: invalid selection." + read -p "IPv6 address [1]: " ip6_number + done + [[ -z "$ip6_number" ]] && ip6_number="1" + ip6=$(ip -6 addr | grep 'inet6 [23]' | cut -d '/' -f 1 | grep -oE '([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}' | sed -n "$ip6_number"p) + fi echo echo "Which protocol do you want for OpenVPN connections?" echo " 1) UDP (recommended)" @@ -326,9 +351,15 @@ dh dh.pem auth SHA512 tls-crypt tc.key topology subnet -server 10.8.0.0 255.255.255.0 -ifconfig-pool-persist ipp.txt" > /etc/openvpn/server/server.conf - echo 'push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server/server.conf +server 10.8.0.0 255.255.255.0" > /etc/openvpn/server/server.conf + # IPv6 + if [[ -z "$ip6" ]]; then + echo 'push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server/server.conf + else + echo 'server-ipv6 fddd:1194:1194:1194::/64' >> /etc/openvpn/server/server.conf + echo 'push "redirect-gateway def1 ipv6 bypass-dhcp"' >> /etc/openvpn/server/server.conf + fi + echo 'ifconfig-pool-persist ipp.txt' >> /etc/openvpn/server/server.conf # DNS case "$dns" in 1|"") @@ -377,6 +408,12 @@ crl-verify crl.pem" >> /etc/openvpn/server/server.conf echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/30-openvpn-forward.conf # Enable without waiting for a reboot or service restart echo 1 > /proc/sys/net/ipv4/ip_forward + if [[ -n "$ip6" ]]; then + # Enable net.ipv6.conf.all.forwarding for the system + echo "net.ipv6.conf.all.forwarding=1" >> /etc/sysctl.d/30-openvpn-forward.conf + # Enable without waiting for a reboot or service restart + echo 1 > /proc/sys/net/ipv6/conf/all/forwarding + fi if pgrep firewalld; then # Using both permanent and not permanent rules to avoid a firewalld # reload. @@ -389,6 +426,12 @@ crl-verify crl.pem" >> /etc/openvpn/server/server.conf # Set NAT for the VPN subnet firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip" firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip" + if [[ -n "$ip6" ]]; then + firewall-cmd --zone=trusted --add-source=fddd:1194:1194:1194::/64 + firewall-cmd --permanent --zone=trusted --add-source=fddd:1194:1194:1194::/64 + firewall-cmd --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6" + firewall-cmd --permanent --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6" + fi else # Create a service to set up persistent iptables rules echo "[Unit] @@ -402,10 +445,18 @@ ExecStart=/sbin/iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCE ExecStop=/sbin/iptables -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $ip ExecStop=/sbin/iptables -D INPUT -p $protocol --dport $port -j ACCEPT ExecStop=/sbin/iptables -D FORWARD -s 10.8.0.0/24 -j ACCEPT -ExecStop=/sbin/iptables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT -RemainAfterExit=yes +ExecStop=/sbin/iptables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" > /etc/systemd/system/openvpn-iptables.service + if [[ -n "$ip6" ]]; then + echo "ExecStart=/sbin/ip6tables -t nat -A POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to $ip6 +ExecStart=/sbin/ip6tables -I FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT +ExecStart=/sbin/ip6tables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT +ExecStop=/sbin/ip6tables -t nat -D POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to $ip6 +ExecStop=/sbin/ip6tables -D FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT +ExecStop=/sbin/ip6tables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" >> /etc/systemd/system/openvpn-iptables.service + fi + echo "RemainAfterExit=yes [Install] -WantedBy=multi-user.target" > /etc/systemd/system/openvpn-iptables.service +WantedBy=multi-user.target" >> /etc/systemd/system/openvpn-iptables.service systemctl enable --now openvpn-iptables.service fi # If SELinux is enabled and a custom port was selected, we need this From 6f9daf49f54c7f564f00a771b2f9b5fd9ac38fb0 Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 16 Apr 2020 23:33:14 +0200 Subject: [PATCH 10/65] Small style improvements --- openvpn-install.sh | 305 ++++++++++++++++++++++----------------------- 1 file changed, 151 insertions(+), 154 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index d3c3f003..fde64896 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -73,137 +73,9 @@ new_client () { } > ~/"$1".ovpn } -if [[ -e /etc/openvpn/server/server.conf ]]; then - while : - do +if [[ ! -e /etc/openvpn/server/server.conf ]]; then clear - echo "Looks like OpenVPN is already installed." - echo - echo "What do you want to do?" - echo " 1) Add a new user" - echo " 2) Revoke an existing user" - echo " 3) Remove OpenVPN" - echo " 4) Exit" - read -p "Select an option: " option - until [[ "$option" =~ ^[1-4]$ ]]; do - echo "$option: invalid selection." - read -p "Select an option: " option - done - case "$option" in - 1) - echo - echo "Tell me a name for the client certificate." - read -p "Client name: " unsanitized_client - client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") - while [[ -z "$client" || -e /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt ]]; do - echo "$client: invalid client name." - read -p "Client name: " unsanitized_client - client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") - done - cd /etc/openvpn/server/easy-rsa/ - EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full "$client" nopass - # Generates the custom client.ovpn - new_client "$client" - echo - echo "Client $client added, configuration is available at:" ~/"$client.ovpn" - exit - ;; - 2) - # This option could be documented a bit better and maybe even be simplified - # ...but what can I say, I want some sleep too - number_of_clients=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep -c "^V") - if [[ "$number_of_clients" = 0 ]]; then - echo - echo "You have no existing clients!" - exit - fi - echo - echo "Select the existing client certificate you want to revoke:" - tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') ' - read -p "Select one client: " client_number - until [[ "$client_number" =~ ^[0-9]+$ && "$client_number" -le "$number_of_clients" ]]; do - echo "$client_number: invalid selection." - read -p "Select one client: " client_number - done - client=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$client_number"p) - echo - read -p "Do you really want to revoke access for client $client? [y/N]: " revoke - until [[ "$revoke" =~ ^[yYnN]*$ ]]; do - echo "$revoke: invalid selection." - read -p "Do you really want to revoke access for client $client? [y/N]: " revoke - done - if [[ "$revoke" =~ ^[yY]$ ]]; then - cd /etc/openvpn/server/easy-rsa/ - ./easyrsa --batch revoke "$client" - EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl - rm -f /etc/openvpn/server/crl.pem - cp /etc/openvpn/server/easy-rsa/pki/crl.pem /etc/openvpn/server/crl.pem - # CRL is read with each client connection, when OpenVPN is dropped to nobody - chown nobody:"$group_name" /etc/openvpn/server/crl.pem - echo - echo "Certificate for client $client revoked!" - else - echo - echo "Certificate revocation for client $client aborted!" - fi - exit - ;; - 3) - echo - read -p "Do you really want to remove OpenVPN? [y/N]: " remove - until [[ "$remove" =~ ^[yYnN]*$ ]]; do - echo "$remove: invalid selection." - read -p "Do you really want to remove OpenVPN? [y/N]: " remove - done - if [[ "$remove" =~ ^[yY]$ ]]; then - port=$(grep '^port ' /etc/openvpn/server/server.conf | cut -d " " -f 2) - protocol=$(grep '^proto ' /etc/openvpn/server/server.conf | cut -d " " -f 2) - if pgrep firewalld; then - ip=$(firewall-cmd --direct --get-rules ipv4 nat POSTROUTING | grep '\-s 10.8.0.0/24 '"'"'!'"'"' -d 10.8.0.0/24' | grep -oE '[^ ]+$') - # Using both permanent and not permanent rules to avoid a firewalld reload. - firewall-cmd --remove-port="$port"/"$protocol" - firewall-cmd --zone=trusted --remove-source=10.8.0.0/24 - firewall-cmd --permanent --remove-port="$port"/"$protocol" - firewall-cmd --permanent --zone=trusted --remove-source=10.8.0.0/24 - firewall-cmd --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip" - firewall-cmd --permanent --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip" - if grep -qs "server-ipv6" /etc/openvpn/server/server.conf; then - ip6=$(firewall-cmd --direct --get-rules ipv6 nat POSTROUTING | grep '\-s fddd:1194:1194:1194::/64 '"'"'!'"'"' -d fddd:1194:1194:1194::/64' | grep -oE '[^ ]+$') - firewall-cmd --zone=trusted --remove-source=fddd:1194:1194:1194::/64 - firewall-cmd --permanent --zone=trusted --remove-source=fddd:1194:1194:1194::/64 - firewall-cmd --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6" - firewall-cmd --permanent --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6" - fi - else - systemctl disable --now openvpn-iptables.service - rm -f /etc/systemd/system/openvpn-iptables.service - fi - if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then - semanage port -d -t openvpn_port_t -p "$protocol" "$port" - fi - systemctl disable --now openvpn-server@server.service - rm -rf /etc/openvpn/server - rm -f /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf - rm -f /etc/sysctl.d/30-openvpn-forward.conf - if [[ "$os" = "debian" ]]; then - apt-get remove --purge -y openvpn - else - yum remove openvpn -y - fi - echo - echo "OpenVPN removed!" - else - echo - echo "Removal aborted!" - fi - exit - ;; - 4) exit;; - esac - done -else - clear - echo "Welcome to this OpenVPN "road warrior" installer!" + echo 'Welcome to this OpenVPN road warrior installer!' echo echo "I need to ask you a few questions before starting setup." echo "You can use the default options and just press enter if you are ok with them." @@ -229,7 +101,7 @@ else echo "This server is behind NAT. What is the public IPv4 address or hostname?" get_public_ip=$(wget -4qO- "http://whatismyip.akamai.com/" || curl -4Ls "http://whatismyip.akamai.com/") read -p "Public IPv4 address / hostname [$get_public_ip]: " public_ip - [ -z "$public_ip" ] && public_ip="$get_public_ip" + [[ -z "$public_ip" ]] && public_ip="$get_public_ip" fi # If system has a single IPv6, it is selected automatically if [[ $(ip -6 addr | grep -c 'inet6 [23]') -eq 1 ]]; then @@ -363,33 +235,33 @@ server 10.8.0.0 255.255.255.0" > /etc/openvpn/server/server.conf # DNS 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 - resolv_conf="/run/systemd/resolve/resolv.conf" - else - resolv_conf="/etc/resolv.conf" - fi - # Obtain the resolvers from resolv.conf and use them for OpenVPN - grep -v '#' "$resolv_conf" | grep nameserver | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | while read line; do - echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server/server.conf - done + # Locate the proper resolv.conf + # Needed for systems running systemd-resolved + if grep -q "127.0.0.53" "/etc/resolv.conf"; then + resolv_conf="/run/systemd/resolve/resolv.conf" + else + resolv_conf="/etc/resolv.conf" + fi + # Obtain the resolvers from resolv.conf and use them for OpenVPN + grep -v '#' "$resolv_conf" | grep nameserver | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | while read line; do + echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server/server.conf + done ;; 2) - echo 'push "dhcp-option DNS 1.1.1.1"' >> /etc/openvpn/server/server.conf - echo 'push "dhcp-option DNS 1.0.0.1"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 1.1.1.1"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 1.0.0.1"' >> /etc/openvpn/server/server.conf ;; 3) - echo 'push "dhcp-option DNS 8.8.8.8"' >> /etc/openvpn/server/server.conf - echo 'push "dhcp-option DNS 8.8.4.4"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 8.8.8.8"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 8.8.4.4"' >> /etc/openvpn/server/server.conf ;; 4) - echo 'push "dhcp-option DNS 208.67.222.222"' >> /etc/openvpn/server/server.conf - echo 'push "dhcp-option DNS 208.67.220.220"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 208.67.222.222"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 208.67.220.220"' >> /etc/openvpn/server/server.conf ;; 5) - echo 'push "dhcp-option DNS 64.6.64.6"' >> /etc/openvpn/server/server.conf - echo 'push "dhcp-option DNS 64.6.65.6"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 64.6.64.6"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 64.6.65.6"' >> /etc/openvpn/server/server.conf ;; esac echo "keepalive 10 120 @@ -471,10 +343,8 @@ WantedBy=multi-user.target" >> /etc/systemd/system/openvpn-iptables.service fi semanage port -a -t openvpn_port_t -p "$protocol" "$port" fi - # If the server is behind a NAT, use the correct IP address - if [[ "$public_ip" != "" ]]; then - ip="$public_ip" - fi + # If the server is behind NAT, use the correct IP address + [[ ! -z "$public_ip" ]] && ip="$public_ip" # client-common.txt is created so we have a template to add further users later echo "client dev tun @@ -499,4 +369,131 @@ verb 3" > /etc/openvpn/server/client-common.txt echo echo "Your client configuration is available at:" ~/"$client.ovpn" echo "If you want to add more clients, just run this script again!" +else + clear + echo "Looks like OpenVPN is already installed." + echo + echo "What do you want to do?" + echo " 1) Add a new user" + echo " 2) Revoke an existing user" + echo " 3) Remove OpenVPN" + echo " 4) Exit" + read -p "Select an option: " option + until [[ "$option" =~ ^[1-4]$ ]]; do + echo "$option: invalid selection." + read -p "Select an option: " option + done + case "$option" in + 1) + echo + echo "Tell me a name for the client certificate." + read -p "Client name: " unsanitized_client + client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") + while [[ -z "$client" || -e /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt ]]; do + echo "$client: invalid client name." + read -p "Client name: " unsanitized_client + client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") + done + cd /etc/openvpn/server/easy-rsa/ + EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full "$client" nopass + # Generates the custom client.ovpn + new_client "$client" + echo + echo "Client $client added, configuration is available at:" ~/"$client.ovpn" + exit + ;; + 2) + # This option could be documented a bit better and maybe even be simplified + # ...but what can I say, I want some sleep too + number_of_clients=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep -c "^V") + if [[ "$number_of_clients" = 0 ]]; then + echo + echo "You have no existing clients!" + exit + fi + echo + echo "Select the existing client certificate you want to revoke:" + tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') ' + read -p "Select one client: " client_number + until [[ "$client_number" =~ ^[0-9]+$ && "$client_number" -le "$number_of_clients" ]]; do + echo "$client_number: invalid selection." + read -p "Select one client: " client_number + done + client=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$client_number"p) + echo + read -p "Do you really want to revoke access for client $client? [y/N]: " revoke + until [[ "$revoke" =~ ^[yYnN]*$ ]]; do + echo "$revoke: invalid selection." + read -p "Do you really want to revoke access for client $client? [y/N]: " revoke + done + if [[ "$revoke" =~ ^[yY]$ ]]; then + cd /etc/openvpn/server/easy-rsa/ + ./easyrsa --batch revoke "$client" + EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl + rm -f /etc/openvpn/server/crl.pem + cp /etc/openvpn/server/easy-rsa/pki/crl.pem /etc/openvpn/server/crl.pem + # CRL is read with each client connection, when OpenVPN is dropped to nobody + chown nobody:"$group_name" /etc/openvpn/server/crl.pem + echo + echo "Certificate for client $client revoked!" + else + echo + echo "Certificate revocation for client $client aborted!" + fi + exit + ;; + 3) + echo + read -p "Do you really want to remove OpenVPN? [y/N]: " remove + until [[ "$remove" =~ ^[yYnN]*$ ]]; do + echo "$remove: invalid selection." + read -p "Do you really want to remove OpenVPN? [y/N]: " remove + done + if [[ "$remove" =~ ^[yY]$ ]]; then + port=$(grep '^port ' /etc/openvpn/server/server.conf | cut -d " " -f 2) + protocol=$(grep '^proto ' /etc/openvpn/server/server.conf | cut -d " " -f 2) + if pgrep firewalld; then + ip=$(firewall-cmd --direct --get-rules ipv4 nat POSTROUTING | grep '\-s 10.8.0.0/24 '"'"'!'"'"' -d 10.8.0.0/24' | grep -oE '[^ ]+$') + # Using both permanent and not permanent rules to avoid a firewalld reload. + firewall-cmd --remove-port="$port"/"$protocol" + firewall-cmd --zone=trusted --remove-source=10.8.0.0/24 + firewall-cmd --permanent --remove-port="$port"/"$protocol" + firewall-cmd --permanent --zone=trusted --remove-source=10.8.0.0/24 + firewall-cmd --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip" + firewall-cmd --permanent --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip" + if grep -qs "server-ipv6" /etc/openvpn/server/server.conf; then + ip6=$(firewall-cmd --direct --get-rules ipv6 nat POSTROUTING | grep '\-s fddd:1194:1194:1194::/64 '"'"'!'"'"' -d fddd:1194:1194:1194::/64' | grep -oE '[^ ]+$') + firewall-cmd --zone=trusted --remove-source=fddd:1194:1194:1194::/64 + firewall-cmd --permanent --zone=trusted --remove-source=fddd:1194:1194:1194::/64 + firewall-cmd --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6" + firewall-cmd --permanent --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6" + fi + else + systemctl disable --now openvpn-iptables.service + rm -f /etc/systemd/system/openvpn-iptables.service + fi + if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then + semanage port -d -t openvpn_port_t -p "$protocol" "$port" + fi + systemctl disable --now openvpn-server@server.service + rm -rf /etc/openvpn/server + rm -f /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf + rm -f /etc/sysctl.d/30-openvpn-forward.conf + if [[ "$os" = "debian" ]]; then + apt-get remove --purge -y openvpn + else + yum remove openvpn -y + fi + echo + echo "OpenVPN removed!" + else + echo + echo "Removal aborted!" + fi + exit + ;; + 4) + exit + ;; + esac fi From c6159aefb8cd6b065062a419f681e84af47ba425 Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 16 Apr 2020 23:42:11 +0200 Subject: [PATCH 11/65] Update DNS providers - Verisign removed (performance is subpar compared to competitors) - NTT is back (fast and reliable) - AdGuard added (for ad blocking) --- openvpn-install.sh | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index fde64896..d64b47a6 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -152,9 +152,10 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then echo " 2) 1.1.1.1" echo " 3) Google" echo " 4) OpenDNS" - echo " 5) Verisign" + echo " 5) NTT" + echo " 6) AdGuard" read -p "DNS [1]: " dns - until [[ -z "$dns" || "$dns" =~ ^[1-5]$ ]]; do + until [[ -z "$dns" || "$dns" =~ ^[1-6]$ ]]; do echo "$dns: invalid selection." read -p "DNS [1]: " dns done @@ -260,8 +261,12 @@ server 10.8.0.0 255.255.255.0" > /etc/openvpn/server/server.conf echo 'push "dhcp-option DNS 208.67.220.220"' >> /etc/openvpn/server/server.conf ;; 5) - echo 'push "dhcp-option DNS 64.6.64.6"' >> /etc/openvpn/server/server.conf - echo 'push "dhcp-option DNS 64.6.65.6"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 129.250.35.250"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 129.250.35.251"' >> /etc/openvpn/server/server.conf + ;; + 6) + echo 'push "dhcp-option DNS 176.103.130.130"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 176.103.130.131"' >> /etc/openvpn/server/server.conf ;; esac echo "keepalive 10 120 From cec053def4aea0c8c9bc9cc4fcc4ce3def2d5695 Mon Sep 17 00:00:00 2001 From: Nyr Date: Tue, 21 Apr 2020 02:28:29 +0200 Subject: [PATCH 12/65] Miscellaneous improvements - Fix #694: added sanitization during the public IP address configuration and switch to AWS checkip since the Akamai service doesn't support HTTPS. - Add validation to cover an unlikely case where: server is behind NAT, checkip service is unreachable and user doesn't provide input when asked for the public IP address or hostname. - Other small improvements not worth describing in detail. --- README.md | 2 +- openvpn-install.sh | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index cad322c4..3c08cc51 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## openvpn-install OpenVPN [road warrior](http://en.wikipedia.org/wiki/Road_warrior_%28computing%29) installer for Debian, Ubuntu and CentOS. -This script will let you setup your own VPN server in no more than a minute, even if you haven't used OpenVPN before. It has been designed to be as unobtrusive and universal as possible. +This script will let you set up your own VPN server in no more than a minute, even if you haven't used OpenVPN before. It has been designed to be as unobtrusive and universal as possible. ### Installation Run the script and follow the assistant: diff --git a/openvpn-install.sh b/openvpn-install.sh index d64b47a6..f5c1c388 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -62,15 +62,15 @@ new_client () { cat /etc/openvpn/server/easy-rsa/pki/ca.crt echo "" echo "" - sed -ne '/BEGIN CERTIFICATE/,$ p' /etc/openvpn/server/easy-rsa/pki/issued/"$1".crt + sed -ne '/BEGIN CERTIFICATE/,$ p' /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt echo "" echo "" - cat /etc/openvpn/server/easy-rsa/pki/private/"$1".key + cat /etc/openvpn/server/easy-rsa/pki/private/"$client".key echo "" echo "" sed -ne '/BEGIN OpenVPN Static key/,$ p' /etc/openvpn/server/tc.key echo "" - } > ~/"$1".ovpn + } > ~/"$client".ovpn } if [[ ! -e /etc/openvpn/server/server.conf ]]; then @@ -99,8 +99,14 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then if echo "$ip" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then echo echo "This server is behind NAT. What is the public IPv4 address or hostname?" - get_public_ip=$(wget -4qO- "http://whatismyip.akamai.com/" || curl -4Ls "http://whatismyip.akamai.com/") + # Get public IP and sanitize with grep + get_public_ip=$(grep -oE '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' <<< "$(wget -T 5 -t 1 -4qO- "https://checkip.amazonaws.com/" || curl -m 5 -4Ls "https://checkip.amazonaws.com/")") read -p "Public IPv4 address / hostname [$get_public_ip]: " public_ip + # If the checkip service is unavailable and user didn't provide input, ask again + until [[ -n "$get_public_ip" || -n $public_ip ]]; do + echo "Invalid input." + read -p "Public IPv4 address / hostname: " public_ip + done [[ -z "$public_ip" ]] && public_ip="$get_public_ip" fi # If system has a single IPv6, it is selected automatically @@ -142,7 +148,7 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then echo "What port do you want OpenVPN listening to?" read -p "Port [1194]: " port until [[ -z "$port" || "$port" =~ ^[0-9]+$ && "$port" -le 65535 ]]; do - echo "$port: invalid selection." + echo "$port: invalid port." read -p "Port [1194]: " port done [[ -z "$port" ]] && port="1194" @@ -368,7 +374,7 @@ verb 3" > /etc/openvpn/server/client-common.txt # Enable and start the OpenVPN service systemctl enable --now openvpn-server@server.service # Generates the custom client.ovpn - new_client "$client" + new_client echo echo "Finished!" echo @@ -402,7 +408,7 @@ else cd /etc/openvpn/server/easy-rsa/ EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full "$client" nopass # Generates the custom client.ovpn - new_client "$client" + new_client echo echo "Client $client added, configuration is available at:" ~/"$client.ovpn" exit From f659724a6f222bfbd03f5399426f2dbe97ec5f6b Mon Sep 17 00:00:00 2001 From: Nyr Date: Tue, 21 Apr 2020 16:45:49 +0200 Subject: [PATCH 13/65] Addresses #694 - Use a checkip service which works fine over HTTP to avoid issues in systems where ca-certificates is not available - Increase timeout to 10 seconds, because the new service is a bit slower from some locations - Improve grep sanitization --- openvpn-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index f5c1c388..d35419c4 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -100,7 +100,7 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then echo echo "This server is behind NAT. What is the public IPv4 address or hostname?" # Get public IP and sanitize with grep - get_public_ip=$(grep -oE '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' <<< "$(wget -T 5 -t 1 -4qO- "https://checkip.amazonaws.com/" || curl -m 5 -4Ls "https://checkip.amazonaws.com/")") + get_public_ip=$(grep -m 1 -oE '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' <<< "$(wget -T 10 -t 1 -4qO- "http://ip1.dynupdate.no-ip.com/" || curl -m 10 -4Ls "http://ip1.dynupdate.no-ip.com/")") read -p "Public IPv4 address / hostname [$get_public_ip]: " public_ip # If the checkip service is unavailable and user didn't provide input, ask again until [[ -n "$get_public_ip" || -n $public_ip ]]; do From 11b929ac82fc0854edaecc86d849e8b6eca1fe0d Mon Sep 17 00:00:00 2001 From: Nyr Date: Fri, 24 Apr 2020 17:48:24 +0200 Subject: [PATCH 14/65] Reworked OS detection - Made OS detection more flexible and fine-grained - Fedora is now officially supported --- README.md | 2 +- openvpn-install.sh | 82 ++++++++++++++++++++++++++-------------------- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 3c08cc51..f48d81a6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ## openvpn-install -OpenVPN [road warrior](http://en.wikipedia.org/wiki/Road_warrior_%28computing%29) installer for Debian, Ubuntu and CentOS. +OpenVPN [road warrior](http://en.wikipedia.org/wiki/Road_warrior_%28computing%29) installer for Ubuntu, Debian, CentOS and Fedora. This script will let you set up your own VPN server in no more than a minute, even if you haven't used OpenVPN before. It has been designed to be as unobtrusive and universal as possible. diff --git a/openvpn-install.sh b/openvpn-install.sh index d35419c4..2b21209a 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -5,35 +5,55 @@ # Copyright (c) 2013 Nyr. Released under the MIT License. -if grep -qs "14.04" /etc/os-release; then - echo "Ubuntu 14.04 is too old and not supported" +# Detect Debian users running the script with "sh" instead of bash +if readlink /proc/$$/exe | grep -q "dash"; then + echo "This script needs to be run with bash, not sh" exit fi -if grep -qs "jessie" /etc/os-release; then - echo "Debian 8 is too old and not supported" +if [[ "$EUID" -ne 0 ]]; then + echo "Sorry, you need to run this as root" exit fi -if grep -qs "CentOS release 6" /etc/redhat-release; then - echo "CentOS 6 is too old and not supported" +# Detect OS +# $os_version variables aren't always in use, but are kept here for convenience +if grep -qs "ubuntu" /etc/os-release; then + os="ubuntu" + os_version=$(grep 'VERSION_ID' /etc/os-release | cut -d '"' -f 2 | tr -d '.') + group_name="nogroup" +elif [[ -e /etc/debian_version ]]; then + os="debian" + os_version=$(grep -oE '[0-9]+' /etc/debian_version | head -1) + group_name="nogroup" +elif [[ -e /etc/centos-release ]]; then + os="centos" + os_version=$(grep -oE '[0-9]+' /etc/centos-release | head -1) + group_name="nobody" +elif [[ -e /etc/fedora-release ]]; then + os="fedora" + os_version=$(grep -oE '[0-9]+' /etc/fedora-release | head -1) + group_name="nobody" +else + echo "Looks like you aren't running this installer on Ubuntu, Debian, CentOS or Fedora" exit fi -if grep -qs "Ubuntu 16.04" /etc/os-release; then - echo 'Ubuntu 16.04 is no longer supported in the current version of openvpn-install -Use an older version if Ubuntu 16.04 support is needed: https://git.io/vpn1604' +if [[ "$os" == "ubuntu" && "$os_version" -lt 1804 ]]; then + echo "Ubuntu 18.04 or higher is required to use this installer +This version of Ubuntu is too old and unsupported" exit fi -# Detect Debian users running the script with "sh" instead of bash -if readlink /proc/$$/exe | grep -q "dash"; then - echo "This script needs to be run with bash, not sh" +if [[ "$os" == "debian" && "$os_version" -lt 9 ]]; then + echo "Debian 9 or higher is required to use this installer +This version of Debian is too old and unsupported" exit fi -if [[ "$EUID" -ne 0 ]]; then - echo "Sorry, you need to run this as root" +if [[ "$os" == "centos" && "$os_version" -lt 7 ]]; then + echo "CentOS 7 or higher is required to use this installer +This version of CentOS is too old and unsupported" exit fi @@ -43,17 +63,6 @@ You need to enable TUN before running this script" exit fi -if [[ -e /etc/debian_version ]]; then - os="debian" - group_name="nogroup" -elif [[ -e /etc/centos-release || -e /etc/redhat-release ]]; then - os="centos" - group_name="nobody" -else - echo "Looks like you aren't running this installer on Debian, Ubuntu or CentOS" - exit -fi - new_client () { # Generates the custom client.ovpn { @@ -180,13 +189,15 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then echo "[Service] LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf fi - if [[ "$os" = "debian" ]]; then + if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then apt-get update - apt-get install openvpn iptables openssl ca-certificates -y + apt-get install -y openvpn iptables openssl ca-certificates + elif [[ "$os" = "centos" ]]; then + yum install -y epel-release + yum install -y openvpn iptables openssl ca-certificates tar else - # Else, the distro is CentOS - yum install epel-release -y - yum install openvpn iptables openssl ca-certificates tar -y + # Else, OS must be Fedora + dnf install -y openvpn iptables openssl ca-certificates tar fi # Get easy-rsa easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.7/EasyRSA-3.0.7.tgz' @@ -346,10 +357,10 @@ WantedBy=multi-user.target" >> /etc/systemd/system/openvpn-iptables.service if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then # Install semanage if not already present if ! hash semanage 2>/dev/null; then - if grep -qs "CentOS Linux release 7" "/etc/centos-release"; then - yum install policycoreutils-python -y + if [[ "$os_version" -eq 7 ]]; then + yum install -y policycoreutils-python else - yum install policycoreutils-python-utils -y + yum install -y policycoreutils-python-utils fi fi semanage port -a -t openvpn_port_t -p "$protocol" "$port" @@ -490,10 +501,11 @@ else rm -rf /etc/openvpn/server rm -f /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf rm -f /etc/sysctl.d/30-openvpn-forward.conf - if [[ "$os" = "debian" ]]; then + if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then apt-get remove --purge -y openvpn else - yum remove openvpn -y + # Else, OS must be CentOS or Fedora + yum remove -y openvpn fi echo echo "OpenVPN removed!" From e0fa45b688a6d64708194791848759e46ebc5db3 Mon Sep 17 00:00:00 2001 From: Nyr Date: Wed, 29 Apr 2020 13:24:55 +0200 Subject: [PATCH 15/65] Fixes #642 --- openvpn-install.sh | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 2b21209a..86f6e1d5 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -328,25 +328,27 @@ crl-verify crl.pem" >> /etc/openvpn/server/server.conf fi else # Create a service to set up persistent iptables rules + iptables_path=$(command -v iptables) + ip6tables_path=$(command -v ip6tables) echo "[Unit] Before=network.target [Service] Type=oneshot -ExecStart=/sbin/iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $ip -ExecStart=/sbin/iptables -I INPUT -p $protocol --dport $port -j ACCEPT -ExecStart=/sbin/iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT -ExecStart=/sbin/iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT -ExecStop=/sbin/iptables -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $ip -ExecStop=/sbin/iptables -D INPUT -p $protocol --dport $port -j ACCEPT -ExecStop=/sbin/iptables -D FORWARD -s 10.8.0.0/24 -j ACCEPT -ExecStop=/sbin/iptables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" > /etc/systemd/system/openvpn-iptables.service +ExecStart=$iptables_path -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $ip +ExecStart=$iptables_path -I INPUT -p $protocol --dport $port -j ACCEPT +ExecStart=$iptables_path -I FORWARD -s 10.8.0.0/24 -j ACCEPT +ExecStart=$iptables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT +ExecStop=$iptables_path -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $ip +ExecStop=$iptables_path -D INPUT -p $protocol --dport $port -j ACCEPT +ExecStop=$iptables_path -D FORWARD -s 10.8.0.0/24 -j ACCEPT +ExecStop=$iptables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" > /etc/systemd/system/openvpn-iptables.service if [[ -n "$ip6" ]]; then echo "ExecStart=/sbin/ip6tables -t nat -A POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to $ip6 -ExecStart=/sbin/ip6tables -I FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT -ExecStart=/sbin/ip6tables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT -ExecStop=/sbin/ip6tables -t nat -D POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to $ip6 -ExecStop=/sbin/ip6tables -D FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT -ExecStop=/sbin/ip6tables -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" >> /etc/systemd/system/openvpn-iptables.service +ExecStart=$ip6tables_path -I FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT +ExecStart=$ip6tables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT +ExecStop=$ip6tables_path -t nat -D POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to $ip6 +ExecStop=$ip6tables_path -D FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT +ExecStop=$ip6tables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" >> /etc/systemd/system/openvpn-iptables.service fi echo "RemainAfterExit=yes [Install] From ef30d9863c0f858acee2e8ca6a17d60eaec608a0 Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 30 Apr 2020 00:28:27 +0200 Subject: [PATCH 16/65] Improved firewall management - Always use firewalld for CentOS and Fedora - Cleaner check to find out if firewalld is active --- openvpn-install.sh | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 86f6e1d5..943abeb5 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -181,7 +181,15 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") [[ -z "$client" ]] && client="client" echo - echo "Okay, that was all I needed. We are ready to set up your OpenVPN server now." + echo "We are ready to set up your OpenVPN server now." + # DigitalOcean ships their CentOS and Fedora images without firewalld + # We don't want to silently enable a firewall, so we give a subtle warning + # If the user continues, firewalld will be installed and enabled during setup + if [[ "$os" == "centos" || "$os" == "fedora" ]] && ! systemctl is-active --quiet firewalld.service; then + echo + echo "firewalld, which is required to manage routing tables, will also be installed." + fi + echo read -n1 -r -p "Press any key to continue..." # If running inside a container, disable LimitNPROC to prevent conflicts if systemd-detect-virt -cq; then @@ -194,10 +202,12 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab apt-get install -y openvpn iptables openssl ca-certificates elif [[ "$os" = "centos" ]]; then yum install -y epel-release - yum install -y openvpn iptables openssl ca-certificates tar + yum install -y openvpn firewalld openssl ca-certificates tar + systemctl enable --now firewalld.service else # Else, OS must be Fedora - dnf install -y openvpn iptables openssl ca-certificates tar + dnf install -y openvpn firewalld openssl ca-certificates tar + systemctl enable --now firewalld.service fi # Get easy-rsa easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.7/EasyRSA-3.0.7.tgz' @@ -308,7 +318,7 @@ crl-verify crl.pem" >> /etc/openvpn/server/server.conf # Enable without waiting for a reboot or service restart echo 1 > /proc/sys/net/ipv6/conf/all/forwarding fi - if pgrep firewalld; then + if systemctl is-active --quiet firewalld.service; then # Using both permanent and not permanent rules to avoid a firewalld # reload. # We don't use --add-service=openvpn because that would only work with @@ -360,9 +370,11 @@ WantedBy=multi-user.target" >> /etc/systemd/system/openvpn-iptables.service # Install semanage if not already present if ! hash semanage 2>/dev/null; then if [[ "$os_version" -eq 7 ]]; then + # Centos 7 yum install -y policycoreutils-python else - yum install -y policycoreutils-python-utils + # CentOS 8 or Fedora + dnf install -y policycoreutils-python-utils fi fi semanage port -a -t openvpn_port_t -p "$protocol" "$port" @@ -476,7 +488,7 @@ else if [[ "$remove" =~ ^[yY]$ ]]; then port=$(grep '^port ' /etc/openvpn/server/server.conf | cut -d " " -f 2) protocol=$(grep '^proto ' /etc/openvpn/server/server.conf | cut -d " " -f 2) - if pgrep firewalld; then + if systemctl is-active --quiet firewalld.service; then ip=$(firewall-cmd --direct --get-rules ipv4 nat POSTROUTING | grep '\-s 10.8.0.0/24 '"'"'!'"'"' -d 10.8.0.0/24' | grep -oE '[^ ]+$') # Using both permanent and not permanent rules to avoid a firewalld reload. firewall-cmd --remove-port="$port"/"$protocol" From 61549ffcefcc372dc0ecaca889e5b55c9552c80a Mon Sep 17 00:00:00 2001 From: Nyr Date: Fri, 1 May 2020 17:52:12 +0200 Subject: [PATCH 17/65] Improved firewall installation logic New logic makes way more sense: - If either firewalld or iptables are present, use whatever we have - If not, install firewalld in CentOS/Fedora and iptables in Debian/Ubuntu --- openvpn-install.sh | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 943abeb5..34f54d0b 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -182,12 +182,18 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then [[ -z "$client" ]] && client="client" echo echo "We are ready to set up your OpenVPN server now." - # DigitalOcean ships their CentOS and Fedora images without firewalld - # We don't want to silently enable a firewall, so we give a subtle warning - # If the user continues, firewalld will be installed and enabled during setup - if [[ "$os" == "centos" || "$os" == "fedora" ]] && ! systemctl is-active --quiet firewalld.service; then - echo - echo "firewalld, which is required to manage routing tables, will also be installed." + # Install a firewall in the rare case where one is not already available + if ! systemctl is-active --quiet firewalld.service && ! hash iptables 2>/dev/null; then + if [[ "$os" == "centos" || "$os" == "fedora" ]]; then + firewall="firewalld" + # We don't want to silently enable firewalld, so we give a subtle warning + # If the user continues, firewalld will be installed and enabled during setup + echo + echo "firewalld, which is required to manage routing tables, will also be installed." + elif [[ "$os" == "debian" || "$os" == "ubuntu" ]]; then + # iptables is way less invasive than firewalld so no warning is given + firewall="iptables" + fi fi echo read -n1 -r -p "Press any key to continue..." @@ -199,14 +205,16 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab fi if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then apt-get update - apt-get install -y openvpn iptables openssl ca-certificates + apt-get install -y openvpn openssl ca-certificates $firewall elif [[ "$os" = "centos" ]]; then yum install -y epel-release - yum install -y openvpn firewalld openssl ca-certificates tar - systemctl enable --now firewalld.service + yum install -y openvpn openssl ca-certificates tar $firewall else # Else, OS must be Fedora - dnf install -y openvpn firewalld openssl ca-certificates tar + dnf install -y openvpn openssl ca-certificates tar $firewall + fi + # If firewalld was just installed, enable it + if [[ "$firewall" == "firewalld" ]]; then systemctl enable --now firewalld.service fi # Get easy-rsa From 025148c245bd2b471b28c781b8d95c2133497ff5 Mon Sep 17 00:00:00 2001 From: randomshell Date: Sun, 3 May 2020 13:26:37 +0000 Subject: [PATCH 18/65] Use openvpn status path from systemd service The new systemd service at `/usr/lib/systemd/system/openvpn-server@.service` that comes with openvpn 2.4 includes the status option in `ExecStart=/usr/sbin/openvpn --status %t/openvpn-server/status-%i.log --status-version 2 --suppress-timestamps --config %i.conf` Using this default allows to have multiple servers with their own status files and all in the same log directory. Example `/run/openvpn-server/status-server.log` `/run/openvpn-server/status-server2.log` --- openvpn-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 34f54d0b..818fe3da 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -310,7 +310,6 @@ user nobody group $group_name persist-key persist-tun -status openvpn-status.log verb 3 crl-verify crl.pem" >> /etc/openvpn/server/server.conf if [[ "$protocol" = "udp" ]]; then From 2852150a5b7d611cb59dcfafbf900a8948a3210e Mon Sep 17 00:00:00 2001 From: Nyr Date: Tue, 5 May 2020 16:47:25 +0200 Subject: [PATCH 19/65] OpenVZ nf_tables workaround nf_tables is not available in old OpenVZ kernels, so we need to use iptables-legacy instead. This issue only affects Debian 10 as it is the only distribution using iptables with a nf_tables backend by default. This is supposedly resolved in the newest kernels: https://bit.ly/3fgNZCh Additionally, a bugfix for the ip6tables path is also included. --- openvpn-install.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 34f54d0b..aa7e1c72 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -348,6 +348,12 @@ crl-verify crl.pem" >> /etc/openvpn/server/server.conf # Create a service to set up persistent iptables rules iptables_path=$(command -v iptables) ip6tables_path=$(command -v ip6tables) + # Old OpenVZ kernels don't have nf_tables support + # iptables-nft is the default in Debian 10, but we need to use iptables-legacy + if [[ "$os" == "debian" && "$os_version" -eq 10 && "$(systemd-detect-virt)" == "openvz" ]]; then + iptables_path=$(command -v iptables-legacy) + ip6tables_path=$(command -v ip6tables-legacy) + fi echo "[Unit] Before=network.target [Service] @@ -361,7 +367,7 @@ ExecStop=$iptables_path -D INPUT -p $protocol --dport $port -j ACCEPT ExecStop=$iptables_path -D FORWARD -s 10.8.0.0/24 -j ACCEPT ExecStop=$iptables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" > /etc/systemd/system/openvpn-iptables.service if [[ -n "$ip6" ]]; then - echo "ExecStart=/sbin/ip6tables -t nat -A POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to $ip6 + echo "ExecStart=$ip6tables_path -t nat -A POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to $ip6 ExecStart=$ip6tables_path -I FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT ExecStart=$ip6tables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT ExecStop=$ip6tables_path -t nat -D POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to $ip6 From 07249185dd5501bb68e196ca1e2df7bbd3f6e700 Mon Sep 17 00:00:00 2001 From: Nyr Date: Tue, 5 May 2020 18:23:21 +0200 Subject: [PATCH 20/65] Improve nf_tables test for OVZ This test is more reliable and flexible. --- openvpn-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index aa7e1c72..f374e799 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -348,9 +348,9 @@ crl-verify crl.pem" >> /etc/openvpn/server/server.conf # Create a service to set up persistent iptables rules iptables_path=$(command -v iptables) ip6tables_path=$(command -v ip6tables) - # Old OpenVZ kernels don't have nf_tables support - # iptables-nft is the default in Debian 10, but we need to use iptables-legacy - if [[ "$os" == "debian" && "$os_version" -eq 10 && "$(systemd-detect-virt)" == "openvz" ]]; then + # nf_tables is not available as standard in OVZ kernels. So use iptables-legacy + # if we are in OVZ, with a nf_tables backend and iptables-legacy is available. + if [[ $(systemd-detect-virt) == "openvz" ]] && readlink -f $(command -v iptables) | grep -q "nft" && hash iptables-legacy 2>/dev/null; then iptables_path=$(command -v iptables-legacy) ip6tables_path=$(command -v ip6tables-legacy) fi From b392e7da8b01d702b61b7b53e81fd062097f9e7e Mon Sep 17 00:00:00 2001 From: Nyr Date: Sun, 10 May 2020 20:02:08 +0200 Subject: [PATCH 21/65] Improved easy-rsa setup No need to write the tarball to disk. --- openvpn-install.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index f374e799..bab1d8da 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -219,12 +219,9 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab fi # Get easy-rsa easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.7/EasyRSA-3.0.7.tgz' - wget -O ~/easyrsa.tgz "$easy_rsa_url" 2>/dev/null || curl -Lo ~/easyrsa.tgz "$easy_rsa_url" - tar xzf ~/easyrsa.tgz -C ~/ - mv ~/EasyRSA-3.0.7/ /etc/openvpn/server/ - mv /etc/openvpn/server/EasyRSA-3.0.7/ /etc/openvpn/server/easy-rsa/ + mkdir -p /etc/openvpn/server/easy-rsa/ + { wget -qO- "$easy_rsa_url" 2>/dev/null || curl -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1 chown -R root:root /etc/openvpn/server/easy-rsa/ - rm -f ~/easyrsa.tgz cd /etc/openvpn/server/easy-rsa/ # Create the PKI, set up the CA and the server and client certificates ./easyrsa init-pki From d30e11d019c80648b17d7f76eb81aba4ea8f742a Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 14 May 2020 19:05:05 +0200 Subject: [PATCH 22/65] Improve TUN device check While it looks hackish, I don't think there's a better way (in Bash) to open the /dev/net/tun character device. Checking for presence of /dev/net/tun like were doing is not good enough. --- openvpn-install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index bab1d8da..c87a88d9 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -57,9 +57,11 @@ This version of CentOS is too old and unsupported" exit fi -if [[ ! -e /dev/net/tun ]]; then - echo "The TUN device is not available -You need to enable TUN before running this script" +if [[ -e /dev/net/tun ]] && exec 2>/dev/null 7<>/dev/net/tun; then + exec 7>&- +else + echo "This system does not have the TUN device available +TUN needs to be enabled before running this installer" exit fi From db0b51228b75b8350a283fa7aff872bffa8f0822 Mon Sep 17 00:00:00 2001 From: Nyr Date: Fri, 15 May 2020 18:19:24 +0200 Subject: [PATCH 23/65] Fix TUN device check Fix for the mistaken stderr redirection, sorry about that. Also, run in a subshell so we don't need to manually close the file descriptor. --- openvpn-install.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index c87a88d9..e9808a6f 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -57,9 +57,7 @@ This version of CentOS is too old and unsupported" exit fi -if [[ -e /dev/net/tun ]] && exec 2>/dev/null 7<>/dev/net/tun; then - exec 7>&- -else +if [[ ! -e /dev/net/tun ]] || ! ( exec 7<>/dev/net/tun ) 2>/dev/null; then echo "This system does not have the TUN device available TUN needs to be enabled before running this installer" exit From e14c2359c80f0418967c1ca468a95c10200dfe9b Mon Sep 17 00:00:00 2001 From: Nyr Date: Wed, 20 May 2020 12:09:50 +0200 Subject: [PATCH 24/65] Small improvements --- openvpn-install.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/openvpn-install.sh b/openvpn-install.sh index e9808a6f..b6e19855 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -5,6 +5,9 @@ # Copyright (c) 2013 Nyr. Released under the MIT License. +# Discard stdin. Needed when running from an one-liner which includes a newline +read -N 999999999 -t 0.001 + # Detect Debian users running the script with "sh" instead of bash if readlink /proc/$$/exe | grep -q "dash"; then echo "This script needs to be run with bash, not sh" @@ -16,6 +19,12 @@ if [[ "$EUID" -ne 0 ]]; then exit fi +# Detect OpenVZ 6 +if [[ $(uname -r | cut -d "." -f 1) -eq 2 ]]; then + echo "The system is running an old kernel, which is incompatible with this installer" + exit +fi + # Detect OS # $os_version variables aren't always in use, but are kept here for convenience if grep -qs "ubuntu" /etc/os-release; then @@ -63,6 +72,13 @@ TUN needs to be enabled before running this installer" exit fi +# Detect environments where $PATH does not include the sbin directories +if ! grep -q sbin <<< $PATH; then + echo '$PATH does not include sbin +Try using "su -" instead of "su"' + exit +fi + new_client () { # Generates the custom client.ovpn { From 6f155b997dabd35b06b87785e6bc0fc5c9b863a4 Mon Sep 17 00:00:00 2001 From: Nyr Date: Wed, 20 May 2020 23:33:16 +0200 Subject: [PATCH 25/65] Grammar improvements --- openvpn-install.sh | 97 ++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 51 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index b6e19855..01b5ea8b 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -10,18 +10,18 @@ read -N 999999999 -t 0.001 # Detect Debian users running the script with "sh" instead of bash if readlink /proc/$$/exe | grep -q "dash"; then - echo "This script needs to be run with bash, not sh" + echo 'This installer needs to be run with "bash", not "sh".' exit fi if [[ "$EUID" -ne 0 ]]; then - echo "Sorry, you need to run this as root" + echo "This installer needs to be run with superuser privileges." exit fi # Detect OpenVZ 6 if [[ $(uname -r | cut -d "." -f 1) -eq 2 ]]; then - echo "The system is running an old kernel, which is incompatible with this installer" + echo "The system is running an old kernel, which is incompatible with this installer." exit fi @@ -44,38 +44,38 @@ elif [[ -e /etc/fedora-release ]]; then os_version=$(grep -oE '[0-9]+' /etc/fedora-release | head -1) group_name="nobody" else - echo "Looks like you aren't running this installer on Ubuntu, Debian, CentOS or Fedora" + echo "This installer seems to be running on an unsupported distribution. +Supported distributions are Ubuntu, Debian, CentOS, and Fedora." exit fi if [[ "$os" == "ubuntu" && "$os_version" -lt 1804 ]]; then - echo "Ubuntu 18.04 or higher is required to use this installer -This version of Ubuntu is too old and unsupported" + echo "Ubuntu 18.04 or higher is required to use this installer. +This version of Ubuntu is too old and unsupported." exit fi if [[ "$os" == "debian" && "$os_version" -lt 9 ]]; then - echo "Debian 9 or higher is required to use this installer -This version of Debian is too old and unsupported" + echo "Debian 9 or higher is required to use this installer. +This version of Debian is too old and unsupported." exit fi if [[ "$os" == "centos" && "$os_version" -lt 7 ]]; then - echo "CentOS 7 or higher is required to use this installer -This version of CentOS is too old and unsupported" + echo "CentOS 7 or higher is required to use this installer. +This version of CentOS is too old and unsupported." exit fi if [[ ! -e /dev/net/tun ]] || ! ( exec 7<>/dev/net/tun ) 2>/dev/null; then - echo "This system does not have the TUN device available -TUN needs to be enabled before running this installer" + echo "The system does not have the TUN device available. +TUN needs to be enabled before running this installer." exit fi # Detect environments where $PATH does not include the sbin directories if ! grep -q sbin <<< $PATH; then - echo '$PATH does not include sbin -Try using "su -" instead of "su"' + echo '$PATH does not include sbin. Try using "su -" instead of "su".' exit fi @@ -101,16 +101,13 @@ new_client () { if [[ ! -e /etc/openvpn/server/server.conf ]]; then clear echo 'Welcome to this OpenVPN road warrior installer!' - echo - echo "I need to ask you a few questions before starting setup." - echo "You can use the default options and just press enter if you are ok with them." # If system has a single IPv4, it is selected automatically. Else, ask the user if [[ $(ip -4 addr | grep inet | grep -vEc '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') -eq 1 ]]; then ip=$(ip -4 addr | grep inet | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') else number_of_ip=$(ip -4 addr | grep inet | grep -vEc '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') echo - echo "What IPv4 address should the OpenVPN server use?" + echo "Which IPv4 address should be used?" ip -4 addr | grep inet | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | nl -s ') ' read -p "IPv4 address [1]: " ip_number until [[ -z "$ip_number" || "$ip_number" =~ ^[0-9]+$ && "$ip_number" -le "$number_of_ip" ]]; do @@ -142,7 +139,7 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then if [[ $(ip -6 addr | grep -c 'inet6 [23]') -gt 1 ]]; then number_of_ip6=$(ip -6 addr | grep -c 'inet6 [23]') echo - echo "What IPv6 address should the OpenVPN server use?" + echo "Which IPv6 address should be used?" ip -6 addr | grep 'inet6 [23]' | cut -d '/' -f 1 | grep -oE '([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}' | nl -s ') ' read -p "IPv6 address [1]: " ip6_number until [[ -z "$ip6_number" || "$ip6_number" =~ ^[0-9]+$ && "$ip6_number" -le "$number_of_ip6" ]]; do @@ -153,7 +150,7 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then ip6=$(ip -6 addr | grep 'inet6 [23]' | cut -d '/' -f 1 | grep -oE '([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}' | sed -n "$ip6_number"p) fi echo - echo "Which protocol do you want for OpenVPN connections?" + echo "Which protocol should OpenVPN use?" echo " 1) UDP (recommended)" echo " 2) TCP" read -p "Protocol [1]: " protocol @@ -170,7 +167,7 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then ;; esac echo - echo "What port do you want OpenVPN listening to?" + echo "What port should OpenVPN listen to?" read -p "Port [1194]: " port until [[ -z "$port" || "$port" =~ ^[0-9]+$ && "$port" -le 65535 ]]; do echo "$port: invalid port." @@ -178,40 +175,38 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then done [[ -z "$port" ]] && port="1194" echo - echo "Which DNS do you want to use with the VPN?" + echo "Select a DNS server for the clients:" echo " 1) Current system resolvers" echo " 2) 1.1.1.1" echo " 3) Google" echo " 4) OpenDNS" echo " 5) NTT" echo " 6) AdGuard" - read -p "DNS [1]: " dns + read -p "DNS server [1]: " dns until [[ -z "$dns" || "$dns" =~ ^[1-6]$ ]]; do echo "$dns: invalid selection." - read -p "DNS [1]: " dns + read -p "DNS server [1]: " dns done echo - echo "Finally, tell me a name for the client certificate." - read -p "Client name [client]: " unsanitized_client + echo "Enter a name for the first client:" + read -p "Name [client]: " unsanitized_client # Allow a limited set of characters to avoid conflicts client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") [[ -z "$client" ]] && client="client" echo - echo "We are ready to set up your OpenVPN server now." + echo "OpenVPN installation is ready to begin now." # Install a firewall in the rare case where one is not already available if ! systemctl is-active --quiet firewalld.service && ! hash iptables 2>/dev/null; then if [[ "$os" == "centos" || "$os" == "fedora" ]]; then firewall="firewalld" # We don't want to silently enable firewalld, so we give a subtle warning # If the user continues, firewalld will be installed and enabled during setup - echo echo "firewalld, which is required to manage routing tables, will also be installed." elif [[ "$os" == "debian" || "$os" == "ubuntu" ]]; then # iptables is way less invasive than firewalld so no warning is given firewall="iptables" fi fi - echo read -n1 -r -p "Press any key to continue..." # If running inside a container, disable LimitNPROC to prevent conflicts if systemd-detect-virt -cq; then @@ -430,31 +425,31 @@ verb 3" > /etc/openvpn/server/client-common.txt echo echo "Finished!" echo - echo "Your client configuration is available at:" ~/"$client.ovpn" - echo "If you want to add more clients, just run this script again!" + echo "The client configuration is available in:" ~/"$client.ovpn" + echo "New clients can be added by running this script again." else clear - echo "Looks like OpenVPN is already installed." + echo "OpenVPN is already installed." echo - echo "What do you want to do?" + echo "Select an option:" echo " 1) Add a new user" echo " 2) Revoke an existing user" echo " 3) Remove OpenVPN" echo " 4) Exit" - read -p "Select an option: " option + read -p "Option: " option until [[ "$option" =~ ^[1-4]$ ]]; do echo "$option: invalid selection." - read -p "Select an option: " option + read -p "Option: " option done case "$option" in 1) echo - echo "Tell me a name for the client certificate." - read -p "Client name: " unsanitized_client + echo "Provide a name for the client:" + read -p "Name: " unsanitized_client client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") while [[ -z "$client" || -e /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt ]]; do - echo "$client: invalid client name." - read -p "Client name: " unsanitized_client + echo "$client: invalid name." + read -p "Name: " unsanitized_client client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") done cd /etc/openvpn/server/easy-rsa/ @@ -462,7 +457,7 @@ else # Generates the custom client.ovpn new_client echo - echo "Client $client added, configuration is available at:" ~/"$client.ovpn" + echo "$client added. Configuration available in:" ~/"$client.ovpn" exit ;; 2) @@ -471,23 +466,23 @@ else number_of_clients=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep -c "^V") if [[ "$number_of_clients" = 0 ]]; then echo - echo "You have no existing clients!" + echo "There are no existing clients!" exit fi echo - echo "Select the existing client certificate you want to revoke:" + echo "Select the client to revoke:" tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') ' - read -p "Select one client: " client_number + read -p "Client: " client_number until [[ "$client_number" =~ ^[0-9]+$ && "$client_number" -le "$number_of_clients" ]]; do echo "$client_number: invalid selection." - read -p "Select one client: " client_number + read -p "Client: " client_number done client=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$client_number"p) echo - read -p "Do you really want to revoke access for client $client? [y/N]: " revoke + read -p "Confirm $client revocation? [y/N]: " revoke until [[ "$revoke" =~ ^[yYnN]*$ ]]; do echo "$revoke: invalid selection." - read -p "Do you really want to revoke access for client $client? [y/N]: " revoke + read -p "Confirm $client revocation? [y/N]: " revoke done if [[ "$revoke" =~ ^[yY]$ ]]; then cd /etc/openvpn/server/easy-rsa/ @@ -498,19 +493,19 @@ else # CRL is read with each client connection, when OpenVPN is dropped to nobody chown nobody:"$group_name" /etc/openvpn/server/crl.pem echo - echo "Certificate for client $client revoked!" + echo "$client revoked!" else echo - echo "Certificate revocation for client $client aborted!" + echo "$client revocation aborted!" fi exit ;; 3) echo - read -p "Do you really want to remove OpenVPN? [y/N]: " remove + read -p "Confirm OpenVPN removal? [y/N]: " remove until [[ "$remove" =~ ^[yYnN]*$ ]]; do echo "$remove: invalid selection." - read -p "Do you really want to remove OpenVPN? [y/N]: " remove + read -p "Confirm OpenVPN removal? [y/N]: " remove done if [[ "$remove" =~ ^[yY]$ ]]; then port=$(grep '^port ' /etc/openvpn/server/server.conf | cut -d " " -f 2) @@ -552,7 +547,7 @@ else echo "OpenVPN removed!" else echo - echo "Removal aborted!" + echo "OpenVPN removal aborted!" fi exit ;; From f737b02a9a0db77709313837bea0e227d95ddaca Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 21 May 2020 19:19:31 +0200 Subject: [PATCH 26/65] Small style changes --- openvpn-install.sh | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 01b5ea8b..e60b9946 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -6,7 +6,7 @@ # Discard stdin. Needed when running from an one-liner which includes a newline -read -N 999999999 -t 0.001 +read -N 999999 -t 0.001 # Detect Debian users running the script with "sh" instead of bash if readlink /proc/$$/exe | grep -q "dash"; then @@ -14,11 +14,6 @@ if readlink /proc/$$/exe | grep -q "dash"; then exit fi -if [[ "$EUID" -ne 0 ]]; then - echo "This installer needs to be run with superuser privileges." - exit -fi - # Detect OpenVZ 6 if [[ $(uname -r | cut -d "." -f 1) -eq 2 ]]; then echo "The system is running an old kernel, which is incompatible with this installer." @@ -67,15 +62,20 @@ This version of CentOS is too old and unsupported." exit fi -if [[ ! -e /dev/net/tun ]] || ! ( exec 7<>/dev/net/tun ) 2>/dev/null; then - echo "The system does not have the TUN device available. -TUN needs to be enabled before running this installer." +# Detect environments where $PATH does not include the sbin directories +if ! grep -q sbin <<< "$PATH"; then + echo '$PATH does not include sbin. Try using "su -" instead of "su".' exit fi -# Detect environments where $PATH does not include the sbin directories -if ! grep -q sbin <<< $PATH; then - echo '$PATH does not include sbin. Try using "su -" instead of "su".' +if [[ "$EUID" -ne 0 ]]; then + echo "This installer needs to be run with superuser privileges." + exit +fi + +if [[ ! -e /dev/net/tun ]] || ! ( exec 7<>/dev/net/tun ) 2>/dev/null; then + echo "The system does not have the TUN device available. +TUN needs to be enabled before running this installer." exit fi @@ -125,8 +125,8 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then get_public_ip=$(grep -m 1 -oE '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' <<< "$(wget -T 10 -t 1 -4qO- "http://ip1.dynupdate.no-ip.com/" || curl -m 10 -4Ls "http://ip1.dynupdate.no-ip.com/")") read -p "Public IPv4 address / hostname [$get_public_ip]: " public_ip # If the checkip service is unavailable and user didn't provide input, ask again - until [[ -n "$get_public_ip" || -n $public_ip ]]; do - echo "Invalid input." + until [[ -n "$get_public_ip" || -n "$public_ip" ]]; do + echo "Invalid input." read -p "Public IPv4 address / hostname: " public_ip done [[ -z "$public_ip" ]] && public_ip="$get_public_ip" @@ -194,7 +194,7 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") [[ -z "$client" ]] && client="client" echo - echo "OpenVPN installation is ready to begin now." + echo "OpenVPN installation is ready to begin." # Install a firewall in the rare case where one is not already available if ! systemctl is-active --quiet firewalld.service && ! hash iptables 2>/dev/null; then if [[ "$os" == "centos" || "$os" == "fedora" ]]; then @@ -216,13 +216,13 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab fi if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then apt-get update - apt-get install -y openvpn openssl ca-certificates $firewall + apt-get install -y openvpn openssl ca-certificates "$firewall" elif [[ "$os" = "centos" ]]; then yum install -y epel-release - yum install -y openvpn openssl ca-certificates tar $firewall + yum install -y openvpn openssl ca-certificates tar "$firewall" else # Else, OS must be Fedora - dnf install -y openvpn openssl ca-certificates tar $firewall + dnf install -y openvpn openssl ca-certificates tar "$firewall" fi # If firewalld was just installed, enable it if [[ "$firewall" == "firewalld" ]]; then @@ -358,7 +358,7 @@ crl-verify crl.pem" >> /etc/openvpn/server/server.conf ip6tables_path=$(command -v ip6tables) # nf_tables is not available as standard in OVZ kernels. So use iptables-legacy # if we are in OVZ, with a nf_tables backend and iptables-legacy is available. - if [[ $(systemd-detect-virt) == "openvz" ]] && readlink -f $(command -v iptables) | grep -q "nft" && hash iptables-legacy 2>/dev/null; then + if [[ $(systemd-detect-virt) == "openvz" ]] && readlink -f "$(command -v iptables)" | grep -q "nft" && hash iptables-legacy 2>/dev/null; then iptables_path=$(command -v iptables-legacy) ip6tables_path=$(command -v ip6tables-legacy) fi @@ -402,7 +402,7 @@ WantedBy=multi-user.target" >> /etc/systemd/system/openvpn-iptables.service semanage port -a -t openvpn_port_t -p "$protocol" "$port" fi # If the server is behind NAT, use the correct IP address - [[ ! -z "$public_ip" ]] && ip="$public_ip" + [[ -n "$public_ip" ]] && ip="$public_ip" # client-common.txt is created so we have a template to add further users later echo "client dev tun @@ -432,8 +432,8 @@ else echo "OpenVPN is already installed." echo echo "Select an option:" - echo " 1) Add a new user" - echo " 2) Revoke an existing user" + echo " 1) Add a new client" + echo " 2) Revoke an existing client" echo " 3) Remove OpenVPN" echo " 4) Exit" read -p "Option: " option From bfdd480076a29137d5e0aa38cb5102d8730308f5 Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 21 May 2020 22:36:12 +0200 Subject: [PATCH 27/65] Add Quad9 DNS servers --- openvpn-install.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index e60b9946..90aeb436 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -177,10 +177,10 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then echo echo "Select a DNS server for the clients:" echo " 1) Current system resolvers" - echo " 2) 1.1.1.1" - echo " 3) Google" + echo " 2) Google" + echo " 3) 1.1.1.1" echo " 4) OpenDNS" - echo " 5) NTT" + echo " 5) Quad9" echo " 6) AdGuard" read -p "DNS server [1]: " dns until [[ -z "$dns" || "$dns" =~ ^[1-6]$ ]]; do @@ -292,20 +292,20 @@ server 10.8.0.0 255.255.255.0" > /etc/openvpn/server/server.conf done ;; 2) - echo 'push "dhcp-option DNS 1.1.1.1"' >> /etc/openvpn/server/server.conf - echo 'push "dhcp-option DNS 1.0.0.1"' >> /etc/openvpn/server/server.conf - ;; - 3) echo 'push "dhcp-option DNS 8.8.8.8"' >> /etc/openvpn/server/server.conf echo 'push "dhcp-option DNS 8.8.4.4"' >> /etc/openvpn/server/server.conf ;; + 3) + echo 'push "dhcp-option DNS 1.1.1.1"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 1.0.0.1"' >> /etc/openvpn/server/server.conf + ;; 4) echo 'push "dhcp-option DNS 208.67.222.222"' >> /etc/openvpn/server/server.conf echo 'push "dhcp-option DNS 208.67.220.220"' >> /etc/openvpn/server/server.conf ;; 5) - echo 'push "dhcp-option DNS 129.250.35.250"' >> /etc/openvpn/server/server.conf - echo 'push "dhcp-option DNS 129.250.35.251"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 9.9.9.9"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 149.112.112.112"' >> /etc/openvpn/server/server.conf ;; 6) echo 'push "dhcp-option DNS 176.103.130.130"' >> /etc/openvpn/server/server.conf From ae7e6d7ae5aa8d87af6c9e0ced0472445b020c87 Mon Sep 17 00:00:00 2001 From: Orcun <59258329+sorcun@users.noreply.github.com> Date: Sat, 23 May 2020 13:52:26 +0000 Subject: [PATCH 28/65] egrep IP regex optimizations --- openvpn-install.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 90aeb436..e73c8c49 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -102,27 +102,27 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then clear echo 'Welcome to this OpenVPN road warrior installer!' # If system has a single IPv4, it is selected automatically. Else, ask the user - if [[ $(ip -4 addr | grep inet | grep -vEc '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') -eq 1 ]]; then - ip=$(ip -4 addr | grep inet | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') + if [[ $(ip -4 addr | grep inet | grep -vEc '127(\.[0-9]{1,3}){3}') -eq 1 ]]; then + ip=$(ip -4 addr | grep inet | grep -vE '127(\.[0-9]{1,3}){3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}') else - number_of_ip=$(ip -4 addr | grep inet | grep -vEc '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') + number_of_ip=$(ip -4 addr | grep inet | grep -vEc '127(\.[0-9]{1,3}){3}') echo echo "Which IPv4 address should be used?" - ip -4 addr | grep inet | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | nl -s ') ' + ip -4 addr | grep inet | grep -vE '127(\.[0-9]{1,3}){3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' | nl -s ') ' read -p "IPv4 address [1]: " ip_number until [[ -z "$ip_number" || "$ip_number" =~ ^[0-9]+$ && "$ip_number" -le "$number_of_ip" ]]; do echo "$ip_number: invalid selection." read -p "IPv4 address [1]: " ip_number done [[ -z "$ip_number" ]] && ip_number="1" - ip=$(ip -4 addr | grep inet | grep -vE '127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sed -n "$ip_number"p) + ip=$(ip -4 addr | grep inet | grep -vE '127(\.[0-9]{1,3}){3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' | sed -n "$ip_number"p) fi # If $ip is a private IP address, the server must be behind NAT if echo "$ip" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then echo echo "This server is behind NAT. What is the public IPv4 address or hostname?" # Get public IP and sanitize with grep - get_public_ip=$(grep -m 1 -oE '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' <<< "$(wget -T 10 -t 1 -4qO- "http://ip1.dynupdate.no-ip.com/" || curl -m 10 -4Ls "http://ip1.dynupdate.no-ip.com/")") + get_public_ip=$(grep -m 1 -oE '^[0-9]{1,3}(\.[0-9]{1,3}){3}$' <<< "$(wget -T 10 -t 1 -4qO- "http://ip1.dynupdate.no-ip.com/" || curl -m 10 -4Ls "http://ip1.dynupdate.no-ip.com/")") read -p "Public IPv4 address / hostname [$get_public_ip]: " public_ip # If the checkip service is unavailable and user didn't provide input, ask again until [[ -n "$get_public_ip" || -n "$public_ip" ]]; do @@ -287,7 +287,7 @@ server 10.8.0.0 255.255.255.0" > /etc/openvpn/server/server.conf resolv_conf="/etc/resolv.conf" fi # Obtain the resolvers from resolv.conf and use them for OpenVPN - grep -v '#' "$resolv_conf" | grep nameserver | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | while read line; do + grep -v '#' "$resolv_conf" | grep nameserver | grep -E -o '[0-9]{1,3}(\.[0-9]{1,3}){3}' | while read line; do echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server/server.conf done ;; From 366d46a8ccfbb780b5d5dc1499c466b994a331e1 Mon Sep 17 00:00:00 2001 From: Nyr Date: Mon, 25 May 2020 17:23:55 +0200 Subject: [PATCH 29/65] Fix #762 Variables which can be empty, shouldn't be quoted in this situation. --- openvpn-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 90aeb436..22243386 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -216,13 +216,13 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab fi if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then apt-get update - apt-get install -y openvpn openssl ca-certificates "$firewall" + apt-get install -y openvpn openssl ca-certificates $firewall elif [[ "$os" = "centos" ]]; then yum install -y epel-release - yum install -y openvpn openssl ca-certificates tar "$firewall" + yum install -y openvpn openssl ca-certificates tar $firewall else # Else, OS must be Fedora - dnf install -y openvpn openssl ca-certificates tar "$firewall" + dnf install -y openvpn openssl ca-certificates tar $firewall fi # If firewalld was just installed, enable it if [[ "$firewall" == "firewalld" ]]; then From 221319aa54db9bb5e6ae45facad03b6dacbaba47 Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 28 May 2020 21:29:53 +0200 Subject: [PATCH 30/65] Fix #764 --- openvpn-install.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 99716367..b0de6d26 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -242,8 +242,10 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl # Move the stuff we need cp pki/ca.crt pki/private/ca.key pki/issued/server.crt pki/private/server.key pki/crl.pem /etc/openvpn/server - # CRL is read with each client connection, when OpenVPN is dropped to nobody + # CRL is read with each client connection, while OpenVPN is dropped to nobody chown nobody:"$group_name" /etc/openvpn/server/crl.pem + # Without +x in the directory, OpenVPN can't run a stat() on the CRL file + chmod o+x /etc/openvpn/server/ # Generate key for tls-crypt openvpn --genkey --secret /etc/openvpn/server/tc.key # Create the DH parameters file using the predefined ffdhe2048 group From 13f8b2e00cb3f6e2f670ffdba5f43787cacb3727 Mon Sep 17 00:00:00 2001 From: Nyr Date: Fri, 29 May 2020 14:16:29 +0200 Subject: [PATCH 31/65] resolv.conf parsing optimizations --- openvpn-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index b0de6d26..1a580d3e 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -283,13 +283,13 @@ server 10.8.0.0 255.255.255.0" > /etc/openvpn/server/server.conf 1|"") # Locate the proper resolv.conf # Needed for systems running systemd-resolved - if grep -q "127.0.0.53" "/etc/resolv.conf"; then + if grep -q '^nameserver 127.0.0.53' "/etc/resolv.conf"; then resolv_conf="/run/systemd/resolve/resolv.conf" else resolv_conf="/etc/resolv.conf" fi # Obtain the resolvers from resolv.conf and use them for OpenVPN - grep -v '#' "$resolv_conf" | grep nameserver | grep -E -o '[0-9]{1,3}(\.[0-9]{1,3}){3}' | while read line; do + grep -v '^#\|^;' "$resolv_conf" | grep '^nameserver' | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' | while read line; do echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server/server.conf done ;; From e32cb6db866177c24ee7775751e1775724bc4951 Mon Sep 17 00:00:00 2001 From: Nyr Date: Fri, 17 Jul 2020 19:04:07 +0200 Subject: [PATCH 32/65] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f48d81a6..ffcd0527 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +**New:** [wireguard-install](https://github.com/Nyr/wireguard-install) is also available. + ## openvpn-install OpenVPN [road warrior](http://en.wikipedia.org/wiki/Road_warrior_%28computing%29) installer for Ubuntu, Debian, CentOS and Fedora. From 3ba1308a5050ad03500cecffc4dfa955e3854ed3 Mon Sep 17 00:00:00 2001 From: Nyr Date: Fri, 17 Jul 2020 19:06:11 +0200 Subject: [PATCH 33/65] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ffcd0527..521d4c0f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -**New:** [wireguard-install](https://github.com/Nyr/wireguard-install) is also available. +**New: [wireguard-install](https://github.com/Nyr/wireguard-install) is also available.** ## openvpn-install OpenVPN [road warrior](http://en.wikipedia.org/wiki/Road_warrior_%28computing%29) installer for Ubuntu, Debian, CentOS and Fedora. From 7ddd20911b3544c55d822f898e93c8469e34ff04 Mon Sep 17 00:00:00 2001 From: Nyr Date: Sat, 18 Jul 2020 18:50:59 +0200 Subject: [PATCH 34/65] Bugfix -N is an illegal option for read in sh, so check if the user is using sh first. --- openvpn-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 1a580d3e..2c22d781 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -5,15 +5,15 @@ # Copyright (c) 2013 Nyr. Released under the MIT License. -# Discard stdin. Needed when running from an one-liner which includes a newline -read -N 999999 -t 0.001 - # Detect Debian users running the script with "sh" instead of bash if readlink /proc/$$/exe | grep -q "dash"; then echo 'This installer needs to be run with "bash", not "sh".' exit fi +# Discard stdin. Needed when running from an one-liner which includes a newline +read -N 999999 -t 0.001 + # Detect OpenVZ 6 if [[ $(uname -r | cut -d "." -f 1) -eq 2 ]]; then echo "The system is running an old kernel, which is incompatible with this installer." From da299172df2f07aea38c0431d6f6eba42bafb4c6 Mon Sep 17 00:00:00 2001 From: Nyr Date: Wed, 9 Sep 2020 23:18:31 +0200 Subject: [PATCH 35/65] Update to easy-rsa v3.0.8 --- openvpn-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 2c22d781..379078be 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -229,7 +229,7 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab systemctl enable --now firewalld.service fi # Get easy-rsa - easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.7/EasyRSA-3.0.7.tgz' + easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.8/EasyRSA-3.0.8.tgz' mkdir -p /etc/openvpn/server/easy-rsa/ { wget -qO- "$easy_rsa_url" 2>/dev/null || curl -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1 chown -R root:root /etc/openvpn/server/easy-rsa/ From 26e39cf4d783694dd1e770670b5d2a0c61ab9fb2 Mon Sep 17 00:00:00 2001 From: Nyr Date: Wed, 30 Sep 2020 00:06:55 +0200 Subject: [PATCH 36/65] Update AdGuard DNS IP AdGuard changed their DNS IP recently: https://adguard.com/en/blog/adguard-dns-new-addresses.html Thanks @trantuanminh1754 for noticing. --- openvpn-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 379078be..1f0df4e0 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -310,8 +310,8 @@ server 10.8.0.0 255.255.255.0" > /etc/openvpn/server/server.conf echo 'push "dhcp-option DNS 149.112.112.112"' >> /etc/openvpn/server/server.conf ;; 6) - echo 'push "dhcp-option DNS 176.103.130.130"' >> /etc/openvpn/server/server.conf - echo 'push "dhcp-option DNS 176.103.130.131"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 94.140.14.14"' >> /etc/openvpn/server/server.conf + echo 'push "dhcp-option DNS 94.140.15.15"' >> /etc/openvpn/server/server.conf ;; esac echo "keepalive 10 120 From 01b64d65c8129448cb87597357c2ccac1230542c Mon Sep 17 00:00:00 2001 From: Tomasz Wojdat Date: Thu, 11 Mar 2021 22:49:04 +0100 Subject: [PATCH 37/65] Increase priority of openvpn-forward.conf `30-openvpn-forward.conf` renamed to `99-openvpn-forward.conf`. --- openvpn-install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 25f93e37..4df57832 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -326,12 +326,12 @@ crl-verify crl.pem" >> /etc/openvpn/server/server.conf echo "explicit-exit-notify" >> /etc/openvpn/server/server.conf fi # Enable net.ipv4.ip_forward for the system - echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/30-openvpn-forward.conf + echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/99-openvpn-forward.conf # Enable without waiting for a reboot or service restart echo 1 > /proc/sys/net/ipv4/ip_forward if [[ -n "$ip6" ]]; then # Enable net.ipv6.conf.all.forwarding for the system - echo "net.ipv6.conf.all.forwarding=1" >> /etc/sysctl.d/30-openvpn-forward.conf + echo "net.ipv6.conf.all.forwarding=1" >> /etc/sysctl.d/99-openvpn-forward.conf # Enable without waiting for a reboot or service restart echo 1 > /proc/sys/net/ipv6/conf/all/forwarding fi @@ -537,7 +537,7 @@ else systemctl disable --now openvpn-server@server.service rm -rf /etc/openvpn/server rm -f /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf - rm -f /etc/sysctl.d/30-openvpn-forward.conf + rm -f /etc/sysctl.d/99-openvpn-forward.conf if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then apt-get remove --purge -y openvpn else From 2cce4599e2812ae2556258aad14cc2e223963259 Mon Sep 17 00:00:00 2001 From: Nyr Date: Mon, 16 Aug 2021 20:22:36 +0200 Subject: [PATCH 38/65] Check for wget or curl --- openvpn-install.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openvpn-install.sh b/openvpn-install.sh index 4df57832..d2255d5c 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -99,6 +99,13 @@ new_client () { } if [[ ! -e /etc/openvpn/server/server.conf ]]; then + # Detect some Debian minimal setups where neither wget nor curl are installed + if ! hash wget 2>/dev/null && ! hash curl 2>/dev/null; then + echo "Wget is required to use this installer." + read -n1 -r -p "Press any key to install Wget and continue..." + apt-get update + apt-get install -y wget + fi clear echo 'Welcome to this OpenVPN road warrior installer!' # If system has a single IPv4, it is selected automatically. Else, ask the user From 94c94bbbc9cd650bbe74e806ca02ec7399a5369a Mon Sep 17 00:00:00 2001 From: Nyr Date: Fri, 3 Sep 2021 18:58:25 +0200 Subject: [PATCH 39/65] Add support for AlmaLinux and Rocky Linux An unrelated fix to avoid one harmless warning during removal is also included. --- README.md | 2 +- openvpn-install.sh | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 521d4c0f..e4f84ee0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ **New: [wireguard-install](https://github.com/Nyr/wireguard-install) is also available.** ## openvpn-install -OpenVPN [road warrior](http://en.wikipedia.org/wiki/Road_warrior_%28computing%29) installer for Ubuntu, Debian, CentOS and Fedora. +OpenVPN [road warrior](http://en.wikipedia.org/wiki/Road_warrior_%28computing%29) installer for Ubuntu, Debian, AlmaLinux, Rocky Linux, CentOS and Fedora. This script will let you set up your own VPN server in no more than a minute, even if you haven't used OpenVPN before. It has been designed to be as unobtrusive and universal as possible. diff --git a/openvpn-install.sh b/openvpn-install.sh index d2255d5c..b39e7951 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -30,9 +30,9 @@ elif [[ -e /etc/debian_version ]]; then os="debian" os_version=$(grep -oE '[0-9]+' /etc/debian_version | head -1) group_name="nogroup" -elif [[ -e /etc/centos-release ]]; then +elif [[ -e /etc/almalinux-release || -e /etc/rocky-release || -e /etc/centos-release ]]; then os="centos" - os_version=$(grep -oE '[0-9]+' /etc/centos-release | head -1) + os_version=$(grep -shoE '[0-9]+' /etc/almalinux-release /etc/rocky-release /etc/centos-release | head -1) group_name="nobody" elif [[ -e /etc/fedora-release ]]; then os="fedora" @@ -40,7 +40,7 @@ elif [[ -e /etc/fedora-release ]]; then group_name="nobody" else echo "This installer seems to be running on an unsupported distribution. -Supported distributions are Ubuntu, Debian, CentOS, and Fedora." +Supported distros are Ubuntu, Debian, AlmaLinux, Rocky Linux, CentOS and Fedora." exit fi @@ -202,7 +202,7 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then [[ -z "$client" ]] && client="client" echo echo "OpenVPN installation is ready to begin." - # Install a firewall in the rare case where one is not already available + # Install a firewall if firewalld or iptables are not already available if ! systemctl is-active --quiet firewalld.service && ! hash iptables 2>/dev/null; then if [[ "$os" == "centos" || "$os" == "fedora" ]]; then firewall="firewalld" @@ -542,14 +542,15 @@ else semanage port -d -t openvpn_port_t -p "$protocol" "$port" fi systemctl disable --now openvpn-server@server.service - rm -rf /etc/openvpn/server rm -f /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf rm -f /etc/sysctl.d/99-openvpn-forward.conf if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then + rm -rf /etc/openvpn/server apt-get remove --purge -y openvpn else # Else, OS must be CentOS or Fedora yum remove -y openvpn + rm -rf /etc/openvpn/server fi echo echo "OpenVPN removed!" From 8b6c81f79e61656de5766e94f9c1f0ccf4f3bd82 Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 21 Apr 2022 21:11:44 +0200 Subject: [PATCH 40/65] Ubuntu 22.04 support --- openvpn-install.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index b39e7951..c5136c8b 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -236,7 +236,12 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab systemctl enable --now firewalld.service fi # Get easy-rsa - easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.8/EasyRSA-3.0.8.tgz' + # The latest easy-rsa release is not yet compatible with Ubuntu 22.04 + if [[ "$os" == "ubuntu" && "$os_version" -eq 2204 ]]; then + easy_rsa_url='https://wg.nyr.be/download/EasyRSA-bf19e79.tgz' + else + easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.8/EasyRSA-3.0.8.tgz' + fi mkdir -p /etc/openvpn/server/easy-rsa/ { wget -qO- "$easy_rsa_url" 2>/dev/null || curl -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1 chown -R root:root /etc/openvpn/server/easy-rsa/ From 36f1d82cbaf566a5de08a0792e7f04104f4914c7 Mon Sep 17 00:00:00 2001 From: Nyr Date: Wed, 27 Apr 2022 12:37:53 +0200 Subject: [PATCH 41/65] Replace git.io git.io will stop functioning by the end of this workweek: https://github.blog/changelog/2022-04-25-git-io-deprecation/ --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e4f84ee0..890fd82c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This script will let you set up your own VPN server in no more than a minute, ev ### Installation Run the script and follow the assistant: -`wget https://git.io/vpn -O openvpn-install.sh && bash openvpn-install.sh` +`wget https://github.com/Nyr/openvpn-install/raw/master/openvpn-install.sh && bash openvpn-install.sh` Once it ends, you can run it again to add more users, remove some of them or even completely uninstall OpenVPN. From a7474c95ca1df99d0474eb15b46eb4d4058ad9cf Mon Sep 17 00:00:00 2001 From: Nyr Date: Fri, 29 Apr 2022 16:44:49 +0200 Subject: [PATCH 42/65] Restore git.io git.io will not stop functioning after all: https://github.blog/changelog/2022-04-25-git-io-deprecation/?#changelog-64536 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 890fd82c..e4f84ee0 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This script will let you set up your own VPN server in no more than a minute, ev ### Installation Run the script and follow the assistant: -`wget https://github.com/Nyr/openvpn-install/raw/master/openvpn-install.sh && bash openvpn-install.sh` +`wget https://git.io/vpn -O openvpn-install.sh && bash openvpn-install.sh` Once it ends, you can run it again to add more users, remove some of them or even completely uninstall OpenVPN. From 0709b9498ccdb11ba07890c75b1f7d6c5fd51455 Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 5 May 2022 11:44:36 +0200 Subject: [PATCH 43/65] Update easy-rsa to v3.0.9-rc1 for Ubuntu 22.04 --- openvpn-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index c5136c8b..408f4ba9 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -236,9 +236,9 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab systemctl enable --now firewalld.service fi # Get easy-rsa - # The latest easy-rsa release is not yet compatible with Ubuntu 22.04 + # The latest easy-rsa stable release is not yet compatible with Ubuntu 22.04 if [[ "$os" == "ubuntu" && "$os_version" -eq 2204 ]]; then - easy_rsa_url='https://wg.nyr.be/download/EasyRSA-bf19e79.tgz' + easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.9-rc1/EasyRSA-v3.0.9-rc1.tgz' else easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.8/EasyRSA-3.0.8.tgz' fi From 2c5bb08f4e1ecd117871d06b52c14a764f7fee56 Mon Sep 17 00:00:00 2001 From: Nyr Date: Wed, 18 May 2022 15:16:11 +0200 Subject: [PATCH 44/65] Update to easy-rsa v3.0.9 --- openvpn-install.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 408f4ba9..fd7114ff 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -236,12 +236,7 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab systemctl enable --now firewalld.service fi # Get easy-rsa - # The latest easy-rsa stable release is not yet compatible with Ubuntu 22.04 - if [[ "$os" == "ubuntu" && "$os_version" -eq 2204 ]]; then - easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.9-rc1/EasyRSA-v3.0.9-rc1.tgz' - else - easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.8/EasyRSA-3.0.8.tgz' - fi + easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.9/EasyRSA-v3.0.9.tgz' mkdir -p /etc/openvpn/server/easy-rsa/ { wget -qO- "$easy_rsa_url" 2>/dev/null || curl -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1 chown -R root:root /etc/openvpn/server/easy-rsa/ From c0a3562f64505678394ba99ea9c104fde14118cc Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 19 May 2022 17:59:35 +0200 Subject: [PATCH 45/65] Update to easy-rsa v3.1.0 --- openvpn-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index fd7114ff..effb1f60 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -236,7 +236,7 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab systemctl enable --now firewalld.service fi # Get easy-rsa - easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.9/EasyRSA-v3.0.9.tgz' + easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.0/EasyRSA-3.1.0.tgz' mkdir -p /etc/openvpn/server/easy-rsa/ { wget -qO- "$easy_rsa_url" 2>/dev/null || curl -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1 chown -R root:root /etc/openvpn/server/easy-rsa/ From 1a118b72f86b85134332095cfa5d8adbc1de7a0e Mon Sep 17 00:00:00 2001 From: Nyr Date: Sun, 21 Aug 2022 19:33:38 +0200 Subject: [PATCH 46/65] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e4f84ee0..838c8c23 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Run the script and follow the assistant: Once it ends, you can run it again to add more users, remove some of them or even completely uninstall OpenVPN. ### I want to run my own VPN but don't have a server for that -You can get a VPS from just $1/month at [VirMach](https://billing.virmach.com/aff.php?aff=4109&url=billing.virmach.com/cart.php?gid=18). +You can get a VPS from just 2€/month at [AlphaVPS](https://alphavps.com/clients/aff.php?aff=474&pid=422). ### Donations From d28c8e74e76021705ec5241348a3ee309f275564 Mon Sep 17 00:00:00 2001 From: Nyr Date: Sun, 21 Aug 2022 20:33:34 +0200 Subject: [PATCH 47/65] Fix resolv.conf detection Some systems have other DNS servers along with 127.0.0.53 in /etc/resolv.conf --- openvpn-install.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index effb1f60..36a17d05 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -290,13 +290,13 @@ server 10.8.0.0 255.255.255.0" > /etc/openvpn/server/server.conf 1|"") # Locate the proper resolv.conf # Needed for systems running systemd-resolved - if grep -q '^nameserver 127.0.0.53' "/etc/resolv.conf"; then - resolv_conf="/run/systemd/resolve/resolv.conf" - else + if grep '^nameserver' "/etc/resolv.conf" | grep -qv '127.0.0.53' ; then resolv_conf="/etc/resolv.conf" + else + resolv_conf="/run/systemd/resolve/resolv.conf" fi # Obtain the resolvers from resolv.conf and use them for OpenVPN - grep -v '^#\|^;' "$resolv_conf" | grep '^nameserver' | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' | while read line; do + grep -v '^#\|^;' "$resolv_conf" | grep '^nameserver' | grep -v '127.0.0.53' | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' | while read line; do echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server/server.conf done ;; From f2c44dea4046a83cf012df916bdf9b0e1e537400 Mon Sep 17 00:00:00 2001 From: Nyr Date: Fri, 23 Sep 2022 17:07:43 +0200 Subject: [PATCH 48/65] Change "block-outside-dns" placement This is mainly to work around a bug in Viscosity for macOS: https://www.sparklabs.com/forum/viewtopic.php?t=3152 --- openvpn-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 36a17d05..815031e6 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -321,6 +321,7 @@ server 10.8.0.0 255.255.255.0" > /etc/openvpn/server/server.conf echo 'push "dhcp-option DNS 94.140.15.15"' >> /etc/openvpn/server/server.conf ;; esac + echo 'push "block-outside-dns"' >> /etc/openvpn/server/server.conf echo "keepalive 10 120 cipher AES-256-CBC user nobody @@ -424,7 +425,6 @@ remote-cert-tls server auth SHA512 cipher AES-256-CBC ignore-unknown-option block-outside-dns -block-outside-dns verb 3" > /etc/openvpn/server/client-common.txt # Enable and start the OpenVPN service systemctl enable --now openvpn-server@server.service From f9433870836dfd008fca810780f639bafadaf8b0 Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 13 Oct 2022 21:17:39 +0200 Subject: [PATCH 49/65] Update to easy-rsa v3.1.1 --no-install-recommends is now required for Debian: https://github.com/OpenVPN/easy-rsa/issues/725 --- openvpn-install.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 815031e6..4235723d 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -223,7 +223,7 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab fi if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then apt-get update - apt-get install -y openvpn openssl ca-certificates $firewall + apt-get install -y --no-install-recommends openvpn openssl ca-certificates $firewall elif [[ "$os" = "centos" ]]; then yum install -y epel-release yum install -y openvpn openssl ca-certificates tar $firewall @@ -236,17 +236,17 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab systemctl enable --now firewalld.service fi # Get easy-rsa - easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.0/EasyRSA-3.1.0.tgz' + easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.1/EasyRSA-3.1.1.tgz' mkdir -p /etc/openvpn/server/easy-rsa/ { wget -qO- "$easy_rsa_url" 2>/dev/null || curl -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1 chown -R root:root /etc/openvpn/server/easy-rsa/ cd /etc/openvpn/server/easy-rsa/ # Create the PKI, set up the CA and the server and client certificates - ./easyrsa init-pki + ./easyrsa --batch init-pki ./easyrsa --batch build-ca nopass - EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-server-full server nopass - EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full "$client" nopass - EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl + ./easyrsa --batch --days=3650 build-server-full server nopass + ./easyrsa --batch --days=3650 build-client-full "$client" nopass + ./easyrsa --batch --days=3650 gen-crl # Move the stuff we need cp pki/ca.crt pki/private/ca.key pki/issued/server.crt pki/private/server.key pki/crl.pem /etc/openvpn/server # CRL is read with each client connection, while OpenVPN is dropped to nobody @@ -461,7 +461,7 @@ else client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") done cd /etc/openvpn/server/easy-rsa/ - EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full "$client" nopass + ./easyrsa --batch --days=3650 build-client-full "$client" nopass # Generates the custom client.ovpn new_client echo @@ -495,7 +495,7 @@ else if [[ "$revoke" =~ ^[yY]$ ]]; then cd /etc/openvpn/server/easy-rsa/ ./easyrsa --batch revoke "$client" - EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl + ./easyrsa --batch --days=3650 gen-crl rm -f /etc/openvpn/server/crl.pem cp /etc/openvpn/server/easy-rsa/pki/crl.pem /etc/openvpn/server/crl.pem # CRL is read with each client connection, when OpenVPN is dropped to nobody From d4ae10ec2530747a1f5d78a7dea9e635a124db6c Mon Sep 17 00:00:00 2001 From: Nyr Date: Wed, 18 Jan 2023 18:40:18 +0100 Subject: [PATCH 50/65] Update to easy-rsa v3.1.2 --- openvpn-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 4235723d..637fe3cc 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -236,7 +236,7 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab systemctl enable --now firewalld.service fi # Get easy-rsa - easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.1/EasyRSA-3.1.1.tgz' + easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.2/EasyRSA-3.1.2.tgz' mkdir -p /etc/openvpn/server/easy-rsa/ { wget -qO- "$easy_rsa_url" 2>/dev/null || curl -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1 chown -R root:root /etc/openvpn/server/easy-rsa/ From 9d6d87a6fb9b21fb6c4761fce23746b5d5594495 Mon Sep 17 00:00:00 2001 From: Nyr Date: Fri, 19 May 2023 16:16:50 +0200 Subject: [PATCH 51/65] Update to easy-rsa v3.1.3 --- openvpn-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 637fe3cc..073e94e5 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -236,7 +236,7 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab systemctl enable --now firewalld.service fi # Get easy-rsa - easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.2/EasyRSA-3.1.2.tgz' + easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.3/EasyRSA-3.1.3.tgz' mkdir -p /etc/openvpn/server/easy-rsa/ { wget -qO- "$easy_rsa_url" 2>/dev/null || curl -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1 chown -R root:root /etc/openvpn/server/easy-rsa/ From cd6869bf4d2997d9d81e4a0c9412ff92af2ecbf2 Mon Sep 17 00:00:00 2001 From: Nyr Date: Wed, 14 Jun 2023 12:51:58 +0200 Subject: [PATCH 52/65] Update to easy-rsa v3.1.5 --- openvpn-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 073e94e5..764a889d 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -236,7 +236,7 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab systemctl enable --now firewalld.service fi # Get easy-rsa - easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.3/EasyRSA-3.1.3.tgz' + easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.5/EasyRSA-3.1.5.tgz' mkdir -p /etc/openvpn/server/easy-rsa/ { wget -qO- "$easy_rsa_url" 2>/dev/null || curl -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1 chown -R root:root /etc/openvpn/server/easy-rsa/ From af2710df4623579c4acf84b06c5ec2b04f7594ab Mon Sep 17 00:00:00 2001 From: Nyr Date: Sat, 14 Oct 2023 19:22:24 +0200 Subject: [PATCH 53/65] Update to easy-rsa v3.1.7 --- openvpn-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 764a889d..96cb98c5 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -236,7 +236,7 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab systemctl enable --now firewalld.service fi # Get easy-rsa - easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.5/EasyRSA-3.1.5.tgz' + easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.7/EasyRSA-3.1.7.tgz' mkdir -p /etc/openvpn/server/easy-rsa/ { wget -qO- "$easy_rsa_url" 2>/dev/null || curl -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1 chown -R root:root /etc/openvpn/server/easy-rsa/ From 4b412c94b4314c0c7a9a90381a454f622dac3ea6 Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 19 Oct 2023 16:17:28 +0200 Subject: [PATCH 54/65] Fix #970 --- openvpn-install.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 96cb98c5..d13261d1 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -50,10 +50,16 @@ This version of Ubuntu is too old and unsupported." exit fi -if [[ "$os" == "debian" && "$os_version" -lt 9 ]]; then - echo "Debian 9 or higher is required to use this installer. +if [[ "$os" == "debian" ]]; then + if grep -q '/sid' /etc/debian_version; then + echo "Debian Testing and Debian Unstable are unsupported by this installer." + exit + fi + if [[ "$os_version" -lt 9 ]]; then + echo "Debian 9 or higher is required to use this installer. This version of Debian is too old and unsupported." - exit + exit + fi fi if [[ "$os" == "centos" && "$os_version" -lt 7 ]]; then From 52b12468b1b70ce349a46a7598034a0931e4d5d7 Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 26 Oct 2023 16:11:50 +0200 Subject: [PATCH 55/65] Remove --cipher parameter --cipher has been deprecated since v2.4 and was kept for compatibility purposes. --- openvpn-install.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index d13261d1..ff1d0db2 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -329,7 +329,6 @@ server 10.8.0.0 255.255.255.0" > /etc/openvpn/server/server.conf esac echo 'push "block-outside-dns"' >> /etc/openvpn/server/server.conf echo "keepalive 10 120 -cipher AES-256-CBC user nobody group $group_name persist-key @@ -429,7 +428,6 @@ persist-key persist-tun remote-cert-tls server auth SHA512 -cipher AES-256-CBC ignore-unknown-option block-outside-dns verb 3" > /etc/openvpn/server/client-common.txt # Enable and start the OpenVPN service From 6936231d86f67f99e1777600ad06e052752447d5 Mon Sep 17 00:00:00 2001 From: Nyr Date: Wed, 8 Nov 2023 12:40:11 +0100 Subject: [PATCH 56/65] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 838c8c23..82f7a27f 100644 --- a/README.md +++ b/README.md @@ -16,5 +16,7 @@ Once it ends, you can run it again to add more users, remove some of them or eve You can get a VPS from just 2€/month at [AlphaVPS](https://alphavps.com/clients/aff.php?aff=474&pid=422). ### Donations - If you want to show your appreciation, you can donate via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VBAYDL34Z7J6L) or [cryptocurrency](https://pastebin.com/raw/M2JJpQpC). Thanks! + +### Sponsor +This project is proudly sponsored by our friends at [FrogeHost](https://froge.host/?utm_source=nyr). From b86d97d3e321d83edec56395a162fb95429783b0 Mon Sep 17 00:00:00 2001 From: Nyr Date: Tue, 23 Apr 2024 14:06:10 +0200 Subject: [PATCH 57/65] Remove support for old distros The following versions are no longer supported: - Debian 10 - Ubuntu 18.04 - Ubuntu 20.04 - CentOS/Alma/Rocky 7 - CentOS/Alma/Rocky 8 - Fedora 31 --- openvpn-install.sh | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index ff1d0db2..ff56a664 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -14,12 +14,6 @@ fi # Discard stdin. Needed when running from an one-liner which includes a newline read -N 999999 -t 0.001 -# Detect OpenVZ 6 -if [[ $(uname -r | cut -d "." -f 1) -eq 2 ]]; then - echo "The system is running an old kernel, which is incompatible with this installer." - exit -fi - # Detect OS # $os_version variables aren't always in use, but are kept here for convenience if grep -qs "ubuntu" /etc/os-release; then @@ -44,8 +38,8 @@ Supported distros are Ubuntu, Debian, AlmaLinux, Rocky Linux, CentOS and Fedora. exit fi -if [[ "$os" == "ubuntu" && "$os_version" -lt 1804 ]]; then - echo "Ubuntu 18.04 or higher is required to use this installer. +if [[ "$os" == "ubuntu" && "$os_version" -lt 2204 ]]; then + echo "Ubuntu 22.04 or higher is required to use this installer. This version of Ubuntu is too old and unsupported." exit fi @@ -55,15 +49,15 @@ if [[ "$os" == "debian" ]]; then echo "Debian Testing and Debian Unstable are unsupported by this installer." exit fi - if [[ "$os_version" -lt 9 ]]; then - echo "Debian 9 or higher is required to use this installer. + if [[ "$os_version" -lt 11 ]]; then + echo "Debian 11 or higher is required to use this installer. This version of Debian is too old and unsupported." exit fi fi -if [[ "$os" == "centos" && "$os_version" -lt 7 ]]; then - echo "CentOS 7 or higher is required to use this installer. +if [[ "$os" == "centos" && "$os_version" -lt 9 ]]; then + echo "CentOS 9 or higher is required to use this installer. This version of CentOS is too old and unsupported." exit fi @@ -231,8 +225,8 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab apt-get update apt-get install -y --no-install-recommends openvpn openssl ca-certificates $firewall elif [[ "$os" = "centos" ]]; then - yum install -y epel-release - yum install -y openvpn openssl ca-certificates tar $firewall + dnf install -y epel-release + dnf install -y openvpn openssl ca-certificates tar $firewall else # Else, OS must be Fedora dnf install -y openvpn openssl ca-certificates tar $firewall @@ -260,7 +254,7 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab # Without +x in the directory, OpenVPN can't run a stat() on the CRL file chmod o+x /etc/openvpn/server/ # Generate key for tls-crypt - openvpn --genkey --secret /etc/openvpn/server/tc.key + openvpn --genkey secret /etc/openvpn/server/tc.key # Create the DH parameters file using the predefined ffdhe2048 group echo '-----BEGIN DH PARAMETERS----- MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz @@ -405,13 +399,7 @@ WantedBy=multi-user.target" >> /etc/systemd/system/openvpn-iptables.service if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then # Install semanage if not already present if ! hash semanage 2>/dev/null; then - if [[ "$os_version" -eq 7 ]]; then - # Centos 7 - yum install -y policycoreutils-python - else - # CentOS 8 or Fedora dnf install -y policycoreutils-python-utils - fi fi semanage port -a -t openvpn_port_t -p "$protocol" "$port" fi @@ -553,7 +541,7 @@ else apt-get remove --purge -y openvpn else # Else, OS must be CentOS or Fedora - yum remove -y openvpn + dnf remove -y openvpn rm -rf /etc/openvpn/server fi echo From 1a484a642fd20ae751433d1c7b4e2d2235485b9f Mon Sep 17 00:00:00 2001 From: Nyr Date: Tue, 23 Apr 2024 16:44:52 +0200 Subject: [PATCH 58/65] Improve error message --- openvpn-install.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index ff56a664..5c4d5da9 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -57,8 +57,9 @@ This version of Debian is too old and unsupported." fi if [[ "$os" == "centos" && "$os_version" -lt 9 ]]; then - echo "CentOS 9 or higher is required to use this installer. -This version of CentOS is too old and unsupported." + os_name=$(sed 's/ release.*//' /etc/almalinux-release /etc/rocky-release /etc/centos-release 2>/dev/null | head -1) + echo "$os_name 9 or higher is required to use this installer. +This version of $os_name is too old and unsupported." exit fi From e4a9a310eb2d0a14dc76516b01f42b0174a2b88d Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 23 May 2024 19:18:24 +0200 Subject: [PATCH 59/65] Update to easy-rsa v3.2.0 --- openvpn-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 5c4d5da9..98ffd1d9 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -237,7 +237,7 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab systemctl enable --now firewalld.service fi # Get easy-rsa - easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.7/EasyRSA-3.1.7.tgz' + easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.2.0/EasyRSA-3.2.0.tgz' mkdir -p /etc/openvpn/server/easy-rsa/ { wget -qO- "$easy_rsa_url" 2>/dev/null || curl -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1 chown -R root:root /etc/openvpn/server/easy-rsa/ From 62781749e530830acb803d17566c3ef4ec8bd7e1 Mon Sep 17 00:00:00 2001 From: Nyr Date: Mon, 9 Sep 2024 14:23:16 +0200 Subject: [PATCH 60/65] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 82f7a27f..c577f5f0 100644 --- a/README.md +++ b/README.md @@ -18,5 +18,7 @@ You can get a VPS from just 2€/month at [AlphaVPS](https://alphavps.com/client ### Donations If you want to show your appreciation, you can donate via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VBAYDL34Z7J6L) or [cryptocurrency](https://pastebin.com/raw/M2JJpQpC). Thanks! -### Sponsor +### Sponsors This project is proudly sponsored by our friends at [FrogeHost](https://froge.host/?utm_source=nyr). + +For a commercial VPN with strong anti-censorship capabilities (最强翻墙VPN) from $1/month, check out [Clever VPN](https://www.clever-vpn.net/?wg-referral=01LOULuQoi). \ No newline at end of file From 52d545081a08392ef1ca91364905b419688c39ad Mon Sep 17 00:00:00 2001 From: Nyr Date: Fri, 13 Sep 2024 20:33:57 +0200 Subject: [PATCH 61/65] Update to easy-rsa v3.2.1 --- openvpn-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openvpn-install.sh b/openvpn-install.sh index 98ffd1d9..3de597bb 100644 --- a/openvpn-install.sh +++ b/openvpn-install.sh @@ -237,7 +237,7 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab systemctl enable --now firewalld.service fi # Get easy-rsa - easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.2.0/EasyRSA-3.2.0.tgz' + easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.2.1/EasyRSA-3.2.1.tgz' mkdir -p /etc/openvpn/server/easy-rsa/ { wget -qO- "$easy_rsa_url" 2>/dev/null || curl -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1 chown -R root:root /etc/openvpn/server/easy-rsa/ From 85963d31e6131704ed71febcd646b4c79f2bdade Mon Sep 17 00:00:00 2001 From: Nyr Date: Fri, 22 Nov 2024 13:08:56 +0100 Subject: [PATCH 62/65] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c577f5f0..99aedfe5 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Run the script and follow the assistant: Once it ends, you can run it again to add more users, remove some of them or even completely uninstall OpenVPN. ### I want to run my own VPN but don't have a server for that -You can get a VPS from just 2€/month at [AlphaVPS](https://alphavps.com/clients/aff.php?aff=474&pid=422). +You can get a VPS from just 2 [EUR](https://alphavps.com/clients/store/openvpn?aff=474¤cy=1)/[USD](https://alphavps.com/clients/store/openvpn?aff=474¤cy=6) per month at [AlphaVPS](https://alphavps.com/clients/store/openvpn?aff=474¤cy=1). ### Donations If you want to show your appreciation, you can donate via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VBAYDL34Z7J6L) or [cryptocurrency](https://pastebin.com/raw/M2JJpQpC). Thanks! From c15f4dd357ce49a8a53425e8049ea012ae70a7ef Mon Sep 17 00:00:00 2001 From: Nyr Date: Fri, 22 Nov 2024 13:12:30 +0100 Subject: [PATCH 63/65] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 99aedfe5..c20e6f59 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Run the script and follow the assistant: Once it ends, you can run it again to add more users, remove some of them or even completely uninstall OpenVPN. ### I want to run my own VPN but don't have a server for that -You can get a VPS from just 2 [EUR](https://alphavps.com/clients/store/openvpn?aff=474¤cy=1)/[USD](https://alphavps.com/clients/store/openvpn?aff=474¤cy=6) per month at [AlphaVPS](https://alphavps.com/clients/store/openvpn?aff=474¤cy=1). +You can get a VPS from just 2 [EUR](https://alphavps.com/clients/store/openvpn?aff=474¤cy=1) or [USD](https://alphavps.com/clients/store/openvpn?aff=474¤cy=6) per month at [AlphaVPS](https://alphavps.com/clients/store/openvpn?aff=474¤cy=1). ### Donations If you want to show your appreciation, you can donate via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VBAYDL34Z7J6L) or [cryptocurrency](https://pastebin.com/raw/M2JJpQpC). Thanks! From d5289e138cd1648cbfa09ee9cdc119a60f3afba8 Mon Sep 17 00:00:00 2001 From: Nyr Date: Tue, 10 Dec 2024 17:08:26 +0100 Subject: [PATCH 64/65] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c20e6f59..612a940d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Run the script and follow the assistant: Once it ends, you can run it again to add more users, remove some of them or even completely uninstall OpenVPN. ### I want to run my own VPN but don't have a server for that -You can get a VPS from just 2 [EUR](https://alphavps.com/clients/store/openvpn?aff=474¤cy=1) or [USD](https://alphavps.com/clients/store/openvpn?aff=474¤cy=6) per month at [AlphaVPS](https://alphavps.com/clients/store/openvpn?aff=474¤cy=1). +You can get a VPS from just 2 [EUR](https://alphavps.com/clients/cart.php?a=add&pid=457?aff=474¤cy=1) or [USD](https://alphavps.com/clients/cart.php?a=add&pid=457?aff=474¤cy=6) per month at [AlphaVPS](https://alphavps.com/clients/cart.php?a=add&pid=457?aff=474¤cy=1). ### Donations If you want to show your appreciation, you can donate via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VBAYDL34Z7J6L) or [cryptocurrency](https://pastebin.com/raw/M2JJpQpC). Thanks! From 51a25a5a50158f4df34311368a6e31d69f814720 Mon Sep 17 00:00:00 2001 From: Nyr Date: Thu, 12 Dec 2024 13:14:10 +0100 Subject: [PATCH 65/65] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 612a940d..fae9e1f0 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Run the script and follow the assistant: Once it ends, you can run it again to add more users, remove some of them or even completely uninstall OpenVPN. ### I want to run my own VPN but don't have a server for that -You can get a VPS from just 2 [EUR](https://alphavps.com/clients/cart.php?a=add&pid=457?aff=474¤cy=1) or [USD](https://alphavps.com/clients/cart.php?a=add&pid=457?aff=474¤cy=6) per month at [AlphaVPS](https://alphavps.com/clients/cart.php?a=add&pid=457?aff=474¤cy=1). +You can get a VPS from just [2 EUR](https://alphavps.com/clients/cart.php?a=add&pid=457&aff=474¤cy=1) or [2 USD](https://alphavps.com/clients/cart.php?a=add&pid=457&aff=474¤cy=6) per month at [AlphaVPS](https://alphavps.com/clients/cart.php?a=add&pid=457&aff=474¤cy=1). ### Donations If you want to show your appreciation, you can donate via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VBAYDL34Z7J6L) or [cryptocurrency](https://pastebin.com/raw/M2JJpQpC). Thanks!