annotate openvpn-install.sh @ 0:ebdb0cecebc0 default tip

新增
author Pluto <meokcin@gmail.com>
date Sun, 01 Sep 2024 16:38:41 +0800
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
Pluto <meokcin@gmail.com>
parents:
diff changeset
1 #!/bin/bash
Pluto <meokcin@gmail.com>
parents:
diff changeset
2 #
Pluto <meokcin@gmail.com>
parents:
diff changeset
3 # https://github.com/hwdsl2/openvpn-install
Pluto <meokcin@gmail.com>
parents:
diff changeset
4 #
Pluto <meokcin@gmail.com>
parents:
diff changeset
5 # Based on the work of Nyr and contributors at:
Pluto <meokcin@gmail.com>
parents:
diff changeset
6 # https://github.com/Nyr/openvpn-install
Pluto <meokcin@gmail.com>
parents:
diff changeset
7 #
Pluto <meokcin@gmail.com>
parents:
diff changeset
8 # Copyright (c) 2022-2024 Lin Song <linsongui@gmail.com>
Pluto <meokcin@gmail.com>
parents:
diff changeset
9 # Copyright (c) 2013-2023 Nyr
Pluto <meokcin@gmail.com>
parents:
diff changeset
10 #
Pluto <meokcin@gmail.com>
parents:
diff changeset
11 # Released under the MIT License, see the accompanying file LICENSE.txt
Pluto <meokcin@gmail.com>
parents:
diff changeset
12 # or https://opensource.org/licenses/MIT
Pluto <meokcin@gmail.com>
parents:
diff changeset
13
Pluto <meokcin@gmail.com>
parents:
diff changeset
14 exiterr() { echo "Error: $1" >&2; exit 1; }
Pluto <meokcin@gmail.com>
parents:
diff changeset
15 exiterr2() { exiterr "'apt-get install' failed."; }
Pluto <meokcin@gmail.com>
parents:
diff changeset
16 exiterr3() { exiterr "'yum install' failed."; }
Pluto <meokcin@gmail.com>
parents:
diff changeset
17 exiterr4() { exiterr "'zypper install' failed."; }
Pluto <meokcin@gmail.com>
parents:
diff changeset
18
Pluto <meokcin@gmail.com>
parents:
diff changeset
19 check_ip() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
20 IP_REGEX='^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$'
Pluto <meokcin@gmail.com>
parents:
diff changeset
21 printf '%s' "$1" | tr -d '\n' | grep -Eq "$IP_REGEX"
Pluto <meokcin@gmail.com>
parents:
diff changeset
22 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
23
Pluto <meokcin@gmail.com>
parents:
diff changeset
24 check_os() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
25 if grep -qs "ubuntu" /etc/os-release; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
26 os="ubuntu"
Pluto <meokcin@gmail.com>
parents:
diff changeset
27 os_version=$(grep 'VERSION_ID' /etc/os-release | cut -d '"' -f 2 | tr -d '.')
Pluto <meokcin@gmail.com>
parents:
diff changeset
28 group_name="nogroup"
Pluto <meokcin@gmail.com>
parents:
diff changeset
29 elif [[ -e /etc/debian_version ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
30 os="debian"
Pluto <meokcin@gmail.com>
parents:
diff changeset
31 os_version=$(grep -oE '[0-9]+' /etc/debian_version | head -1)
Pluto <meokcin@gmail.com>
parents:
diff changeset
32 group_name="nogroup"
Pluto <meokcin@gmail.com>
parents:
diff changeset
33 elif [[ -e /etc/almalinux-release || -e /etc/rocky-release || -e /etc/centos-release ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
34 os="centos"
Pluto <meokcin@gmail.com>
parents:
diff changeset
35 os_version=$(grep -shoE '[0-9]+' /etc/almalinux-release /etc/rocky-release /etc/centos-release | head -1)
Pluto <meokcin@gmail.com>
parents:
diff changeset
36 group_name="nobody"
Pluto <meokcin@gmail.com>
parents:
diff changeset
37 elif grep -qs "Amazon Linux release 2 " /etc/system-release; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
38 os="centos"
Pluto <meokcin@gmail.com>
parents:
diff changeset
39 os_version="7"
Pluto <meokcin@gmail.com>
parents:
diff changeset
40 group_name="nobody"
Pluto <meokcin@gmail.com>
parents:
diff changeset
41 elif grep -qs "Amazon Linux release 2023" /etc/system-release; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
42 exiterr "Amazon Linux 2023 is not supported."
Pluto <meokcin@gmail.com>
parents:
diff changeset
43 elif [[ -e /etc/fedora-release ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
44 os="fedora"
Pluto <meokcin@gmail.com>
parents:
diff changeset
45 os_version=$(grep -oE '[0-9]+' /etc/fedora-release | head -1)
Pluto <meokcin@gmail.com>
parents:
diff changeset
46 group_name="nobody"
Pluto <meokcin@gmail.com>
parents:
diff changeset
47 elif [[ -e /etc/SUSE-brand && "$(head -1 /etc/SUSE-brand)" == "openSUSE" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
48 os="openSUSE"
Pluto <meokcin@gmail.com>
parents:
diff changeset
49 os_version=$(tail -1 /etc/SUSE-brand | grep -oE '[0-9\\.]+')
Pluto <meokcin@gmail.com>
parents:
diff changeset
50 group_name="nogroup"
Pluto <meokcin@gmail.com>
parents:
diff changeset
51 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
52 exiterr "This installer seems to be running on an unsupported distribution.
Pluto <meokcin@gmail.com>
parents:
diff changeset
53 Supported distros are Ubuntu, Debian, AlmaLinux, Rocky Linux, CentOS, Fedora, openSUSE and Amazon Linux 2."
Pluto <meokcin@gmail.com>
parents:
diff changeset
54 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
55 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
56
Pluto <meokcin@gmail.com>
parents:
diff changeset
57 check_os_ver() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
58 if [[ "$os" == "ubuntu" && "$os_version" -lt 1804 ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
59 exiterr "Ubuntu 18.04 or higher is required to use this installer.
Pluto <meokcin@gmail.com>
parents:
diff changeset
60 This version of Ubuntu is too old and unsupported."
Pluto <meokcin@gmail.com>
parents:
diff changeset
61 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
62
Pluto <meokcin@gmail.com>
parents:
diff changeset
63 if [[ "$os" == "debian" && "$os_version" -lt 9 ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
64 exiterr "Debian 9 or higher is required to use this installer.
Pluto <meokcin@gmail.com>
parents:
diff changeset
65 This version of Debian is too old and unsupported."
Pluto <meokcin@gmail.com>
parents:
diff changeset
66 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
67
Pluto <meokcin@gmail.com>
parents:
diff changeset
68 if [[ "$os" == "centos" && "$os_version" -lt 7 ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
69 exiterr "CentOS 7 or higher is required to use this installer.
Pluto <meokcin@gmail.com>
parents:
diff changeset
70 This version of CentOS is too old and unsupported."
Pluto <meokcin@gmail.com>
parents:
diff changeset
71 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
72 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
73
Pluto <meokcin@gmail.com>
parents:
diff changeset
74 check_nftables() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
75 if [ "$os" = "centos" ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
76 if grep -qs "hwdsl2 VPN script" /etc/sysconfig/nftables.conf \
Pluto <meokcin@gmail.com>
parents:
diff changeset
77 || systemctl is-active --quiet nftables 2>/dev/null; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
78 exiterr "This system has nftables enabled, which is not supported by this installer."
Pluto <meokcin@gmail.com>
parents:
diff changeset
79 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
80 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
81 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
82
Pluto <meokcin@gmail.com>
parents:
diff changeset
83 check_dns_name() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
84 FQDN_REGEX='^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$'
Pluto <meokcin@gmail.com>
parents:
diff changeset
85 printf '%s' "$1" | tr -d '\n' | grep -Eq "$FQDN_REGEX"
Pluto <meokcin@gmail.com>
parents:
diff changeset
86 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
87
Pluto <meokcin@gmail.com>
parents:
diff changeset
88 install_wget() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
89 # Detect some Debian minimal setups where neither wget nor curl are installed
Pluto <meokcin@gmail.com>
parents:
diff changeset
90 if ! hash wget 2>/dev/null && ! hash curl 2>/dev/null; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
91 if [ "$auto" = 0 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
92 echo "Wget is required to use this installer."
Pluto <meokcin@gmail.com>
parents:
diff changeset
93 read -n1 -r -p "Press any key to install Wget and continue..."
Pluto <meokcin@gmail.com>
parents:
diff changeset
94 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
95 export DEBIAN_FRONTEND=noninteractive
Pluto <meokcin@gmail.com>
parents:
diff changeset
96 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
97 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
98 apt-get -yqq update || apt-get -yqq update
Pluto <meokcin@gmail.com>
parents:
diff changeset
99 apt-get -yqq install wget >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
100 ) || exiterr2
Pluto <meokcin@gmail.com>
parents:
diff changeset
101 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
102 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
103
Pluto <meokcin@gmail.com>
parents:
diff changeset
104 install_iproute() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
105 if ! hash ip 2>/dev/null; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
106 if [ "$auto" = 0 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
107 echo "iproute is required to use this installer."
Pluto <meokcin@gmail.com>
parents:
diff changeset
108 read -n1 -r -p "Press any key to install iproute and continue..."
Pluto <meokcin@gmail.com>
parents:
diff changeset
109 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
110 if [ "$os" = "debian" ] || [ "$os" = "ubuntu" ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
111 export DEBIAN_FRONTEND=noninteractive
Pluto <meokcin@gmail.com>
parents:
diff changeset
112 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
113 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
114 apt-get -yqq update || apt-get -yqq update
Pluto <meokcin@gmail.com>
parents:
diff changeset
115 apt-get -yqq install iproute2 >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
116 ) || exiterr2
Pluto <meokcin@gmail.com>
parents:
diff changeset
117 elif [ "$os" = "openSUSE" ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
118 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
119 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
120 zypper install iproute2 >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
121 ) || exiterr4
Pluto <meokcin@gmail.com>
parents:
diff changeset
122 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
123 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
124 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
125 yum -y -q install iproute >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
126 ) || exiterr3
Pluto <meokcin@gmail.com>
parents:
diff changeset
127 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
128 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
129 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
130
Pluto <meokcin@gmail.com>
parents:
diff changeset
131 show_start_setup() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
132 if [ "$auto" = 0 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
133 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
134 echo 'Welcome to this OpenVPN server installer!'
Pluto <meokcin@gmail.com>
parents:
diff changeset
135 echo 'GitHub: https://github.com/hwdsl2/openvpn-install'
Pluto <meokcin@gmail.com>
parents:
diff changeset
136 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
137 echo 'I need to ask you a few questions before starting setup.'
Pluto <meokcin@gmail.com>
parents:
diff changeset
138 echo 'You can use the default options and just press enter if you are OK with them.'
Pluto <meokcin@gmail.com>
parents:
diff changeset
139 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
140 show_header
Pluto <meokcin@gmail.com>
parents:
diff changeset
141 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
142 echo 'Starting OpenVPN setup using default options.'
Pluto <meokcin@gmail.com>
parents:
diff changeset
143 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
144 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
145
Pluto <meokcin@gmail.com>
parents:
diff changeset
146 enter_server_address() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
147 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
148 echo "Do you want OpenVPN clients to connect to this server using a DNS name,"
Pluto <meokcin@gmail.com>
parents:
diff changeset
149 printf "e.g. vpn.example.com, instead of its IP address? [y/N] "
Pluto <meokcin@gmail.com>
parents:
diff changeset
150 read -r response
Pluto <meokcin@gmail.com>
parents:
diff changeset
151 case $response in
Pluto <meokcin@gmail.com>
parents:
diff changeset
152 [yY][eE][sS]|[yY])
Pluto <meokcin@gmail.com>
parents:
diff changeset
153 use_dns_name=1
Pluto <meokcin@gmail.com>
parents:
diff changeset
154 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
155 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
156 *)
Pluto <meokcin@gmail.com>
parents:
diff changeset
157 use_dns_name=0
Pluto <meokcin@gmail.com>
parents:
diff changeset
158 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
159 esac
Pluto <meokcin@gmail.com>
parents:
diff changeset
160 if [ "$use_dns_name" = 1 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
161 read -rp "Enter the DNS name of this VPN server: " server_addr
Pluto <meokcin@gmail.com>
parents:
diff changeset
162 until check_dns_name "$server_addr"; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
163 echo "Invalid DNS name. You must enter a fully qualified domain name (FQDN)."
Pluto <meokcin@gmail.com>
parents:
diff changeset
164 read -rp "Enter the DNS name of this VPN server: " server_addr
Pluto <meokcin@gmail.com>
parents:
diff changeset
165 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
166 ip="$server_addr"
Pluto <meokcin@gmail.com>
parents:
diff changeset
167 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
168 echo "Note: Make sure this DNS name resolves to the IPv4 address"
Pluto <meokcin@gmail.com>
parents:
diff changeset
169 echo " of this server. If you add or update the DNS record"
Pluto <meokcin@gmail.com>
parents:
diff changeset
170 echo " at a later time, reboot this server to take effect."
Pluto <meokcin@gmail.com>
parents:
diff changeset
171 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
172 detect_ip
Pluto <meokcin@gmail.com>
parents:
diff changeset
173 check_nat_ip
Pluto <meokcin@gmail.com>
parents:
diff changeset
174 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
175 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
176
Pluto <meokcin@gmail.com>
parents:
diff changeset
177 find_public_ip() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
178 ip_url1="http://ipv4.icanhazip.com"
Pluto <meokcin@gmail.com>
parents:
diff changeset
179 ip_url2="http://ip1.dynupdate.no-ip.com"
Pluto <meokcin@gmail.com>
parents:
diff changeset
180 # Get public IP and sanitize with grep
Pluto <meokcin@gmail.com>
parents:
diff changeset
181 get_public_ip=$(grep -m 1 -oE '^[0-9]{1,3}(\.[0-9]{1,3}){3}$' <<< "$(wget -T 10 -t 1 -4qO- "$ip_url1" || curl -m 10 -4Ls "$ip_url1")")
Pluto <meokcin@gmail.com>
parents:
diff changeset
182 if ! check_ip "$get_public_ip"; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
183 get_public_ip=$(grep -m 1 -oE '^[0-9]{1,3}(\.[0-9]{1,3}){3}$' <<< "$(wget -T 10 -t 1 -4qO- "$ip_url2" || curl -m 10 -4Ls "$ip_url2")")
Pluto <meokcin@gmail.com>
parents:
diff changeset
184 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
185 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
186
Pluto <meokcin@gmail.com>
parents:
diff changeset
187 detect_ip() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
188 # If system has a single IPv4, it is selected automatically.
Pluto <meokcin@gmail.com>
parents:
diff changeset
189 if [[ $(ip -4 addr | grep inet | grep -vEc '127(\.[0-9]{1,3}){3}') -eq 1 ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
190 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}')
Pluto <meokcin@gmail.com>
parents:
diff changeset
191 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
192 # Use the IP address on the default route
Pluto <meokcin@gmail.com>
parents:
diff changeset
193 ip=$(ip -4 route get 1 | sed 's/ uid .*//' | awk '{print $NF;exit}' 2>/dev/null)
Pluto <meokcin@gmail.com>
parents:
diff changeset
194 if ! check_ip "$ip"; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
195 find_public_ip
Pluto <meokcin@gmail.com>
parents:
diff changeset
196 ip_match=0
Pluto <meokcin@gmail.com>
parents:
diff changeset
197 if [ -n "$get_public_ip" ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
198 ip_list=$(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}')
Pluto <meokcin@gmail.com>
parents:
diff changeset
199 while IFS= read -r line; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
200 if [ "$line" = "$get_public_ip" ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
201 ip_match=1
Pluto <meokcin@gmail.com>
parents:
diff changeset
202 ip="$line"
Pluto <meokcin@gmail.com>
parents:
diff changeset
203 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
204 done <<< "$ip_list"
Pluto <meokcin@gmail.com>
parents:
diff changeset
205 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
206 if [ "$ip_match" = 0 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
207 if [ "$auto" = 0 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
208 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
209 echo "Which IPv4 address should be used?"
Pluto <meokcin@gmail.com>
parents:
diff changeset
210 num_of_ip=$(ip -4 addr | grep inet | grep -vEc '127(\.[0-9]{1,3}){3}')
Pluto <meokcin@gmail.com>
parents:
diff changeset
211 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 ') '
Pluto <meokcin@gmail.com>
parents:
diff changeset
212 read -rp "IPv4 address [1]: " ip_num
Pluto <meokcin@gmail.com>
parents:
diff changeset
213 until [[ -z "$ip_num" || "$ip_num" =~ ^[0-9]+$ && "$ip_num" -le "$num_of_ip" ]]; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
214 echo "$ip_num: invalid selection."
Pluto <meokcin@gmail.com>
parents:
diff changeset
215 read -rp "IPv4 address [1]: " ip_num
Pluto <meokcin@gmail.com>
parents:
diff changeset
216 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
217 [[ -z "$ip_num" ]] && ip_num=1
Pluto <meokcin@gmail.com>
parents:
diff changeset
218 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
219 ip_num=1
Pluto <meokcin@gmail.com>
parents:
diff changeset
220 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
221 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_num"p)
Pluto <meokcin@gmail.com>
parents:
diff changeset
222 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
223 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
224 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
225 if ! check_ip "$ip"; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
226 echo "Error: Could not detect this server's IP address." >&2
Pluto <meokcin@gmail.com>
parents:
diff changeset
227 echo "Abort. No changes were made." >&2
Pluto <meokcin@gmail.com>
parents:
diff changeset
228 exit 1
Pluto <meokcin@gmail.com>
parents:
diff changeset
229 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
230 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
231
Pluto <meokcin@gmail.com>
parents:
diff changeset
232 check_nat_ip() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
233 # If $ip is a private IP address, the server must be behind NAT
Pluto <meokcin@gmail.com>
parents:
diff changeset
234 if printf '%s' "$ip" | grep -qE '^(10|127|172\.(1[6-9]|2[0-9]|3[0-1])|192\.168|169\.254)\.'; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
235 find_public_ip
Pluto <meokcin@gmail.com>
parents:
diff changeset
236 if ! check_ip "$get_public_ip"; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
237 if [ "$auto" = 0 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
238 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
239 echo "This server is behind NAT. What is the public IPv4 address?"
Pluto <meokcin@gmail.com>
parents:
diff changeset
240 read -rp "Public IPv4 address: " public_ip
Pluto <meokcin@gmail.com>
parents:
diff changeset
241 until check_ip "$public_ip"; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
242 echo "Invalid input."
Pluto <meokcin@gmail.com>
parents:
diff changeset
243 read -rp "Public IPv4 address: " public_ip
Pluto <meokcin@gmail.com>
parents:
diff changeset
244 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
245 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
246 echo "Error: Could not detect this server's public IP." >&2
Pluto <meokcin@gmail.com>
parents:
diff changeset
247 echo "Abort. No changes were made." >&2
Pluto <meokcin@gmail.com>
parents:
diff changeset
248 exit 1
Pluto <meokcin@gmail.com>
parents:
diff changeset
249 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
250 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
251 public_ip="$get_public_ip"
Pluto <meokcin@gmail.com>
parents:
diff changeset
252 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
253 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
254 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
255
Pluto <meokcin@gmail.com>
parents:
diff changeset
256 show_config() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
257 if [ "$auto" != 0 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
258 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
259 printf '%s' "Server IP: "
Pluto <meokcin@gmail.com>
parents:
diff changeset
260 [ -n "$public_ip" ] && printf '%s\n' "$public_ip" || printf '%s\n' "$ip"
Pluto <meokcin@gmail.com>
parents:
diff changeset
261 echo "Port: UDP/1194"
Pluto <meokcin@gmail.com>
parents:
diff changeset
262 echo "Client name: client"
Pluto <meokcin@gmail.com>
parents:
diff changeset
263 echo "Client DNS: Google Public DNS"
Pluto <meokcin@gmail.com>
parents:
diff changeset
264 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
265 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
266
Pluto <meokcin@gmail.com>
parents:
diff changeset
267 detect_ipv6() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
268 ip6=""
Pluto <meokcin@gmail.com>
parents:
diff changeset
269 if [[ $(ip -6 addr | grep -c 'inet6 [23]') -ne 0 ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
270 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 1p)
Pluto <meokcin@gmail.com>
parents:
diff changeset
271 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
272 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
273
Pluto <meokcin@gmail.com>
parents:
diff changeset
274 select_protocol() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
275 if [ "$auto" = 0 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
276 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
277 echo "Which protocol should OpenVPN use?"
Pluto <meokcin@gmail.com>
parents:
diff changeset
278 echo " 1) UDP (recommended)"
Pluto <meokcin@gmail.com>
parents:
diff changeset
279 echo " 2) TCP"
Pluto <meokcin@gmail.com>
parents:
diff changeset
280 read -rp "Protocol [1]: " protocol
Pluto <meokcin@gmail.com>
parents:
diff changeset
281 until [[ -z "$protocol" || "$protocol" =~ ^[12]$ ]]; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
282 echo "$protocol: invalid selection."
Pluto <meokcin@gmail.com>
parents:
diff changeset
283 read -rp "Protocol [1]: " protocol
Pluto <meokcin@gmail.com>
parents:
diff changeset
284 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
285 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
286 protocol=1
Pluto <meokcin@gmail.com>
parents:
diff changeset
287 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
288 case "$protocol" in
Pluto <meokcin@gmail.com>
parents:
diff changeset
289 1|"")
Pluto <meokcin@gmail.com>
parents:
diff changeset
290 protocol=udp
Pluto <meokcin@gmail.com>
parents:
diff changeset
291 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
292 2)
Pluto <meokcin@gmail.com>
parents:
diff changeset
293 protocol=tcp
Pluto <meokcin@gmail.com>
parents:
diff changeset
294 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
295 esac
Pluto <meokcin@gmail.com>
parents:
diff changeset
296 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
297
Pluto <meokcin@gmail.com>
parents:
diff changeset
298 select_port() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
299 if [ "$auto" = 0 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
300 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
301 echo "Which port should OpenVPN listen to?"
Pluto <meokcin@gmail.com>
parents:
diff changeset
302 read -rp "Port [1194]: " port
Pluto <meokcin@gmail.com>
parents:
diff changeset
303 until [[ -z "$port" || "$port" =~ ^[0-9]+$ && "$port" -le 65535 ]]; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
304 echo "$port: invalid port."
Pluto <meokcin@gmail.com>
parents:
diff changeset
305 read -rp "Port [1194]: " port
Pluto <meokcin@gmail.com>
parents:
diff changeset
306 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
307 [[ -z "$port" ]] && port=1194
Pluto <meokcin@gmail.com>
parents:
diff changeset
308 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
309 port=1194
Pluto <meokcin@gmail.com>
parents:
diff changeset
310 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
311 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
312
Pluto <meokcin@gmail.com>
parents:
diff changeset
313 enter_custom_dns() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
314 read -rp "Enter primary DNS server: " dns1
Pluto <meokcin@gmail.com>
parents:
diff changeset
315 until check_ip "$dns1"; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
316 echo "Invalid DNS server."
Pluto <meokcin@gmail.com>
parents:
diff changeset
317 read -rp "Enter primary DNS server: " dns1
Pluto <meokcin@gmail.com>
parents:
diff changeset
318 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
319 read -rp "Enter secondary DNS server (Enter to skip): " dns2
Pluto <meokcin@gmail.com>
parents:
diff changeset
320 until [ -z "$dns2" ] || check_ip "$dns2"; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
321 echo "Invalid DNS server."
Pluto <meokcin@gmail.com>
parents:
diff changeset
322 read -rp "Enter secondary DNS server (Enter to skip): " dns2
Pluto <meokcin@gmail.com>
parents:
diff changeset
323 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
324 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
325
Pluto <meokcin@gmail.com>
parents:
diff changeset
326 select_dns() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
327 if [ "$auto" = 0 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
328 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
329 echo "Select a DNS server for the clients:"
Pluto <meokcin@gmail.com>
parents:
diff changeset
330 echo " 1) Current system resolvers"
Pluto <meokcin@gmail.com>
parents:
diff changeset
331 echo " 2) Google Public DNS"
Pluto <meokcin@gmail.com>
parents:
diff changeset
332 echo " 3) Cloudflare DNS"
Pluto <meokcin@gmail.com>
parents:
diff changeset
333 echo " 4) OpenDNS"
Pluto <meokcin@gmail.com>
parents:
diff changeset
334 echo " 5) Quad9"
Pluto <meokcin@gmail.com>
parents:
diff changeset
335 echo " 6) AdGuard DNS"
Pluto <meokcin@gmail.com>
parents:
diff changeset
336 echo " 7) Custom"
Pluto <meokcin@gmail.com>
parents:
diff changeset
337 read -rp "DNS server [2]: " dns
Pluto <meokcin@gmail.com>
parents:
diff changeset
338 until [[ -z "$dns" || "$dns" =~ ^[1-7]$ ]]; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
339 echo "$dns: invalid selection."
Pluto <meokcin@gmail.com>
parents:
diff changeset
340 read -rp "DNS server [2]: " dns
Pluto <meokcin@gmail.com>
parents:
diff changeset
341 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
342 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
343 dns=2
Pluto <meokcin@gmail.com>
parents:
diff changeset
344 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
345 if [ "$dns" = 7 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
346 enter_custom_dns
Pluto <meokcin@gmail.com>
parents:
diff changeset
347 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
348 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
349
Pluto <meokcin@gmail.com>
parents:
diff changeset
350 set_client_name() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
351 # Allow a limited set of characters to avoid conflicts
Pluto <meokcin@gmail.com>
parents:
diff changeset
352 client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client")
Pluto <meokcin@gmail.com>
parents:
diff changeset
353 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
354
Pluto <meokcin@gmail.com>
parents:
diff changeset
355 enter_client_name() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
356 if [ "$auto" = 0 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
357 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
358 echo "Enter a name for the first client:"
Pluto <meokcin@gmail.com>
parents:
diff changeset
359 read -rp "Name [client]: " unsanitized_client
Pluto <meokcin@gmail.com>
parents:
diff changeset
360 set_client_name
Pluto <meokcin@gmail.com>
parents:
diff changeset
361 [[ -z "$client" ]] && client=client
Pluto <meokcin@gmail.com>
parents:
diff changeset
362 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
363 client=client
Pluto <meokcin@gmail.com>
parents:
diff changeset
364 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
365 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
366
Pluto <meokcin@gmail.com>
parents:
diff changeset
367 check_firewall() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
368 # Install a firewall if firewalld or iptables are not already available
Pluto <meokcin@gmail.com>
parents:
diff changeset
369 if ! systemctl is-active --quiet firewalld.service && ! hash iptables 2>/dev/null; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
370 if [[ "$os" == "centos" || "$os" == "fedora" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
371 firewall="firewalld"
Pluto <meokcin@gmail.com>
parents:
diff changeset
372 elif [[ "$os" == "openSUSE" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
373 firewall="firewalld"
Pluto <meokcin@gmail.com>
parents:
diff changeset
374 elif [[ "$os" == "debian" || "$os" == "ubuntu" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
375 firewall="iptables"
Pluto <meokcin@gmail.com>
parents:
diff changeset
376 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
377 if [[ "$firewall" == "firewalld" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
378 # We don't want to silently enable firewalld, so we give a subtle warning
Pluto <meokcin@gmail.com>
parents:
diff changeset
379 # If the user continues, firewalld will be installed and enabled during setup
Pluto <meokcin@gmail.com>
parents:
diff changeset
380 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
381 echo "Note: firewalld, which is required to manage routing tables, will also be installed."
Pluto <meokcin@gmail.com>
parents:
diff changeset
382 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
383 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
384 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
385
Pluto <meokcin@gmail.com>
parents:
diff changeset
386 abort_and_exit() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
387 echo "Abort. No changes were made." >&2
Pluto <meokcin@gmail.com>
parents:
diff changeset
388 exit 1
Pluto <meokcin@gmail.com>
parents:
diff changeset
389 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
390
Pluto <meokcin@gmail.com>
parents:
diff changeset
391 confirm_setup() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
392 if [ "$auto" = 0 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
393 printf "Do you want to continue? [Y/n] "
Pluto <meokcin@gmail.com>
parents:
diff changeset
394 read -r response
Pluto <meokcin@gmail.com>
parents:
diff changeset
395 case $response in
Pluto <meokcin@gmail.com>
parents:
diff changeset
396 [yY][eE][sS]|[yY]|'')
Pluto <meokcin@gmail.com>
parents:
diff changeset
397 :
Pluto <meokcin@gmail.com>
parents:
diff changeset
398 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
399 *)
Pluto <meokcin@gmail.com>
parents:
diff changeset
400 abort_and_exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
401 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
402 esac
Pluto <meokcin@gmail.com>
parents:
diff changeset
403 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
404 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
405
Pluto <meokcin@gmail.com>
parents:
diff changeset
406 get_export_dir() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
407 export_to_home_dir=0
Pluto <meokcin@gmail.com>
parents:
diff changeset
408 export_dir=~/
Pluto <meokcin@gmail.com>
parents:
diff changeset
409 if [ -n "$SUDO_USER" ] && getent group "$SUDO_USER" >/dev/null 2>&1; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
410 user_home_dir=$(getent passwd "$SUDO_USER" 2>/dev/null | cut -d: -f6)
Pluto <meokcin@gmail.com>
parents:
diff changeset
411 if [ -d "$user_home_dir" ] && [ "$user_home_dir" != "/" ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
412 export_dir="$user_home_dir/"
Pluto <meokcin@gmail.com>
parents:
diff changeset
413 export_to_home_dir=1
Pluto <meokcin@gmail.com>
parents:
diff changeset
414 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
415 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
416 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
417
Pluto <meokcin@gmail.com>
parents:
diff changeset
418 new_client() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
419 get_export_dir
Pluto <meokcin@gmail.com>
parents:
diff changeset
420 # Generates the custom client.ovpn
Pluto <meokcin@gmail.com>
parents:
diff changeset
421 {
Pluto <meokcin@gmail.com>
parents:
diff changeset
422 cat /etc/openvpn/server/client-common.txt
Pluto <meokcin@gmail.com>
parents:
diff changeset
423 echo "<ca>"
Pluto <meokcin@gmail.com>
parents:
diff changeset
424 cat /etc/openvpn/server/easy-rsa/pki/ca.crt
Pluto <meokcin@gmail.com>
parents:
diff changeset
425 echo "</ca>"
Pluto <meokcin@gmail.com>
parents:
diff changeset
426 echo "<cert>"
Pluto <meokcin@gmail.com>
parents:
diff changeset
427 sed -ne '/BEGIN CERTIFICATE/,$ p' /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt
Pluto <meokcin@gmail.com>
parents:
diff changeset
428 echo "</cert>"
Pluto <meokcin@gmail.com>
parents:
diff changeset
429 echo "<key>"
Pluto <meokcin@gmail.com>
parents:
diff changeset
430 cat /etc/openvpn/server/easy-rsa/pki/private/"$client".key
Pluto <meokcin@gmail.com>
parents:
diff changeset
431 echo "</key>"
Pluto <meokcin@gmail.com>
parents:
diff changeset
432 echo "<tls-crypt>"
Pluto <meokcin@gmail.com>
parents:
diff changeset
433 sed -ne '/BEGIN OpenVPN Static key/,$ p' /etc/openvpn/server/tc.key
Pluto <meokcin@gmail.com>
parents:
diff changeset
434 echo "</tls-crypt>"
Pluto <meokcin@gmail.com>
parents:
diff changeset
435 } > "$export_dir$client".ovpn
Pluto <meokcin@gmail.com>
parents:
diff changeset
436 if [ "$export_to_home_dir" = 1 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
437 chown "$SUDO_USER:$SUDO_USER" "$export_dir$client".ovpn
Pluto <meokcin@gmail.com>
parents:
diff changeset
438 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
439 chmod 600 "$export_dir$client".ovpn
Pluto <meokcin@gmail.com>
parents:
diff changeset
440 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
441
Pluto <meokcin@gmail.com>
parents:
diff changeset
442 update_sysctl() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
443 mkdir -p /etc/sysctl.d
Pluto <meokcin@gmail.com>
parents:
diff changeset
444 conf_fwd="/etc/sysctl.d/99-openvpn-forward.conf"
Pluto <meokcin@gmail.com>
parents:
diff changeset
445 conf_opt="/etc/sysctl.d/99-openvpn-optimize.conf"
Pluto <meokcin@gmail.com>
parents:
diff changeset
446 # Enable net.ipv4.ip_forward for the system
Pluto <meokcin@gmail.com>
parents:
diff changeset
447 echo 'net.ipv4.ip_forward=1' > "$conf_fwd"
Pluto <meokcin@gmail.com>
parents:
diff changeset
448 if [[ -n "$ip6" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
449 # Enable net.ipv6.conf.all.forwarding for the system
Pluto <meokcin@gmail.com>
parents:
diff changeset
450 echo "net.ipv6.conf.all.forwarding=1" >> "$conf_fwd"
Pluto <meokcin@gmail.com>
parents:
diff changeset
451 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
452 # Optimize sysctl settings such as TCP buffer sizes
Pluto <meokcin@gmail.com>
parents:
diff changeset
453 base_url="https://github.com/hwdsl2/vpn-extras/releases/download/v1.0.0"
Pluto <meokcin@gmail.com>
parents:
diff changeset
454 conf_url="$base_url/sysctl-ovpn-$os"
Pluto <meokcin@gmail.com>
parents:
diff changeset
455 [ "$auto" != 0 ] && conf_url="${conf_url}-auto"
Pluto <meokcin@gmail.com>
parents:
diff changeset
456 wget -t 3 -T 30 -q -O "$conf_opt" "$conf_url" 2>/dev/null \
Pluto <meokcin@gmail.com>
parents:
diff changeset
457 || curl -m 30 -fsL "$conf_url" -o "$conf_opt" 2>/dev/null \
Pluto <meokcin@gmail.com>
parents:
diff changeset
458 || { /bin/rm -f "$conf_opt"; touch "$conf_opt"; }
Pluto <meokcin@gmail.com>
parents:
diff changeset
459 # Enable TCP BBR congestion control if kernel version >= 4.20
Pluto <meokcin@gmail.com>
parents:
diff changeset
460 if modprobe -q tcp_bbr \
Pluto <meokcin@gmail.com>
parents:
diff changeset
461 && printf '%s\n%s' "4.20" "$(uname -r)" | sort -C -V \
Pluto <meokcin@gmail.com>
parents:
diff changeset
462 && [ -f /proc/sys/net/ipv4/tcp_congestion_control ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
463 cat >> "$conf_opt" <<'EOF'
Pluto <meokcin@gmail.com>
parents:
diff changeset
464 net.core.default_qdisc = fq
Pluto <meokcin@gmail.com>
parents:
diff changeset
465 net.ipv4.tcp_congestion_control = bbr
Pluto <meokcin@gmail.com>
parents:
diff changeset
466 EOF
Pluto <meokcin@gmail.com>
parents:
diff changeset
467 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
468 # Apply sysctl settings
Pluto <meokcin@gmail.com>
parents:
diff changeset
469 sysctl -e -q -p "$conf_fwd"
Pluto <meokcin@gmail.com>
parents:
diff changeset
470 sysctl -e -q -p "$conf_opt"
Pluto <meokcin@gmail.com>
parents:
diff changeset
471 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
472
Pluto <meokcin@gmail.com>
parents:
diff changeset
473 update_rclocal() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
474 ipt_cmd="systemctl restart openvpn-iptables.service"
Pluto <meokcin@gmail.com>
parents:
diff changeset
475 if ! grep -qs "$ipt_cmd" /etc/rc.local; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
476 if [ ! -f /etc/rc.local ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
477 echo '#!/bin/sh' > /etc/rc.local
Pluto <meokcin@gmail.com>
parents:
diff changeset
478 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
479 if [ "$os" = "ubuntu" ] || [ "$os" = "debian" ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
480 sed --follow-symlinks -i '/^exit 0/d' /etc/rc.local
Pluto <meokcin@gmail.com>
parents:
diff changeset
481 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
482 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
483 cat >> /etc/rc.local <<EOF
Pluto <meokcin@gmail.com>
parents:
diff changeset
484
Pluto <meokcin@gmail.com>
parents:
diff changeset
485 $ipt_cmd
Pluto <meokcin@gmail.com>
parents:
diff changeset
486 EOF
Pluto <meokcin@gmail.com>
parents:
diff changeset
487 if [ "$os" = "ubuntu" ] || [ "$os" = "debian" ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
488 echo "exit 0" >> /etc/rc.local
Pluto <meokcin@gmail.com>
parents:
diff changeset
489 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
490 chmod +x /etc/rc.local
Pluto <meokcin@gmail.com>
parents:
diff changeset
491 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
492 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
493
Pluto <meokcin@gmail.com>
parents:
diff changeset
494 show_header() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
495 cat <<'EOF'
Pluto <meokcin@gmail.com>
parents:
diff changeset
496
Pluto <meokcin@gmail.com>
parents:
diff changeset
497 OpenVPN Script
Pluto <meokcin@gmail.com>
parents:
diff changeset
498 https://github.com/hwdsl2/openvpn-install
Pluto <meokcin@gmail.com>
parents:
diff changeset
499 EOF
Pluto <meokcin@gmail.com>
parents:
diff changeset
500 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
501
Pluto <meokcin@gmail.com>
parents:
diff changeset
502 show_header2() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
503 cat <<'EOF'
Pluto <meokcin@gmail.com>
parents:
diff changeset
504
Pluto <meokcin@gmail.com>
parents:
diff changeset
505 Copyright (c) 2022-2024 Lin Song
Pluto <meokcin@gmail.com>
parents:
diff changeset
506 Copyright (c) 2013-2023 Nyr
Pluto <meokcin@gmail.com>
parents:
diff changeset
507 EOF
Pluto <meokcin@gmail.com>
parents:
diff changeset
508 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
509
Pluto <meokcin@gmail.com>
parents:
diff changeset
510 show_usage() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
511 if [ -n "$1" ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
512 echo "Error: $1" >&2
Pluto <meokcin@gmail.com>
parents:
diff changeset
513 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
514 show_header
Pluto <meokcin@gmail.com>
parents:
diff changeset
515 show_header2
Pluto <meokcin@gmail.com>
parents:
diff changeset
516 cat 1>&2 <<EOF
Pluto <meokcin@gmail.com>
parents:
diff changeset
517
Pluto <meokcin@gmail.com>
parents:
diff changeset
518 Usage: bash $0 [options]
Pluto <meokcin@gmail.com>
parents:
diff changeset
519
Pluto <meokcin@gmail.com>
parents:
diff changeset
520 Options:
Pluto <meokcin@gmail.com>
parents:
diff changeset
521 --auto auto install OpenVPN using default options
Pluto <meokcin@gmail.com>
parents:
diff changeset
522 -h, --help show this help message and exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
523
Pluto <meokcin@gmail.com>
parents:
diff changeset
524 To customize install options, run this script without arguments.
Pluto <meokcin@gmail.com>
parents:
diff changeset
525 EOF
Pluto <meokcin@gmail.com>
parents:
diff changeset
526 exit 1
Pluto <meokcin@gmail.com>
parents:
diff changeset
527 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
528
Pluto <meokcin@gmail.com>
parents:
diff changeset
529 ovpnsetup() {
Pluto <meokcin@gmail.com>
parents:
diff changeset
530
Pluto <meokcin@gmail.com>
parents:
diff changeset
531 export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Pluto <meokcin@gmail.com>
parents:
diff changeset
532
Pluto <meokcin@gmail.com>
parents:
diff changeset
533 if [ "$(id -u)" != 0 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
534 exiterr "This installer must be run as root. Try 'sudo bash $0'"
Pluto <meokcin@gmail.com>
parents:
diff changeset
535 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
536
Pluto <meokcin@gmail.com>
parents:
diff changeset
537 # Detect Debian users running the script with "sh" instead of bash
Pluto <meokcin@gmail.com>
parents:
diff changeset
538 if readlink /proc/$$/exe | grep -q "dash"; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
539 exiterr 'This installer needs to be run with "bash", not "sh".'
Pluto <meokcin@gmail.com>
parents:
diff changeset
540 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
541
Pluto <meokcin@gmail.com>
parents:
diff changeset
542 # Detect OpenVZ 6
Pluto <meokcin@gmail.com>
parents:
diff changeset
543 if [[ $(uname -r | cut -d "." -f 1) -eq 2 ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
544 exiterr "The system is running an old kernel, which is incompatible with this installer."
Pluto <meokcin@gmail.com>
parents:
diff changeset
545 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
546
Pluto <meokcin@gmail.com>
parents:
diff changeset
547 check_os
Pluto <meokcin@gmail.com>
parents:
diff changeset
548 check_os_ver
Pluto <meokcin@gmail.com>
parents:
diff changeset
549
Pluto <meokcin@gmail.com>
parents:
diff changeset
550 if [[ ! -e /dev/net/tun ]] || ! ( exec 7<>/dev/net/tun ) 2>/dev/null; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
551 exiterr "The system does not have the TUN device available.
Pluto <meokcin@gmail.com>
parents:
diff changeset
552 TUN needs to be enabled before running this installer."
Pluto <meokcin@gmail.com>
parents:
diff changeset
553 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
554
Pluto <meokcin@gmail.com>
parents:
diff changeset
555 auto=0
Pluto <meokcin@gmail.com>
parents:
diff changeset
556 if [[ ! -e /etc/openvpn/server/server.conf ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
557 check_nftables
Pluto <meokcin@gmail.com>
parents:
diff changeset
558 while [ "$#" -gt 0 ]; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
559 case $1 in
Pluto <meokcin@gmail.com>
parents:
diff changeset
560 --auto)
Pluto <meokcin@gmail.com>
parents:
diff changeset
561 auto=1
Pluto <meokcin@gmail.com>
parents:
diff changeset
562 shift
Pluto <meokcin@gmail.com>
parents:
diff changeset
563 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
564 -h|--help)
Pluto <meokcin@gmail.com>
parents:
diff changeset
565 show_usage
Pluto <meokcin@gmail.com>
parents:
diff changeset
566 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
567 *)
Pluto <meokcin@gmail.com>
parents:
diff changeset
568 show_usage "Unknown parameter: $1"
Pluto <meokcin@gmail.com>
parents:
diff changeset
569 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
570 esac
Pluto <meokcin@gmail.com>
parents:
diff changeset
571 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
572 install_wget
Pluto <meokcin@gmail.com>
parents:
diff changeset
573 install_iproute
Pluto <meokcin@gmail.com>
parents:
diff changeset
574 show_start_setup
Pluto <meokcin@gmail.com>
parents:
diff changeset
575 public_ip=""
Pluto <meokcin@gmail.com>
parents:
diff changeset
576 if [ "$auto" = 0 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
577 enter_server_address
Pluto <meokcin@gmail.com>
parents:
diff changeset
578 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
579 detect_ip
Pluto <meokcin@gmail.com>
parents:
diff changeset
580 check_nat_ip
Pluto <meokcin@gmail.com>
parents:
diff changeset
581 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
582 show_config
Pluto <meokcin@gmail.com>
parents:
diff changeset
583 detect_ipv6
Pluto <meokcin@gmail.com>
parents:
diff changeset
584 select_protocol
Pluto <meokcin@gmail.com>
parents:
diff changeset
585 select_port
Pluto <meokcin@gmail.com>
parents:
diff changeset
586 select_dns
Pluto <meokcin@gmail.com>
parents:
diff changeset
587 enter_client_name
Pluto <meokcin@gmail.com>
parents:
diff changeset
588 if [ "$auto" = 0 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
589 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
590 echo "OpenVPN installation is ready to begin."
Pluto <meokcin@gmail.com>
parents:
diff changeset
591 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
592 check_firewall
Pluto <meokcin@gmail.com>
parents:
diff changeset
593 confirm_setup
Pluto <meokcin@gmail.com>
parents:
diff changeset
594 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
595 echo "Installing OpenVPN, please wait..."
Pluto <meokcin@gmail.com>
parents:
diff changeset
596 # If running inside a container, disable LimitNPROC to prevent conflicts
Pluto <meokcin@gmail.com>
parents:
diff changeset
597 if systemd-detect-virt -cq; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
598 mkdir /etc/systemd/system/openvpn-server@server.service.d/ 2>/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
599 echo "[Service]
Pluto <meokcin@gmail.com>
parents:
diff changeset
600 LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
601 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
602 if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
603 export DEBIAN_FRONTEND=noninteractive
Pluto <meokcin@gmail.com>
parents:
diff changeset
604 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
605 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
606 apt-get -yqq update || apt-get -yqq update
Pluto <meokcin@gmail.com>
parents:
diff changeset
607 apt-get -yqq --no-install-recommends install openvpn >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
608 ) || exiterr2
Pluto <meokcin@gmail.com>
parents:
diff changeset
609 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
610 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
611 apt-get -yqq install openssl ca-certificates $firewall >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
612 ) || exiterr2
Pluto <meokcin@gmail.com>
parents:
diff changeset
613 elif [[ "$os" = "centos" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
614 if grep -qs "Amazon Linux release 2 " /etc/system-release; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
615 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
616 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
617 amazon-linux-extras install epel -y >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
618 ) || exit 1
Pluto <meokcin@gmail.com>
parents:
diff changeset
619 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
620 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
621 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
622 yum -y -q install epel-release >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
623 ) || exiterr3
Pluto <meokcin@gmail.com>
parents:
diff changeset
624 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
625 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
626 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
627 yum -y -q install openvpn openssl ca-certificates tar $firewall >/dev/null 2>&1
Pluto <meokcin@gmail.com>
parents:
diff changeset
628 ) || exiterr3
Pluto <meokcin@gmail.com>
parents:
diff changeset
629 elif [[ "$os" = "fedora" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
630 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
631 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
632 dnf install -y openvpn openssl ca-certificates tar $firewall >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
633 ) || exiterr "'dnf install' failed."
Pluto <meokcin@gmail.com>
parents:
diff changeset
634 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
635 # Else, OS must be openSUSE
Pluto <meokcin@gmail.com>
parents:
diff changeset
636 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
637 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
638 zypper install -y openvpn openssl ca-certificates tar $firewall >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
639 ) || exiterr4
Pluto <meokcin@gmail.com>
parents:
diff changeset
640 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
641 # If firewalld was just installed, enable it
Pluto <meokcin@gmail.com>
parents:
diff changeset
642 if [[ "$firewall" == "firewalld" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
643 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
644 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
645 systemctl enable --now firewalld.service >/dev/null 2>&1
Pluto <meokcin@gmail.com>
parents:
diff changeset
646 )
Pluto <meokcin@gmail.com>
parents:
diff changeset
647 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
648 # Get easy-rsa
Pluto <meokcin@gmail.com>
parents:
diff changeset
649 easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.7/EasyRSA-3.1.7.tgz'
Pluto <meokcin@gmail.com>
parents:
diff changeset
650 mkdir -p /etc/openvpn/server/easy-rsa/
Pluto <meokcin@gmail.com>
parents:
diff changeset
651 { wget -t 3 -T 30 -qO- "$easy_rsa_url" 2>/dev/null || curl -m 30 -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1
Pluto <meokcin@gmail.com>
parents:
diff changeset
652 if [ ! -f /etc/openvpn/server/easy-rsa/easyrsa ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
653 exiterr "Failed to download EasyRSA from $easy_rsa_url."
Pluto <meokcin@gmail.com>
parents:
diff changeset
654 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
655 chown -R root:root /etc/openvpn/server/easy-rsa/
Pluto <meokcin@gmail.com>
parents:
diff changeset
656 cd /etc/openvpn/server/easy-rsa/ || exit 1
Pluto <meokcin@gmail.com>
parents:
diff changeset
657 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
658 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
659 # Create the PKI, set up the CA and the server and client certificates
Pluto <meokcin@gmail.com>
parents:
diff changeset
660 ./easyrsa --batch init-pki >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
661 ./easyrsa --batch build-ca nopass >/dev/null 2>&1
Pluto <meokcin@gmail.com>
parents:
diff changeset
662 ./easyrsa --batch --days=3650 build-server-full server nopass >/dev/null 2>&1
Pluto <meokcin@gmail.com>
parents:
diff changeset
663 ./easyrsa --batch --days=3650 build-client-full "$client" nopass >/dev/null 2>&1
Pluto <meokcin@gmail.com>
parents:
diff changeset
664 ./easyrsa --batch --days=3650 gen-crl >/dev/null 2>&1
Pluto <meokcin@gmail.com>
parents:
diff changeset
665 )
Pluto <meokcin@gmail.com>
parents:
diff changeset
666 # Move the stuff we need
Pluto <meokcin@gmail.com>
parents:
diff changeset
667 cp pki/ca.crt pki/private/ca.key pki/issued/server.crt pki/private/server.key pki/crl.pem /etc/openvpn/server
Pluto <meokcin@gmail.com>
parents:
diff changeset
668 # CRL is read with each client connection, while OpenVPN is dropped to nobody
Pluto <meokcin@gmail.com>
parents:
diff changeset
669 chown nobody:"$group_name" /etc/openvpn/server/crl.pem
Pluto <meokcin@gmail.com>
parents:
diff changeset
670 # Without +x in the directory, OpenVPN can't run a stat() on the CRL file
Pluto <meokcin@gmail.com>
parents:
diff changeset
671 chmod o+x /etc/openvpn/server/
Pluto <meokcin@gmail.com>
parents:
diff changeset
672 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
673 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
674 # Generate key for tls-crypt
Pluto <meokcin@gmail.com>
parents:
diff changeset
675 openvpn --genkey --secret /etc/openvpn/server/tc.key >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
676 )
Pluto <meokcin@gmail.com>
parents:
diff changeset
677 # Create the DH parameters file using the predefined ffdhe2048 group
Pluto <meokcin@gmail.com>
parents:
diff changeset
678 echo '-----BEGIN DH PARAMETERS-----
Pluto <meokcin@gmail.com>
parents:
diff changeset
679 MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
Pluto <meokcin@gmail.com>
parents:
diff changeset
680 +8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
Pluto <meokcin@gmail.com>
parents:
diff changeset
681 87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
Pluto <meokcin@gmail.com>
parents:
diff changeset
682 YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
Pluto <meokcin@gmail.com>
parents:
diff changeset
683 7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
Pluto <meokcin@gmail.com>
parents:
diff changeset
684 ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
Pluto <meokcin@gmail.com>
parents:
diff changeset
685 -----END DH PARAMETERS-----' > /etc/openvpn/server/dh.pem
Pluto <meokcin@gmail.com>
parents:
diff changeset
686 # Generate server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
687 echo "local $ip
Pluto <meokcin@gmail.com>
parents:
diff changeset
688 port $port
Pluto <meokcin@gmail.com>
parents:
diff changeset
689 proto $protocol
Pluto <meokcin@gmail.com>
parents:
diff changeset
690 dev tun
Pluto <meokcin@gmail.com>
parents:
diff changeset
691 ca ca.crt
Pluto <meokcin@gmail.com>
parents:
diff changeset
692 cert server.crt
Pluto <meokcin@gmail.com>
parents:
diff changeset
693 key server.key
Pluto <meokcin@gmail.com>
parents:
diff changeset
694 dh dh.pem
Pluto <meokcin@gmail.com>
parents:
diff changeset
695 auth SHA256
Pluto <meokcin@gmail.com>
parents:
diff changeset
696 tls-crypt tc.key
Pluto <meokcin@gmail.com>
parents:
diff changeset
697 topology subnet
Pluto <meokcin@gmail.com>
parents:
diff changeset
698 server 10.8.0.0 255.255.255.0" > /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
699 # IPv6
Pluto <meokcin@gmail.com>
parents:
diff changeset
700 if [[ -z "$ip6" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
701 echo 'push "block-ipv6"' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
702 echo 'push "ifconfig-ipv6 fddd:1194:1194:1194::2/64 fddd:1194:1194:1194::1"' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
703 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
704 echo 'server-ipv6 fddd:1194:1194:1194::/64' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
705 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
706 echo 'push "redirect-gateway def1 ipv6 bypass-dhcp"' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
707 echo 'ifconfig-pool-persist ipp.txt' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
708 # DNS
Pluto <meokcin@gmail.com>
parents:
diff changeset
709 case "$dns" in
Pluto <meokcin@gmail.com>
parents:
diff changeset
710 1)
Pluto <meokcin@gmail.com>
parents:
diff changeset
711 # Locate the proper resolv.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
712 # Needed for systems running systemd-resolved
Pluto <meokcin@gmail.com>
parents:
diff changeset
713 if grep '^nameserver' "/etc/resolv.conf" | grep -qv '127.0.0.53' ; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
714 resolv_conf="/etc/resolv.conf"
Pluto <meokcin@gmail.com>
parents:
diff changeset
715 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
716 resolv_conf="/run/systemd/resolve/resolv.conf"
Pluto <meokcin@gmail.com>
parents:
diff changeset
717 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
718 # Obtain the resolvers from resolv.conf and use them for OpenVPN
Pluto <meokcin@gmail.com>
parents:
diff changeset
719 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
Pluto <meokcin@gmail.com>
parents:
diff changeset
720 echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
721 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
722 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
723 2|"")
Pluto <meokcin@gmail.com>
parents:
diff changeset
724 echo 'push "dhcp-option DNS 8.8.8.8"' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
725 echo 'push "dhcp-option DNS 8.8.4.4"' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
726 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
727 3)
Pluto <meokcin@gmail.com>
parents:
diff changeset
728 echo 'push "dhcp-option DNS 1.1.1.1"' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
729 echo 'push "dhcp-option DNS 1.0.0.1"' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
730 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
731 4)
Pluto <meokcin@gmail.com>
parents:
diff changeset
732 echo 'push "dhcp-option DNS 208.67.222.222"' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
733 echo 'push "dhcp-option DNS 208.67.220.220"' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
734 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
735 5)
Pluto <meokcin@gmail.com>
parents:
diff changeset
736 echo 'push "dhcp-option DNS 9.9.9.9"' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
737 echo 'push "dhcp-option DNS 149.112.112.112"' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
738 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
739 6)
Pluto <meokcin@gmail.com>
parents:
diff changeset
740 echo 'push "dhcp-option DNS 94.140.14.14"' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
741 echo 'push "dhcp-option DNS 94.140.15.15"' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
742 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
743 7)
Pluto <meokcin@gmail.com>
parents:
diff changeset
744 echo "push \"dhcp-option DNS $dns1\"" >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
745 if [ -n "$dns2" ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
746 echo "push \"dhcp-option DNS $dns2\"" >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
747 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
748 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
749 esac
Pluto <meokcin@gmail.com>
parents:
diff changeset
750 echo 'push "block-outside-dns"' >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
751 echo "keepalive 10 120
Pluto <meokcin@gmail.com>
parents:
diff changeset
752 cipher AES-128-GCM
Pluto <meokcin@gmail.com>
parents:
diff changeset
753 user nobody
Pluto <meokcin@gmail.com>
parents:
diff changeset
754 group $group_name
Pluto <meokcin@gmail.com>
parents:
diff changeset
755 persist-key
Pluto <meokcin@gmail.com>
parents:
diff changeset
756 persist-tun
Pluto <meokcin@gmail.com>
parents:
diff changeset
757 verb 3
Pluto <meokcin@gmail.com>
parents:
diff changeset
758 crl-verify crl.pem" >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
759 if [[ "$protocol" = "udp" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
760 echo "explicit-exit-notify" >> /etc/openvpn/server/server.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
761 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
762 update_sysctl
Pluto <meokcin@gmail.com>
parents:
diff changeset
763 if systemctl is-active --quiet firewalld.service; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
764 # Using both permanent and not permanent rules to avoid a firewalld
Pluto <meokcin@gmail.com>
parents:
diff changeset
765 # reload.
Pluto <meokcin@gmail.com>
parents:
diff changeset
766 # We don't use --add-service=openvpn because that would only work with
Pluto <meokcin@gmail.com>
parents:
diff changeset
767 # the default port and protocol.
Pluto <meokcin@gmail.com>
parents:
diff changeset
768 firewall-cmd -q --add-port="$port"/"$protocol"
Pluto <meokcin@gmail.com>
parents:
diff changeset
769 firewall-cmd -q --zone=trusted --add-source=10.8.0.0/24
Pluto <meokcin@gmail.com>
parents:
diff changeset
770 firewall-cmd -q --permanent --add-port="$port"/"$protocol"
Pluto <meokcin@gmail.com>
parents:
diff changeset
771 firewall-cmd -q --permanent --zone=trusted --add-source=10.8.0.0/24
Pluto <meokcin@gmail.com>
parents:
diff changeset
772 # Set NAT for the VPN subnet
Pluto <meokcin@gmail.com>
parents:
diff changeset
773 firewall-cmd -q --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
Pluto <meokcin@gmail.com>
parents:
diff changeset
774 firewall-cmd -q --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
Pluto <meokcin@gmail.com>
parents:
diff changeset
775 if [[ -n "$ip6" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
776 firewall-cmd -q --zone=trusted --add-source=fddd:1194:1194:1194::/64
Pluto <meokcin@gmail.com>
parents:
diff changeset
777 firewall-cmd -q --permanent --zone=trusted --add-source=fddd:1194:1194:1194::/64
Pluto <meokcin@gmail.com>
parents:
diff changeset
778 firewall-cmd -q --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
Pluto <meokcin@gmail.com>
parents:
diff changeset
779 firewall-cmd -q --permanent --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
Pluto <meokcin@gmail.com>
parents:
diff changeset
780 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
781 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
782 # Create a service to set up persistent iptables rules
Pluto <meokcin@gmail.com>
parents:
diff changeset
783 iptables_path=$(command -v iptables)
Pluto <meokcin@gmail.com>
parents:
diff changeset
784 ip6tables_path=$(command -v ip6tables)
Pluto <meokcin@gmail.com>
parents:
diff changeset
785 # nf_tables is not available as standard in OVZ kernels. So use iptables-legacy
Pluto <meokcin@gmail.com>
parents:
diff changeset
786 # if we are in OVZ, with a nf_tables backend and iptables-legacy is available.
Pluto <meokcin@gmail.com>
parents:
diff changeset
787 if [[ $(systemd-detect-virt) == "openvz" ]] && readlink -f "$(command -v iptables)" | grep -q "nft" && hash iptables-legacy 2>/dev/null; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
788 iptables_path=$(command -v iptables-legacy)
Pluto <meokcin@gmail.com>
parents:
diff changeset
789 ip6tables_path=$(command -v ip6tables-legacy)
Pluto <meokcin@gmail.com>
parents:
diff changeset
790 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
791 echo "[Unit]
Pluto <meokcin@gmail.com>
parents:
diff changeset
792 Before=network.target
Pluto <meokcin@gmail.com>
parents:
diff changeset
793 [Service]
Pluto <meokcin@gmail.com>
parents:
diff changeset
794 Type=oneshot
Pluto <meokcin@gmail.com>
parents:
diff changeset
795 ExecStart=$iptables_path -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
Pluto <meokcin@gmail.com>
parents:
diff changeset
796 ExecStart=$iptables_path -I INPUT -p $protocol --dport $port -j ACCEPT
Pluto <meokcin@gmail.com>
parents:
diff changeset
797 ExecStart=$iptables_path -I FORWARD -s 10.8.0.0/24 -j ACCEPT
Pluto <meokcin@gmail.com>
parents:
diff changeset
798 ExecStart=$iptables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
Pluto <meokcin@gmail.com>
parents:
diff changeset
799 ExecStop=$iptables_path -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
Pluto <meokcin@gmail.com>
parents:
diff changeset
800 ExecStop=$iptables_path -D INPUT -p $protocol --dport $port -j ACCEPT
Pluto <meokcin@gmail.com>
parents:
diff changeset
801 ExecStop=$iptables_path -D FORWARD -s 10.8.0.0/24 -j ACCEPT
Pluto <meokcin@gmail.com>
parents:
diff changeset
802 ExecStop=$iptables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" > /etc/systemd/system/openvpn-iptables.service
Pluto <meokcin@gmail.com>
parents:
diff changeset
803 if [[ -n "$ip6" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
804 echo "ExecStart=$ip6tables_path -t nat -A POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
Pluto <meokcin@gmail.com>
parents:
diff changeset
805 ExecStart=$ip6tables_path -I FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT
Pluto <meokcin@gmail.com>
parents:
diff changeset
806 ExecStart=$ip6tables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
Pluto <meokcin@gmail.com>
parents:
diff changeset
807 ExecStop=$ip6tables_path -t nat -D POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
Pluto <meokcin@gmail.com>
parents:
diff changeset
808 ExecStop=$ip6tables_path -D FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT
Pluto <meokcin@gmail.com>
parents:
diff changeset
809 ExecStop=$ip6tables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" >> /etc/systemd/system/openvpn-iptables.service
Pluto <meokcin@gmail.com>
parents:
diff changeset
810 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
811 echo "RemainAfterExit=yes
Pluto <meokcin@gmail.com>
parents:
diff changeset
812 [Install]
Pluto <meokcin@gmail.com>
parents:
diff changeset
813 WantedBy=multi-user.target" >> /etc/systemd/system/openvpn-iptables.service
Pluto <meokcin@gmail.com>
parents:
diff changeset
814 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
815 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
816 systemctl enable --now openvpn-iptables.service >/dev/null 2>&1
Pluto <meokcin@gmail.com>
parents:
diff changeset
817 )
Pluto <meokcin@gmail.com>
parents:
diff changeset
818 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
819 if [ "$os" != "openSUSE" ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
820 update_rclocal
Pluto <meokcin@gmail.com>
parents:
diff changeset
821 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
822 # If SELinux is enabled and a custom port was selected, we need this
Pluto <meokcin@gmail.com>
parents:
diff changeset
823 if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
824 # Install semanage if not already present
Pluto <meokcin@gmail.com>
parents:
diff changeset
825 if ! hash semanage 2>/dev/null; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
826 if [[ "$os_version" -eq 7 ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
827 # Centos 7
Pluto <meokcin@gmail.com>
parents:
diff changeset
828 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
829 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
830 yum -y -q install policycoreutils-python >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
831 ) || exiterr3
Pluto <meokcin@gmail.com>
parents:
diff changeset
832 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
833 # CentOS 8/9 or Fedora
Pluto <meokcin@gmail.com>
parents:
diff changeset
834 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
835 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
836 dnf install -y policycoreutils-python-utils >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
837 ) || exiterr "'dnf install' failed."
Pluto <meokcin@gmail.com>
parents:
diff changeset
838 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
839 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
840 semanage port -a -t openvpn_port_t -p "$protocol" "$port"
Pluto <meokcin@gmail.com>
parents:
diff changeset
841 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
842 # If the server is behind NAT, use the correct IP address
Pluto <meokcin@gmail.com>
parents:
diff changeset
843 [[ -n "$public_ip" ]] && ip="$public_ip"
Pluto <meokcin@gmail.com>
parents:
diff changeset
844 # client-common.txt is created so we have a template to add further users later
Pluto <meokcin@gmail.com>
parents:
diff changeset
845 echo "client
Pluto <meokcin@gmail.com>
parents:
diff changeset
846 dev tun
Pluto <meokcin@gmail.com>
parents:
diff changeset
847 proto $protocol
Pluto <meokcin@gmail.com>
parents:
diff changeset
848 remote $ip $port
Pluto <meokcin@gmail.com>
parents:
diff changeset
849 resolv-retry infinite
Pluto <meokcin@gmail.com>
parents:
diff changeset
850 nobind
Pluto <meokcin@gmail.com>
parents:
diff changeset
851 persist-key
Pluto <meokcin@gmail.com>
parents:
diff changeset
852 persist-tun
Pluto <meokcin@gmail.com>
parents:
diff changeset
853 remote-cert-tls server
Pluto <meokcin@gmail.com>
parents:
diff changeset
854 auth SHA256
Pluto <meokcin@gmail.com>
parents:
diff changeset
855 cipher AES-128-GCM
Pluto <meokcin@gmail.com>
parents:
diff changeset
856 ignore-unknown-option block-outside-dns block-ipv6
Pluto <meokcin@gmail.com>
parents:
diff changeset
857 verb 3" > /etc/openvpn/server/client-common.txt
Pluto <meokcin@gmail.com>
parents:
diff changeset
858 # Enable and start the OpenVPN service
Pluto <meokcin@gmail.com>
parents:
diff changeset
859 if [ "$os" != "openSUSE" ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
860 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
861 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
862 systemctl enable --now openvpn-server@server.service >/dev/null 2>&1
Pluto <meokcin@gmail.com>
parents:
diff changeset
863 )
Pluto <meokcin@gmail.com>
parents:
diff changeset
864 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
865 ln -s /etc/openvpn/server/* /etc/openvpn >/dev/null 2>&1
Pluto <meokcin@gmail.com>
parents:
diff changeset
866 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
867 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
868 systemctl enable --now openvpn@server.service >/dev/null 2>&1
Pluto <meokcin@gmail.com>
parents:
diff changeset
869 )
Pluto <meokcin@gmail.com>
parents:
diff changeset
870 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
871 # Generates the custom client.ovpn
Pluto <meokcin@gmail.com>
parents:
diff changeset
872 new_client
Pluto <meokcin@gmail.com>
parents:
diff changeset
873 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
874 echo "Finished!"
Pluto <meokcin@gmail.com>
parents:
diff changeset
875 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
876 echo "The client configuration is available in: $export_dir$client.ovpn"
Pluto <meokcin@gmail.com>
parents:
diff changeset
877 echo "New clients can be added by running this script again."
Pluto <meokcin@gmail.com>
parents:
diff changeset
878 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
879 show_header
Pluto <meokcin@gmail.com>
parents:
diff changeset
880 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
881 echo "OpenVPN is already installed."
Pluto <meokcin@gmail.com>
parents:
diff changeset
882 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
883 echo "Select an option:"
Pluto <meokcin@gmail.com>
parents:
diff changeset
884 echo " 1) Add a new client"
Pluto <meokcin@gmail.com>
parents:
diff changeset
885 echo " 2) Export config for an existing client"
Pluto <meokcin@gmail.com>
parents:
diff changeset
886 echo " 3) List existing clients"
Pluto <meokcin@gmail.com>
parents:
diff changeset
887 echo " 4) Revoke an existing client"
Pluto <meokcin@gmail.com>
parents:
diff changeset
888 echo " 5) Remove OpenVPN"
Pluto <meokcin@gmail.com>
parents:
diff changeset
889 echo " 6) Exit"
Pluto <meokcin@gmail.com>
parents:
diff changeset
890 read -rp "Option: " option
Pluto <meokcin@gmail.com>
parents:
diff changeset
891 until [[ "$option" =~ ^[1-6]$ ]]; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
892 echo "$option: invalid selection."
Pluto <meokcin@gmail.com>
parents:
diff changeset
893 read -rp "Option: " option
Pluto <meokcin@gmail.com>
parents:
diff changeset
894 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
895 case "$option" in
Pluto <meokcin@gmail.com>
parents:
diff changeset
896 1)
Pluto <meokcin@gmail.com>
parents:
diff changeset
897 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
898 echo "Provide a name for the client:"
Pluto <meokcin@gmail.com>
parents:
diff changeset
899 read -rp "Name: " unsanitized_client
Pluto <meokcin@gmail.com>
parents:
diff changeset
900 [ -z "$unsanitized_client" ] && abort_and_exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
901 set_client_name
Pluto <meokcin@gmail.com>
parents:
diff changeset
902 while [[ -z "$client" || -e /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt ]]; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
903 echo "$client: invalid name."
Pluto <meokcin@gmail.com>
parents:
diff changeset
904 read -rp "Name: " unsanitized_client
Pluto <meokcin@gmail.com>
parents:
diff changeset
905 [ -z "$unsanitized_client" ] && abort_and_exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
906 set_client_name
Pluto <meokcin@gmail.com>
parents:
diff changeset
907 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
908 cd /etc/openvpn/server/easy-rsa/ || exit 1
Pluto <meokcin@gmail.com>
parents:
diff changeset
909 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
910 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
911 ./easyrsa --batch --days=3650 build-client-full "$client" nopass >/dev/null 2>&1
Pluto <meokcin@gmail.com>
parents:
diff changeset
912 )
Pluto <meokcin@gmail.com>
parents:
diff changeset
913 # Generates the custom client.ovpn
Pluto <meokcin@gmail.com>
parents:
diff changeset
914 new_client
Pluto <meokcin@gmail.com>
parents:
diff changeset
915 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
916 echo "$client added. Configuration available in: $export_dir$client.ovpn"
Pluto <meokcin@gmail.com>
parents:
diff changeset
917 exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
918 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
919 2)
Pluto <meokcin@gmail.com>
parents:
diff changeset
920 num_of_clients=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep -c "^V")
Pluto <meokcin@gmail.com>
parents:
diff changeset
921 if [[ "$num_of_clients" = 0 ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
922 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
923 echo "There are no existing clients!"
Pluto <meokcin@gmail.com>
parents:
diff changeset
924 exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
925 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
926 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
927 echo "Select the client to export:"
Pluto <meokcin@gmail.com>
parents:
diff changeset
928 tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
Pluto <meokcin@gmail.com>
parents:
diff changeset
929 read -rp "Client: " client_num
Pluto <meokcin@gmail.com>
parents:
diff changeset
930 [ -z "$client_num" ] && abort_and_exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
931 until [[ "$client_num" =~ ^[0-9]+$ && "$client_num" -le "$num_of_clients" ]]; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
932 echo "$client_num: invalid selection."
Pluto <meokcin@gmail.com>
parents:
diff changeset
933 read -rp "Client: " client_num
Pluto <meokcin@gmail.com>
parents:
diff changeset
934 [ -z "$client_num" ] && abort_and_exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
935 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
936 client=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$client_num"p)
Pluto <meokcin@gmail.com>
parents:
diff changeset
937 new_client
Pluto <meokcin@gmail.com>
parents:
diff changeset
938 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
939 echo "$client exported. Configuration available in: $export_dir$client.ovpn"
Pluto <meokcin@gmail.com>
parents:
diff changeset
940 exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
941 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
942 3)
Pluto <meokcin@gmail.com>
parents:
diff changeset
943 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
944 echo "Checking for existing client(s)..."
Pluto <meokcin@gmail.com>
parents:
diff changeset
945 num_of_clients=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep -c "^V")
Pluto <meokcin@gmail.com>
parents:
diff changeset
946 if [[ "$num_of_clients" = 0 ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
947 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
948 echo "There are no existing clients!"
Pluto <meokcin@gmail.com>
parents:
diff changeset
949 exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
950 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
951 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
952 tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
Pluto <meokcin@gmail.com>
parents:
diff changeset
953 if [ "$num_of_clients" = 1 ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
954 printf '\n%s\n' "Total: 1 client"
Pluto <meokcin@gmail.com>
parents:
diff changeset
955 elif [ -n "$num_of_clients" ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
956 printf '\n%s\n' "Total: $num_of_clients clients"
Pluto <meokcin@gmail.com>
parents:
diff changeset
957 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
958 exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
959 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
960 4)
Pluto <meokcin@gmail.com>
parents:
diff changeset
961 num_of_clients=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep -c "^V")
Pluto <meokcin@gmail.com>
parents:
diff changeset
962 if [[ "$num_of_clients" = 0 ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
963 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
964 echo "There are no existing clients!"
Pluto <meokcin@gmail.com>
parents:
diff changeset
965 exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
966 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
967 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
968 echo "Select the client to revoke:"
Pluto <meokcin@gmail.com>
parents:
diff changeset
969 tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
Pluto <meokcin@gmail.com>
parents:
diff changeset
970 read -rp "Client: " client_num
Pluto <meokcin@gmail.com>
parents:
diff changeset
971 [ -z "$client_num" ] && abort_and_exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
972 until [[ "$client_num" =~ ^[0-9]+$ && "$client_num" -le "$num_of_clients" ]]; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
973 echo "$client_num: invalid selection."
Pluto <meokcin@gmail.com>
parents:
diff changeset
974 read -rp "Client: " client_num
Pluto <meokcin@gmail.com>
parents:
diff changeset
975 [ -z "$client_num" ] && abort_and_exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
976 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
977 client=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$client_num"p)
Pluto <meokcin@gmail.com>
parents:
diff changeset
978 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
979 read -rp "Confirm $client revocation? [y/N]: " revoke
Pluto <meokcin@gmail.com>
parents:
diff changeset
980 until [[ "$revoke" =~ ^[yYnN]*$ ]]; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
981 echo "$revoke: invalid selection."
Pluto <meokcin@gmail.com>
parents:
diff changeset
982 read -rp "Confirm $client revocation? [y/N]: " revoke
Pluto <meokcin@gmail.com>
parents:
diff changeset
983 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
984 if [[ "$revoke" =~ ^[yY]$ ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
985 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
986 echo "Revoking $client..."
Pluto <meokcin@gmail.com>
parents:
diff changeset
987 cd /etc/openvpn/server/easy-rsa/ || exit 1
Pluto <meokcin@gmail.com>
parents:
diff changeset
988 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
989 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
990 ./easyrsa --batch revoke "$client" >/dev/null 2>&1
Pluto <meokcin@gmail.com>
parents:
diff changeset
991 ./easyrsa --batch --days=3650 gen-crl >/dev/null 2>&1
Pluto <meokcin@gmail.com>
parents:
diff changeset
992 )
Pluto <meokcin@gmail.com>
parents:
diff changeset
993 rm -f /etc/openvpn/server/crl.pem
Pluto <meokcin@gmail.com>
parents:
diff changeset
994 cp /etc/openvpn/server/easy-rsa/pki/crl.pem /etc/openvpn/server/crl.pem
Pluto <meokcin@gmail.com>
parents:
diff changeset
995 # CRL is read with each client connection, when OpenVPN is dropped to nobody
Pluto <meokcin@gmail.com>
parents:
diff changeset
996 chown nobody:"$group_name" /etc/openvpn/server/crl.pem
Pluto <meokcin@gmail.com>
parents:
diff changeset
997 get_export_dir
Pluto <meokcin@gmail.com>
parents:
diff changeset
998 ovpn_file="$export_dir$client.ovpn"
Pluto <meokcin@gmail.com>
parents:
diff changeset
999 if [ -f "$ovpn_file" ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
1000 echo "Removing $ovpn_file..."
Pluto <meokcin@gmail.com>
parents:
diff changeset
1001 rm -f "$ovpn_file"
Pluto <meokcin@gmail.com>
parents:
diff changeset
1002 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
1003 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
1004 echo "$client revoked!"
Pluto <meokcin@gmail.com>
parents:
diff changeset
1005 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
1006 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
1007 echo "$client revocation aborted!"
Pluto <meokcin@gmail.com>
parents:
diff changeset
1008 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
1009 exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
1010 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
1011 5)
Pluto <meokcin@gmail.com>
parents:
diff changeset
1012 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
1013 read -rp "Confirm OpenVPN removal? [y/N]: " remove
Pluto <meokcin@gmail.com>
parents:
diff changeset
1014 until [[ "$remove" =~ ^[yYnN]*$ ]]; do
Pluto <meokcin@gmail.com>
parents:
diff changeset
1015 echo "$remove: invalid selection."
Pluto <meokcin@gmail.com>
parents:
diff changeset
1016 read -rp "Confirm OpenVPN removal? [y/N]: " remove
Pluto <meokcin@gmail.com>
parents:
diff changeset
1017 done
Pluto <meokcin@gmail.com>
parents:
diff changeset
1018 if [[ "$remove" =~ ^[yY]$ ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
1019 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
1020 echo "Removing OpenVPN, please wait..."
Pluto <meokcin@gmail.com>
parents:
diff changeset
1021 port=$(grep '^port ' /etc/openvpn/server/server.conf | cut -d " " -f 2)
Pluto <meokcin@gmail.com>
parents:
diff changeset
1022 protocol=$(grep '^proto ' /etc/openvpn/server/server.conf | cut -d " " -f 2)
Pluto <meokcin@gmail.com>
parents:
diff changeset
1023 if systemctl is-active --quiet firewalld.service; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
1024 ip=$(firewall-cmd --direct --get-rules ipv4 nat POSTROUTING | grep '\-s 10.8.0.0/24 '"'"'!'"'"' -d 10.8.0.0/24' | grep -oE '[^ ]+$')
Pluto <meokcin@gmail.com>
parents:
diff changeset
1025 # Using both permanent and not permanent rules to avoid a firewalld reload.
Pluto <meokcin@gmail.com>
parents:
diff changeset
1026 firewall-cmd -q --remove-port="$port"/"$protocol"
Pluto <meokcin@gmail.com>
parents:
diff changeset
1027 firewall-cmd -q --zone=trusted --remove-source=10.8.0.0/24
Pluto <meokcin@gmail.com>
parents:
diff changeset
1028 firewall-cmd -q --permanent --remove-port="$port"/"$protocol"
Pluto <meokcin@gmail.com>
parents:
diff changeset
1029 firewall-cmd -q --permanent --zone=trusted --remove-source=10.8.0.0/24
Pluto <meokcin@gmail.com>
parents:
diff changeset
1030 firewall-cmd -q --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
Pluto <meokcin@gmail.com>
parents:
diff changeset
1031 firewall-cmd -q --permanent --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j MASQUERADE
Pluto <meokcin@gmail.com>
parents:
diff changeset
1032 if grep -qs "server-ipv6" /etc/openvpn/server/server.conf; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
1033 ip6=$(firewall-cmd --direct --get-rules ipv6 nat POSTROUTING | grep '\-s fddd:1194:1194:1194::/64 '"'"'!'"'"' -d fddd:1194:1194:1194::/64' | grep -oE '[^ ]+$')
Pluto <meokcin@gmail.com>
parents:
diff changeset
1034 firewall-cmd -q --zone=trusted --remove-source=fddd:1194:1194:1194::/64
Pluto <meokcin@gmail.com>
parents:
diff changeset
1035 firewall-cmd -q --permanent --zone=trusted --remove-source=fddd:1194:1194:1194::/64
Pluto <meokcin@gmail.com>
parents:
diff changeset
1036 firewall-cmd -q --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
Pluto <meokcin@gmail.com>
parents:
diff changeset
1037 firewall-cmd -q --permanent --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j MASQUERADE
Pluto <meokcin@gmail.com>
parents:
diff changeset
1038 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
1039 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
1040 systemctl disable --now openvpn-iptables.service
Pluto <meokcin@gmail.com>
parents:
diff changeset
1041 rm -f /etc/systemd/system/openvpn-iptables.service
Pluto <meokcin@gmail.com>
parents:
diff changeset
1042 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
1043 if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
1044 semanage port -d -t openvpn_port_t -p "$protocol" "$port"
Pluto <meokcin@gmail.com>
parents:
diff changeset
1045 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
1046 if [ "$os" != "openSUSE" ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
1047 systemctl disable --now openvpn-server@server.service
Pluto <meokcin@gmail.com>
parents:
diff changeset
1048 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
1049 systemctl disable --now openvpn@server.service
Pluto <meokcin@gmail.com>
parents:
diff changeset
1050 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
1051 rm -f /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
1052 rm -f /etc/sysctl.d/99-openvpn-forward.conf /etc/sysctl.d/99-openvpn-optimize.conf
Pluto <meokcin@gmail.com>
parents:
diff changeset
1053 if [ ! -f /usr/bin/wg-quick ] && [ ! -f /usr/sbin/ipsec ] \
Pluto <meokcin@gmail.com>
parents:
diff changeset
1054 && [ ! -f /usr/local/sbin/ipsec ]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
1055 echo 0 > /proc/sys/net/ipv4/ip_forward
Pluto <meokcin@gmail.com>
parents:
diff changeset
1056 echo 0 > /proc/sys/net/ipv6/conf/all/forwarding
Pluto <meokcin@gmail.com>
parents:
diff changeset
1057 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
1058 ipt_cmd="systemctl restart openvpn-iptables.service"
Pluto <meokcin@gmail.com>
parents:
diff changeset
1059 if grep -qs "$ipt_cmd" /etc/rc.local; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
1060 sed --follow-symlinks -i "/^$ipt_cmd/d" /etc/rc.local
Pluto <meokcin@gmail.com>
parents:
diff changeset
1061 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
1062 if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
1063 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
1064 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
1065 rm -rf /etc/openvpn/server
Pluto <meokcin@gmail.com>
parents:
diff changeset
1066 apt-get remove --purge -y openvpn >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
1067 )
Pluto <meokcin@gmail.com>
parents:
diff changeset
1068 elif [[ "$os" = "openSUSE" ]]; then
Pluto <meokcin@gmail.com>
parents:
diff changeset
1069 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
1070 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
1071 zypper remove -y openvpn >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
1072 rm -rf /etc/openvpn/server
Pluto <meokcin@gmail.com>
parents:
diff changeset
1073 )
Pluto <meokcin@gmail.com>
parents:
diff changeset
1074 rm -f /etc/openvpn/ipp.txt
Pluto <meokcin@gmail.com>
parents:
diff changeset
1075 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
1076 # Else, OS must be CentOS or Fedora
Pluto <meokcin@gmail.com>
parents:
diff changeset
1077 (
Pluto <meokcin@gmail.com>
parents:
diff changeset
1078 set -x
Pluto <meokcin@gmail.com>
parents:
diff changeset
1079 yum -y -q remove openvpn >/dev/null
Pluto <meokcin@gmail.com>
parents:
diff changeset
1080 rm -rf /etc/openvpn/server
Pluto <meokcin@gmail.com>
parents:
diff changeset
1081 )
Pluto <meokcin@gmail.com>
parents:
diff changeset
1082 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
1083 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
1084 echo "OpenVPN removed!"
Pluto <meokcin@gmail.com>
parents:
diff changeset
1085 else
Pluto <meokcin@gmail.com>
parents:
diff changeset
1086 echo
Pluto <meokcin@gmail.com>
parents:
diff changeset
1087 echo "OpenVPN removal aborted!"
Pluto <meokcin@gmail.com>
parents:
diff changeset
1088 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
1089 exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
1090 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
1091 6)
Pluto <meokcin@gmail.com>
parents:
diff changeset
1092 exit
Pluto <meokcin@gmail.com>
parents:
diff changeset
1093 ;;
Pluto <meokcin@gmail.com>
parents:
diff changeset
1094 esac
Pluto <meokcin@gmail.com>
parents:
diff changeset
1095 fi
Pluto <meokcin@gmail.com>
parents:
diff changeset
1096 }
Pluto <meokcin@gmail.com>
parents:
diff changeset
1097
Pluto <meokcin@gmail.com>
parents:
diff changeset
1098 ## Defer setup until we have the complete script
Pluto <meokcin@gmail.com>
parents:
diff changeset
1099 ovpnsetup "$@"
Pluto <meokcin@gmail.com>
parents:
diff changeset
1100
Pluto <meokcin@gmail.com>
parents:
diff changeset
1101 exit 0
备案号:苏ICP备2024087954号-2 | 渝公网安备50010402001513