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