I've recently been receiving some spam from some Russian IP's. As each spam attempt was from a different IP, blocking individual ones was a little futile and time consuming. I did a quick Google and ended up at Deekayen's website as it seems he has had similar issues. His solution was an Apache level "Deny"… My solution uses iptables.
See, if someone is coming to my site with mal-intent, ideally I dont want them near the server - much less the site! Even with Apach Deny rules, each spam attempt will be costing me bandwidth + a server hit. Additionally, if I were to do a site Drupal upgrade then its quite likely my .htaccess would get overwritten thus opening me up to spam again.
My solution requires root access to your server and that the server be running a version of Linux (I'm pretty sure they all ship with iptable's now). Initially, I simply did the following - assuming 18.104.22.168 is the offending IP:
iptables -I INPUT -s 22.214.171.124 -j DROP
The manual page for iptables defines DROP as:
DROP means to drop the packet on the floor
The problem with this is that for every offending IP, you would need to add a rule in. What if you KNEW that every ip in the 126.96.36.199 - 188.8.131.52 range was going to offend. Well, there are a number of ways to do this. One uses a subnet mask and the other (untested) uses the iptables ip-range facility.
This method is EXACTLY the same as the previous example however you slightly change the IP address…
iptables -I INPUT -s 184.108.40.206/24 -j DROP
The /24 on the end tells iptables that the source address should me a 24 bit mask of 220.127.116.11. For more information on subnetting an IP - please read this Wikipedia artcle on the subject. I dont know a lot about it…
IP-Tables IP-Range Solution
I didn't personally use this method - mainly because it was less effort to block the entire range rather than a specifc smaller range, however this solution provides finer control over what actually gets blocked. For example, you might not want to block 18.104.22.168 - 22.214.171.124 - you might only want to block 126.96.36.199 - 188.8.131.52 inclusively. As I said, I haven't personally tried this method, however it is a suggested alternative in a forum post over at ServerBeach.com about Blocking an IP Range. This is example given in that forum by aryani.
iptables -I INPUT -m iprange --src-range 184.108.40.206-220.127.116.11 -j DROP
The manual page describes it as follows…
This matches on a given arbitrary range of IPv4 addresses
- [!]--src-range ip-ip
- Match source IP in the specified range.
- [!]--dst-range ip-ip
- Match destination IP in the specified range.
I cannot find any mention of the "-m iprange" part in the manual though. I wonder if that's OS-specific.
Where do I find these IP address things?
Well, you have a number of options. I have the Spam module installed on this site so anything that is considered spam will go there first to be moderated. The Spam module logs the IP address of anything it considers spam however Drupal doesn't (unfortunately) log the IP address of commenter's by default. Maybe there is a module which will do this?
If you have access to the server logs, you could search through them for attempted connections to your site's comment script. With linux - this is VERY easy, for example:
grep 'comment/reply' /path/to/logs/httpd/my_log
That will search for anything with 'comment/reply' in it. I'm sure a linux and/or regular expression guru could work up something "better", but thats a basic example. If there are too many results, you can always pipe the results to a reader like less or more. Most logs will also contain the date/time that this access attempt happened plus a note of if it was a GET or POST request.
One other option is that could lookup common IP's from a blacklisting website.
What website could I use for this? Could I help?
Why yes - of course you could help!
Enter Project Honey Pot which is a really cool community driven anti-spam site. You can register for free and you gain access to a list of IP addresses which have been logged spamming in some way. If you feel generous, you could host a "Honey Pot" on your website which can help them find new or existing harvesters. I've set one up on this site - it can be seen here.
If you're feeling particularly generous, you can also offer a subdomain (or maybe full domain) for spamming. Basically, you add an MX record to a subdomain of your own domain to point at one of Project Honey Pot's MX server's. This is only likely only be possible through a decent Registrar, 123reg doesn't seem to support it. Any email that gets sent to this subdomain (eg, firstname.lastname@example.org) will get sent to Project Honey Pot and they can analyse it for spam. If it is spam - they make a note of the source IP. I don't KNOW, but I assume these email addresses get used on the Honey Pot pages.
There are LOADS of services out there to help out with spam. Most simply offer a service to block spam on your website, for example Akismet. Personally I dont want these people on my site. If all they're going to do is waste my time tidying up after them and waste my server resources (such as CPU cycles and bandwidth) then they can simply not have access (this reminds me of a parental approach on toys - "if you cant play with it sensibly then you cant play with it at all"). I'd much rather a situation where as soon as a known spammer tries to get to my site, they get turned down at the door for EVERYTHING. The knock on advantage of turning away spammers is that it reduces my illegitimate hits and therefore my Google Adsense CTR (Click Through Rate) might go up therefore increasing the value of a click on my site.
I'd be interested to hear what methods others are using to protect themselves - Drupal or otherwise!