-   Linux - Security (
-   -   Using .htaccess to block ip ranges (

noobie143 02-18-2015 12:35 AM

Using .htaccess to block ip ranges
I have used a .htaccess file with lines like this to block ip addresses from China

order allow,deny
allow from all
deny from
deny from

I know that the file works because when I spoof using Chinese ip addresses I get blocked.

However, when i type
netstat -tanp | grep ':80\b' | grep SYN_RECV | awk '{print $5}' | cut -d':' -f1 | sort | uniq -c | sort -nr

at the command prompt I still see a lot of Chinese ip addresses.

Can someone tell me what is happening?

TenTenths 02-18-2015 08:18 AM

.htaccess rules deny the requests at apache level, the tcp connection is still made to the server it just doesn't get serviced by apache.

noobie143 02-18-2015 08:30 AM

Thanks a lot. The ip's I blocked are still able to bring down my server periodically even though they can't get to Apache.

I have enabled Syn cookies now. Is there anything else I can do to stop the attacks? They seem pretty relentless.

TenTenths 02-18-2015 08:36 AM

.htaccess doesn't do anything to block the traffic requests, if you can't block at router level then you can block with iptables. I've a blog post on how to implement iptables blocking of a list of countries. It assumes you know what iptables are and how to implement a basic firewall.

noobie143 02-18-2015 08:53 AM

The link you posted doesn't seem to be working. I don't know anything about iptables but I suppose I shall have to learn in a hurry.


TenTenths 02-18-2015 08:58 AM

If you're still spoofing or coming from a Chinese IP address then you'll have been blocked..... ;) ;)


Originally Posted by My Blog Post
There are times when you’ll want to limit access and block whole countries. Why? Because there are times when it’s necessary.

Here’s a script that builds a script….

It downloads the IP ranges from, works through a list of two letter country codes to create a bash script that will:
  • Delete an existing iptables chain.
  • Creates a new chain “BadCountry”.
  • Adds this to the top of the INPUT chain to pass anything on port 80 to the BadCountry chain.
  • Adds all the IP blocks in the relevant countries to the BadCountry chain with a reject/unreachable.

Feel free to adapt it to your needs.

(Oh, and you can also call the script with the parameter undo and it’ll delete the chain.)




if [ "${PARAM}" == "undo" ] ; then

  iptables -D INPUT -p tcp -m tcp --dport 80 -j BadCountry
  iptables --flush BadCountry
  iptables -X BadCountry


  echo $(date) IP Blocking GLOBAL START
  #First call ourselves to undo (delete the chain)
  ${0} undo

  #This is where the executable script that does the table update will live.

  #Change this to a folder you can write to
  cd /root/ipblocks
  #and delete any zone file tar/zip files 
  rm -f all-zones.tar.*

  echo $(date) Download Countries START

  wget ""

  tar -zxvf all-zones.tar.gz > /dev/null

  echo $(date) Download Countries FINISH

  echo $(date) Build Countries START

  echo "#!/bin/bash" > ${TABLESCRIPT}

  echo "iptables -N BadCountry" >> ${TABLESCRIPT}

  echo "iptables -I INPUT -p tcp -m tcp --dport 80 -j BadCountry" >> ${TABLESCRIPT}

  echo "iptables -A BadCountry -j RETURN" >> ${TABLESCRIPT}

  for COUNTRY in hk cn in id kr my ph tw th vn pk ; do
    awk {'print "iptables -I BadCountry -s "$1" -j REJECT --reject-with icmp-port-unreachable"'} ${COUNTRY}.zone >> ${TABLESCRIPT}

  echo $(date) Build Countries FINISH

  echo $(date) Updating iptables START

  #Make our script executable
  chmod 700 ${TABLESCRIPT}

  #And now execute it

  echo $(date) Updating iptables FINISH

# Elvis Has Left The Server.

noobie143 02-18-2015 09:01 AM

This looks complicated. But thanks. I will read through it and get back when I run into trouble understanding something.

TenTenths 02-18-2015 09:06 AM

It's a bit complicated, but what you're trying to do is a bit complicated as you're looking to ban whole countries at tcp level.

I would advise that you need to check and try some iptables tutorials before use as a badly configured iptables firewall could block you from having remote access to your server.

There is an existing thread on here that covers the same thing.

Habitual 02-18-2015 09:29 AM

Not to mention that using many "Deny from"s in an .htaccess is a huge resource waster.
Apache has to read that file for every file served. Whereas in a .conf file, it does not.
Firewall block keeps them from even wasting any further apache resources.

I use CSF (configserverfirewall) for country blocking.

noobie143 02-18-2015 08:09 PM

Thanks once again. I have started reading tutorials.

The Syn Flood attacks are, as you said, at the OS level, so banning them from Apache by using .htaccess is not very useful. So why does restarting Apache make all the SYN connections go away?

noobie143 02-18-2015 11:53 PM

I saw this in an iptables tutorial:

iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

Syn-flood attack means that the attackers open a new connection, but do not state what they want (ie. SYN, ACK, whatever). They just want to take up our servers' resources. We won't accept such packages.

Will this help?

noobie143 02-19-2015 12:37 AM

I posted a whole lot of lines like this covering Chinese ip ranges

iptables -A INPUT -s -j DROP

into my /etc/sysconfig/iptables file

and did

service iptables restart

I also removed the .htaccess file I used earlier.

So far I can't see any SYN_RECV from China.

TenTenths 02-19-2015 02:54 AM


Originally Posted by noobie143 (Post 5319753)
So why does restarting Apache make all the SYN connections go away?

Because it effectively "closes" port 80 and force closes any tcp connections to port 80.


Originally Posted by noobie143 (Post 5319836)
I posted a whole lot of lines like this covering Chinese ip ranges

iptables -A INPUT -s -j DROP

into my /etc/sysconfig/iptables file

and did

service iptables restart

I also removed the .htaccess file I used earlier.

So far I can't see any SYN_RECV from China.

So what you've done is add a load of DROP rules to the INPUT chain. What my script does is similar. Mine downloads country IP ranges automatically, created a new chain that gets added to the "top" of the INPUT chain and only gets called for specific types of traffic (in my example only port 80) and also rejects the packet rather than drop it. Of course it would be very easy to change it to create DROP rules instead.

The reason I implemented my blocking in this way allows me to have my "static" iptables configuration and to generate the "BadCountry" chain dynamically. I can also run my script with the "undo" parameter to remove just the country blocking.

If you're happy with your method then that's the most important thing. Personally I'm lazy, I have my script run on a regular basis and don't need to manually create a lot of rules. shows 5370 ip ranges for CN so manually adding that lot would take you a bit of time :) :)

noobie143 02-19-2015 03:22 AM

My method did not work.

I copied the lines like iptables -A INPUT -s -j DROP
to the /etc/sysconfig/iptables-config file

Apparently if there is a way of doing it by copy pasting, this is not the file to do it in

noobie143 02-19-2015 03:58 AM offers an iptables ban file. It has about 5000 lines each of which is like this:
iptables -A INPUT -s -j DROP

I want to upload it to my server, read each line and execute it from the command prompt. I am asking for the simplest way because I do not want to execute bash scripts that I do not understand.

All times are GMT -5. The time now is 03:08 PM.