LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Security (http://www.linuxquestions.org/questions/linux-security-4/)
-   -   Iptables - external file of bad IPs (http://www.linuxquestions.org/questions/linux-security-4/iptables-external-file-of-bad-ips-526490/)

Elomis 02-07-2007 02:56 PM

Iptables - external file of bad IPs
 
Hi Guys,
Is it possible to point IPtables to an external file of denied IPs? There's a bunch of high quality lists freely available on the internet of IPs owned by spammers, record companies and the other of the internet's nasties, and I'd like to be able to tell IPtables that these people are undesirable without having to do 50,000 iptables -A INPUT -s {nextipinlist}

fotoguy 02-07-2007 03:40 PM

For my script I just used this little bit of code that reads a text file and automatically makes the rules to suit. You need to have at least one entry otherwise you will get errors if it tries to add a rule with no source address.

Code:

BLOCKED_IP="/etc/ipblock"
if [ -f $BLOCKED_IP ]; then
        while read BLOCKED; do
                $IPTABLES -A INPUT -i eth0 -s $BLOCKED -j DROP
                $IPTABLES -A OUTPUT -o eth0 -d $BLOCKED -j DROP
        done < $BLOCKED_IP
fi


Elomis 02-07-2007 04:02 PM

Ooh. Good idea. Pity it can't be modular in that it can point to the file which I can then update, but I guess I am asking too much from a simple firwall implementatin.

Thanks.

anomie 02-07-2007 04:18 PM

My usual bit on the subject: Allow only the subnets that really need access. Deny everything else by default.

fotoguy 02-10-2007 10:27 PM

Quote:

Originally Posted by Elomis
Ooh. Good idea. Pity it can't be modular in that it can point to the file which I can then update, but I guess I am asking too much from a simple firwall implementatin.

Thanks.


You can point it to any file that you want and you can update the file with new entries one per line, the only thing is you would need to reload the script to re-read and add rules to it.

Or you could create a cron job that runs a script to update and read your file for you and add the rules on the fly. All rules that you add with show if you use iptables-L, so you could have the script check the /etc/ipblock for entries and then check then against the current rules.

This way you could have them block the instant the rule applies, rather than having to reload the iptables script all the time. Just put together a little scipt that seems to work, although I haven't tested it extensively, you could also expand the script to check your log files as well and add entries from any host doing things they shouldn't be doing.

Code:

#!/bin/bash

BLOCK_LIST=`cat /etc/ipblock`
CURRENT_RULES=`iptables -L`
IPTABLES=`whereis iptables | awk '{print $2}'`

for ENTRIES in $BLOCK_LIST; do
        SUCCESS=0
        grep "$ENTRIES" "$CURRENT_RULES"
                if [ ! "$?" = "$SUCCESS" ]; then # if the rule is not found, add it
                        $IPTABLES -I INPUT -i eth0 -s $ENTRIES -j DROP
                        $IPTABLES -I OUTPUT -o eth0 -d $ENTRIES -j DROP
                fi
done

Using the -I (insert) rather than the -A (append) in the rule will place it at the the top, this makes sure you will get the drop rule first.

Dave_Devnull 05-20-2009 04:36 AM

I stumbled accross this whilst looking for a way to populate bad IP's into an existing iptables. I appreciate the thread is old but still hits the top of the searches.

The above example bombs out with errors on my bash version, and lacks a few basics like allowing comments in the list and checking the file even exists. It also overlooks the possibility of single, CIDR and ranges in the list. Hopefully this version may help anyone who needs it;

Code:

#!/bin/bash
#
# assumes that the IP addresses you wish to block are put in file /etc/firewall.blocks
# this file can contain comments starting with ; or #
# but these must not be included on the end of IP addresses
# #comment allowed
# ;comment allowed
# 192.168.1.2 ;NOT ALLOWED
# 192.168.1.2 #NOT ALLOWED
# firewall blocks can be single IP, CIDR, or a RANGE
# 192.168.1.1
# 192.168.1.0/24
# 192.168.1.1-192.168.1.10
#
BLOCK_LIST=/etc/firewall.blocks
if [ ! -f $BLOCK_LIST ]
        then
                echo "Unable to add blocks to IPTABLES because file $BLOCK_LIST is missing"
                exit
        fi
CURRENT_RULES=`iptables -nL`

while read entries ;do
        # skip comment lines starting with ; or #
        case $entries in
                \#*|\;*)
                continue
                ;;
        esac

        if [[ $CURRENT_RULES =~ $entries ]]
        then
                printf "%-20s %20s\n" $entries 'already referenced in iptable - skipping'
                else
                # is this CIDR, range or single IP?
                        if [[ $entries =~ "-" ]]
                        then
                        #--src-range
                        printf "%-20s %20s %1s %1s\n" 'ADDING RULE:' 'iptables -A INPUT --src-range' $entries '-j DROP'
                        iptables -A INPUT --src-range $entries -j DROP
                        else
                        #--CIDR or single
                        printf "%-20s %20s %1s %1s\n" 'ADDING RULE:' 'iptables -A INPUT -s' $entries '-j DROP'
                        iptables -A INPUT -s $entries -j DROP
                        fi
                fi
done < $BLOCK_LIST

Not all IPTABLES support the --src-range and may STB if used. If you see errors like;

Code:

iptables v1.4.0: Unknown arg `--src-range'
Then use single or CIDR instead. Script is then modified to this shorter version


Code:

#!/bin/bash
#
# assumes that the IP addresses you wish to block are put in file /etc/firewall.blocks
# this file can contain comments starting with ; or #
# but these must not be included on the end of IP addresses
# #comment allowed
# ;comment allowed
# 192.168.1.2 ;NOT ALLOWED
# 192.168.1.2 #NOT ALLOWED
# firewall blocks can be single IP OR CIDR
# 192.168.1.1
# 192.168.1.0/24
#
BLOCK_LIST=/etc/firewall.blocks
if [ ! -f $BLOCK_LIST ]
        then
                echo "Unable to add blocks to IPTABLES because file $BLOCK_LIST is missing"
                exit
        fi
CURRENT_RULES=`iptables -nL`

while read entries ;do
        # skip comment lines starting with ; or #
        case $entries in
                \#*|\;*)
                continue
                ;;
        esac

                if [[ $CURRENT_RULES =~ $entries ]]
                then
                printf "%-20s %20s\n" $entries 'already referenced in iptable - skipping'
                else
                printf "%-20s %20s %1s %1s\n" 'ADDING RULE:' 'iptables -A FIREWALL -s' $entries '-j DROP'
                iptables -A FIREWALL -s $entries -j DROP
                fi
done < $BLOCK_LIST


pmol123 04-18-2013 04:44 PM

Script I use to update IPtables in real time.
 
This morning I woke up to find that was getting a Denial Of Service (DOS) attack from Russia. They were hitting me from dozens of IP blocks. They must have either had a large pool of IPs or some sort of proxy list/service. Every time I blocked an IP, another one popped up. Finally, I looked for a script, and found I needed to write my own solution. The following is a bit agressive, but they were running my TOP LOAD LEVEL to over 200.

Here is a quick script I wrote to block the DOS in realtime.

PHP Code:

cat  <output of the logs> | php ipchains.php <something unique in the logs

PHP Code:

PHP Code:

<?php

//*****************
//*** ipchains.php
//*****************

$ip_arr = array();

while(
1)
{
   
$line trim(fgets(STDIN)); // reads one line from STDIN
   
$ip trimstrtok$line" ") );

   if( !
array_key_exists$ip$ip_arr ) )
      
$ip_arr[$ip] = 0;

   
$regex sprintf"/%s/"$argv[1] );

   
$cnt preg_match_all$regex$line );

   if( 
$cnt ) continue;

   
$ip_arr[$ip] += 1;

   if( 
$ip_arr[$ip] == 1  )
     {
//     printf( "%s\n", $argv[1] );
//     printf( "%d\n", $cnt );
//     printf( "%s\n", $line );

       
printf"-A BLOCK1 -s %s/24 -j DROP\n"$ip );

       
$cmd sprintf"/sbin/iptables  -I BLOCK1  -d %s/24 -j DROP"$ip );
       
system$cmd );
     }
}


?>

Assumptions:
1) BLOCK1 is a Chain already created.
2) BLOCK1 is a Chain that is run/called from the INPUT CHAIN
3) Periodically you will need to run "ipchains -S BLOCK1" and put output in /etc/sysconfig file.
4) You are familiar with PHP
5) You understand web log line items/fields and output.


Patrick
http://www.ExpertWitness.com

chrism01 04-18-2013 08:04 PM

You could use fail2ban http://linux.die.net/man/8/fail2ban to dynamically+automatically update the list on an address-by-address basis.
For sets of ipaddresses, see ipset http://www.linuxjournal.com/content/...urations-ipset


All times are GMT -5. The time now is 12:41 AM.