#!/bin/csh -f
# ipblock
# -----------------------------------------------------------------------------
# Shell script to permanantly block one or more IP addresses.
# -----------------------------------------------------------------------------
# Usage:  See Usage section below or run with -h or --help option to see usage.
# Assumptions:
# Effects:
# Notes:
# Implementation Notes:
# Portability Issues:
# Revision History:
#   $Log$
# -----------------------------------------------------------------------------

if ("$1" == "" || "$1" == "-h" || "$1" == "--help") then
    echo "Usage: $0:t [options] IP_Address..."
    echo "options:"
    echo "-D = Delete the block, allowing the IP addresses access again"
    echo "-v = Verbose mode.  Show iptables -L -v before and after each"
    echo "-p = Save resulting iptables settings to survive the next re-boot"
    exit 1
endif

# Collect command line options
set perm_option             = "false"
set verbose_option          = "false"
set iptables_action_option  = "-I"
set iptables_action_message = "block"
while ($#argv > 0)
    if ("$1" == "-h" || "$1" == "--help") then
        shift
        # If help option was anywhere among the options, call recursively
        # with just that option, and exit.
        $0:t --help
        exit 1
    else if ("$1" == "-p") then
        shift
        set perm_option = "true"
    else if ("$1" == "-v") then
        shift
        set verbose_option = "true"
    else if ("$1" == "-D") then
        shift
        set iptables_action_option = "-D"
        set iptables_action_message = "unblock"
    else
        # Not a recognized option.  Assume it's the first parameter
        break
    endif
end

if ($#argv == 0) then
    beep "No IP address specified"
    $0:t --help
    exit 1
endif

while ($#argv > 0)

    if ("$verbose_option" == "true") then
        echo "****************************************************************"
        echo "iptables before the change:"
        echo "****************************************************************"
        sudo iptables -L -v
        echo "****************************************************************"
    endif
    echo sudo iptables ${iptables_action_option} INPUT -s $1 -j DROP
         sudo iptables ${iptables_action_option} INPUT -s $1 -j DROP
    set rc = $status
    if ($rc != 0) then
        beep "Error ${iptables_action_message}ing IP address $1"
        exit $rc
    endif 
    if ("$verbose_option" == "true") then
        echo "****************************************************************"
        echo "iptables after the change:"
        echo "****************************************************************"
        sudo iptables -L -v
        echo "****************************************************************"
    endif

    if ("$perm_option" == "true") then
        sudo service iptables save
    endif

    # Send email to root to tell admins that this troublesome IP address has 
    # been blocked.  Use the same subject line format as fail2ban so the email 
    # messages can be sorted by subject to see this one grouped with others 
    # from fail2ban about this temporary bans of the same IP address.
    set host = `hostname -s`
    set person = `logname`
    echo "IP address $1 ${iptables_action_message}ed by $person on $host via $0:t" | mail -s "[Fail2Ban] SSH: banned $1 -- $host ipblock $1 ${iptables_action_message}ed by $person" root

    # Wait a full second for the mail to get handed off to sendmail.  
    # Otherwise, this script sometimes ends before the mail goes, and when 
    # run remotely via ssh, the script ends, and the ssh session ends, and 
    # the mail never gets sent.  Is there a better way to make sure all 
    # piped commands are completed before proceeding?  This must be a 
    # special problem with the handoff to sendmail.  Most piped commands 
    # are reliably synchronous.
    echo "Waiting a second for email to be sent..."
    sleep 1

    # Move on to the next IP address
    shift

end