Skip to content

Instantly share code, notes, and snippets.

@allenyllee
Created February 3, 2021 12:19
Show Gist options
  • Save allenyllee/7951c7dd8e1288f88aaceb142fd3fef4 to your computer and use it in GitHub Desktop.
Save allenyllee/7951c7dd8e1288f88aaceb142fd3fef4 to your computer and use it in GitHub Desktop.
#!/bin/bash
# Assumming brute force attack has constant hit rate, says X hit per Y seconds, across enough long time range, says T seconds.
# Every time we block a suspisuous ip for a period of time and unblock it,
# we should wait T seconds to see if there were further attack with rate X/Y hit/seconds.
# If this ip still has attack action during T seconds with hit rate X/Y, send it to block list which has doubled block time.
#
L1_period=300
L2_period=3600
L1_hit_upper=12
L1_hit_lower=1
L2_hit=7
during_period=3600
during_hit=5
# create ipsets to store different block time range buckets
ipset create timer0L1 hash:ip counters timeout $L1_period
ipset create timer0L2 hash:ip counters timeout $L2_period
ipset create blockset hash:ip timeout $during_period
ipset create allowset hash:ip
# block 10 min
hit_period=600
wait_time=$(($hit_period+$during_period))
ipset create timer1 hash:ip counters timeout $wait_time
iptables -X black1
iptables -N black1
iptables -A black1 -j SET --add-set blockset src --timeout $hit_period
iptables -A black1 -j SET --add-set timer1 src
iptables -A black1 -j LOG --log-prefix 'black1-DROP: '
iptables -A black1 -j DROP
# block 20 min
hit_period=$(($hit_period*2))
during_period=$(($during_period*2))
wait_time=$(($hit_period+$during_period))
ipset create timer2 hash:ip counters timeout $wait_time
iptables -X black2
iptables -N black2
iptables -A black2 -j SET --add-set blockset src --timeout $hit_period
iptables -A black2 -j SET --add-set timer2 src
iptables -A black2 -j LOG --log-prefix 'black2-DROP: '
iptables -A black2 -j DROP
# block 40 min
hit_period=$(($hit_period*2))
during_period=$(($during_period*2))
wait_time=$(($hit_period+$during_period))
ipset create timer3 hash:ip counters timeout $wait_time
iptables -X black3
iptables -N black3
iptables -A black3 -j SET --add-set blockset src --timeout $hit_period
iptables -A black3 -j SET --add-set timer3 src
iptables -A black3 -j LOG --log-prefix 'black3-DROP: '
iptables -A black3 -j DROP
# block 1 day
hit_period=86400
during_period=28800
wait_time=$(($hit_period+$during_period))
ipset create timer4 hash:ip counters timeout $wait_time
iptables -X black4
iptables -N black4
iptables -A black4 -j SET --add-set blockset src --timeout $hit_period
iptables -A black4 -j SET --add-set timer4 src
iptables -A black4 -j LOG --log-prefix 'black4-DROP: '
iptables -A black4 -j DROP
# block 24 days
hit_period=2073600
during_period=57600
wait_time=$(($hit_period+$during_period))
iptables -X black0
iptables -N black0
iptables -A black0 -j SET --add-set blockset src --timeout $hit_period
iptables -A black0 -j SET --del-set timer4 src
iptables -A black0 -j SET --add-set timer4 src --timeout $wait_time
iptables -A black0 -j LOG --log-prefix 'black0-DROP: '
iptables -A black0 -j DROP
# just for log when drop from blockset
iptables -X blackb
iptables -N blackb
iptables -A blackb -j LOG --log-prefix 'blackb-DROP: '
iptables -A blackb -j DROP
# timer L2 (long term cumulative rules)
iptables -X blackL2
iptables -N blackL2
iptables -A blackL2 -m set --match-set timer0L2 src --packets-gt $L2_hit -j black1
iptables -A blackL2 -j SET --add-set timer0L2 src
iptables -A blackL2 -j SET --add-set timer0L1 src
iptables -A blackL2 -j ACCEPT
# create limiter chain
iptables -X limiter
iptables -N limiter
iptables -A limiter -m set --match-set allowset src -j ACCEPT
iptables -A limiter -m set --match-set blockset src -j blackb
iptables -A limiter -m set --match-set timer4 src --packets-gt $during_hit -j black0
iptables -A limiter -m set --match-set timer3 src --packets-gt $during_hit -j black4
iptables -A limiter -m set --match-set timer2 src --packets-gt $during_hit -j black3
iptables -A limiter -m set --match-set timer1 src --packets-gt $during_hit -j black2
iptables -A limiter -m set --match-set timer0L1 src --packets-gt $L1_hit_upper -j black1
iptables -A limiter -m set --match-set timer0L1 src --packets-gt $L1_hit_lower -j ACCEPT
iptables -A limiter -m set --match-set timer0L2 src -j blackL2
iptables -A limiter -j SET --add-set timer0L2 src
iptables -A limiter -j SET --add-set timer0L1 src
iptables -A limiter -j ACCEPT
# create rules to limiter chain
iptables -A INPUT -p TCP --dport ssh -m state --state NEW -j limiter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment