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