Forums

ahorli
ahorli
Offline
Resolved
0 votes
Hi everybody,

here is a script i found that keeps most Chinese and Russian hackers off my system.
To find more information about this script visit http://ipinfodb.com
With this script you have the possibility to block a list of whole countrys.
You could also specify ports that should still be accessible.
To get it up an runnig do the following:

touch /usr/bin/blockcountry.sh
chmod 755 /usr/bin/blockcountry.sh
copy this into the new file:
#!/bin/bash
### IpInfoDB iptables countries block bash script###
### Slightly modified script from http://www.cyberciti.biz
### Countries code available : http://ipinfodb.com/country.txt ###
### Block all traffic from RUSSIA (RU) and CHINA (CN). Use ISO code ##
ISO="RU CN"

### Set PATH ###
IPT=/sbin/iptables
WGET=/usr/bin/wget
EGREP=/bin/egrep
ZONEROOT="/root/iptables/"
IPTCBRESTORE="/root/iptables/iptables.cb"

### Network config ###
####change this to reflect your servers wan interface ###
IPTCBDEVICE=eth0

### Uncomment this to add exceptions from the blocking i.e. allow blocked countrys access to specific ports ###
#ALLOWPORTS=80,443
#ALLOWSUBNET=192.168.0.0/255.255.0.0

### No editing below ###
CBLIST="countrydrop"
MAXZONEAGE=6
DLROOT="http://ipinfodb.com/country_query_test.php?country="

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
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

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


Now all you have to do is run the script.
To automatically execute it weekly you cou add the following script to /etc/cron.weekly folder:
#!/bin/bash
blockcountry.sh
exit 0


cheers
Axel
Wednesday, April 28 2010, 03:02 PM
Share this post:
Responses (132)
  • Accepted Answer

    Tuesday, August 31 2021, 03:51 PM - #Permalink
    Resolved
    0 votes
    Nick Howitt wrote:

    Sorry, I did not take in your lines fully. You've dropped the "-i your_WAN_interface" from the command so it will block everything so either:
    $IPTABLES -I INPUT -i your_WAN_interface -m conntrack --ctstate NEW -m set ! --match-set country-list src -j DROP

    or:
    $IPTABLES -I INPUT -i your_WAN_interface -m conntrack --ctstate NEW -m set ! --match-set country-list src ! -p icmp -j DROP


    Sorry Nick, Thought I'd replied!

    Yes that works a treat. Thanks for that. :D


    Better late than never I suppose ....
    The reply is currently minimized Show
  • Accepted Answer

    Thursday, April 30 2020, 09:25 AM - #Permalink
    Resolved
    0 votes
    Sorry, I did not take in your lines fully. You've dropped the "-i your_WAN_interface" from the command so it will block everything so either:
    $IPTABLES -I INPUT -i your_WAN_interface -m conntrack --ctstate NEW -m set ! --match-set country-list src -j DROP

    or:
    $IPTABLES -I INPUT -i your_WAN_interface -m conntrack --ctstate NEW -m set ! --match-set country-list src ! -p icmp -j DROP
    The reply is currently minimized Show
  • Accepted Answer

    Thursday, April 30 2020, 07:51 AM - #Permalink
    Resolved
    0 votes
    Nick Howitt wrote:

    There is no point in using the multiport switch if you are not specifying ports. You could simplify to a single rule:
    $IPTABLES -I INPUT -m conntrack --ctstate NEW -m set ! --match-set country-list src -j DROP


    [edit]
    but it is arguably naughty as it blocks pings. You could try:
    $IPTABLES -I INPUT -m conntrack --ctstate NEW -m set ! --match-set country-list src ! -p icmp -j DROP

    [/edit]


    Well that dont work as it blocks everything, including LAN

    Think I'll just leave it as is.
    The reply is currently minimized Show
  • Accepted Answer

    Tuesday, April 28 2020, 07:05 PM - #Permalink
    Resolved
    0 votes
    There is no point in using the multiport switch if you are not specifying ports. You could simplify to a single rule:
    $IPTABLES -I INPUT -m conntrack --ctstate NEW -m set ! --match-set country-list src -j DROP


    [edit]
    but it is arguably naughty as it blocks pings. You could try:
    $IPTABLES -I INPUT -m conntrack --ctstate NEW -m set ! --match-set country-list src ! -p icmp -j DROP

    [/edit]
    The reply is currently minimized Show
  • Accepted Answer

    Tuesday, April 28 2020, 03:18 PM - #Permalink
    Resolved
    0 votes
    Nick Howitt wrote:

    I've now put it into a proper Howto in the Knowledgebase

    @John, it looks like my script has moved on a bit from when I posted. MAXELEM is now parameterised. This is a trivial change and you don't need it. I've also set it to e-mail me if the update fails.

    Also writing it up has shown a stupidity in my firewall rules. You can remove:
    -m state --state NEW
    from the firewall rules. This should have been replaced by:
    -m conntrack --ctstate NEW
    And not supplemented with it.


    Sorry to be a pain but what is the rule to block all traffic except from what's enabled within the country list?

    Would the following work ?

    $IPTABLES -I INPUT -m conntrack --ctstate NEW -m set ! --match-set country-list src -p tcp -m multiport -j DROP


    $IPTABLES -I INPUT -m conntrack --ctstate NEW -m set ! --match-set country-list src -p udp -m multiport -j DROP
    The reply is currently minimized Show
  • Accepted Answer

    Monday, January 06 2020, 11:55 AM - #Permalink
    Resolved
    2 votes
    I've now put it into a proper Howto in the Knowledgebase

    @John, it looks like my script has moved on a bit from when I posted. MAXELEM is now parameterised. This is a trivial change and you don't need it. I've also set it to e-mail me if the update fails.

    Also writing it up has shown a stupidity in my firewall rules. You can remove:
    -m state --state NEW
    from the firewall rules. This should have been replaced by:
    -m conntrack --ctstate NEW
    And not supplemented with it.
    Like
    1
    The reply is currently minimized Show
  • Accepted Answer

    Monday, January 06 2020, 10:57 AM - #Permalink
    Resolved
    0 votes
    Hi Tony,
    It is also an issue in Europe as many ISP's are multi-national so operate cross-boarder. I know there was a time when an area around Bristol, UK appeared to be in Germany, much to the annoyance of people trying to use the BBC TV iPlayer and website. In theory the source of the geo-lists I've used should compensate for that as much as they can but it is only as good as their sources.

    There is also a geolite2-country rpm but I have never investigated how to use it. maxmind.com, the creators of the geolite2-country, also have a more accurate subscription service.

    If anyone finds more accurate sources, I am happy to investigate. I did have a python script which could consolidate big lists but it became irrelevant with the current source. Having said that, my python programming is a little weak.
    The reply is currently minimized Show
  • Accepted Answer

    Monday, January 06 2020, 05:38 AM - #Permalink
    Resolved
    0 votes
    One thing to be aware of...
    With tcp4 addresses being scare they can move between countries. An ISP here in Australia experienced unexpected growth and become short of tcp4 addresses. They bough an allocation from an ISP in New Zealand. Thus some some users here in Australia suddenly found their location had suddenly become reported as in NZ, much to their annoyance...
    The reply is currently minimized Show
  • Accepted Answer

    Monday, January 06 2020, 02:24 AM - #Permalink
    Resolved
    0 votes
    With the help of Nick Howett and others, I have placed a complete and up to date, (January 2020), how-to with easy to follow steps to allow your ClearOS box to block whole countries from your open ports at a similar post located at the link below:
    The reply is currently minimized Show
  • Accepted Answer

    Sunday, October 14 2018, 04:36 PM - #Permalink
    Resolved
    0 votes
    There cannot ever be a 1-click solution without high risk. Say you want to block China. What then if you send an e-mail to Foxconn because you have a problem product. Are you blocking their replies? If you are doing filesharing, do you want to block lots of countries who may legitimately be sharing? etc.

    I have given a framework for creating a country IP list in ipset which can then be used by iptables, but your rules are then up to you. You may want to just allow US/Canada or block Asia, so it is up to you with how you want to write your rules. Only you know the exceptions.

    You need three elements:
    1 - the script to generate the set which goes in cron.monthly or cron.weekly
    2 - the script to load the ipset set on boot in /etc/rc.d/rc.local (and remember to enable it)
    3 - the firewall script to do what you want - either block or allow.
    (4 - possibly the /etc/sysconfig/modules/ip_set.modules file but you may now get away without it.)
    The reply is currently minimized Show
  • Accepted Answer

    Sunday, October 14 2018, 08:30 AM - #Permalink
    Resolved
    0 votes
    In 2018 and using ClearOs7 what is the status for this ?

    No one click "block all the blood-sucker" app ?

    Or a simple guide for intrepid ignorant having a root access :)
    The reply is currently minimized Show
  • Accepted Answer

    Friday, September 07 2018, 08:02 AM - #Permalink
    Resolved
    0 votes
    Oh the joys of country blocking! I was working on a python script to consolidate the subnets into a shorter list when I found ipdeny.com was no longer working (it is back up now) and I discovered some things. I found some new web sites with free country data and modified the script to use a new site. As part of my research I also found that IP blocks allocated to one country can be delegated to another. Typical of this is a story I heard a while back of someone in part of England unable to use the iPlayer at bbc.co.uk web site as his IP showed he was in Germany. His IP at top level was allocated to Germany where his ISP's parent was, but some of the IP's had been delegated to the UK at a lower level. It looks like ipdeny.com uses top level allocations only but the problem is then finding a site you can trust to do the lower level allocations. I've started using ip.ludost.net. I've had to replace the main script (/etc/cron.monthly/country_list) with the following:

    #!/bin/bash

    # A list of the ISO country codes can be found at http://en.wikipedia.org/wiki/ISO_3166-1
    # Countries are case insensitive for this script

    ISO="at be ch cy cz de dk es fr gb gr ie it lu mt nl pt eu va sm mc je gg im"

    if [ "`lsmod | grep ip_set`" = "" ]; then
    modprobe ip_set
    fi

    # Destroy country-list-temp in case it exists and is populated
    ipset destroy -q country-list-temp

    # Make sure the new lists exist
    ipset create country-list nethash maxelem 524288 -exist
    ipset create country-list-temp nethash maxelem 524288 -exist

    # Load the country list
    curl -s -d country=1 --data-urlencode "country_list=$ISO" -d format_template=prefix https://ip.ludost.net/cgi/process | grep -v ^# | while read -r line
    do
    ipset -A -exist country-list-temp $line
    done

    # Make the temp list current
    ipset swap country-list country-list-temp

    # Destroy the (now old) temp list
    ipset destroy -q country-list-temp

    # Create save list for loading on boot
    ipset save country-list > /usr/src/ipset_country-list.save
    sed -i 's/create/create -exist/g' /usr/src/ipset_country-list.save
    sed -i 's/add/add -exist/g' /usr/src/ipset_country-list.save

    logger -t country-list "Updated"

    The maxelem value can be adjusted and by default is a 65536 and it should be a power of 2. This is the number of elements in the list. I have chosen a huge number because it may cover other peoples requirements. I could get away with 131072 for myself. Run the script manually once to make sure it works. Increase the value as necessary.

    All the rest of the set up is the same

    The advantage of this script is that the IP list is already consolidated. The disadvantage is that is is more that twice as long for the same country codes (78785 records compared to 33190) so it really depends on which one you trust. Interestingly, if you extend the list to cover all the EU, the list gets shorter (c. 72,000 lines) as gaps get filled in the list of IP blocks allowing more consolidation of subnets.

    Note, if you do country blocking and run your own mail server/MTA I strongly suggest you don't country block port 25 unless you want to risk missing out on e-mails.
    The reply is currently minimized Show
  • Accepted Answer

    Sunday, August 26 2018, 07:44 AM - #Permalink
    Resolved
    0 votes
    If anyone is using my blocking country blocking script from this thread, the site ipdeny.com is currently serving corrupt data and the all-zones.tar.gz is only 56KB, way too small. I have not been able to find another source for the tar file.

    I am separately working on a python script to do the same as the main bash script and one version of it will pick off the individual country files rather than work off the all-zones file, and I have found an alternative source for the individual files. Unfortunately the script is not ready for publishing and won't be for a while (my python skills are basic).
    The reply is currently minimized Show
  • Accepted Answer

    Wednesday, August 12 2015, 09:10 PM - #Permalink
    Resolved
    0 votes
    Nick Howitt wrote:

    It is massively o/t but logwatch is almost install and forget. I've tweaked it to get rid of a few OpenVPN and stunnel (if you don't know, don't ask! It is to do with relaying e-mail via your ISP on port 465) messages. By default it mails to root nightly so you need to have root aliased to you or change the default. You can also run it from the command line to test (just by typing logwatch). It gives a summary of all logged iptables/firewall messages among other things. There are addons for it and I use a postfix one to give me postfix information.


    Looks very interesting and nice to have. I think I have to google a bit more to find out about logwatch...
    The reply is currently minimized Show
  • Accepted Answer

    Tuesday, August 11 2015, 08:34 PM - #Permalink
    Resolved
    0 votes
    It is massively o/t but logwatch is almost install and forget. I've tweaked it to get rid of a few OpenVPN and stunnel (if you don't know, don't ask! It is to do with relaying e-mail via your ISP on port 465) messages. By default it mails to root nightly so you need to have root aliased to you or change the default. You can also run it from the command line to test (just by typing logwatch). It gives a summary of all logged iptables/firewall messages among other things. There are addons for it and I use a postfix one to give me postfix information.
    The reply is currently minimized Show
  • Accepted Answer

    Tuesday, August 11 2015, 08:01 PM - #Permalink
    Resolved
    0 votes
    Nick Howitt wrote:

    @Marcel,
    That's looking better. You should start seeing hits on port 22 or, if you block the US, go to grc.com and get it to scan port 22. If you don't have port 22 open then you can remove that from the firewall rule as it gets a relatively large number of hits.


    Bingo!


    Aug 11 17:41:58 voyager kernel: COUNTRY_BLOCK: IN=eth0 OUT= MAC=0c:c4:7a:08:a2:a4:00:17:10:85:aa:05:08:00 SRC=188.242.59.86 DST=31.151.121.130 LEN=48 TOS=0x00 PREC=0x00 TTL=116 ID=40671 PROTO=TCP SPT=23466 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0



    Obviously only adjust logwatch if you use it! It gives a nice daily update of things happening on the server.


    Okay, how do you use logwatch. Looks interesting.., super that you share your knowledge here...
    The reply is currently minimized Show
  • Accepted Answer

    Tuesday, August 11 2015, 04:53 PM - #Permalink
    Resolved
    0 votes
    @Marcel,
    That's looking better. You should start seeing hits on port 22 or, if you block the US, go to grc.com and get it to scan port 22. If you don't have port 22 open then you can remove that from the firewall rule as it gets a relatively large number of hits.

    Obviously only adjust logwatch if you use it! It gives a nice daily update of things happening on the server.
    The reply is currently minimized Show
  • Accepted Answer

    Tuesday, August 11 2015, 01:19 PM - #Permalink
    Resolved
    0 votes
    Nick Howitt wrote:

    Found the change I did to logwatch. In /usr/share/logwatch/default.conf/logfiles add lines LogFile = firewall
    Archive = firewall.* to the relevant bits (though it probably does not matter where).


    Nick, is this correct?

    I can't find the directory "/usr/share/logwatch"

    [edit]
    hmmm.., obvious had to install logwatch.
    [/edit]
    The reply is currently minimized Show
  • Accepted Answer

    Tuesday, August 11 2015, 12:57 PM - #Permalink
    Resolved
    0 votes
    Nick, I make things difficult for you... :o

    What i did on the cli


    iptables -I INPUT -i eth0 -m set --match-set ipset_country-list src -p tcp -m multiport --dports 22,3483,4040,8888,9000,9091,32400 -m state --state NEW -j COUNTRY_BLOCK


    See the "ipset_country-list"

    but the firewall rule in /etc/clearos/firewall.d/20-ipset-block is okay.


    iptables -I INPUT -i eth0 -m set --match-set country-list src -p tcp -m multiport --dports 22,3483,4040,8888,9000,9091,32400 -m state --state NEW -j COUNTRY_BLOCK


    Men this confused me too! Stupid action!

    After manualy set the firewal rule with succes and then a reboot. I see the following:

    When I do:


    iptables - nvL


    the first rows of this out is:


    [root@voyager firewall.d]# iptables -nvL
    Chain INPUT (policy DROP 162 packets, 45400 bytes)
    pkts bytes target prot opt in out source destination
    0 0 COUNTRY_BLOCK tcp -- eth0 * 0.0.0.0/0 0.0.0.0/0 match-set country-list src multiport dports 22,3483,4040,8888,9000,9091,32400 state NEW
    36 2736 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:123 state RELATED,ESTABLISHED
    0 0 DROP all -- eth0 * 69.64.49.133 0.0.0.0/0
    0 0 DROP all -- eth0 * 94.122.111.215 0.0.0.0/0
    0 0 DROP all -- eth0 * 204.42.253.131 0.0.0.0/0
    The reply is currently minimized Show
  • Accepted Answer

    Tuesday, August 11 2015, 10:40 AM - #Permalink
    Resolved
    0 votes
    I'm getting more and more confused. The file /usr/src/ipset_country-list.save has nothing to do with the firewall, it is just an export of the ipset set that you restore from (in rc.local) if you restart the server. I do not understand the error message either. ipset_country-list should never be referred to by iptables, only country-list which is the name of the table in ipset. Have you changed your firewall rule from what you posted (apart from removing the !)? Or have you change the name of the ipset set from what I scripted? You can do an "ipset list -name" to list the sets you have. Don't worry if they repeat a little.
    The reply is currently minimized Show
  • Accepted Answer

    Tuesday, August 11 2015, 08:48 AM - #Permalink
    Resolved
    0 votes
    Nick Howitt wrote:

    No, it looks like you've taken out the "--sport 25" but left in the "!" after 32400. Remove the "!" as well.


    Damn, that I didn't see that...

    Now it throws the following error.


    iptables v1.4.7: Set ipset_country-list doesn't exist.


    if I do


    [root@voyager src]# locate ipset_country-list
    /usr/src/ipset_country-list.save


    Why can't iptables find it? Path issue?
    The reply is currently minimized Show
  • Accepted Answer

    Tuesday, August 11 2015, 08:08 AM - #Permalink
    Resolved
    0 votes
    No, it looks like you've taken out the "--sport 25" but left in the "!" after 32400. Remove the "!" as well.
    The reply is currently minimized Show
  • Accepted Answer

    Tuesday, August 11 2015, 07:24 AM - #Permalink
    Resolved
    0 votes
    Nick,

    There is something wrong with this rule


    iptables -I INPUT -i eth0 -m set --match-set country-list src -p tcp -m multiport --dports 22,3483,4040,8888,9000,9091,32400 ! -m state --state NEW -j COUNTRY_BLOCK


    When I try to load this it outputs a error


    iptables v1.4.7: unexpected ! flag before --match
    Try `iptables -h' or 'iptables --help' for more information.


    [edit]
    Is that a typo "--match-set" must be "--match -set"?
    [/edit]
    The reply is currently minimized Show
  • Accepted Answer

    Monday, August 10 2015, 09:01 PM - #Permalink
    Resolved
    0 votes
    Found the change I did to logwatch. In /usr/share/logwatch/default.conf/logfiles add lines
    LogFile = firewall
    Archive = firewall.*
    to the relevant bits (though it probably does not matter where).
    The reply is currently minimized Show
  • Accepted Answer

    Monday, August 10 2015, 08:01 PM - #Permalink
    Resolved
    0 votes
    Nick Howitt wrote:

    As I said in my earlier post you need to remove the "! --sport 25" bit from your last rule. The error message is telling you you cannot have --dport and --sports with the multiport option.


    Ah, understood.


    Nick Howitt wrote:

    To redirect firewall messages to another file, add a file, /etc/rsyslog.d/anything.conf. In it add:

    # Split out Firewall messages
    if $programname == 'kernel' then -/var/log/firewall

    and restart rsyslog.

    Then to make the file rotate add /etc/logrotate.conf or /etc/logrotate.d/any_name.conf:

    # rotate the firewall log
    /var/log/firewall {
    notifempty
    missingok
    weekly
    copytruncate
    create 0664 root root
    rotate 4
    }

    [edit]
    That then messed up the output from logwatch so I had to adjust that somewhere to also read the new log file.
    [/edit]


    Thanks! I'll try this tomorrow.

    [edit]
    these code /code tags in a quote are terrible.
    [/edit]
    The reply is currently minimized Show
  • Accepted Answer

    Monday, August 10 2015, 07:45 PM - #Permalink
    Resolved
    0 votes
    To redirect firewall messages to another file, add a file, /etc/rsyslog.d/anything.conf. In it add:
    # Split out Firewall messages
    if $programname == 'kernel' then -/var/log/firewall
    & ~
    and restart rsyslog.

    Then to make the file rotate add /etc/logrotate.conf or /etc/logrotate.d/any_name.conf:
    # rotate the firewall log
    /var/log/firewall {
    notifempty
    missingok
    weekly
    copytruncate
    create 0664 root root
    rotate 4
    }


    [edit]
    That then messed up the output from logwatch so I had to adjust that somewhere to also read the new log file.
    [/edit]
    The reply is currently minimized Show
  • Accepted Answer

    Monday, August 10 2015, 07:36 PM - #Permalink
    Resolved
    0 votes
    As I said in my earlier post you need to remove the "! --sport 25" bit from your last rule. The error message is telling you you cannot have --dport and --sports with the multiport option.
    The reply is currently minimized Show
  • Accepted Answer

    Monday, August 10 2015, 07:11 PM - #Permalink
    Resolved
    0 votes

    if [ "`lsmod | grep ip_set`" = "" ]; then
    modprobe ip_set
    fi

    # Block non-RIPE and other country addresses
    ipset create country-list nethash --hashsize 3456 -exist
    iptables -N COUNTRY_BLOCK > /dev/null 2>&1
    #comment out the next line if you do not want any firewall logging
    iptables -A COUNTRY_BLOCK -j LOG --log-level INFO --log-prefix "COUNTRY_BLOCK: "
    iptables -A COUNTRY_BLOCK -j DROP
    iptables -I INPUT -i eth0 -m set --match-set country-list src -p tcp -m multiport --dports 3483,4040,8888,9000,9091,32400 ! --sport 25 -m state --state NEW -j COUNTRY_BLOCK


    I have added this to "/etc/clearos/firewall.d/20-ip_set-block. This are ports used by Logitech Media Server, Subsonic, Transmission, Plex.
    The reply is currently minimized Show
  • Accepted Answer

    Monday, August 10 2015, 10:16 AM - #Permalink
    Resolved
    1 votes
    To check the rules are loaded you can do "iptables -nvL". You should see a rule at the top of the INPUT chain with your specific selection criteria and a COUNTRY_BLOCK chain at the bottom of the listing with a LOG and DROP rule.

    What rule(s) are you trying to load into the INPUT chain?
    The reply is currently minimized Show
  • Accepted Answer

    Sunday, August 09 2015, 08:59 PM - #Permalink
    Resolved
    0 votes
    btw if I do ipset --list I can see all entries loaded...
    The reply is currently minimized Show
  • Accepted Answer

    Sunday, August 09 2015, 08:52 PM - #Permalink
    Resolved
    0 votes
    Nick Howitt wrote:

    As I've said multiple times on the forum always check the firewall rules at the command line before making them permanent :slaps_himself_on_the_head:

    In this case the rule:
    iptables -I INPUT -i eth0 -m set --match-set country-list src -p tcp -m multiport --dports 443,587,993 ! --sport 25 -m state --state NEW -j COUNTRY_BLOCK
    is failing as the error message says:
    iptables v1.4.7: multiport can only have one option
    Try `iptables -h' or 'iptables --help' for more information.



    So this is way to check if the firewall rules are loaded? If I do this with the ports I've set I have the same output.


    With the option "--state NEW" I think you can safely remove the "--sport 25" option as I thing the SMTP protocol is from a high port to port 25 but I am not 100% certain.I wish a more knowledgeable SMTP person would chip in. (Thinking some more, "--state NEW" must be totally irrelevant but I'd love some confirmation)


    Okay, not completly sure if understand this stuff... I'll also do some googling.


    A firewall line would be in /var/log/massages something like:
    Aug  9 20:50:17 server kernel: COUNTRY_BLOCK: IN=eth0 OUT= MAC=94:de:80:ba:89:ca:00:30:b8:d0:b9:34:08:00 SRC=4.79.142.206 DST=82.19.158.192 LEN=44 TOS=0x00 PREC=0x00 TTL=227 ID=61440 PROTO=TCP SPT=47454 DPT=22 WINDOW=8192 RES=0x00 SYN URGP=0 
    Aug 9 20:50:18 server kernel: COUNTRY_BLOCK: IN=eth0 OUT= MAC=94:de:80:ba:89:ca:00:30:b8:d0:b9:34:08:00 SRC=4.79.142.206 DST=82.19.158.192 LEN=44 TOS=0x00 PREC=0x00 TTL=227 ID=61440 PROTO=TCP SPT=47454 DPT=22 WINDOW=8192 RES=0x00 SYN URGP=0

    I redirect all my firewall messages to /var/log/firewall.


    Not seen any of this entries in messages. How do you redirect firewall messages to a seperate log? Good thing to do!


    To test also try blocking tcp:22 and you should see some hits fairly quickly. If not, go to grc.com and do a "shields up" test against one of your chosen ports. The above log is from a shields up test on port 22.


    Interesting site. With shield up you can only test if ports are open of closed. Correct?
    The reply is currently minimized Show
  • Accepted Answer

    Sunday, August 09 2015, 07:59 PM - #Permalink
    Resolved
    0 votes
    As I've said multiple times on the forum always check the firewall rules at the command line before making them permanent :slaps_himself_on_the_head:

    In this case the rule:
    iptables -I INPUT -i eth0 -m set --match-set country-list src -p tcp -m multiport --dports 443,587,993 ! --sport 25 -m state --state NEW -j COUNTRY_BLOCK
    is failing as the error message says:
    iptables v1.4.7: multiport can only have one option
    Try `iptables -h' or 'iptables --help' for more information.
    With the option "--state NEW" I think you can safely remove the "--sport 25" option as I thing the SMTP protocol is from a high port to port 25 but I am not 100% certain.I wish a more knowledgeable SMTP person would chip in. (Thinking some more, "--state NEW" must be totally irrelevant but I'd love some confirmation)

    A firewall line would be in /var/log/massages something like:
    Aug  9 20:50:17 server kernel: COUNTRY_BLOCK: IN=eth0 OUT= MAC=94:de:80:ba:89:ca:00:30:b8:d0:b9:34:08:00 SRC=4.79.142.206 DST=82.19.158.192 LEN=44 TOS=0x00 PREC=0x00 TTL=227 ID=61440 PROTO=TCP SPT=47454 DPT=22 WINDOW=8192 RES=0x00 SYN URGP=0 
    Aug 9 20:50:18 server kernel: COUNTRY_BLOCK: IN=eth0 OUT= MAC=94:de:80:ba:89:ca:00:30:b8:d0:b9:34:08:00 SRC=4.79.142.206 DST=82.19.158.192 LEN=44 TOS=0x00 PREC=0x00 TTL=227 ID=61440 PROTO=TCP SPT=47454 DPT=22 WINDOW=8192 RES=0x00 SYN URGP=0
    I redirect all my firewall messages to /var/log/firewall.

    To test also try blocking tcp:22 and you should see some hits fairly quickly. If not, go to grc.com and do a "shields up" test against one of your chosen ports. The above log is from a shields up test on port 22.
    The reply is currently minimized Show
  • Accepted Answer

    Sunday, August 09 2015, 07:02 PM - #Permalink
    Resolved
    0 votes
    @Nick, how looks this log message? Can't find any blocks...
    The reply is currently minimized Show
  • Accepted Answer

    Wednesday, August 05 2015, 07:47 AM - #Permalink
    Resolved
    0 votes
    That's fine. I had already adjusted one of my posts earlier in the thread.
    The reply is currently minimized Show
  • Accepted Answer

    Wednesday, August 05 2015, 07:33 AM - #Permalink
    Resolved
    0 votes
    Nick Howitt wrote:
    Thanks for the feedback. The main script is missing the first three lines from the firewall script which would have modprobe'd for you. Stick:

    if [ "`lsmod | grep ip_set`" = "" ]; then
    modprobe ip_set
    fi

    somewhere before the first ipset command.



    I adjusted the main script. Do you agree with the change?



    # A list of the ISO country codes can be found at http://en.wikipedia.org/wiki/ISO_3166-1
    # Use lower case for this script

    ISO="ae al am az by il iq ir jo kg kw kz lb om qa ro ru sa sy tj tm tr ua uz ye"

    cd /usr/tmp
    rm -f *.zone
    rm -f all-zones.tar.gz

    # Download the file
    if ! wget http://www.ipdeny.com/ipblocks/data/countries/all-zones.tar.gz -q ;
    then
    exit 1
    fi
    tar xzf all-zones.tar.gz --wildcards '*.zone' > /dev/null

    # Check if ipset is loaded
    if [ "`lsmod | grep ip_set`" = "" ]; then
    modprobe ip_set
    fi

    # Destroy country-list-temp in case it exists and is populated
    ipset destroy -q country-list-temp

    # Make sure the new lists exist
    ipset create country-list nethash --hashsize 65536 -exist
    ipset create country-list-temp nethash --hashsize 65536 -exist

    for COUNTRY in $ISO ; do

    if [ -f $COUNTRY.zone ] ; then
    # Load the country list
    while read line
    do
    ipset -A -exist country-list-temp $line
    done < $COUNTRY.zone
    fi

    done

    # Make the temp list current
    ipset swap country-list country-list-temp

    # Destroy the new temp list
    ipset destroy -q country-list-temp

    rm -f *.zone
    rm -f all-zones.tar.gz

    ipset save country-list > /usr/src/ipset_country-list.save
    sed -i 's/create/create -exist/g' /usr/src/ipset_country-list.save
    sed -i 's/add/add -exist/g' /usr/src/ipset_country-list.save
    The reply is currently minimized Show
  • Accepted Answer

    Monday, August 03 2015, 07:36 AM - #Permalink
    Resolved
    0 votes
    AE=UAE (United Arab Emirates). I am not sure if AF is part of RIPE so I block it anyway. I'll have to check.
    The reply is currently minimized Show
  • Accepted Answer

    Sunday, August 02 2015, 09:16 PM - #Permalink
    Resolved
    0 votes
    Okay Nick I'll check the ipset command. Interesting stuff. :)

    I'll already found the ipset_country-list.save file. So that is working OK.

    Which country is AE? Or is that a typo and must be AF (Afganistan)?
    The reply is currently minimized Show
  • Accepted Answer

    Sunday, August 02 2015, 09:07 PM - #Permalink
    Resolved
    0 votes
    You will see blocks in /var/log/messages if you enabled them in your firewall rules. Google "man ipset" for the various ipset commands available where you can see which sets you have and the contents of the sets. Also, if it has worked, you should have a /usr/src/ipset_country-list.save file (which was created by the ipset commands extracting information from the set you've just created).
    The reply is currently minimized Show
  • Accepted Answer

    Sunday, August 02 2015, 08:39 PM - #Permalink
    Resolved
    0 votes
    No problem of course!

    how do I check whether the block list is loaded?

    I think I have to check "var/log/messages" to see if there are dropped connections.
    The reply is currently minimized Show
  • Accepted Answer

    Sunday, August 02 2015, 08:10 PM - #Permalink
    Resolved
    0 votes
    Thanks for the feedback. The main script is missing the first three lines from the firewall script which would have modprobe'd for you. Stick:
    if [ "`lsmod | grep ip_set`" = "" ]; then
    modprobe ip_set
    fi
    somewhere before the first ipset command.
    The reply is currently minimized Show
Your Reply