Fixing up anti-spam plugins in Wordpress (and other apps) for Mosso

Monday, January 19. 2009
Comments

A lot of companies moved their web applications, or parts of them, to the cloud in 2008. Some people have had issues, for others (and AWS in particular), it's been one success story.

Because some of us like to focus on the business side and not run servers ourselves, providers like Mosso (a division of Rackspace) and MediaTemple offer scalable webhosting environments available to everyone.

Some of them call their offering cloud, others call it grid. Apparently it's the same. And I'm sure I am oversimplifying the services they offer (and I mean no disrespect), but scalable webhosting is what it really is.

Mosso in particular caught people's attention because they had a lot of issues in the beginning and because most of us know there is no such thing as 100% uptime for 100 USD/month, I don't want to poke them too hard for it.

One important thing to take into account when moving into the cloud is that on the configuration side, any virtual solution is slightly different from regular webhosting.

In particular one of the issues which my friend Allen Stern ran into when he moved to Mosso was that due to the virtual nature of the entire setup, none of his anti spam plugins in Drupal and Wordpress worked. Reason is that the IP populated in $_SERVER['REMOTE_ADDR'] is always the IP of Mosso's loadbalancer, which runs in front of the server farm and distributes all traffic to servers where resources are vacant.

Mosso instead populates the $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'] header but because the majority of PHP developers are used to a very specific setup — the LAMP stack — they rarely waste time by thinking ahead of other environments.

In this case, the plugins will blacklist Mosso's loadbalancer soon and you will end up with a lot of comments which you will need to moderate. This blacklisting makes using those plugins (e.g. Akismet, Mollom) useless.

While I'm certainly amazed that Mosso could not fix this at the server level, here are a couple solutions (free of charge) for their customer base to use to fix the problem themselves.

PHP to the rescue

For everyone involved, there are multiple solutions to this problem.

The hack!

Mass-replace REMOTE_ADDR with HTTP_X_CLUSTER_CLIENT_IP.

The disadvantage is that if you run software such as Wordpress, you will loose the easy update feature since you edited all files.

Still semi-dirty

Find a file (e.g. a configuration file) which is included by the software everywhere and add the following line into it: $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];

There is no real disadvantage here, the only thing you need to keep in mind is that you probably need to re-add this to the file in case the software itself updates it and overwrites your changes.

The clean solution!

My favorite is to put the above statement into its own file (e.g. ip-fix.php) and use auto_prepend_file to fix the IP everywhere - period. The great advantage here is that this fix (while probably not the best in terms of performance) is sort of independent of the server (.htaccess requires Apache, or at least htscanner) you run and all the updates and changes you do to it.

In a nutshell, you should paste the following into a .htaccess file:

php_value auto_prepend_file /complete/path/to/ip-fix.php.

Would you trade an arm for a leg?

All three solutions are of course less than ideal because they require the customer to fix something that should be fixed on the serverside. For example, Mosso could patch the Apache to override the header, or use a webserver such as nginx etc. which does it out of the box.

According to my buddy Allen, it worked for him, and Mosso wants to roll out my work-around for all customers. (Just by the way Mosso — I'm always available for consulting! :-D)

Other providers

I do know that this is an issue with other providers as well. And while Mosso uses HTTP_X_CLUSTER_CLIENT_IP, all you need to find out is where your provider hides the real IP address, to make apply this workaround to your environment. And that's all.

Here is an idea of how to go about it:

  1. Go to http://whatismyip.com and write down your IP-Address.
  2. Create a .php file with the following contents in it, and upload it: <?php phpinfo(); ?>
  3. Open the URL of the file in your browser and look for your IP address.

In case there is no other IP-related header populated, you will need to rely on the client-side to get this IP and/or utilize captchas to defend yourself from spam. Or, of course, move providers. ;-)