-
Notifications
You must be signed in to change notification settings - Fork 2
/
openvpn-install.sh
410 lines (394 loc) · 13.9 KB
/
openvpn-install.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
#!/bin/bash
#--------------------------------------------------------------------------------
# Name: openvpn-install.sh
# Version: 1.0
# Author: L0rdDarkF0rce
# Contact: [email protected]
#--------------------------------------------------------------------------------
# OpenVPN road warrior installer for Slackware 14.2. It based on Nyr's original
# script. It has been designed to be as unobtrusive as possible.
#
# This script will work on Slackware 14.2 (but I don't see why it wouldn't work
# in other versions of Slackware. If you see something that is not working as
# expected drop me a line and I'll take a look at it and see if I can fix it or
# give you any ideas to get it working.
#--------------------------------------------------------------------------------
# MIT License
#
# Copyright (c) 2016 l0rddarkf0rce
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#--------------------------------------------------------------------------------
if [[ -e /etc/slackware-version ]]; then
GROUPNAME=nogroup
RCLOCAL='/etc/rc.d/rc.local'
chmod +x $RCLOCAL
else
echo "Looks like you aren't running this installer on a Slackware system"
exit 1
fi
if [[ "$EUID" -ne 0 ]]; then
echo "Sorry, you need to run this as root"
exit 2
fi
if [[ ! -e /dev/net/tun ]]; then
echo "TUN is not available"
exit 3
fi
# Check if a package is installed. Return 1 if it is otherwise return 0.
installed() {
if ls /var/log/packages/$1* 1> /dev/null 2>&1; then
return 1
else
return 0
fi
}
# Generate the Client's .ovpn file
newclient () {
# Generates the custom client.ovpn
cp /etc/openvpn/client-common.txt ~/$1.ovpn
echo "<ca>" >> ~/$1.ovpn
cat /etc/openvpn/ca.crt >> ~/$1.ovpn
echo "</ca>" >> ~/$1.ovpn
echo "<cert>" >> ~/$1.ovpn
cat /etc/openvpn/easy-rsa/easyrsa3/pki/issued/$1.crt >> ~/$1.ovpn
echo "</cert>" >> ~/$1.ovpn
echo "<key>" >> ~/$1.ovpn
cat /etc/openvpn/easy-rsa/easyrsa3/pki/private/$1.key >> ~/$1.ovpn
echo "</key>" >> ~/$1.ovpn
echo "<tls-auth>" >> ~/$1.ovpn
cat /etc/openvpn/ta.key >> ~/$1.ovpn
echo "</tls-auth>" >> ~/$1.ovpn
echo "iroute 10.8.0.0 255.255.255.0" > /etc/openvpn/ccd/$1
}
# Try to get our IP from the system and fallback to the Internet.
# I do this to make the script compatible with NATed servers and to avoid getting an IPv6.
IP=$(ifconfig eth0 | grep 'inet ' | awk '{print $2}')
DG=$(ip route | grep eth0 | grep -v default | cut -d'/' -f1)
NM=$(ifconfig eth0 | grep 'inet ' | awk '{print $4}')
if [[ "$IP" = "" ]]; then
IP=$(wget -qO- ipv4.icanhazip.com)
fi
SERVERNAME=`hostname`
if [[ -e /etc/openvpn/server.conf ]]; then
while :
do
clear
echo "Looks like OpenVPN is already installed"
echo ""
echo "What do you want to do?"
echo " 1) Add a cert for a new user"
echo " 2) Revoke existing user cert"
echo " 3) Remove OpenVPN"
echo " 4) Exit"
read -p "Select an option [1-4]: " option
case $option in
1)
echo ""
echo "Tell me a name for the client cert"
echo "Please, use one word only, no special characters"
read -p "Client name: " -e -i client CLIENT
cd /etc/openvpn/easy-rsa/easyrsa3
./easyrsa build-client-full $CLIENT nopass
# Generates the custom client.ovpn
newclient "$CLIENT"
echo ""
echo "Client $CLIENT added, certs available at ~/$CLIENT.ovpn"
exit
;;
2)
# This option could be documented a bit better and maybe even be simplimplified
# ...but what can I say, I want some sleep too
NUMBEROFCLIENTS=$(tail -n +2 /etc/openvpn/easy-rsa/easyrsa3/pki/index.txt | grep -c "^V")
if [[ "$NUMBEROFCLIENTS" = '0' ]]; then
echo ""
echo "You have no existing clients!"
exit 6
fi
echo ""
echo "Select the existing client certificate you want to revoke"
tail -n +2 /etc/openvpn/easy-rsa/easyrsa3/pki/index.txt | grep "^V" | cut -d '=' -f 2 | nl -s ') '
if [[ "$NUMBEROFCLIENTS" = '1' ]]; then
read -p "Select one client [1]: " CLIENTNUMBER
else
read -p "Select one client [1-$NUMBEROFCLIENTS]: " CLIENTNUMBER
fi
CLIENT=$(tail -n +2 /etc/openvpn/easy-rsa/easyrsa3/pki/index.txt | grep "^V" | cut -d '=' -f 2 | sed -n "$CLIENTNUMBER"p)
cd /etc/openvpn/easy-rsa/easyrsa3/
./easyrsa --batch revoke $CLIENT
./easyrsa gen-crl
rm -rf pki/reqs/$CLIENT.req
rm -rf pki/private/$CLIENT.key
rm -rf pki/issued/$CLIENT.crt
rm -rf /etc/openvpn/crl.pem
cp /etc/openvpn/easy-rsa/easyrsa3/pki/crl.pem /etc/openvpn/crl.pem
# CRL is read with each client connection, when OpenVPN is dropped to nobody
chown nobody:$GROUPNAME /etc/openvpn/crl.pem
echo ""
echo "Certificate for client $CLIENT revoked"
exit
;;
3)
echo ""
read -p "Do you really want to remove OpenVPN? [y/n]: " -e -i n REMOVE
if [[ "$REMOVE" = 'y' ]]; then
PORT=$(grep '^port ' /etc/openvpn/server.conf | cut -d " " -f 2)
if iptables -L | grep -qE 'REJECT|DROP'; then
sed -i "/iptables -I INPUT -p udp --dport $PORT -j ACCEPT/d" $RCLOCAL
sed -i "/iptables -I FORWARD -s 10.8.0.0\/24 -j ACCEPT/d" $RCLOCAL
sed -i "/iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT/d" $RCLOCAL
fi
sed -i '/iptables -t nat -A POSTROUTING -s 10.8.0.0\/24 -j SNAT --to /d' $RCLOCAL
if hash sestatus 2>/dev/null; then
if sestatus | grep "Current mode" | grep -qs "enforcing"; then
if [[ "$PORT" != '1194' ]]; then
semanage port -d -t openvpn_port_t -p udp $PORT
fi
fi
fi
removepkg openvpn
rm -rf /etc/openvpn
rm -rf /usr/share/doc/openvpn*
echo ""
echo "OpenVPN removed!"
else
echo ""
echo "Removal aborted!"
fi
exit
;;
4) exit;;
esac
done
else
clear
echo 'Welcome to this quick OpenVPN "road warrior" installer'
echo ""
# OpenVPN setup and first user creation
echo "I need to ask you a few questions before starting the setup"
echo "You can leave the default options and just press enter if you are ok with them"
echo ""
echo "First I need to know the IPv4 address of the network interface you want OpenVPN"
echo "listening to."
read -p "IP address: " -e -i $IP IP
echo ""
read -p "The server name is : " -e -i $SERVERNAME SERVERNAME
echo ""
echo "What port do you want for OpenVPN?"
read -p "Port: " -e -i 1194 PORT
echo ""
echo "What DNS do you want to use with the VPN?"
echo " 1) Current system resolvers"
echo " 2) Google"
echo " 3) OpenDNS"
echo " 4) NTT"
echo " 5) Hurricane Electric"
echo " 6) Verisign"
read -p "DNS [1-6]: " -e -i 1 DNS
echo ""
echo "Finally, tell me your name for the client cert"
echo "Please, use one word only, no special characters"
read -p "Client name: " -e -i client CLIENT
echo ""
echo "Okay, that was all I needed. We are ready to setup your OpenVPN server now"
read -n1 -r -p "Press any key to continue..."
# Check that we have all necessary packages installed
for pkg in "openvpn" "iptables" "openssl" "ca-certificates"
do
installed $pkg
pkginstalled=$?
if [ $pkginstalled -eq 0 ]; then
pkgs+="$pkg "
fi
done
if [[ -n $pkgs ]]; then
echo "The following packages are not installed"
echo " $pkgs"
read -p "Do you want to install them [Y/n]? " -e -i "Y" answer
if [ $answer == "Y" ]; then
slackpkg install $pkgs
else
echo "Cannot continue without all necessary packages."
echo "Aborting!"
exit 4
fi
fi
# An old version of easy-rsa was available by default in some openvpn packages
if [[ -d /etc/openvpn/easy-rsa/ ]]; then
rm -rf /etc/openvpn/easy-rsa/
fi
# Get easy-rsa
git clone git://github.com/OpenVPN/easy-rsa
mv easy-rsa /etc/openvpn
chown -R root:root /etc/openvpn/easy-rsa/
cd /etc/openvpn
mkdir ccd
cd easy-rsa/easyrsa3
# Create the PKI, set up the CA, the DH params and the server + client certificates
./easyrsa init-pki
./easyrsa --batch build-ca nopass
./easyrsa gen-dh
./easyrsa build-server-full $SERVERNAME nopass
./easyrsa build-client-full $CLIENT nopass
./easyrsa gen-crl
# Move the stuff we need
cp pki/ca.crt pki/private/ca.key pki/dh.pem pki/issued/$SERVERNAME.crt pki/private/$SERVERNAME.key pki/crl.pem /etc/openvpn
# CRL is read with each client connection, when OpenVPN is dropped to nobody
chown nobody:$GROUPNAME /etc/openvpn/crl.pem
# Generate key for tls-auth
openvpn --genkey --secret /etc/openvpn/ta.key
# Generate server.conf
echo "port $PORT
proto udp
dev tun
sndbuf 0
rcvbuf 0
ca /etc/openvpn/ca.crt
cert /etc/openvpn/$SERVERNAME.crt
key /etc/openvpn/$SERVERNAME.key
dh /etc/openvpn/dh.pem
tls-auth /etc/openvpn/ta.key 0
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
log-append /var/log/openvpn.log" > /etc/openvpn/server.conf
push "route $DG $NM"
client-config-dir /etc/openvpn/ccd
route 10.8.0.0 255.255.255.0
echo 'push "redirect-gateway def1 bypass-dhcp"' >> /etc/openvpn/server.conf
# DNS
case $DNS in
1)
# Obtain the resolvers from resolv.conf and use them for OpenVPN
grep -v '#' /etc/resolv.conf | grep 'nameserver' | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | while read line; do
echo "push \"dhcp-option DNS $line\"" >> /etc/openvpn/server.conf
done
;;
2)
echo 'push "dhcp-option DNS 8.8.8.8"' >> /etc/openvpn/server.conf
echo 'push "dhcp-option DNS 8.8.4.4"' >> /etc/openvpn/server.conf
;;
3)
echo 'push "dhcp-option DNS 208.67.222.222"' >> /etc/openvpn/server.conf
echo 'push "dhcp-option DNS 208.67.220.220"' >> /etc/openvpn/server.conf
;;
4)
echo 'push "dhcp-option DNS 129.250.35.250"' >> /etc/openvpn/server.conf
echo 'push "dhcp-option DNS 129.250.35.251"' >> /etc/openvpn/server.conf
;;
5)
echo 'push "dhcp-option DNS 74.82.42.42"' >> /etc/openvpn/server.conf
;;
6)
echo 'push "dhcp-option DNS 64.6.64.6"' >> /etc/openvpn/server.conf
echo 'push "dhcp-option DNS 64.6.65.6"' >> /etc/openvpn/server.conf
;;
esac
echo "keepalive 10 120
cipher AES-128-CBC
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
verb 3
crl-verify /etc/openvpn/crl.pem
daemon" >> /etc/openvpn/server.conf
# Enable net.ipv4.ip_forward for the system
if ! grep -q "echo 1 > /proc/sys/net/ipv4/ip_forward" "/etc/rc.d/rc.local"; then
echo "echo 1 > /proc/sys/net/ipv4/ip_forward" >> /etc/rc.d/rc.local
fi
# Avoid an unneeded reboot
echo 1 > /proc/sys/net/ipv4/ip_forward
# Set NAT for the VPN subnet
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
sed -i "1 a\iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE" $RCLOCAL
if iptables -L | grep -qE 'REJECT|DROP'; then
# If iptables has at least one REJECT rule, we asume this is needed.
# Not the best approach but I can't think of other and this shouldn't
# cause problems.
iptables -A INPUT -p udp --dport $PORT -j ACCEPT
iptables -A INPUT -i tun0 -j ACCEPT
iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT
iptables -I FORWARD -i eth0 -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sed -i "1 a\iptables -A INPUT -p udp --dport $PORT -j ACCEPT" $RCLOCAL
sed -i "1 a\iptables -A INPUT -i tun0 -j ACCEPT" $RCLOCAL
sed -i "1 a\iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT" $RCLOCAL
sed -i "1 a\iptables -I FORWARD -i eth0 -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT" $RCLOCAL
fi
# And finally, restart OpenVPN
if [[ -e /etc/rc.d/rc.openvpn ]]; then
if [ -x /etc/rc.d/rc.openvpn ]; then
/etc/rc.d/rc.openvpn restart
else
bash /etc/rc.d/rc.openvpn restart
fi
else
# Kill openvpn if it is running
/usr/bin/killall openvpn
# Start openvpn
/usr/sbin/openvpn /etc/openvpn/server.conf
# Print a message telling the user that rc.openvpn needs to be created
echo /etc/rc.d/rc.openvpn was not found, you must create one and modify
echo /etc/rc.d/rc.local in order for OpenVPN to start automatically on reboot!
fi
# Try to detect a NATed connection and ask about it to potential LowEndSpirit users
EXTERNALIP=$(wget -qO- ipv4.icanhazip.com)
if [[ "$IP" != "$EXTERNALIP" ]]; then
echo ""
echo "Looks like your server is behind a NAT! The external IP is $EXTERNALIP"
echo ""
echo "If your server is NATed, I need to know the external IP if you want to"
echo "access it from the Internet. If that's not the case, just answer no."
echo ""
read -p "Do you want to use the external address (Y/n)? " -e -i "Y" USEREXTERNALIP
if [[ "$USEREXTERNALIP" = "Y" ]]; then
IP=$USEREXTERNALIP
fi
fi
# client-common.txt is created so we have a template to add further users later
echo "client
dev tun
proto udp
sndbuf 0
rcvbuf 0
remote $IP $PORT
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-128-CBC
comp-lzo
setenv opt block-outside-dns
key-direction 1
verb 3" > /etc/openvpn/client-common.txt
# Generates the custom client.ovpn
newclient "$CLIENT"
echo ""
echo "Finished!"
echo ""
echo "Your client config is available at ~/$CLIENT.ovpn"
echo "If you want to add more clients, you simply need to run this script another time!"
echo ""
echo "A number of firewall rules were added to /etc/rc.d/rc.local, if you have a"
echo "startup script for your firewall it will be a good idea to move them to your"
echo "firewall script."
fi