-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathddosutil.sh
executable file
·467 lines (386 loc) · 13.7 KB
/
ddosutil.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
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
#!/bin/bash
################################################
# ddoSutil 1.0 russ@vigeek.net
################################################
# Const
FAILED=1
SUCCESS=0
# Chain name.
CHAIN="ddoSutil"
# This holds a string for logging to identify which utility is logging what.
PROGRAM="main"
# Which iptables.
IP_TABLES=`which iptables`
IP_TABLES_SAVE=`which iptables-save`
# Source the config.
if [ -f "ddosutil.conf" ] ; then
. ./ddosutil.conf
else
echo -e "Unable to read the configuration file"
exit $FAILED
fi
################################################
# General Functions & Init
################################################
eecho () {
echo -e "\e[1;31mddoSutil:\033[0m $1"
}
log () {
if [ -n "$VERBOSE" ] ; then eecho "$1" ; fi
echo "$(date +%m-%d-%Y\ %H:%M:%S) | [$PROGRAM] | $1" >> $LOG_FILE
}
# Create initial log entry
log "ddoSutil has kicked off"
# See if CSF/LFD is running.
CSFD=`pidof lfd`
if [ -n "$CSFD" ] ; then
log "CSF [lfd] daemon detected"
eecho "The CSF [lfd] daemon is currently running..."
eecho "If using the ddoSutil firewall this may overwrite our rules"
eecho "The CSF [lfd] daemon can be temporarily disabled: csf --disable"
fi
# See if APF is installed.
APFD=`pidof apfd`
if [ -n "$APFD" ] ; then
log "APF [apfd] daemon detected"
eecho "The APF [apfd] daemon is currently running..."
eecho "If using the ddoSutil firewall this may overwrite our rules"
eecho "APF can be temporarily disabled by stopping the service"
fi
# Whatever the current rules are attempt to back them up.
if [ ! -f iptables.back ] ; then
log "saving current iptable rules to iptables.back"
$IP_TABLES_SAVE > iptables.back
fi
################################################
# Firewall Builder
################################################
PROGRAM="FWBuilder"
if [ $FW_BUILDER -eq "1" ] ; then
log "firewall builder is enabled, building rules."
# Flush the current rules.
$IP_TABLES -F &> /dev/null
if [ $? -eq $FAILED ] ; then
log "Unable to clear iptable rules."
return $FAILED
fi
# Prepare baseline rules
$IP_TABLES -F -t nat
$IP_TABLES -F -t mangle
$IP_TABLES -F -t filter
$IP_TABLES -X
# We should now have a cleared out policy, let's create a chain.
$IP_TABLES -N $CHAIN &> /dev/null
if [ $? -eq $FAILED ] ; then
log "Unable to create iptable rules"
return $FAILED
fi
# Accept All Out
$IP_TABLES -P OUTPUT ACCEPT
# Accept All In (we will block after our rules.)
$IP_TABLES -P INPUT ACCEPT
# Accept lo
$IP_TABLES -A INPUT -i lo -j ACCEPT
log "flushed the firewall and created baseline policy"
# Drop INVALID packets
if [ $DROP_INVALID -eq "1" ] ; then $IP_TABLES -A INPUT -m state --state INVALID -j DROP ; fi
# Accept all in Established Related State
$IP_TABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Only accept new connections in SYN state.
$IP_TABLES -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
# Drop fragmented packets.
if [ $DROP_FRAGMENTED -eq "1" ] ; then $IP_TABLES -A INPUT -f -j DROP ; fi
# Drop Xmas packets
if [ $DROP_XMAS -eq "1" ] ; then $IP_TABLES -A INPUT -p tcp --tcp-flags ALL ALL -j DROP ; fi
# Drop NULL packets
if [ $DROP_NULL -eq "1" ] ; then $IP_TABLES -A INPUT -p tcp --tcp-flags ALL NONE -j DROP ; fi
log "enabled baseline drop rules for undesirable packets"
# Begin building a simple firewall
for IFACE in ${IFACE_LIST//,/ } ; do
log "Opening requested ports on [$IFACE]"
for tcpin in ${TCP_IN//,/ } ; do
$IP_TABLES -A INPUT -p tcp -i $IFACE --dport $tcpin -m state --state NEW -j ACCEPT
done
for tcpin in ${UDP_IN//,/ } ; do
$IP_TABLES -A INPUT -p udp -i $IFACE--dport $tcpin -m state --state NEW -j ACCEPT
done
done
# We add our final lines at the end of the script to enforce blocking.
fi
################################################
# DShield Blocker
# Maintains a list of suspicious networks
################################################
PROGRAM="DShield"
if [ $DSHIELD_BLOCK="1" ] ; then
log "enabling dshield block list"
wget -q -O 'dshield.lst' http://feeds.dshield.org/block.txt
if [ ! -f dshield.lst ] ; then
eecho "Error downloading dshield list"
return $FAILURE
fi
$IP_TABLES -N $PROGRAM
for dlist in `cat dshield.lst | grep ^[0-9] | awk '{print $1,$3}' | sed '{s| |/|g}'` ; do
$IP_TABLES -A $PROGRAM -s $dlist -j DROP
done
$IP_TABLES -A $PROGRAM -j RETURN
$IP_TABLES -I INPUT 1 -j $PROGRAM
fi
################################################
# Abuse.ch ZeusTracker Blocker
# Maintains a list of known botnets
################################################
PROGRAM="ZeusBlock"
if [ $ZEUS_BLOCK="1" ] ; then
log "enabling zeus block list"
wget -q -O 'zeustrack.lst' --no-check-certificate https://zeustracker.abuse.ch/blocklist.php?download=ipblocklist
if [ ! -f zeustrack.lst ] ; then
eecho "Error downloading zeus tracker list"
return $FAILURE
fi
# Begin creating list.
$IP_TABLES -N $PROGRAM
for dlist in `cat zeustrack.lst | grep -v '#'` ; do
$IP_TABLES -A $PROGRAM -s $dlist -j DROP
done
$IP_TABLES -A $PROGRAM -j RETURN
$IP_TABLES -I INPUT 1 -j $PROGRAM
fi
################################################
# viGeek ddoSutil Blocking
# We maintain a small botnet list.
################################################
PROGRAM="viGeek"
if [ $VIGEEK_BLOCK="1" ] ; then
log "enabling viGeek block list"
wget -q -O 'vigeek.lst' http://vigeek.net/projects/ddoSutil/vigeek.txt
if [ ! -f vigeek.lst ] ; then
eecho "Error downloading dshield list"
return $FAILURE
fi
# Begin creaitng list
$IP_TABLES -N $PROGRAM
for dlist in `cat vigeek.lst | grep -v '#'` ; do
$IP_TABLES -A $PROGRAM -s $dlist -j DROP
done
$IP_TABLES -A $PROGRAM -j RETURN
$IP_TABLES -I INPUT 1 -j $PROGRAM
fi
##############################################################
# IANA Blocking
##############################################################
PROGRAM="IANA"
if [ $IANA_BLOCK -eq "1" ] ; then
log "blocking IANA reserved ip ranges"
$IP_TABLES -N $PROGRAM
#
$IP_TABLES -A $PROGRAM -s 0.0.0.0/7 -j DROP
$IP_TABLES -A $PROGRAM -s 2.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 5.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 14.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 23.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 27.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 31.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 36.0.0.0/7 -j DROP
$IP_TABLES -A $PROGRAM -s 39.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 42.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 46.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 49.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 50.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 100.0.0.0/6 -j DROP
$IP_TABLES -A $PROGRAM -s 104.0.0.0/6 -j DROP
$IP_TABLES -A $PROGRAM -s 175.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 176.0.0.0/7 -j DROP
$IP_TABLES -A $PROGRAM -s 179.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 181.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 182.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 185.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 223.0.0.0/8 -j DROP
$IP_TABLES -A $PROGRAM -s 240.0.0.0/4 -j DROP
#
$IP_TABLES -A $PROGRAM -j RETURN
# BLOCK it
$IP_TABLES -I INPUT 1 -j $PROGRAM
fi
################################################
# Cymru Bogon Blocker
################################################
PROGRAM="bogon"
if [ $BOGON_BLOCK="1" ] ; then
log "enabling team-cymru.org bogon block list"
wget -q -O 'bogon.lst' http://www.team-cymru.org/Services/Bogons/bogon-bn-nonagg.txt
if [ ! -f bogon.lst ] ; then
eecho "Error downloading bogon list"
return $FAILURE
fi
# Begin creaitng list
$IP_TABLES -N $PROGRAM
for dlist in `cat bogon.lst | grep -v '#'` ; do
$IP_TABLES -A $PROGRAM -s $dlist -j DROP
done
$IP_TABLES -A $PROGRAM -j RETURN
$IP_TABLES -I INPUT 1 -j $PROGRAM
fi
################################################
# GeoIP Blocker
################################################
PROGRAM="geoIP"
ddosutil_geoip () {
if [ $GEOIP_BLOCK = "1" ] ; then
log "enabling geoIP blocking"
if [ $USE_MIRROR -eq 1 ] ; then
GET_SUCCESS=$(curl -s -w %{size_download} -o 'GeoIP.zip' -z GeoIP.zip http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip)
else
GET_SUCCESS=$(curl -s -w %{size_download} -o 'GeoIP.zip' -z GeoIP.zip http://vigeek.net/files/GeoIPCountryCSV.zip)
fi
if [ $GET_SUCCESS -eq 0 ] ; then
log "Local version of GeoIP list current, no download required."
else
log "Local version outdated, downloaded latest GeoIP list total transfer: $GET_SUCCESS"
fi
# Trim spaces if any from our csv list
SAVE_FILE="ddosutil-geoip.lst"
# Check if our chain exists, if not, create it.
$IP_TABLES -L ddoSutil &> /dev/null
if [ $? -eq 0 ] ; then
$IP_TABLES -N ddoSutil
fi
# Build our list.
# Add for loop (trim space and csv from geo_list)
zcat GeoIP.zip | grep -i "$COUNTRY_NAME" | cut -d "," -f1,2 | sed 's/,/-/g' | tr -d '"' > $SAVE_FILE
if [ -f $SAVE_FILE ] ; then
if [ $(cat $SAVE_FILE | wc -l) -eq 0 ] ; then
log "Error: no geoIP list built, is this correct: $COUNTRY_NAME"
else
log "Completed building geoIP list for $COUNTRY_NAME total records $(cat $COUNTRY_NAME | wc -l)"
echo -en "\e[1;31mdSutil:\033[0m working, please wait."
for i in `cat $SAVE_FILE`; do
$IP_TABLES -A ddoSutil -s 0/0 -d 0/0 -m iprange --src-range $i -j DROP
let COUNTER+=1
if [ $(( $COUNTER % 2 )) -eq 0 ]; then
echo -n "."
fi
done
ask_them "Begin blocking connections from $COUNTRY_NAME?"
if ($USER_ACTION) ; then
$IP_TABLES -I INPUT -j $SAVE_FILE
$IP_TABLES -I FORWARD -j $SAVE_FILE
fi
fi
fi
fi
}
################################################
# Connection Limiting
################################################
PROGRAM="ConnLimit"
if [ $CONN_LIMIT -eq "1" ] ; then
log "limiting connections to $CONN_MAX per source"
$IP_TABLES -N $PROGRAM &> /dev/null
if [ $? -eq $FAILED ] ; then
# The chain exists, so we will just add to it....
log "chain exists, adding connection limiting to it."
fi
for CPORT in ${LIMIT_PORTS//,/ } ; do
$IP_TABLES -A $PROGRAM -p tcp --syn --dport $CPORT -m connlimit --connlimit-above $CONN_MAX -j REJECT
done
# Make it active.
$IP_TABLES -A $PROGRAM -j RETURN
$IP_TABLES -I INPUT 1 -j $PROGRAM
fi
################################################
# SYN Flood Protection
################################################
PROGRAM="SYNProtect"
if [ $SYN_LIMIT -eq "1" ] ; then
log "enabling SYN protection with limit of $CONN_MAX per source"
$IP_TABLES -N $PROGRAM &> /dev/null
if [ $? -eq $FAILED ] ; then
# The chain exists, so we will just add to it....
log "chain exists, adding SYN flood blocking to existing chain."
fi
for CPORT in ${LIMIT_PORTS//,/ } ; do
$IP_TABLES -A $PROGRAM -p tcp --syn --dport $CPORT -m connlimit --connlimit-above $CONN_MAX -j REJECT
done
$IP_TABLES -A $PROGRAM -j RETURN
$IP_TABLES -I INPUT 1 -j $PROGRAM
fi
# SYN Cookies.
if [ $SYN_COOKIES -eq "1" ] ; then echo 1 > /proc/sys/net/ipv4/tcp_syncookies ; fi
# Set SYN Retries limitations.
if [ $SYN_RETRIES -eq "1" ] ; then
echo $SYN_ACK_RETRY > /proc/sys/net/ipv4/tcp_synack_retries
echo $SYN_RETRY > /proc/sys/net/ipv4/tcp_syn_retries
fi
################################################
# Timeout Reductions + others.
################################################
if [ $TIMEOUT_REDUCE -eq "1" ] ; then
log "Enabling timeout reductions"
echo 10 > /proc/sys/net/ipv4/tcp_fin_timeout
echo 1200 > /proc/sys/net/ipv4/tcp_keepalive_time
echo 0 > /proc/sys/net/ipv4/tcp_sack
echo 0 > /proc/sys/net/ipv4/tcp_window_scaling
# Slightly reduce the default tcp_retries.
echo 3 > /proc/sys/net/ipv4/tcp_retries1
echo 10 > /proc/sys/net/ipv4/tcp_retries2
echo 40 > /proc/sys/net/ipv4/tcp_keepalive_intvl
fi
################################################
# Basic spoof protection.
################################################
PROGRAM="SPOOFprotect"
if [ $SPOOF_PROTECT -eq "1" ] ; then
log "Implementing basic spoof protection"
# Ancient host.conf modifications.
if [ -z "$(grep 'order hosts,bind' /etc/host.conf)" ] ; then
echo -e "order hosts,bind" >> /etc/host.conf
fi
if [ -z "$(grep 'multi on' /etc/host.conf)" ] ; then
echo -e "multi on" >> /etc/host.conf
fi
if [ -z "$(grep 'nospoof on' /etc/host.conf)" ] ; then
echo -e "nospoof on" >> /etc/host.conf
fi
if [ -z "$(grep 'spoofalert on' /etc/host.conf)" ] ; then
echo -e "spoofalert on" >> /etc/host.conf
fi
# Enable reverse path filter on all interfaces.
for rpf in /proc/sys/net/ipv4/conf/*/rp_filter; do
echo 1 > $rpf
done
fi
################################################
# ddoSutil Harden functions
################################################
if [ $DDOSUTIL_HARDEN -eq "1" ] ; then
log "Implementing TCP stack optimizations"
# Reduce overhead by disabling timestamps and metrics.
echo 1 > /proc/sys/net/ipv4/tcp_no_metrics_save
echo 0 >/proc/sys/net/ipv4/tcp_timestamps
# Reuse and recycle time wait connections, reduces spawning overhead.
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
# Overflow handling
eho 1 > /proc/sys/net/ipv4/tcp_abort_on_overflow
fi
if [ $DDOSUTIL_UP_QUEUE -eq "1" ] ; then
# Set back log queue, first verify our new value is greater than old.
CUR_VALUE=`cat /proc/sys/net/ipv4/tcp_max_syn_backlog`
if [ ! $CUR_VALUE -gt 4096 ] ; then
echo -e 4096 > /proc/sys/net/ipv4/tcp_max_syn_backlog
fi
CUR_VALUE=`cat /proc/sys/net/core/somaxconn`
if [ ! $CUR_VALUE -gt 1024 ] ; then
echo -e 1024 > /proc/sys/net/ipv4/tcp_max_syn_backlog
fi
CUR_VALUE=`cat /proc/sys/net/core/netdev_max_backlog`
if [ ! $CUR_VALUE -gt 2000 ] ; then
echo -e 2000 > /proc/sys/net/core/netdev_max_backlog
fi
fi
################################################
# Finish IPTable rules.
################################################
# Final DROP Rules on inbound.
$IP_TABLES -A INPUT -j DROP