Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- root@Asustek:~# cat /opt/etc/init.d/S95asiablock
- #!/bin/sh
- ##############################################################################
- ## S95countryblock
- ## Written by: JP van Melis
- ## Intended platform: DD-WRT Linux router
- #
- # This script downloads a blacklist from the Internet which will be used by iptables
- # If available it will use "aggregate" to combine subnets
- # http://www.mail-archive.com/nanog@nanog.org/msg14737.html
- # ftp://ftp.isc.org/isc/aggregate/aggregate-1.6.tar.gz
- #
- # Make sure Optware programs come first as they support all the options I need
- export PATH=/opt/usr/sbin:/opt/sbin:/opt/bin:/bin:/usr/bin:/sbin:/usr/sbin:/jffs/sbin:/jffs/bin:/jffs/usr/sbin:/jffs/usr/bin:/mmc/sbin:/mmc/bin:/mmc/usr/sbin:/mmc/usr/bin
- # Constants
- # cn = China
- # af = Afghanistan
- # au = Australia
- # pk = pakistan
- # ph = philippines
- # in = india
- # my = malaysia
- # ua = ukrain
- # ng = nigeria
- # sg = singapore
- # th = Thailand
- # kh = cambodia
- # li = Liechtenstein
- # These countries will be blocked specifically
- ISO_spam="af cn ng in th sg pk my kh li vn kr ph"
- ISO_ham="us"
- # You can limit the amount of logentries per minute
- LOGONCE=1
- KEYWORD=asia
- NAME=asiablock
- URLBASE="http://www.ipdeny.com/ipblocks/data/countries"
- AGE=10
- CONFDIR=/tmp/etc/config
- WORKDIR=/tmp
- SAVEDIR=/tmp
- [ -d /opt/etc ] && SAVEDIR=/opt/etc
- scriptname=${0##*/}
- SPAMips=${WORKDIR}/spamips.${KEYWORD}
- HAMips=${WORKDIR}/hamips.${KEYWORD}
- COUNTRYfile=${WORKDIR}/country.${KEYWORD}
- COUNTRYtemp=${WORKDIR}/.country.${KEYWORD}
- HAMinclude=${SAVEDIR}/${KEYWORD}.ham
- SPAMinclude=${SAVEDIR}/${KEYWORD}.spam
- SPAMCHAIN=SPAM${KEYWORD}
- SPAMfile=iptables.${KEYWORD}
- SPAMfilepath=${SAVEDIR}/${SPAMfile}
- SPAMrules=${SAVEDIR}/${SPAMfile}.rules
- SYMLINK=${CONFDIR}/${KEYWORD}.prewall
- SPAMACTION=DROP
- # SPAMACTION=REJECT
- SPAMLOGSTOP=${SPAMACTION}${KEYWORD}
- AGE_SPAMfilepath=0
- [ -f ${SPAMfilepath} ] && AGE_SPAMfilepath=`date +%s -r ${SPAMfilepath}`
- if [ -z "`which ipcalc`" ] ; then
- echo "Script needs 'ipcalc', abort" >&2
- exit 1
- fi
- if [ -z "$1" ] ; then
- case `echo "$0" | sed 's:^.*/\(.*\):\1:g'` in
- S??*) rc="start" ;;
- K??*) rc="stop" ;;
- *) rc="usage" ;;
- esac
- else
- rc="$1"
- fi
- createblocknet ()
- {
- optlog "${scriptname}" "Create static network to block"
- # You can put comments after the subnet as a reminder
- # If you put a comment before, this specific subnet will not be included
- echo -n "43.0.0.0/8 # Japan
- 58.0.0.0/7 # A lot of 'decent' countries, as well...
- 60.0.0.0/7
- 110.0.0.0/7
- 112.0.0.0/6
- 116.0.0.0/6
- 120.0.0.0/6
- 124.0.0.0/7
- 126.0.0.0/8
- # 169.0.0.0/8 # too much US.. not added
- 180.0.0.0/8
- 202.0.0.0/8
- 203.0.0.0/8 # A lot of 'down under'
- 210.0.0.0/7
- 218.0.0.0/7
- 220.0.0.0/7
- 222.0.0.0/8 # Japan" | egrep -o '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]+' >${WORKDIR}/${KEYWORD}net
- optlog "${scriptname}" "network consists of `cat ${WORKDIR}/${KEYWORD}net | wc -l` subnets"
- }
- createclassA_list ()
- {
- optlog "${scriptname}" "Break down big network into Class A subnets"
- echo -n "" >${WORKDIR}/classA.${KEYWORD}
- while read asialine ; do
- brcast=`ipcalc -nb "${asialine}" | grep -i Broadcast | tr -cd '[0-9].' | awk -F\. '{print $1}'`
- network=`echo ${asialine} | awk -F\. '{print $1}'`
- while [ ${network} -le ${brcast} ] ; do
- echo "^${network}\\." >>${WORKDIR}/classA.${KEYWORD}
- let network+=1
- done
- done<${WORKDIR}/${KEYWORD}net
- }
- createblocklist ()
- {
- # remove file if the last line doesn't contain a bracket
- if [ -f ${SPAMfilepath} ] ; then
- if ! tail -n1 ${SPAMfilepath} | grep -q "^#" ; then
- optlog "${scriptname}" "I will remove ${SPAMfile} because the current one is invalid"
- rm -f ${SPAMfilepath} 2>/dev/null
- else
- # remove file if it is older than this script
- [ ${AGE_SPAMfilepath} -lt `date +%s -r ${0}` ] && rm -f ${SPAMfilepath} 2>/dev/null
- # remove file if it is older than 20 days
- find ${SAVEDIR} -mtime +${AGE} -type f -name ${SPAMfile} -exec rm {} \;
- [ -f ${SPAMfilepath} ] || optlog "${scriptname}" "Removed ${SPAMfilepath} because it was older than ${AGE} days or the file $0"
- fi
- fi
- sanitize ()
- {
- sanfile="${1}"
- if [ -f ${sanfile} ] ; then
- # Sanitize HAMinclude, but not more than necessary
- if [ ${AGE_SPAMfilepath} -lt `date +%s -r ${sanfile}` ] ; then
- fdate="`date -r ${sanfile}`"
- rm -f ${SPAMfilepath} 2>/dev/null
- sed -i -e "s/^[1-9][0-9]*\.[0-9]*\.[0-9]*\.[0-9]*$/&\/32/" ${sanfile}
- if [ ! -z "`which aggregate`" ] && [ `cat ${sanfile} | wc -l` -gt 1 ] ; then
- egrep -o '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]+' ${sanfile} >/tmp/netsonly
- cat /tmp/netsonly | aggregate >/tmp/sanfile
- # I can just replace the file with the aggregated list, but then I would need
- # to lookup all the whois data again. These lookups are limited from a given IP
- if [ `cat /tmp/sanfile | wc -l` -ne `cat ${sanfile} | wc -l` ] ; then
- # Collect all the lines that are in aggregated list
- grep -f /tmp/sanfile ${sanfile} >/tmp/sanfile2
- # Add the ones that were not there
- grep -v -f /tmp/netsonly /tmp/sanfile >>/tmp/sanfile2
- mv /tmp/sanfile2 ${sanfile}
- fi
- [ -f /tmp/sanfile ] && rm -f /tmp/sanfile 2>/dev/null
- fi
- if [ -n "`which whois`" ] ; then
- changed=0
- cp ${sanfile} /tmp/sanfile
- while read line ; do
- # only entries with merely CIDR will be replaced
- if echo "$line" | egrep -q '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]+$' ; then
- let changed+=1
- IP=`echo "$line" | egrep -o '^([0-9]{1,3}\.){3}[0-9]{1,3}'`
- IPpadded="`echo "${line}" | awk '{ printf("%-18s\n", $0)}' | sed 's/\//\\\\\//'`"
- orgname="`whois ${IP} 2>/dev/null | grep -i -e 'orgname:' -e 'netname:' -e 'descr:' | head -n1 | awk -F: '{print $2}' | sed -e 's/\&/\\\\&/' | sed 's/^[ \t]*//;s/[ \t]*$//'`"
- [ -z "${orgname}" ] || optlog "${scriptname}" "found ${orgname} at ${IP}"
- sed -i -e "s/${IP}.*/${IPpadded}\t# ${orgname}/" ${sanfile}
- fi
- done </tmp/sanfile
- if [ ${changed} -gt 0 ] ; then
- optlog "${scriptname}" "changed ${changed} entries in ${sanfile}"
- sort -t'/' -k2 -n ${sanfile} -o /tmp/sanfile
- mv /tmp/sanfile ${sanfile}
- fi
- rm -f /tmp/sanfile 2>/dev/null
- fi
- touch -d "${fdate}" ${sanfile}
- fi
- else
- echo -n "" >${sanfile}
- fi
- }
- sanitize ${HAMinclude}
- sanitize ${SPAMinclude}
- if [ -f ${SPAMfilepath} ] ; then
- optlog "${scriptname}" "Using existing file: ${SPAMfilepath}"
- else
- createblocknet
- createclassA_list
- # Create chain in 2 files
- echo -e "# bof" >${SPAMfilepath}
- echo -e "iptables -N ${SPAMCHAIN}" >>${SPAMfilepath}
- echo -e "iptables -N ${KEYWORD}" >>${SPAMfilepath}
- echo -e "iptables -N ${SPAMLOGSTOP}" >>${SPAMfilepath}
- echo -e "iptables -F ${SPAMCHAIN}" >>${SPAMfilepath}
- echo -e "iptables -F ${KEYWORD}" >>${SPAMfilepath}
- echo -e "iptables -F ${SPAMLOGSTOP}" >>${SPAMfilepath}
- if [ ${LOGONCE} -eq 0 ] ; then
- echo -e "iptables -A ${SPAMLOGSTOP} -j LOG --log-prefix \"[${KEYWORD} ${SPAMACTION}] : \" --log-tcp-options --log-ip-options" >>${SPAMfilepath}
- echo -e "iptables -A ${SPAMLOGSTOP} -j ${SPAMACTION}" >>${SPAMfilepath}
- else
- echo -e "iptables -A ${SPAMLOGSTOP} -m recent ! --rcheck --seconds 1200 --name ${SPAMLOGSTOP} --rsource -j LOG --log-prefix \"[${KEYWORD} ${SPAMACTION} (1st pkt)] : \" --log-tcp-options --log-ip-options" >>${SPAMfilepath}
- echo -e "iptables -A ${SPAMLOGSTOP} -m recent --set --name ${SPAMLOGSTOP} --rsource -j ${SPAMACTION}" >>${SPAMfilepath}
- fi
- echo -e "iptables-restore -n <${SPAMrules}" >>${SPAMfilepath}
- echo -e "*filter" >${SPAMrules}
- if [ ! -s ${WORKDIR}/${KEYWORD}net ] ; then
- optlog "${scriptname}" "No HAM needed because there's no general SPAMlist"
- else
- echo -n "" >${HAMips}
- # Whitelist these countries if they are within Asia's subnet
- for c in ${ISO_ham} ; do
- cURL=${URLBASE}/${c}.zone
- n=1
- while true ; do
- optlog "${scriptname}" "Downloading ${cURL} to ${COUNTRYfile}"
- wget -q -O ${COUNTRYfile} ${cURL}
- [ -f ${COUNTRYfile} ] && grep -q "/" ${COUNTRYfile} && break
- [ $n -gt 5 ] && break
- let n+=1
- sleep 30
- done
- if [ -f ${COUNTRYfile} ] ; then
- # subnet will be extracted
- egrep -o '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]+' ${COUNTRYfile} >${COUNTRYtemp}
- down_nets=`cat ${COUNTRYtemp} | wc -l`
- optlog "${scriptname}" "Downloaded ${down_nets} subnets from country \"${c}\""
- grep -f ${WORKDIR}/classA.${KEYWORD} ${COUNTRYtemp} >${COUNTRYfile}
- in_classA=`cat ${COUNTRYfile} | wc -l`
- optlog "${scriptname}" "${in_classA} subnets are in spamnet"
- if [ ! -z "`which aggregate`" ] && [ ${in_classA} -gt 1 ] ; then
- aggregate <${COUNTRYfile} >${COUNTRYtemp}
- mv ${COUNTRYtemp} ${COUNTRYfile}
- agg_nets=`cat ${COUNTRYfile} | wc -l`
- optlog "${scriptname}" "\"aggregate\" brought this down to ${agg_nets} subnets"
- fi
- cat ${COUNTRYfile} >>${HAMips}
- else
- optlog "${scriptname}" "Failed to download ${cURL}"
- fi
- done
- [ -f ${HAMinclude} ] && cat ${HAMinclude} >>${HAMips}
- exceptions=`cat ${HAMips} | wc -l`
- optlog "${scriptname}" "A total of ${exceptions} exceptions to the general blocklist are found"
- if [ ! -z "`which aggregate`" ] && [ ${exceptions} -gt 1 ] ; then
- aggregate <${HAMips} >${WORKDIR}/aggregate
- mv ${WORKDIR}/aggregate ${HAMips}
- fi
- optlog "${scriptname}" "Create Hamlist"
- sed -e "s/.*/-A ${KEYWORD} -s & -j RETURN/" ${HAMips} >>${SPAMrules}
- fi
- optlog "${scriptname}" "Hamlist created"
- echo "-A ${KEYWORD} -j ${SPAMCHAIN}" >>${SPAMrules}
- echo "-A ${KEYWORD} -j RETURN" >>${SPAMrules}
- rm ${SPAMips} 2>/dev/null
- # Block these countries!!
- for c in ${ISO_spam} ; do
- cURL=${URLBASE}/${c}.zone
- n=1
- while true ; do
- optlog "${scriptname}" "Downloading ${cURL} to ${COUNTRYfile}"
- wget -q -O ${COUNTRYfile} ${cURL}
- [ -f ${COUNTRYfile} ] && grep -q "/" ${COUNTRYfile} && break
- [ $n -gt 5 ] && break
- let n+=1
- sleep 30
- done
- if [ ! -f ${COUNTRYfile} ] ; then
- optlog "${scriptname}" "Error downloading ${cURL}"
- else
- # subnet will be extracted
- egrep -o '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]+' ${COUNTRYfile} >${COUNTRYtemp}
- down_nets=`cat ${COUNTRYtemp} | wc -l`
- optlog "${scriptname}" "Downloaded ${down_nets} subnets from country \"${c}\""
- if [ -z "`which aggregate`" ] ; then
- mv ${COUNTRYtemp} ${COUNTRYfile}
- else
- aggregate <${COUNTRYtemp} >${COUNTRYfile}
- rm ${COUNTRYtemp} 2>/dev/null
- agg_nets=`cat ${COUNTRYfile} | wc -l`
- optlog "${scriptname}" "\"aggregate\" brought this down to ${agg_nets} subnets"
- fi
- nRULES=`cat ${COUNTRYfile} 2>/dev/null | wc -l`
- nCURips=`cat ${SPAMips} 2>/dev/null | wc -l`
- optlog "${scriptname}" "Checking ${nRULES} rules for country \"${c}\""
- grep -vf ${WORKDIR}/classA.${KEYWORD} ${COUNTRYfile} >>${SPAMips}
- optlog "${scriptname}" "$(( `cat ${SPAMips} | wc -l` - ${nCURips})) rules added for country ${c}"
- fi
- done
- optlog "${scriptname}" "Removing file \"${COUNTRYfile}\""
- rm ${COUNTRYfile}
- cat ${WORKDIR}/${KEYWORD}net >>${SPAMips}
- [ -f ${SPAMinclude} ] && cat ${SPAMinclude} >>${SPAMips}
- blocks=`cat ${SPAMips} | wc -l`
- optlog "${scriptname}" "A total of ${blocks} blocks are found"
- if [ -z "`which aggregate`" ] ; then
- optlog "${scriptname}" "\"aggregate\" is missing :-("
- else
- aggregate<${SPAMips} >${WORKDIR}/aggregate 2>/dev/null
- # aggregate returns a 'Floating point exception' when the result should be 0.0.0.0/0
- if [ $? -gt 128 ] ; then
- echo '0.0.0.0/0' >${SPAMips}
- else
- sort -t'/' -k2 -n ${WORKDIR}/aggregate -o ${SPAMips}
- fi
- blocks=`cat ${SPAMips} | wc -l`
- optlog "${scriptname}" "\"aggregate\" brought it down to ${blocks} blocks"
- fi
- sed -e "s/.*/-A ${SPAMCHAIN} -s & -j ${SPAMLOGSTOP}/" ${SPAMips} >>${SPAMrules}
- echo "-A ${SPAMCHAIN} -j RETURN" >>${SPAMrules}
- echo "COMMIT" >>${SPAMrules}
- echo "# eof" >>${SPAMfilepath}
- # if the whole Internet is blocked in the SPAMchain then that chain is not necessart anymore
- if grep -q '0.0.0.0/0' ${SPAMips} ; then
- sed -i -e "s/-A ${KEYWORD} -j SPAM${KEYWORD}/-A ${KEYWORD} -j ${SPAMLOGSTOP}/" ${SPAMrules}
- fi
- rm ${SPAMips}
- rm ${WORKDIR}/aggregate
- fi
- }
- # Start/Stop/Status samba
- case "$rc" in
- start)
- mkdir -p ${CONFDIR} 2>/dev/null
- createblocklist
- if [ -f "${SPAMfilepath}" ] ; then
- chmod +x "${SPAMfilepath}"
- rm -f ${SYMLINK}
- # echo -e "iptables-restore -n <${SPAMfilepath}" >${SYMLINK}
- # chmod +x ${SYMLINK}
- ln -s ${SPAMfilepath} ${SYMLINK}
- optlog "${scriptname}" "Restart firewall"
- lines=`cat ${SPAMrules} | wc -l`
- secs=`date +%s`
- stopservice firewall
- iptables -F
- rm /tmp/.ipt
- startservice firewall
- secs=$((`date +%s` - ${secs}))
- optlog "${scriptname}" "It took ${secs} seconds to load ${lines} rules into iptables"
- else
- optlog "${scriptname}" "Failed to create ${SPAMfile}"
- exit 1
- fi
- ;;
- stop)
- if [ -h ${SYMLINK} ] ; then
- # replace symlink with a file with a chain which just says RETURN
- mkdir -p ${CONFDIR} 2>/dev/null
- rm -f ${SYMLINK}
- echo -e "iptables -N ${SPAMCHAIN}" >${SYMLINK}
- echo -e "iptables -F ${SPAMCHAIN}" >>${SYMLINK}
- echo -e "iptables -N ${KEYWORD}" >>${SYMLINK}
- echo -e "iptables -F ${KEYWORD}" >>${SYMLINK}
- echo -e "iptables -A ${KEYWORD} -j RETURN" >>${SYMLINK}
- chmod +x ${SYMLINK}
- optlog "${scriptname}" "Restart firewall"
- rm /tmp/.ipt
- startservice firewall
- fi
- ;;
- status)
- HAMNUM=$((`iptables -nL ${KEYWORD} 2>/dev/null | wc -l` - 4))
- if [ -e ${SYMLINK} ] ; then
- if [ -h ${SYMLINK} ] ; then
- SPAMNUM=$((`iptables -nL SPAM${KEYWORD} | wc -l` - 3))
- if iptables -nL SPAMworld | tail -n4 | grep -q "${SPAMLOGSTOP}" ; then
- echo "${NAME} is blocking the world but whitelisting ${HAMNUM} subnets"
- else
- echo "${NAME} is blocking ${SPAMNUM} subnets whilst whitelisting ${HAMNUM}"
- fi
- else
- echo "${NAME} is not blocking now"
- fi
- FORWARDref=`iptables -nL FORWARD | grep -c "${KEYWORD} "`
- INPUTref=`iptables -nL INPUT | grep -c "${KEYWORD} "`
- echo "It is referred to ${FORWARDref} time(s) in the chain FORWARD and ${INPUTref} times in the chain INPUT"
- else
- if [ ${HAMNUM} -le 4 ] ; then
- echo "$NAME is not active"
- else
- echo "Although ${NAME} is disabled, the chain ${KEYWORD} has $((${HAMNUM} + 2)) entries"
- fi
- fi
- ;;
- esac
- root@Asustek:~#
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement