Hi list*, *recently**i had a request for a VM for one of our qmailers.

Subsequently , after deployment, we found the VM to be compromised, so hackers got in before I could secure the qmail VM.

I rebuilt the VM, and added " My " firewall rules , and sent it off again. No probs this time. I was asked if they could share the firewall rules, No probs, but I looked for a way to block by country.

Here is what I found, and modified for our qmail needs ( rules etc )
Thanks go to the original script writer, I merely modified it.

Firewall script , so you can block specific countries, eg China ( ISO cn ) working as of July 16th 2014
*
***No offense meant to any countries listed here, for demo purposes only******

Do a ISO country code look up for your needs

*Tested on qmail-Centos5, and qmail-Centos6.*

Should work an other iptables type firewalls

*Install & Setup.*
***** Backup your existing firewall script. ***
Centos5 qmail install ( *cp /etc/rc.d/firewall.ruleset /etc.rc.d/firewall.org***) Centos6 qmail install ( *cp /etc/sysconfig/iptables /etc/sysconfig/iptables.org* )

copy script to your server, make executable ( *chmod +x country_block.sh* )
*Edit file, and modify to your needs.*
specific areas
*ISO="af cn kr" *
# Set your own ports you need , these are set for a standard qmail install..remove 3306 if you dont do database sync`s
*ALLOWPORTS=22,25,80,110,143,443,465,587,993,995,3306
#Set your subnet
ALLOWSUBNET=192.168.0.0/255.255.0.0*


Run script
*./country_block.sh*
Wait until complete.
check it added the rules, *iptables -L -n*, you should see a whole bunch of " countrydrop " lines

_*Centos 5 Qmail installs*_
Save iptables to your /etc/rc.d/firewall.ruleset
*/sbin/iptables-save > /etc/rc.d/firewall.ruleset*

Stop and start firewall
*firewall down**
**firewall up*
Check again *iptables -L -n*

_*Centos 6 Qmail installs*_
Save iptables to your /etc/sysconfig/iptables
*/sbin/iptables-save > /etc/sysconfig/iptables*

Some say this may cause slowness on the email server, I have not found that to be the case. Based on " My ruleset " ( thousands of entries ) I have been running the rules for years.

Dave M



#!/bin/bash
# Origin from http://www.cyberciti.biz/faq/block-entier-country-using-iptables
# Modified again by Madd Macc, for qmail installs
# include ability to cache the address list, create chains by subnet thus 
# optimizing rule execution, clean up the rules without wiping the existing 
# tables, include port overrides to allow traffic deemed 'safe', and leverage 
# iptables-restore to optimize rules loading.
### Example Block all traffic from AFGHANISTAN (af), CHINA (CN) and KOREA(kr). 
Add or remove as desired
### Use Country ISO code ###

ISO="af cn kr" 

### Set PATH ###
IPT=/sbin/iptables
WGET=/usr/bin/wget
EGREP=/bin/egrep
 
### No editing below ###
CBLIST="countrydrop"
ZONEROOT="/var/iptables"
IPTCBRESTORE="/etc/sysconfig/iptables.cb"
IPTCBDEVICE=eth0
# Set your own ports you need , these are set for a standard qmail 
install..remove 3306 if you dont do database sync`s
ALLOWPORTS=22,25,80,110,143,443,465,587,993,995,3306
#Set your subnet 
ALLOWSUBNET=192.168.0.0/255.255.0.0
MAXZONEAGE=7
DLROOT="http://www.ipdeny.com/ipblocks/data/countries";
 
cleanOldRules(){
    $IPT -L $CBLIST > /dev/null 2>&1
    if [ $? = 0 ] ; then
        $IPT -D INPUT ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST
        $IPT -D OUTPUT ${IPTCBDEVICE:+-o }${IPTCBDEVICE} -j $CBLIST
        $IPT -D FORWARD ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST
    fi
    $IPT -F $CBLIST
    $IPT -X $CBLIST

    for i  in `$IPT -L -n | grep Chain | cut -f 2 -d ' ' | grep '\-$CBLIST'`
    do
        $IPT -F ${i}
        $IPT -X ${i}
    done
}

updateZoneFiles() {
    ZONEARCH=${ZONEROOT}/arch
    mkdir -p ${ZONEARCH}
    find ${ZONEROOT} -maxdepth 1 -mindepth 1 -ctime +${MAXZONEAGE} -exec mv {} 
${ZONEARCH} \;

    for c  in $ISO
    do
        # local zone file
        tDB=$ZONEROOT/$c.zone
        
        if [ -f $tDB ] ; then
            printf "Zone file %s is new enough - no update required.\n" $tDB
        else
            # get fresh zone file if it is newer than MAXZONEAGE days
            $WGET -O $tDB $DLROOT/$c.zone
        fi
    done
    oldzones=`find ${ZONEROOT} -mindepth 1 -maxdepth 1 -type f -exec basename 
{} \; | cut -f 1 -d '.'`
    # Archive old zones no longer blocked
    for z in $oldzones ; do
        archme=${c}
        for c  in $ISO ; do
            if [ $c = $z ] ; then archme="X"; fi
        done
        if [ $archme = $z ] ; then
            mv ${archme} ${ZONEARCH}
        else
            printf "Working from previous zone file for %s\n" ${z}
        fi
    done
}
 
createIPTLoadFile() {
    printf "# Generated by %s on" $0 > ${IPTCBRESTORE}
    printf "%s " `date` >> ${IPTCBRESTORE}
    printf "\n*filter\n" >> ${IPTCBRESTORE}
    # Create CBLIST chain
    printf ":$CBLIST - [0:0]\n" >> ${IPTCBRESTORE}
    printf "%s INPUT ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST\n" "-I" > 
${IPTCBRESTORE}.tmp
    printf "%s OUTPUT ${IPTCBDEVICE:+-o }${IPTCBDEVICE} -j $CBLIST\n" "-I"  >> 
${IPTCBRESTORE}.tmp
    printf "%s FORWARD ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST\n" "-I" >> 
${IPTCBRESTORE}.tmp

    printf "%s $CBLIST -m state --state RELATED,ESTABLISHED -j ACCEPT\n" "-I">> 
${IPTCBRESTORE}.tmp
    if [ "Z${ALLOWPORTS}" = "Z" ] ; then
        printf "Blocking all traffic from country - no ports allowed\n"
    else
        printf "%s $CBLIST -p tcp -m multiport --dports ${ALLOWPORTS} -j 
RETURN\n" "-I">> ${IPTCBRESTORE}.tmp
    fi

    if [ "Z${ALLOWSUBNET}" = "Z" ] ; then
        printf "Blocking all traffic from country - no subnets excluded\n"
    else
        printf "%s $CBLIST -s ${ALLOWSUBNET} -j RETURN\n" "-I">> 
${IPTCBRESTORE}.tmp
    fi

    for c  in $ISO
    do
        # local zone file
        tDB=$ZONEROOT/$c.zone
        
        # country specific log message
        SPAMDROPMSG="iptables: ${c}-Country-Drop: "
        
        # Create drop chain for identified packets
        CBLISTDROP=${c}-${CBLIST}-DROP
        printf ":${CBLISTDROP} - [0:0]\n" >> ${IPTCBRESTORE}
        printf "%s ${CBLISTDROP} -j LOG --log-prefix \"$SPAMDROPMSG\"\n" "-A" 
>> ${IPTCBRESTORE}.tmp
        printf "%s ${CBLISTDROP} -j DROP\n" "-A" >> ${IPTCBRESTORE}.tmp
    
        # Load IP ranges into chains correlating to first octet
        BADIPS=$(egrep -v "^#|^$" $tDB)
        for ipblock in $BADIPS
        do
            topip=`echo $ipblock | cut -f 1 -d '.'`
            chainExists=`grep -c :${topip}-${CBLIST} ${IPTCBRESTORE}`
            if [ $chainExists = 0 ] ; then
                printf "Creating chain for octet %s\n" ${topip}
                printf ":$topip-$CBLIST - [0:0]\n" >> ${IPTCBRESTORE}
                sip=${topip}.0.0.0/8
                printf "%s $CBLIST -s ${sip} -j $topip-$CBLIST\n" "-A" >> 
${IPTCBRESTORE}.tmp
            fi
            printf "  Adding rule for %s to chain for octet %s\n" ${ipblock} 
${topip}
            printf "%s $topip-$CBLIST -s $ipblock -j ${CBLISTDROP}\n" "-A" >> 
${IPTCBRESTORE}.tmp
        done
    done
    cat ${IPTCBRESTORE}.tmp >> ${IPTCBRESTORE} && rm -f ${IPTCBRESTORE}.tmp
    printf "COMMIT\n# Completed on " >> ${IPTCBRESTORE}
    printf "%s " `date` >> ${IPTCBRESTORE}
    printf "\n" >> ${IPTCBRESTORE}
}

directLoadTables() {
    # Create CBLIST chain
    $IPT -N $CBLIST
    $IPT -I INPUT ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST
    $IPT -I OUTPUT ${IPTCBDEVICE:+-o }${IPTCBDEVICE} -j $CBLIST
    $IPT -I FORWARD ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST

    if [ "Z${ALLOWPORTS}" = "Z" ] ; then
        printf "Blocking all traffic from country - no ports allowed\n"
    else
        $IPT -I $CBLIST -p tcp -m multiport --dports ${ALLOWPORTS} -j RETURN
    fi

    if [ "Z${ALLOWSUBNET}" = "Z" ] ; then
        printf "Blocking all traffic from country - no subnets allowed\n"
    else
        $IPT -I $CBLIST -s ${ALLOWSUBNET} -j RETURN
    fi

    for c  in $ISO
    do
        # local zone file
        tDB=$ZONEROOT/$c.zone
        
        # country specific log message
        SPAMDROPMSG="$c Country Drop"
        
        # Create drop chain for identified packets
        CBLISTDROP=${c}-${CBLIST}-DROP
        $IPT -N ${CBLISTDROP}
        $IPT -A ${CBLISTDROP} -j LOG --log-prefix "$SPAMDROPMSG"
        $IPT -A ${CBLISTDROP} -j DROP
    
        # Load IP ranges into chains correlating to first octet
        BADIPS=$(egrep -v "^#|^$" $tDB)
        for ipblock in $BADIPS
        do
            topip=`echo $ipblock | cut -f 1 -d '.'`
            $IPT -L $topip-$CBLIST > /dev/null 2>&1
            if [ $? = 1 ] ; then
                printf "Creating chain for octet %s\n" ${topip}
                $IPT -N $topip-$CBLIST
                sip=${topip}.0.0.0/8
                $IPT -A $CBLIST -s ${sip} -j $topip-$CBLIST
            fi
            printf "  Adding rule for %s to chain for octet %s\n" ${ipblock} 
${topip}
            $IPT -A $topip-$CBLIST -s $ipblock -j ${CBLISTDROP}
        done
    done
}

loadTables() {
    createIPTLoadFile
    ${IPT}-restore -n ${IPTCBRESTORE}
    #directLoadTables
    printf "Country block instituted for: %s\n" "$ISO"
}

# create a dir
[ ! -d $ZONEROOT ] && /bin/mkdir -p $ZONEROOT
 
# clean old rules
cleanOldRules
 
# update zone files as needed
updateZoneFiles

# create a new iptables list
loadTables

exit 0

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to