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