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