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