#!/bin/bash

# Make sure you have ipset installed
# Debian: apt-get install -y ipset
# Redhat: yum install -y ipset

# Find the path of commands
IPT_CMD="$(which iptables)"
IPSET_CMD="$(which ipset)"

# Reset and create a greylist with 
# a timeout of 15 minutes (900 seconds)
$IPSET_CMD create greylist hash:ip timeout 900
$IPSET_CMD flush greylist

# Flush all chains
$IPT_CMD -F
$IPT_CMD -X

# Allow unlimited traffic on the loopback interface
$IPT_CMD -A INPUT -i lo -j ACCEPT
$IPT_CMD -A OUTPUT -o lo -j ACCEPT

# Set default policies
$IPT_CMD --policy INPUT DROP
$IPT_CMD --policy OUTPUT DROP
$IPT_CMD --policy FORWARD DROP

#
# Block all the bots caught in the greylist
# Insert the rule at the beginning of the ruleset
# This rule need to be before the first
# ESTABLISHED,RELATED rule
$IPT_CMD -I INPUT -m set  --match-set greylist src  -j DROP 

#
# Make sure that our servers don't try to communicate anything
# back to these parasites
$IPT_CMD -I OUTPUT -p tcp -m tcp -m set  --match-set greylist dst  -j REJECT  --reject-with icmp-port-unreachable
$IPT_CMD -I OUTPUT -p udp -m udp -m set  --match-set greylist dst  -j REJECT  --reject-with icmp-port-unreachable
$IPT_CMD -I OUTPUT -m set  --match-set greylist dst  -j REJECT  --reject-with icmp-proto-unreachable

# Previously initiated and accepted exchanges bypass rule checking
# Allow unlimited outbound traffic
$IPT_CMD -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT_CMD -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT


# SSH 
# Do not kick yourself out
$IPT_CMD -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT

# Greylist parasite on port 80
# Check whether the connection is below the threshold of 100 connections/second
# If over add it to the ipset grey list http
$IPT_CMD -N GREYLIST_80_TOO_FAST
$IPT_CMD -A INPUT -p tcp -m tcp  --dport 80 -m recent --name http --update --seconds 1 --hitcount 100  -j GREYLIST_80_TOO_FAST
$IPT_CMD -A GREYLIST_80_TOO_FAST  -j LOG  --log-level info --log-prefix "RL: http too fast "
$IPT_CMD -A GREYLIST_80_TOO_FAST  -j SET --add-set greylist src

# If pass the rule before, then add the counter of 1
$IPT_CMD -A INPUT -p tcp -m tcp  --dport 80 -m recent --name http --set

# Allow the http connection if its below the thresholds
$IPT_CMD -A INPUT -p tcp -m tcp  --dport 80  -m state --state NEW  -j ACCEPT 

# Greylist parasite on port 443
# Check whether the connection is below the threshold of 100 connections/second
# If over add it to the ipset grey list https
$IPT_CMD -N GREYLIST_443_TOO_FAST
$IPT_CMD -A INPUT -p tcp -m tcp  --dport 443 -m recent --name https --update --seconds 1 --hitcount 100  -j GREYLIST_443_TOO_FAST
$IPT_CMD -A GREYLIST_443_TOO_FAST  -j LOG  --log-level info --log-prefix "RL: https too fast "
$IPT_CMD -A GREYLIST_443_TOO_FAST  -j SET --add-set greylist src

# If pass the rule before, then add the counter of 1
$IPT_CMD -A INPUT -p tcp -m tcp  --dport 443 -m recent --name https --set

# Allow the https connection if its below the thresholds
$IPT_CMD -A INPUT -p tcp -m tcp  --dport 443  -m state --state NEW  -j ACCEPT 

# Default deny with logging
$IPT_CMD -N DefaultDeny 
$IPT_CMD -A INPUT  -m state --state NEW  -j DefaultDeny 
$IPT_CMD -A DefaultDeny  -j LOG  --log-level info --log-prefix "Default DENY- "
$IPT_CMD -A DefaultDeny  -j DROP 
