|
|
$ {& m3 A1 d$ u) \ C& D5 x
- #!/bin/bash
- B/ K7 v; J) k" \0 M - #
# f" @& h' {# f7 l# a* u- ~ - # https://github.com/Nyr/openvpn-install
! m# {" Y3 A$ S8 s- f - #
+ f, I% K! O8 N" T - # Copyright (c) 2013 Nyr. Released under the MIT License.
2 Y! \2 Y) H1 g0 T5 h/ a- k - ; f+ q' A3 Z" v5 c) W8 r) S$ C/ `1 ?
- + W% @7 C" P3 _1 N! a
- # Detect Debian users running the script with "sh" instead of bash+ w0 o1 l3 U& ~ S9 }& }! H, n# o
- if readlink /proc/$$/exe | grep -q "dash"; then' w6 W2 p) ?9 y! W4 r1 l% q7 o
- echo 'This installer needs to be run with "bash", not "sh".': s- T, [. i" I! W, K
- exit, u0 x" T& B D3 v! p% i
- fi
8 n( h G5 e- b/ F - g! H3 y2 a; k" |* s* S
- # Discard stdin. Needed when running from an one-liner which includes a newline
& S# z2 d6 _4 J8 A8 }3 a+ C - read -N 999999 -t 0.001
2 w/ S! d3 a) @0 a( T- K5 u
+ ?+ O6 B; C, O3 `( i2 y8 q- # Detect OpenVZ 6
! { k4 a' c" s) S6 |8 z# ? - if [[ $(uname -r | cut -d "." -f 1) -eq 2 ]]; then$ z5 f. [. Q- o9 W0 W
- echo "The system is running an old kernel, which is incompatible with this installer."
5 q, F4 ~; K' P% E0 E - exit, J8 z' B4 q: J* L( W5 B; `$ l
- fi
L1 z6 |; ^0 O/ j. {
# I3 B1 z" `5 ?% J4 ]+ X! d- # Detect OS
5 A+ L( a h1 { Y" A3 o9 X - # $os_version variables aren't always in use, but are kept here for convenience
4 W0 Z7 e) h5 U# a4 g- a - if grep -qs "ubuntu" /etc/os-release; then1 p" Q- a \3 |
- os="ubuntu"" N7 a3 j; Z) H* e& z
- os_version=$(grep 'VERSION_ID' /etc/os-release | cut -d '"' -f 2 | tr -d '.')9 ?/ m1 A: z; T$ M- o: i, g3 y
- group_name="nogroup"* P. S3 Z$ g$ j3 g# C
- elif [[ -e /etc/debian_version ]]; then2 x8 k9 q0 a1 X9 l6 y
- os="debian"
/ K9 T; `* ?- z. P, ~9 L/ C5 d - os_version=$(grep -oE '[0-9]+' /etc/debian_version | head -1)4 W4 X0 S7 f# q* ?2 x
- group_name="nogroup"
4 v% q1 L4 f& ]: j& L( A% {& [ - elif [[ -e /etc/almalinux-release || -e /etc/rocky-release || -e /etc/centos-release ]]; then
5 X& X; e- O1 X+ h9 k! i - os="centos"
; M+ e0 ^+ U# O7 ~, s% u - os_version=$(grep -shoE '[0-9]+' /etc/almalinux-release /etc/rocky-release /etc/centos-release | head -1)0 V8 N8 a ^# G$ Q' O
- group_name="nobody"# K O# M5 k: _' G
- elif [[ -e /etc/fedora-release ]]; then# ]9 D+ @. J L7 ^% N
- os="fedora"
$ Y% @3 R8 N2 z! V2 B - os_version=$(grep -oE '[0-9]+' /etc/fedora-release | head -1)# H! ]' f/ ^' j7 {) l1 n9 D1 U
- group_name="nobody"7 V2 _: M& {' c8 r3 @; [
- else
) Y* {8 W. o+ \0 y - echo "This installer seems to be running on an unsupported distribution.
' O* V" ` U, v# h( j2 C - Supported distros are Ubuntu, Debian, AlmaLinux, Rocky Linux, CentOS and Fedora."1 x* D$ `5 U" [& |
- exit+ E$ W) O- L1 t2 v$ U' i) }8 Z; Q
- fi) \$ o j9 ]9 ]# B+ ]: y
- 1 n* ^+ v- |6 W7 j z) E
- if [[ "$os" == "ubuntu" && "$os_version" -lt 1804 ]]; then
1 F3 @# T' W0 [& ?9 d - echo "Ubuntu 18.04 or higher is required to use this installer.6 Q* |% l) z; l
- This version of Ubuntu is too old and unsupported."# t) h2 @, u- q( l- J" p
- exit- I- C/ @/ Z; z& D# q* E
- fi; _2 l; e# F/ N( i3 Y
- 5 g: M$ F0 A4 q; k
- if [[ "$os" == "debian" && "$os_version" -lt 9 ]]; then
0 Z4 ^" y, `7 k# l# v! \- L - echo "Debian 9 or higher is required to use this installer.
) y% \; O# @ f5 [ - This version of Debian is too old and unsupported."/ ^9 a9 a9 z( ]+ \0 c, s4 E$ b$ Z$ U2 u
- exit
" c4 P% Y- t8 s# [* C g - fi. b- K- q7 x V2 n, ]- f$ e4 Y) P
- / o8 x1 M/ j4 s9 g' I: G) |
- if [[ "$os" == "centos" && "$os_version" -lt 7 ]]; then' J( [3 j: m+ h" \* O: v) J
- echo "CentOS 7 or higher is required to use this installer.
% y9 s! K) t/ B2 N - This version of CentOS is too old and unsupported."
( E3 ?/ l5 v! D3 X# J - exit7 }+ N) d. H4 d+ P9 _& T( N
- fi# W: G- ^: |# ?: f; q
- # A! w9 c* \8 t7 ^! N" w8 @
- # Detect environments where $PATH does not include the sbin directories! C# Q: P+ s" L( T
- if ! grep -q sbin <<< "$PATH"; then1 T8 P6 C" Q& d# _" t; P3 j
- echo '$PATH does not include sbin. Try using "su -" instead of "su".'6 ~# K' [" W) J* k
- exit- F+ j2 b5 j5 U& b/ J# ~9 m
- fi" W1 y' i+ }7 ^' ]9 V6 a& f
' i* R% u" N. Z/ C( s( F/ k- if [[ "$EUID" -ne 0 ]]; then
$ |. ^% P/ W, V# o: X/ T+ ` ~- s$ _ - echo "This installer needs to be run with superuser privileges."
5 @# f, M$ E" B - exit) j& d9 a! i: t
- fi
: A( r) k2 O6 L1 B+ U9 {( b
. U& C+ |7 i( @4 m0 s( ]- if [[ ! -e /dev/net/tun ]] || ! ( exec 7<>/dev/net/tun ) 2>/dev/null; then- A9 f$ J5 S# Z2 e0 W
- echo "The system does not have the TUN device available.1 v, Y9 g8 _2 @6 q. k
- TUN needs to be enabled before running this installer."3 g! s8 x" k! E/ t* ]
- exit* c: B. E" R5 m O
- fi' \, Y. n) S U0 N2 B
- + y# j7 x* ~1 I6 }" _) E
- new_client () {
- D, ^0 ]* `& ?% N1 |: _7 l - # Generates the custom client.ovpn
4 B& C4 A% y5 s8 {7 D+ T - {
6 G; e- ^) r$ b5 ?' z! f1 { - cat /etc/openvpn/server/client-common.txt
6 _% _2 K/ Q/ [ - echo "<ca>"0 e6 [8 _4 U4 [
- cat /etc/openvpn/server/easy-rsa/pki/ca.crt8 ?' ]" ]+ V9 g H* V P
- echo "</ca>"7 {5 L; l- g+ ^
- echo "<cert>"
; u! A2 o1 g; ^' I) ~6 k$ r% I - sed -ne '/BEGIN CERTIFICATE/,$ p' /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt
' N- _; r; g0 l9 O5 N - echo "</cert>"% C6 F: B6 o2 [2 N0 V @: r
- echo "<key>"
3 E- m6 u' {! @! c4 B# ]9 y5 H - cat /etc/openvpn/server/easy-rsa/pki/private/"$client".key
, j, q# I2 Q! J" g - echo "</key>"4 n/ X6 g9 ~) c
- echo "<tls-crypt>", ~/ J" W& N% u( k. c
- sed -ne '/BEGIN OpenVPN Static key/,$ p' /etc/openvpn/server/tc.key
. ^& b( L [) T - echo "</tls-crypt>"
" i5 M! S3 J% x6 ]* j0 j - } > ~/"$client".ovpn
) p% V& M- C8 S& @ - }
( d7 |2 n; h" F# X* _ - / D; U% f* V e2 H, m
- if [[ ! -e /etc/openvpn/server/server.conf ]]; then
9 F5 [- G7 q6 c$ d+ H) v - # Detect some Debian minimal setups where neither wget nor curl are installed
1 k. R# S5 Z8 D p7 f8 e - if ! hash wget 2>/dev/null && ! hash curl 2>/dev/null; then
1 ~; e9 U8 N( Q! f, f( E ~( H - echo "Wget is required to use this installer."3 c7 v+ X* s3 k4 K
- read -n1 -r -p "Press any key to install Wget and continue..."
& f& b5 t/ h9 p8 u; i3 g - apt-get update# W1 w V& e- m! Z+ `6 f7 @! g1 T
- apt-get install -y wget
) t9 _* E' G+ l- `$ M0 Z - fi
; T) p7 y$ ], L - clear) Z: R% d& w4 b4 N8 K: q# x
- echo 'Welcome to this OpenVPN road warrior installer!'# g+ I7 A" h1 ?" W2 d3 ], Z
- # If system has a single IPv4, it is selected automatically. Else, ask the user. X. b. d: W% h* d% Z
- if [[ $(ip -4 addr | grep inet | grep -vEc '127(\.[0-9]{1,3}){3}') -eq 1 ]]; then
* S5 d$ D6 N8 P6 B& h - 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}')# e" x, C% l( q" c& ^
- else; L1 K& \: ?$ u5 e& C
- number_of_ip=$(ip -4 addr | grep inet | grep -vEc '127(\.[0-9]{1,3}){3}')
: E" C' z. g6 G& W$ m# _+ t - echo
3 W# t+ G- l6 u! |- M6 X5 u, Z - echo "Which IPv4 address should be used?" p+ @+ k8 j7 x ^% L
- 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 ') ', A% @$ _8 w% j
- read -p "IPv4 address [1]: " ip_number
# C0 T6 s2 x) M$ C" V - until [[ -z "$ip_number" || "$ip_number" =~ ^[0-9]+$ && "$ip_number" -le "$number_of_ip" ]]; do
3 }) h! _& f$ a' I: x6 m - echo "$ip_number: invalid selection."
! w5 ?8 _: w8 t& `, I& | - read -p "IPv4 address [1]: " ip_number
' y4 w, e2 @) @/ _/ p) m3 ^/ Z - done
5 K/ k5 C! B* `8 L3 \ - [[ -z "$ip_number" ]] && ip_number="1"
5 u% e% A1 E# K Z$ @6 G: t - ip=$(ip -4 addr | grep inet | grep -vE '127(\.[0-9]{1,3}){3}' | cut -d '/' -f 1 | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' | sed -n "$ip_number"p)
. b& z# T. R) ?/ v5 z - fi
$ Z O5 K/ m# |3 Y# k% R - # If $ip is a private IP address, the server must be behind NAT5 I& X1 {1 Y. q2 A) t: E- N$ G
- if echo "$ip" | grep -qE '^(10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|192\.168)'; then2 m1 k# e) i4 ^2 f
- echo6 c# v+ T% B% x8 s! Z
- echo "This server is behind NAT. What is the public IPv4 address or hostname?"
" [' `2 I5 e4 T8 X - # Get public IP and sanitize with grep
7 k3 j: I7 z; e0 | A& X3 d - get_public_ip=$(grep -m 1 -oE '^[0-9]{1,3}(\.[0-9]{1,3}){3}$' <<< "$(wget -T 10 -t 1 -4qO- "http://ip1.dynupdate.no-ip.com/" || curl -m 10 -4Ls "http://ip1.dynupdate.no-ip.com/")")
$ c$ L- b1 d% a. B* G2 M! E( y - read -p "Public IPv4 address / hostname [$get_public_ip]: " public_ip
0 b p% k5 i1 c. d# M3 d - # If the checkip service is unavailable and user didn't provide input, ask again* E) l6 t8 I0 F) M
- until [[ -n "$get_public_ip" || -n "$public_ip" ]]; do0 C. @" } K% h$ V6 c8 _
- echo "Invalid input."9 r- [$ E# o1 \: G9 I
- read -p "Public IPv4 address / hostname: " public_ip# p, @# @* O4 p1 i( K6 d- y! ?# a
- done! M% @ S# s) c$ T
- [[ -z "$public_ip" ]] && public_ip="$get_public_ip"
$ j3 T( A2 C" v+ g - fi
; a1 k) u) W" m& Z% ` - # If system has a single IPv6, it is selected automatically
* u9 ?! k/ h' q: z - if [[ $(ip -6 addr | grep -c 'inet6 [23]') -eq 1 ]]; then
4 Z2 L$ t: F& W) r - 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}')) W: m: b7 f7 U, U
- fi
; l$ J1 e' ]& @, ]8 P - # If system has multiple IPv6, ask the user to select one- a4 c4 x4 v0 ?( A) M5 r
- if [[ $(ip -6 addr | grep -c 'inet6 [23]') -gt 1 ]]; then
@$ L: m% S1 r3 g: C% G9 K5 c - number_of_ip6=$(ip -6 addr | grep -c 'inet6 [23]')+ @" G! a2 n4 _# E1 {
- echo/ x) @. t9 f0 G0 N% K# Z4 m9 g
- echo "Which IPv6 address should be used?"" }# J' q3 F4 f# H4 o3 ]
- ip -6 addr | grep 'inet6 [23]' | cut -d '/' -f 1 | grep -oE '([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}' | nl -s ') '
0 n; t+ m( V9 z) L1 k+ w - read -p "IPv6 address [1]: " ip6_number
) ?4 T0 A( D5 e7 V - until [[ -z "$ip6_number" || "$ip6_number" =~ ^[0-9]+$ && "$ip6_number" -le "$number_of_ip6" ]]; do' y$ u, c2 E2 b& O4 t% ?
- echo "$ip6_number: invalid selection."* C5 t3 w& `3 u
- read -p "IPv6 address [1]: " ip6_number
+ T9 e+ y+ z. c9 P - done/ A! N. `, S/ U5 s
- [[ -z "$ip6_number" ]] && ip6_number="1"9 r# X$ C# V1 P) t4 N: P/ S
- ip6=$(ip -6 addr | grep 'inet6 [23]' | cut -d '/' -f 1 | grep -oE '([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}' | sed -n "$ip6_number"p)
5 h! M, F% K/ V% u: n! T& s - fi* R- V. V z- N' v. z/ r5 t
- echo
8 \# E* g- r3 W& b1 U - echo "Which protocol should OpenVPN use?"( @9 l2 t: f9 U6 `$ O" s
- echo " 1) UDP (recommended)"
% x' \* f6 O; k+ z7 g - echo " 2) TCP"# c) v2 n+ w; j
- read -p "Protocol [1]: " protocol8 e" w4 S/ G" X0 a
- until [[ -z "$protocol" || "$protocol" =~ ^[12]$ ]]; do
( E" W. [2 _1 O h' z# |, B4 T - echo "$protocol: invalid selection."
) |+ _9 v; \ ?" |. { - read -p "Protocol [1]: " protocol
0 i) m9 q8 Z. m - done
1 J" w8 \6 I& v7 V ?/ x5 h - case "$protocol" in9 \2 R, Z# x X
- 1|"") ; [; V$ x8 H8 C% p# p( T# ?
- protocol=udp) p: ]5 @, D* M4 e9 V
- ;;! R; ]" `1 t$ Q; d
- 2) 3 y# g' _ {% r& p
- protocol=tcp$ L+ D' A6 v" d
- ;;
, s7 b6 r7 E+ O0 v6 H - esac
" l3 v1 K0 o9 e/ E$ K - echo
! ]. q! l1 t! z" s' p& Q - echo "What port should OpenVPN listen to?"
. i9 e* S2 c6 |) i - read -p "Port [1194]: " port
5 N+ a, T' w6 {8 U( F C9 f8 g - until [[ -z "$port" || "$port" =~ ^[0-9]+$ && "$port" -le 65535 ]]; do0 O$ K# O) d: p4 O3 v F. F
- echo "$port: invalid port."
0 U, {! w7 V" n4 K% w; C1 Q - read -p "Port [1194]: " port
% A- [* q0 \/ D4 M - done
; v7 s: G9 U3 S" X: d- n - [[ -z "$port" ]] && port="1194"+ \% o7 r+ U4 w# ]$ g
- echo
; _- }) F9 v8 [. e0 k9 `5 D' ] - echo "Select a DNS server for the clients:"3 {* ~5 v K1 T1 M2 \
- echo " 1) Current system resolvers"
& O% l) e4 t: Q) Q5 s( @, h% b - echo " 2) Google"
# s: n: _, g' A ? - echo " 3) 1.1.1.1"
8 t+ N1 ^8 N0 j% n7 k1 t- z - echo " 4) OpenDNS"
9 b2 K: E6 r2 R3 l) n7 d3 c - echo " 5) Quad9"
6 E! r$ H8 i7 ^! e! Y+ P9 D - echo " 6) AdGuard"' ?- `1 u. u* O$ @0 R9 F' e
- read -p "DNS server [1]: " dns
/ c: @/ F- j$ M" u( ~: g$ m - until [[ -z "$dns" || "$dns" =~ ^[1-6]$ ]]; do* B G" d" {% N$ Q7 S
- echo "$dns: invalid selection."! O5 N! ?( H$ q; a
- read -p "DNS server [1]: " dns0 ^0 ]6 t9 X" D; t z
- done
% w m5 ~# [" w2 S0 } - echo
/ r7 i; N+ E6 @* i# l6 [ - echo "Enter a name for the first client:"3 {. A D. F7 i5 q% z
- read -p "Name [client]: " unsanitized_client# g: G' |, |- y, g7 `
- # Allow a limited set of characters to avoid conflicts
r1 }8 r6 `3 U: w7 Q* {7 ` - client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client")
# c) ]. n8 z" ]. _/ p - [[ -z "$client" ]] && client="client"
! Z: A" Y1 G9 j# } a7 d - echo
" x! r* y4 k1 U5 n( d. W% ` - echo "OpenVPN installation is ready to begin."/ P4 E8 U; z1 I7 c8 ~
- # Install a firewall if firewalld or iptables are not already available
* ?! h" o5 k6 ^; [% V - if ! systemctl is-active --quiet firewalld.service && ! hash iptables 2>/dev/null; then' D6 Q+ S- Q- u5 \, C( T
- if [[ "$os" == "centos" || "$os" == "fedora" ]]; then7 D( s8 e2 o3 @/ h1 M1 h
- firewall="firewalld"
' t* g7 Y/ E% y( M* l/ R3 | - # We don't want to silently enable firewalld, so we give a subtle warning
2 q2 }+ d* n* e: L i; ~# v: P - # If the user continues, firewalld will be installed and enabled during setup U& I3 M3 f9 `1 t: U
- echo "firewalld, which is required to manage routing tables, will also be installed.". x4 N, Y" H' C% o, d& y
- elif [[ "$os" == "debian" || "$os" == "ubuntu" ]]; then" S! q; G" T3 _; U; I- L
- # iptables is way less invasive than firewalld so no warning is given; g" Z0 P% _5 w# \( H
- firewall="iptables"
6 _4 ~/ j! w% r - fi0 [8 q( S6 l7 X* H5 |; [/ G' a3 q9 d# K
- fi# s& ^6 T" p ?. j# M
- read -n1 -r -p "Press any key to continue..."
4 ^5 S( O% p" l6 p1 r9 `( _ - # If running inside a container, disable LimitNPROC to prevent conflicts' F8 C% v6 v) n8 o% k
- if systemd-detect-virt -cq; then" [. e- p) v! P
- mkdir /etc/systemd/system/openvpn-server@server.service.d/ 2>/dev/null% }8 c5 n7 S0 q% v3 @( s f
- echo "[Service]
/ D' `1 X! g$ a6 c, a0 _8 z/ Q - LimitNPROC=infinity" > /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf2 y% u3 `+ j7 y; |3 L3 G( v+ \
- fi8 S" s: E* ]( d) X, u* J# w4 [
- if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then" z. o) ^" o4 ^4 d: f- f/ Q) C! f5 d
- apt-get update
. _# u9 m `" p4 z+ y: K - apt-get install -y openvpn openssl ca-certificates $firewall5 ^4 `, r3 v* Z
- elif [[ "$os" = "centos" ]]; then9 {: m! q( R, g
- yum install -y epel-release
7 K3 r9 _( `. C" Y( i - yum install -y openvpn openssl ca-certificates tar $firewall5 W) n6 E$ P+ I' g2 ?
- else
4 Q* Q8 z9 `# X, k2 k/ H - # Else, OS must be Fedora
: ?8 p) F5 o, R2 R9 W - dnf install -y openvpn openssl ca-certificates tar $firewall8 [1 P; W+ l" D" W$ s5 m& u
- fi
H, I- p. p9 d6 }' _8 y: V - # If firewalld was just installed, enable it4 l' @% o+ v5 ` W F9 `5 Y' p
- if [[ "$firewall" == "firewalld" ]]; then2 n% x' @( r# ?
- systemctl enable --now firewalld.service
~* E. @' `. y- X! G - fi
% \: R& V" \: Z. ^ - # Get easy-rsa
E4 s' q. g! y1 Z- o( X) W: p O - easy_rsa_url='https://github.com/OpenVPN/easy-rsa/releases/download/v3.1.0/EasyRSA-3.1.0.tgz'
6 G2 n' m: R4 \# {- J$ T8 M* {1 K - mkdir -p /etc/openvpn/server/easy-rsa/% M+ I/ {3 u% b. U+ c( c
- { wget -qO- "$easy_rsa_url" 2>/dev/null || curl -sL "$easy_rsa_url" ; } | tar xz -C /etc/openvpn/server/easy-rsa/ --strip-components 1
% i% \, z+ S. P3 ^3 ^ - chown -R root:root /etc/openvpn/server/easy-rsa/+ \" }2 g0 _$ v- D+ L$ L$ P
- cd /etc/openvpn/server/easy-rsa/$ t, u6 @4 N; P/ P- W
- # Create the PKI, set up the CA and the server and client certificates
. }% x6 }. @" k) |3 R& y - ./easyrsa init-pki
) n2 B6 G8 _( }+ @: i; P$ v6 ^ - ./easyrsa --batch build-ca nopass% D8 y& ]" R/ L; M
- EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-server-full server nopass
; b) B4 a. o& z4 S# c% J& x - EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full "$client" nopass
% d9 e7 C- v! O0 d( M7 V$ Z/ l - EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl
; V! ^; v$ ?+ d6 S0 k5 G! m; V - # Move the stuff we need" F) y8 ^ s1 a( {7 b \; r
- cp pki/ca.crt pki/private/ca.key pki/issued/server.crt pki/private/server.key pki/crl.pem /etc/openvpn/server" ~/ A' z$ b" t
- # CRL is read with each client connection, while OpenVPN is dropped to nobody
: z! ?. E. p" O" J3 n( I - chown nobody:"$group_name" /etc/openvpn/server/crl.pem( @/ I4 C6 F1 |8 R/ `7 _# o; q
- # Without +x in the directory, OpenVPN can't run a stat() on the CRL file* }5 g/ c. c. u
- chmod o+x /etc/openvpn/server/
4 _+ ]/ R6 W8 T4 p7 n7 E; Y - # Generate key for tls-crypt
8 T V) `/ L+ T0 W& y v) S7 Z - openvpn --genkey --secret /etc/openvpn/server/tc.key
3 U9 d; ?/ ?; N/ F# t% M: ^ - # Create the DH parameters file using the predefined ffdhe2048 group
( y6 _' b" V4 r/ j% w( D - echo '-----BEGIN DH PARAMETERS-----( Y8 f' ]5 H% T5 L* z2 g1 R3 y
- MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz* |; H9 H9 d5 k) A
- +8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a2 d2 j9 J# D1 o5 @
- 87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
9 c5 M k' B% X8 c% x0 V - YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
" P8 t1 g6 {4 G7 w. I9 O - 7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
/ c* @1 L# o9 n% c s - ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==+ k7 {5 O G. M, r' y& m/ D
- -----END DH PARAMETERS-----' > /etc/openvpn/server/dh.pem
* k4 m2 p0 ^$ [- ~: _" J" X$ k - # Generate server.conf, K9 t% m% o5 a- O; s! O
- echo "local $ip
. p! c; z; n% S4 Y s9 K3 i. W' f* ^ - port $port
. [' g, O& \, ~$ k+ x! F2 n+ E - proto $protocol
; i) Q& a& F1 a! E/ F$ E5 [ - dev tun
7 z9 u. T: N I) E) `0 Y! M - ca ca.crt
* G# y; C' A2 o5 d: ~& b- D - cert server.crt$ M; x# G* ~# Q0 W4 M& o# R: p$ K
- key server.key8 s: v6 }, G3 |. r8 F; }' P- h+ f
- dh dh.pem( [8 {7 B- L7 P) u8 J" P3 ?6 d o
- auth SHA512
/ Y V! g/ ~+ U. c7 J - tls-crypt tc.key
& T2 x- n& A ]& k7 j( y - topology subnet9 D5 V9 H i8 J3 g
- server 10.8.0.0 255.255.255.0" > /etc/openvpn/server/server.conf
0 F6 |/ d- I! J3 e( Y. D - # IPv6& m; {7 o' v" z- n6 L+ ]" g
- if [[ -z "$ip6" ]]; then
7 ^4 G+ F% x2 z- h - echo 'push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server/server.conf o7 [) H$ w+ L. b2 a" r% g1 p
- else
( {5 ]7 I* z. m9 A1 T, d - echo 'server-ipv6 fddd:1194:1194:1194::/64' >> /etc/openvpn/server/server.conf
1 B0 l" q5 d, v' o - echo 'push "redirect-gateway def1 ipv6 bypass-dhcp"' >> /etc/openvpn/server/server.conf
6 P( x2 q/ x3 q8 `% e - fi
* |! L @9 _! m3 T8 W' i+ {. X - echo 'ifconfig-pool-persist ipp.txt' >> /etc/openvpn/server/server.conf
' n: Q/ k' Y* D3 Z - # DNS% P! K; z( Q- K+ d! f
- case "$dns" in
1 D8 G* M+ R7 X3 w9 P - 1|""). U& u* y7 o3 S9 j8 |
- # Locate the proper resolv.conf
; j/ Z! b2 `+ X) _8 ~. F - # Needed for systems running systemd-resolved
9 c+ D) e J# q( _ - if grep -q '^nameserver 127.0.0.53' "/etc/resolv.conf"; then
0 g( N" k2 l& n: B y9 r - resolv_conf="/run/systemd/resolve/resolv.conf"
# |0 d% {+ A$ @( A - else8 ~: Y( i+ ~* p: z2 {
- resolv_conf="/etc/resolv.conf"( |3 g% M; F% A, o0 F) \, y5 f
- fi. M0 z' g+ S+ x: p' b
- # Obtain the resolvers from resolv.conf and use them for OpenVPN8 p7 Z& Y3 B# E. X& R
- grep -v '^#\|^;' "$resolv_conf" | grep '^nameserver' | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' | while read line; do! u& v1 h& H! ]% {, ` G: T0 S
- echo "push "dhcp-option DNS $line"" >> /etc/openvpn/server/server.conf
3 W1 ~ P5 H9 d& R4 S0 i* Y, Q" f# F0 C - done. f2 r% p g$ a5 k
- ;;% E: t+ g0 B' c4 b( x
- 2)* _5 \# [1 d' @ o$ I7 N
- echo 'push "dhcp-option DNS 8.8.8.8"' >> /etc/openvpn/server/server.conf
! a. U1 C4 X# [' K - echo 'push "dhcp-option DNS 8.8.4.4"' >> /etc/openvpn/server/server.conf4 \# R$ a- a1 _, F; s9 Y+ o& q
- ;;! Q/ O3 k9 H- [* F
- 3)
0 h9 A( Z, \3 R9 U" b - echo 'push "dhcp-option DNS 1.1.1.1"' >> /etc/openvpn/server/server.conf
4 i* f# Q f( w* a - echo 'push "dhcp-option DNS 1.0.0.1"' >> /etc/openvpn/server/server.conf
5 N- s+ C2 }2 j: Q' D! P( g7 R: R5 T - ;;3 R( g& T" q& l* J' x5 ?
- 4)9 F6 w* {1 a$ q* c7 n
- echo 'push "dhcp-option DNS 208.67.222.222"' >> /etc/openvpn/server/server.conf' g Z$ t' z6 e/ F1 C
- echo 'push "dhcp-option DNS 208.67.220.220"' >> /etc/openvpn/server/server.conf
9 [0 m, V4 C4 j0 v, L5 I - ;;
! m7 |6 z. |/ x9 {0 |( S - 5)
" s. }; n3 J: p7 h. j! H4 g( P - echo 'push "dhcp-option DNS 9.9.9.9"' >> /etc/openvpn/server/server.conf
+ V' o% M1 t9 X - echo 'push "dhcp-option DNS 149.112.112.112"' >> /etc/openvpn/server/server.conf
& `7 j( l/ t+ o& s9 t - ;;7 T( w1 Z; h, L ?
- 6)) `5 T4 \( G: t% ^; R9 _" P& n) T
- echo 'push "dhcp-option DNS 94.140.14.14"' >> /etc/openvpn/server/server.conf" j$ i/ d; A1 U5 m O& {5 M
- echo 'push "dhcp-option DNS 94.140.15.15"' >> /etc/openvpn/server/server.conf+ M8 }& C0 K+ `
- ;;" A7 M G# w( f& u
- esac0 I8 K a; Q' O$ V! X* z
- echo "keepalive 10 120$ z4 u) F- l Q+ G& T' J# b% g7 A
- cipher AES-256-CBC6 R/ Y# R0 `: p/ |7 R9 M- F
- user nobody. ]7 I* C/ ^; O' D% T8 i1 d5 E5 O
- group $group_name
/ i7 N! {, p0 r - persist-key7 G5 u8 M$ o0 ~" E8 M% v$ A
- persist-tun" J% Q' a8 Q# T* F
- verb 3
9 @4 t) x3 t8 Q6 f( ?" W; m; F - crl-verify crl.pem" >> /etc/openvpn/server/server.conf
4 W1 }2 c/ d; K" i2 s+ w) d9 h# A; _ - if [[ "$protocol" = "udp" ]]; then1 f' |; E- F8 \, O) _' N
- echo "explicit-exit-notify" >> /etc/openvpn/server/server.conf
; m& O2 Q6 n2 l; n - fi
: Q# ]: ~* k* @8 ^+ t2 [) | - # Enable net.ipv4.ip_forward for the system" V. y5 s7 j( T
- echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/99-openvpn-forward.conf
' `2 p4 C4 z. Z5 G) [; A% { [ - # Enable without waiting for a reboot or service restart
1 n1 x- {6 j* E" [' H) S - echo 1 > /proc/sys/net/ipv4/ip_forward
8 k C& i: J! V0 g - if [[ -n "$ip6" ]]; then0 B( Q0 b! x9 o2 N! [' _) Z
- # Enable net.ipv6.conf.all.forwarding for the system
2 U. ~! U- {, |( @( \) ~, j/ e - echo "net.ipv6.conf.all.forwarding=1" >> /etc/sysctl.d/99-openvpn-forward.conf: L$ v) M; h2 W
- # Enable without waiting for a reboot or service restart
/ p# V* \* s, a - echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
. S/ X) I) `+ v2 K - fi
$ c% w% ~( I8 w7 s - if systemctl is-active --quiet firewalld.service; then# H0 V8 j2 R1 L2 d4 ~4 Y
- # Using both permanent and not permanent rules to avoid a firewalld5 v' H- ~+ h/ V n2 u1 Q
- # reload.
9 v* A2 y/ D2 H8 \0 n, L5 N - # We don't use --add-service=openvpn because that would only work with
8 p* {9 b4 H6 k - # the default port and protocol.
, G" C9 M4 M- P; ?8 ?2 r3 y* ~$ | - firewall-cmd --add-port="$port"/"$protocol"
6 i1 h& U8 v" |/ x% e& c - firewall-cmd --zone=trusted --add-source=10.8.0.0/24
Y+ Y- w* a; q' [, v3 d - firewall-cmd --permanent --add-port="$port"/"$protocol"
% M% L) ~3 m; x. ~' M+ _( G - firewall-cmd --permanent --zone=trusted --add-source=10.8.0.0/24
, K' ~ [1 h' }% R% B- q9 j - # Set NAT for the VPN subnet! Z2 a- W* ?/ b
- firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip"/ V9 ~7 K9 s* U
- firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip"7 ?7 J( q% ?% {7 _; U! K
- if [[ -n "$ip6" ]]; then
4 u4 Q* d+ f8 u" a+ P3 l - firewall-cmd --zone=trusted --add-source=fddd:1194:1194:1194::/64% _3 S" b& K6 E% d
- firewall-cmd --permanent --zone=trusted --add-source=fddd:1194:1194:1194::/64, A& t0 q. i. M% q" p6 \
- firewall-cmd --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6"/ P- K0 ]5 P( Z8 ~1 Z& O% [
- firewall-cmd --permanent --direct --add-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6"
* r: G4 o' d* _- i$ B2 R, u) R; @ - fi G# s, k" q1 I' w
- else
8 F# p( h7 p! t$ ]3 P2 f2 G - # Create a service to set up persistent iptables rules
: ]3 \+ X; x) X+ f* R# V7 |$ M - iptables_path=$(command -v iptables)
$ D2 F# c7 O+ x8 Q9 S8 B - ip6tables_path=$(command -v ip6tables)6 s( }0 l1 r) y
- # nf_tables is not available as standard in OVZ kernels. So use iptables-legacy
6 h1 S2 ^4 t, D7 e - # if we are in OVZ, with a nf_tables backend and iptables-legacy is available.
$ }: }9 Y" Z" z - if [[ $(systemd-detect-virt) == "openvz" ]] && readlink -f "$(command -v iptables)" | grep -q "nft" && hash iptables-legacy 2>/dev/null; then" A! E# t$ o' i8 `0 P) L' J
- iptables_path=$(command -v iptables-legacy)
5 ^; S) ?/ k- o) a. ^1 L - ip6tables_path=$(command -v ip6tables-legacy): P2 ^+ W b: d* h0 \( i
- fi4 j1 l1 C$ @5 G( F; N- t+ l
- echo "[Unit]
7 i( [% Y6 I% S - Before=network.target
' @, X$ P/ Q! [8 R0 ?1 i* h/ x - [Service]
+ i! J% @8 m8 G% n! Q) N1 p - Type=oneshot
& u) ^. z/ o4 \0 k - ExecStart=$iptables_path -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $ip
+ `& Z0 n: S8 m1 _2 U - ExecStart=$iptables_path -I INPUT -p $protocol --dport $port -j ACCEPT
h8 N c# a1 y6 u; R E - ExecStart=$iptables_path -I FORWARD -s 10.8.0.0/24 -j ACCEPT
$ P; X+ m$ d+ c5 w9 W% G - ExecStart=$iptables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
4 ` p5 @3 v7 L - ExecStop=$iptables_path -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to $ip
3 m1 p6 u2 c! W2 ` - ExecStop=$iptables_path -D INPUT -p $protocol --dport $port -j ACCEPT0 ~' g, `1 G" R0 s; r
- ExecStop=$iptables_path -D FORWARD -s 10.8.0.0/24 -j ACCEPT
3 y. z" _' L/ b5 n - ExecStop=$iptables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" > /etc/systemd/system/openvpn-iptables.service8 n7 o$ z6 z6 c9 u& d
- if [[ -n "$ip6" ]]; then
+ H5 K2 [& f0 u$ a: E- s+ a' A - echo "ExecStart=$ip6tables_path -t nat -A POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to $ip6
4 t$ @# Q9 n6 t5 Y* L - ExecStart=$ip6tables_path -I FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT3 u! I7 i) j" b8 K3 e
- ExecStart=$ip6tables_path -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT$ j% E+ j V1 [0 v$ \
- ExecStop=$ip6tables_path -t nat -D POSTROUTING -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to $ip62 S1 U1 S6 r$ E9 U# t7 q+ v
- ExecStop=$ip6tables_path -D FORWARD -s fddd:1194:1194:1194::/64 -j ACCEPT
' g l- `! d; }3 [, F* ?* @ - ExecStop=$ip6tables_path -D FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT" >> /etc/systemd/system/openvpn-iptables.service# O8 K( e0 m! s' P
- fi
6 w9 Y( \. E& e" C1 Y - echo "RemainAfterExit=yes
5 L0 u. H# C% x/ B" A - [Install]- m7 I, R' D6 W% G$ i% \
- WantedBy=multi-user.target" >> /etc/systemd/system/openvpn-iptables.service
# O$ J+ O) k0 Y% C. x2 X C - systemctl enable --now openvpn-iptables.service
% B' @6 C; C: ]) w# o' V4 i - fi
0 d4 o' _' V l8 S' N$ I4 p( t - # If SELinux is enabled and a custom port was selected, we need this5 A( q' f; Y* G1 Z
- if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then; P; O" N) v- B. n8 o( U
- # Install semanage if not already present
9 y. U3 R: ^. V) s- w; p) F5 M2 _ - if ! hash semanage 2>/dev/null; then
6 Q) ]9 o G$ n, f- j5 Z- D - if [[ "$os_version" -eq 7 ]]; then" O! K& \ L( `/ g+ f$ X
- # Centos 7
* f: i; r% F5 b: m) @, C1 e - yum install -y policycoreutils-python& u5 H- r( G: h+ ^9 u( I( x8 g
- else
: ~( r& b" n! X - # CentOS 8 or Fedora8 a7 s" {- n. K
- dnf install -y policycoreutils-python-utils
3 D) H; } q% d- P - fi
) K, o/ Z( h8 I" T+ A+ d# a: I! D - fi( W& j. k6 g2 |, b( R" K: g
- semanage port -a -t openvpn_port_t -p "$protocol" "$port"
2 [' E5 L9 ]" V; Y; b - fi
, v9 j' [6 o8 m) j - # If the server is behind NAT, use the correct IP address
6 Z! W/ w6 A2 F8 W - [[ -n "$public_ip" ]] && ip="$public_ip"
9 X& k0 v! p$ q - # client-common.txt is created so we have a template to add further users later
: C5 O& g+ ^4 ^ - echo "client( p8 P' y* P M
- dev tun' U- X4 m$ l! W6 g1 Q% D$ b: ^
- proto $protocol$ A, J, R. ]7 R9 V! W. ~6 w
- remote $ip $port
+ | f. E: P, l2 ^ - resolv-retry infinite
& j# [, C2 @; [1 u$ l - nobind, e4 U1 J& b. C! Z: N/ |2 ?" w" H" A
- persist-key
& w7 h8 l* o+ P. J7 Q" ^! n8 |0 q/ [ - persist-tun
6 a( |. q2 J9 q' i1 x - remote-cert-tls server9 D/ B( l# a9 I7 | t
- auth SHA512. u \+ h; m3 h- i$ ^5 ?
- cipher AES-256-CBC
2 j! F5 S- X8 u - ignore-unknown-option block-outside-dns ?/ a* y1 M7 C, ]
- block-outside-dns
* B/ B) H; P! W! b: l) @ \7 @ - verb 3" > /etc/openvpn/server/client-common.txt! ~4 W) k. g: K+ M" i1 L
- # Enable and start the OpenVPN service- _+ E% D# S2 w5 J, |
- systemctl enable --now openvpn-server@server.service9 k: p7 v+ g# a! b/ x2 i
- # Generates the custom client.ovpn# J) e$ f# g/ e8 |- @) y, ~0 s% K
- new_client
+ E* G3 T& \" Q0 Y4 C - echo2 P) K. D" _4 @5 V. k
- echo "Finished!"+ K3 H( s* C! p. X, ]# c. `) f9 {
- echo& h4 K/ l* ~: c5 d) U
- echo "The client configuration is available in:" ~/"$client.ovpn"
* m- `5 E, k# Z - echo "New clients can be added by running this script again."
8 m" ^7 C5 O4 }+ z: Y - else
# ]) l/ ]( L: r4 a) _9 u' H$ ` {$ m# \ - clear
* L; i _5 s( u - echo "OpenVPN is already installed."2 u3 s- J# s, P
- echo
3 B2 g% m; c# v; f8 e+ r6 x# m- m - echo "Select an option:"8 w# r+ I1 C& y) J: X$ F/ L
- echo " 1) Add a new client"
' Y* a }" q% s8 [ - echo " 2) Revoke an existing client"
; B- F6 {& Y; @ - echo " 3) Remove OpenVPN"2 F: r. A+ p: g8 t
- echo " 4) Exit"7 g2 G1 p9 c# O# R
- read -p "Option: " option! t6 c. ?5 q, e, y
- until [[ "$option" =~ ^[1-4]$ ]]; do
) K9 w& z+ T! Q/ G' \4 Y: l2 m+ V - echo "$option: invalid selection."5 h+ i) H; H# F5 n/ w+ v! E" z
- read -p "Option: " option$ i- G# _1 x ?* J" y/ F, S, s# t3 O+ D
- done: `1 s+ b' A, {1 Z! q3 n8 Q
- case "$option" in# A+ `, |! s0 S k
- 1)! U& t" d* x0 {5 c: ^, G; T1 g
- echo3 D- g5 V- Z+ l: @& u6 i8 I
- echo "Provide a name for the client:"
' j6 m2 A# z% i4 G2 I) H - read -p "Name: " unsanitized_client
1 d2 K0 B' {! [: k* Z i4 {& T - client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client")
3 E/ P# q! Q2 B3 V# s* N6 v - while [[ -z "$client" || -e /etc/openvpn/server/easy-rsa/pki/issued/"$client".crt ]]; do
( I' @' ~" l1 @6 E: K: f `7 d - echo "$client: invalid name."3 { U# T }' `- `9 t& i! O
- read -p "Name: " unsanitized_client
/ D+ ]; ~ E C$ H0 ^ - client=$(sed 's/[^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-]/_/g' <<< "$unsanitized_client")! g, X; w4 @- v/ a
- done4 I5 E; d- P' _. W. J
- cd /etc/openvpn/server/easy-rsa/
! x8 ]7 w& E: f+ Z8 }8 G9 w% L - EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full "$client" nopass
3 ]' U* o, b2 T - # Generates the custom client.ovpn) A5 N6 g- }5 F: I8 m( R
- new_client
1 ?: S- B$ E! Y) z- A - echo
0 [3 U9 Y2 ]$ o4 t: ^/ O - echo "$client added. Configuration available in:" ~/"$client.ovpn"" A: `. X2 `0 H
- exit. }! D: i, E( M9 W( f
- ;;
' n# Y2 W" x6 O7 M R - 2): n! x; j/ u! W
- # This option could be documented a bit better and maybe even be simplified
( U7 ~2 E- H8 v! N, H7 b - # ...but what can I say, I want some sleep too( e$ x, j2 K T) b# M4 q) q
- number_of_clients=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep -c "^V")
0 e1 g1 z* [0 \ - if [[ "$number_of_clients" = 0 ]]; then
8 |4 s8 H! Y1 w* y; H7 e- P8 k8 R - echo- f- Y8 s1 y1 D& ]
- echo "There are no existing clients!"
* |/ o; L* Z' ~/ |+ n% K3 o - exit4 t5 G% ~6 L6 u" w5 }
- fi
4 s5 o! E5 j* N! A; p - echo& s& s& J5 {5 M% k4 A5 q
- echo "Select the client to revoke:"- P$ G0 `+ I$ a K! S" l
- tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '- q& O3 P$ q7 p a
- read -p "Client: " client_number6 t$ Z# a- s, f1 k+ E& }2 |2 `& y
- until [[ "$client_number" =~ ^[0-9]+$ && "$client_number" -le "$number_of_clients" ]]; do
7 P; K2 A! b h+ a3 M9 W# y - echo "$client_number: invalid selection."- W! O Y; d2 E! K
- read -p "Client: " client_number: `7 o+ ]9 }, B: ]3 o( ^+ g* z
- done5 C( {% N7 Y* G; ^, n6 e% i$ n
- client=$(tail -n +2 /etc/openvpn/server/easy-rsa/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$client_number"p)+ Z. V& \7 q) ~7 o; c4 r
- echo2 p& t9 E3 z5 P* f
- read -p "Confirm $client revocation? [y/N]: " revoke8 x& L3 D4 T% d; t0 W' @
- until [[ "$revoke" =~ ^[yYnN]*$ ]]; do
0 M. s1 s! }+ T2 i+ j) R - echo "$revoke: invalid selection."
9 @2 Q5 `# D' J% J - read -p "Confirm $client revocation? [y/N]: " revoke/ s a$ i5 H* [
- done/ U7 t% Y8 G' M: i! |
- if [[ "$revoke" =~ ^[yY]$ ]]; then' @# X" L5 X8 R& e g0 \2 d
- cd /etc/openvpn/server/easy-rsa/
/ }9 C0 G6 @7 H0 U - ./easyrsa --batch revoke "$client"+ v8 P( W3 T7 |' u
- EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl5 q% N# S6 ]% j" @
- rm -f /etc/openvpn/server/crl.pem* v* y3 `& n, o
- cp /etc/openvpn/server/easy-rsa/pki/crl.pem /etc/openvpn/server/crl.pem
8 n9 B+ v; F8 E5 x6 e5 v/ ` F - # CRL is read with each client connection, when OpenVPN is dropped to nobody4 t' o" b) u3 I' z' j
- chown nobody:"$group_name" /etc/openvpn/server/crl.pem- s$ k$ U: [7 V; ^' O
- echo. s# o2 U6 [# `0 }9 h0 V
- echo "$client revoked!"
6 y5 T: ]) I- g' i; A# l9 l - else
9 c( Q0 q$ }) T* e - echo6 i: [0 A6 j0 f. w& Y
- echo "$client revocation aborted!": X( e. G7 d+ o3 m
- fi
3 [* h& J& f; v6 ^ - exit! ^9 Y& G8 z( H4 s
- ;;
5 }/ X$ l+ t* h$ O1 _ - 3)
) S+ h+ u' H: c" ^/ M - echo3 K) q0 u q! y; z) |7 a
- read -p "Confirm OpenVPN removal? [y/N]: " remove
+ \% O# K7 Z% s& |$ R3 s) t - until [[ "$remove" =~ ^[yYnN]*$ ]]; do
" F7 C0 a6 B* J8 z Y - echo "$remove: invalid selection."
+ q! [2 |* r7 u9 N1 |0 _ - read -p "Confirm OpenVPN removal? [y/N]: " remove4 J8 p7 x0 `: `9 j* d9 U s
- done$ d z) ^( X# c* ]
- if [[ "$remove" =~ ^[yY]$ ]]; then' G9 a' @" ]) p) L" f, \9 w; S, ^
- port=$(grep '^port ' /etc/openvpn/server/server.conf | cut -d " " -f 2)
5 W2 X$ `" u5 a) e8 U - protocol=$(grep '^proto ' /etc/openvpn/server/server.conf | cut -d " " -f 2)+ W8 B- a Q# H9 d* S4 b) a, y
- if systemctl is-active --quiet firewalld.service; then1 ^* f8 X' D) K: A( F2 c C, }
- ip=$(firewall-cmd --direct --get-rules ipv4 nat POSTROUTING | grep '\-s 10.8.0.0/24 '"'"'!'"'"' -d 10.8.0.0/24' | grep -oE '[^ ]+$')
& }7 T; ?5 h1 j/ r$ N/ m' I - # Using both permanent and not permanent rules to avoid a firewalld reload.. i) c3 `5 \7 t: T) n2 W
- firewall-cmd --remove-port="$port"/"$protocol"
. |5 ]) \3 s4 c7 h; U! z8 p, c7 X - firewall-cmd --zone=trusted --remove-source=10.8.0.0/24" M3 ?% N; `( Y
- firewall-cmd --permanent --remove-port="$port"/"$protocol"
. `2 g$ Y- p/ G - firewall-cmd --permanent --zone=trusted --remove-source=10.8.0.0/24
, D ~( v/ l% { - firewall-cmd --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip"
; |3 T) u1 i/ X2 a - firewall-cmd --permanent --direct --remove-rule ipv4 nat POSTROUTING 0 -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to "$ip"
: t4 K9 |+ m, ]9 P - if grep -qs "server-ipv6" /etc/openvpn/server/server.conf; then2 a7 y% j( n$ X# `- f4 N7 ]
- ip6=$(firewall-cmd --direct --get-rules ipv6 nat POSTROUTING | grep '\-s fddd:1194:1194:1194::/64 '"'"'!'"'"' -d fddd:1194:1194:1194::/64' | grep -oE '[^ ]+$'), O7 {( Q2 h# ]8 ?7 n) p! ?
- firewall-cmd --zone=trusted --remove-source=fddd:1194:1194:1194::/64( h, F2 ? }8 u3 a
- firewall-cmd --permanent --zone=trusted --remove-source=fddd:1194:1194:1194::/64' D0 V I! U1 d8 [7 r% j
- firewall-cmd --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6"
+ l8 o5 M" P' c' ]- V1 b6 h8 r. i - firewall-cmd --permanent --direct --remove-rule ipv6 nat POSTROUTING 0 -s fddd:1194:1194:1194::/64 ! -d fddd:1194:1194:1194::/64 -j SNAT --to "$ip6"9 s8 T. ]( [1 f% x
- fi Z! u; {: t" L+ s& z' T
- else0 A2 [( |# o0 T9 O, U
- systemctl disable --now openvpn-iptables.service
% \4 v: C9 |# S' N - rm -f /etc/systemd/system/openvpn-iptables.service) W5 S M) U# [/ U2 C A! w: j" {6 k
- fi; G8 _% R5 ~! u* b& q; k
- if sestatus 2>/dev/null | grep "Current mode" | grep -q "enforcing" && [[ "$port" != 1194 ]]; then
$ z/ P4 Q5 z" M1 K - semanage port -d -t openvpn_port_t -p "$protocol" "$port"
& Y, K. E& v& `$ H - fi
# ^) P, O7 ~5 `! d# m% C - systemctl disable --now openvpn-server@server.service8 ?6 b3 ?7 c( ?6 m: p7 F
- rm -f /etc/systemd/system/openvpn-server@server.service.d/disable-limitnproc.conf
" H& D# S& w! |4 b8 F. H2 J% M - rm -f /etc/sysctl.d/99-openvpn-forward.conf- W z- c2 J/ y9 o& g7 d' Y
- if [[ "$os" = "debian" || "$os" = "ubuntu" ]]; then' x9 L' U$ O2 B9 h& C6 }
- rm -rf /etc/openvpn/server( |4 Y3 I4 I! b& n( P- ^! u: B
- apt-get remove --purge -y openvpn
; C- F$ y- F. i% O - else
* y) l. U5 @) e8 I. E. w2 b3 N* \& _ - # Else, OS must be CentOS or Fedora
) N. E, ^2 B% i - yum remove -y openvpn+ Y" ?# V, a3 n' {
- rm -rf /etc/openvpn/server, q: {8 y5 q: g
- fi
' ? W# `5 }8 f7 G4 B - echo: D0 H' h9 ~. r2 r0 b/ }7 ~/ I
- echo "OpenVPN removed!"
; K9 r5 `! A4 c& n% T - else
. ?! u. w. K5 ~- {$ b" U) J: t - echo4 m, q5 `7 |3 w
- echo "OpenVPN removal aborted!"
# r- ^; L% i$ X( P - fi
, Q+ e; Y; l$ n( W: r% N - exit9 j) x8 y( O' |0 Z9 r
- ;;2 \3 G x1 F4 b. N/ w5 {
- 4)
9 v8 c: F; {$ ^5 f; C$ ~7 o - exit
, b) d) x6 S6 H1 G. \ t - ;;
/ J Q9 W# _- L7 U - esac
" ^8 f' v# T/ b$ R - fi
2 ^/ A( G G* t3 O8 p5 h) v/ L" f
复制代码 * x5 v" M. U$ L, ~- y1 y
W0 U8 L9 f! k1 r V* N/ X$ D# A0 k( g8 o) `0 [
5 Y0 v5 I8 A2 e7 `1 E) [ |
|