Update from ORG (#1)

* 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.

* Improve nf_tables test for OVZ

This test is more reliable and flexible.

* Improved easy-rsa setup

No need to write the tarball to disk.

* 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.

* 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.

* Small improvements

* Grammar improvements

* Small style changes

* Add Quad9 DNS servers

* egrep IP regex optimizations

* Fix #762

Variables which can be empty, shouldn't be quoted in this situation.

* Fix #764

* resolv.conf parsing optimizations

* Update README.md

* Update README.md

* Bugfix

-N is an illegal option for read in sh, so check if the user is using sh first.

* Update to easy-rsa v3.0.8

* Update AdGuard DNS IP

AdGuard changed their DNS IP recently:
https://adguard.com/en/blog/adguard-dns-new-addresses.html

Thanks @trantuanminh1754 for noticing.

Co-authored-by: Nyr <me@nyr.be>
Co-authored-by: Orcun <59258329+sorcun@users.noreply.github.com>
This commit is contained in:
toornet 2021-02-03 14:57:45 -04:00 committed by GitHub
parent 61549ffcef
commit 32a91d606c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 100 additions and 82 deletions

View File

@ -1,3 +1,5 @@
**New: [wireguard-install](https://github.com/Nyr/wireguard-install) is also available.**
## openvpn-install ## 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, CentOS and Fedora.

View File

@ -7,12 +7,16 @@
# Detect Debian users running the script with "sh" instead of bash # Detect Debian users running the script with "sh" instead of bash
if readlink /proc/$$/exe | grep -q "dash"; then 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 exit
fi fi
if [[ "$EUID" -ne 0 ]]; then # Discard stdin. Needed when running from an one-liner which includes a newline
echo "Sorry, you need to run this as root" 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 exit
fi fi
@ -35,31 +39,43 @@ elif [[ -e /etc/fedora-release ]]; then
os_version=$(grep -oE '[0-9]+' /etc/fedora-release | head -1) os_version=$(grep -oE '[0-9]+' /etc/fedora-release | head -1)
group_name="nobody" group_name="nobody"
else 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 exit
fi fi
if [[ "$os" == "ubuntu" && "$os_version" -lt 1804 ]]; then if [[ "$os" == "ubuntu" && "$os_version" -lt 1804 ]]; then
echo "Ubuntu 18.04 or higher is required to use this installer echo "Ubuntu 18.04 or higher is required to use this installer.
This version of Ubuntu is too old and unsupported" This version of Ubuntu is too old and unsupported."
exit exit
fi fi
if [[ "$os" == "debian" && "$os_version" -lt 9 ]]; then if [[ "$os" == "debian" && "$os_version" -lt 9 ]]; then
echo "Debian 9 or higher is required to use this installer echo "Debian 9 or higher is required to use this installer.
This version of Debian is too old and unsupported" This version of Debian is too old and unsupported."
exit exit
fi fi
if [[ "$os" == "centos" && "$os_version" -lt 7 ]]; then if [[ "$os" == "centos" && "$os_version" -lt 7 ]]; then
echo "CentOS 7 or higher is required to use this installer echo "CentOS 7 or higher is required to use this installer.
This version of CentOS is too old and unsupported" This version of CentOS is too old and unsupported."
exit exit
fi fi
if [[ ! -e /dev/net/tun ]]; then # Detect environments where $PATH does not include the sbin directories
echo "The TUN device is not available if ! grep -q sbin <<< "$PATH"; then
You need to enable TUN before running this script" echo '$PATH does not include sbin. Try using "su -" instead of "su".'
exit
fi
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 exit
fi fi
@ -85,35 +101,32 @@ new_client () {
if [[ ! -e /etc/openvpn/server/server.conf ]]; then if [[ ! -e /etc/openvpn/server/server.conf ]]; then
clear 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."
# If system has a single IPv4, it is selected automatically. Else, ask the user # 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 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}\.[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}') 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 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
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 ') ' 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 read -p "IPv4 address [1]: " ip_number
until [[ -z "$ip_number" || "$ip_number" =~ ^[0-9]+$ && "$ip_number" -le "$number_of_ip" ]]; do until [[ -z "$ip_number" || "$ip_number" =~ ^[0-9]+$ && "$ip_number" -le "$number_of_ip" ]]; do
echo "$ip_number: invalid selection." echo "$ip_number: invalid selection."
read -p "IPv4 address [1]: " ip_number read -p "IPv4 address [1]: " ip_number
done done
[[ -z "$ip_number" ]] && ip_number="1" [[ -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 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 if echo "$ip" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then
echo echo
echo "This server is behind NAT. What is the public IPv4 address or hostname?" echo "This server is behind NAT. What is the public IPv4 address or hostname?"
# Get public IP and sanitize with grep # 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 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 # If the checkip service is unavailable and user didn't provide input, ask again
until [[ -n "$get_public_ip" || -n $public_ip ]]; do until [[ -n "$get_public_ip" || -n "$public_ip" ]]; do
echo "Invalid input." echo "Invalid input."
read -p "Public IPv4 address / hostname: " public_ip read -p "Public IPv4 address / hostname: " public_ip
done done
[[ -z "$public_ip" ]] && public_ip="$get_public_ip" [[ -z "$public_ip" ]] && public_ip="$get_public_ip"
@ -126,7 +139,7 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then
if [[ $(ip -6 addr | grep -c 'inet6 [23]') -gt 1 ]]; then if [[ $(ip -6 addr | grep -c 'inet6 [23]') -gt 1 ]]; then
number_of_ip6=$(ip -6 addr | grep -c 'inet6 [23]') number_of_ip6=$(ip -6 addr | grep -c 'inet6 [23]')
echo 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 ') ' 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 read -p "IPv6 address [1]: " ip6_number
until [[ -z "$ip6_number" || "$ip6_number" =~ ^[0-9]+$ && "$ip6_number" -le "$number_of_ip6" ]]; do until [[ -z "$ip6_number" || "$ip6_number" =~ ^[0-9]+$ && "$ip6_number" -le "$number_of_ip6" ]]; do
@ -137,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) 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 fi
echo echo
echo "Which protocol do you want for OpenVPN connections?" echo "Which protocol should OpenVPN use?"
echo " 1) UDP (recommended)" echo " 1) UDP (recommended)"
echo " 2) TCP" echo " 2) TCP"
read -p "Protocol [1]: " protocol read -p "Protocol [1]: " protocol
@ -154,7 +167,7 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then
;; ;;
esac esac
echo echo
echo "What port do you want OpenVPN listening to?" echo "What port should OpenVPN listen to?"
read -p "Port [1194]: " port read -p "Port [1194]: " port
until [[ -z "$port" || "$port" =~ ^[0-9]+$ && "$port" -le 65535 ]]; do until [[ -z "$port" || "$port" =~ ^[0-9]+$ && "$port" -le 65535 ]]; do
echo "$port: invalid port." echo "$port: invalid port."
@ -162,40 +175,38 @@ if [[ ! -e /etc/openvpn/server/server.conf ]]; then
done done
[[ -z "$port" ]] && port="1194" [[ -z "$port" ]] && port="1194"
echo 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 " 1) Current system resolvers"
echo " 2) 1.1.1.1" echo " 2) Google"
echo " 3) Google" echo " 3) 1.1.1.1"
echo " 4) OpenDNS" echo " 4) OpenDNS"
echo " 5) NTT" echo " 5) Quad9"
echo " 6) AdGuard" echo " 6) AdGuard"
read -p "DNS [1]: " dns read -p "DNS server [1]: " dns
until [[ -z "$dns" || "$dns" =~ ^[1-6]$ ]]; do until [[ -z "$dns" || "$dns" =~ ^[1-6]$ ]]; do
echo "$dns: invalid selection." echo "$dns: invalid selection."
read -p "DNS [1]: " dns read -p "DNS server [1]: " dns
done done
echo echo
echo "Finally, tell me a name for the client certificate." echo "Enter a name for the first client:"
read -p "Client name [client]: " unsanitized_client read -p "Name [client]: " unsanitized_client
# Allow a limited set of characters to avoid conflicts # Allow a limited set of characters to avoid conflicts
client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client")
[[ -z "$client" ]] && client="client" [[ -z "$client" ]] && client="client"
echo echo
echo "We are ready to set up your OpenVPN server now." echo "OpenVPN installation is ready to begin."
# Install a firewall in the rare case where one is not already available # 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 ! systemctl is-active --quiet firewalld.service && ! hash iptables 2>/dev/null; then
if [[ "$os" == "centos" || "$os" == "fedora" ]]; then if [[ "$os" == "centos" || "$os" == "fedora" ]]; then
firewall="firewalld" firewall="firewalld"
# We don't want to silently enable firewalld, so we give a subtle warning # 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 # 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." echo "firewalld, which is required to manage routing tables, will also be installed."
elif [[ "$os" == "debian" || "$os" == "ubuntu" ]]; then elif [[ "$os" == "debian" || "$os" == "ubuntu" ]]; then
# iptables is way less invasive than firewalld so no warning is given # iptables is way less invasive than firewalld so no warning is given
firewall="iptables" firewall="iptables"
fi fi
fi fi
echo
read -n1 -r -p "Press any key to continue..." read -n1 -r -p "Press any key to continue..."
# If running inside a container, disable LimitNPROC to prevent conflicts # If running inside a container, disable LimitNPROC to prevent conflicts
if systemd-detect-virt -cq; then if systemd-detect-virt -cq; then
@ -218,13 +229,10 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab
systemctl enable --now firewalld.service systemctl enable --now firewalld.service
fi fi
# Get easy-rsa # 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'
wget -O ~/easyrsa.tgz "$easy_rsa_url" 2>/dev/null || curl -Lo ~/easyrsa.tgz "$easy_rsa_url" mkdir -p /etc/openvpn/server/easy-rsa/
tar xzf ~/easyrsa.tgz -C ~/ { wget -qO- "$easy_rsa_url" 2>/dev/null || curl -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1
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/ chown -R root:root /etc/openvpn/server/easy-rsa/
rm -f ~/easyrsa.tgz
cd /etc/openvpn/server/easy-rsa/ cd /etc/openvpn/server/easy-rsa/
# Create the PKI, set up the CA and the server and client certificates # Create the PKI, set up the CA and the server and client certificates
./easyrsa init-pki ./easyrsa init-pki
@ -234,8 +242,10 @@ LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disab
EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
# Move the stuff we need # 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 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 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 # 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 # Create the DH parameters file using the predefined ffdhe2048 group
@ -273,35 +283,35 @@ server 10.8.0.0 255.255.255.0" > /etc/openvpn/server/server.conf
1|"") 1|"")
# Locate the proper resolv.conf # Locate the proper resolv.conf
# Needed for systems running systemd-resolved # 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" resolv_conf="/run/systemd/resolve/resolv.conf"
else else
resolv_conf="/etc/resolv.conf" resolv_conf="/etc/resolv.conf"
fi fi
# Obtain the resolvers from resolv.conf and use them for OpenVPN # 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 -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 echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server/server.conf
done done
;; ;;
2) 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.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.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) 4)
echo 'push "dhcp-option DNS 208.67.222.222"' >> /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 echo 'push "dhcp-option DNS 208.67.220.220"' >> /etc/openvpn/server/server.conf
;; ;;
5) 5)
echo 'push "dhcp-option DNS 129.250.35.250"' >> /etc/openvpn/server/server.conf echo 'push "dhcp-option DNS 9.9.9.9"' >> /etc/openvpn/server/server.conf
echo 'push "dhcp-option DNS 129.250.35.251"' >> /etc/openvpn/server/server.conf echo 'push "dhcp-option DNS 149.112.112.112"' >> /etc/openvpn/server/server.conf
;; ;;
6) 6)
echo 'push "dhcp-option DNS 176.103.130.130"' >> /etc/openvpn/server/server.conf echo 'push "dhcp-option DNS 94.140.14.14"' >> /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.15.15"' >> /etc/openvpn/server/server.conf
;; ;;
esac esac
echo "keepalive 10 120 echo "keepalive 10 120
@ -348,6 +358,12 @@ crl-verify crl.pem" >> /etc/openvpn/server/server.conf
# Create a service to set up persistent iptables rules # Create a service to set up persistent iptables rules
iptables_path=$(command -v iptables) iptables_path=$(command -v iptables)
ip6tables_path=$(command -v ip6tables) 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
iptables_path=$(command -v iptables-legacy)
ip6tables_path=$(command -v ip6tables-legacy)
fi
echo "[Unit] echo "[Unit]
Before=network.target Before=network.target
[Service] [Service]
@ -361,7 +377,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 -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 ExecStop=$iptables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" > /etc/systemd/system/openvpn-iptables.service
if [[ -n "$ip6" ]]; then 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 -s fddd:1194:1194:1194::/64 -j ACCEPT
ExecStart=$ip6tables_path -I FORWARD -m state --state RELATED,ESTABLISHED -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 -t nat -D POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to $ip6
@ -388,7 +404,7 @@ WantedBy=multi-user.target" >> /etc/systemd/system/openvpn-iptables.service
semanage port -a -t openvpn_port_t -p "$protocol" "$port" semanage port -a -t openvpn_port_t -p "$protocol" "$port"
fi fi
# If the server is behind NAT, use the correct IP address # 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 # client-common.txt is created so we have a template to add further users later
echo "client echo "client
dev tun dev tun
@ -411,31 +427,31 @@ verb 3" > /etc/openvpn/server/client-common.txt
echo echo
echo "Finished!" echo "Finished!"
echo echo
echo "Your client configuration is available at:" ~/"$client.ovpn" echo "The client configuration is available in:" ~/"$client.ovpn"
echo "If you want to add more clients, just run this script again!" echo "New clients can be added by running this script again."
else else
clear clear
echo "Looks like OpenVPN is already installed." echo "OpenVPN is already installed."
echo echo
echo "What do you want to do?" echo "Select an option:"
echo " 1) Add a new user" echo " 1) Add a new client"
echo " 2) Revoke an existing user" echo " 2) Revoke an existing client"
echo " 3) Remove OpenVPN" echo " 3) Remove OpenVPN"
echo " 4) Exit" echo " 4) Exit"
read -p "Select an option: " option read -p "Option: " option
until [[ "$option" =~ ^[1-4]$ ]]; do until [[ "$option" =~ ^[1-4]$ ]]; do
echo "$option: invalid selection." echo "$option: invalid selection."
read -p "Select an option: " option read -p "Option: " option
done done
case "$option" in case "$option" in
1) 1)
echo echo
echo "Tell me a name for the client certificate." echo "Provide a name for the client:"
read -p "Client name: " unsanitized_client read -p "Name: " unsanitized_client
client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client")
while [[ -z "$client" || -e /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt ]]; do while [[ -z "$client" || -e /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt ]]; do
echo "$client: invalid client name." echo "$client: invalid name."
read -p "Client name: " unsanitized_client read -p "Name: " unsanitized_client
client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client") client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client")
done done
cd /etc/openvpn/server/easy-rsa/ cd /etc/openvpn/server/easy-rsa/
@ -443,7 +459,7 @@ else
# Generates the custom client.ovpn # Generates the custom client.ovpn
new_client new_client
echo echo
echo "Client $client added, configuration is available at:" ~/"$client.ovpn" echo "$client added. Configuration available in:" ~/"$client.ovpn"
exit exit
;; ;;
2) 2)
@ -452,23 +468,23 @@ else
number_of_clients=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep -c "^V") number_of_clients=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep -c "^V")
if [[ "$number_of_clients" = 0 ]]; then if [[ "$number_of_clients" = 0 ]]; then
echo echo
echo "You have no existing clients!" echo "There are no existing clients!"
exit exit
fi fi
echo 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 ') ' 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 until [[ "$client_number" =~ ^[0-9]+$ && "$client_number" -le "$number_of_clients" ]]; do
echo "$client_number: invalid selection." echo "$client_number: invalid selection."
read -p "Select one client: " client_number read -p "Client: " client_number
done done
client=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$client_number"p) client=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$client_number"p)
echo 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 until [[ "$revoke" =~ ^[yYnN]*$ ]]; do
echo "$revoke: invalid selection." 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 done
if [[ "$revoke" =~ ^[yY]$ ]]; then if [[ "$revoke" =~ ^[yY]$ ]]; then
cd /etc/openvpn/server/easy-rsa/ cd /etc/openvpn/server/easy-rsa/
@ -479,19 +495,19 @@ else
# CRL is read with each client connection, when OpenVPN is dropped to nobody # CRL is read with each client connection, when OpenVPN is dropped to nobody
chown nobody:"$group_name" /etc/openvpn/server/crl.pem chown nobody:"$group_name" /etc/openvpn/server/crl.pem
echo echo
echo "Certificate for client $client revoked!" echo "$client revoked!"
else else
echo echo
echo "Certificate revocation for client $client aborted!" echo "$client revocation aborted!"
fi fi
exit exit
;; ;;
3) 3)
echo 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 until [[ "$remove" =~ ^[yYnN]*$ ]]; do
echo "$remove: invalid selection." 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 done
if [[ "$remove" =~ ^[yY]$ ]]; then if [[ "$remove" =~ ^[yY]$ ]]; then
port=$(grep '^port ' /etc/openvpn/server/server.conf | cut -d " " -f 2) port=$(grep '^port ' /etc/openvpn/server/server.conf | cut -d " " -f 2)
@ -533,7 +549,7 @@ else
echo "OpenVPN removed!" echo "OpenVPN removed!"
else else
echo echo
echo "Removal aborted!" echo "OpenVPN removal aborted!"
fi fi
exit exit
;; ;;