Category Archives: drupal

Infosec consultant and blogger Xavier Mertens suffered from a GET flood last week. The would-be DDOS originated from WordPress blogs that seemed non-related both geographically and content-wise, were using different versions of WordPress and seemed not to be compromised.

So what gives? WordPress blogs autonomously trying to DDOS other WordPress blogs? My best guess; a WordPress plugin gone rogue. The great WordPress HTTP API makes It easy enough to create a plugin that fetches targets from a control server and issues requests to those targets at a given time. It’s only a matter of hiding that behavior inside a plugin that seems useful and getting people to install that. The easiest way; finding an older plugin with an existing userbase and taking over development from the original developer (as i did with Autoptimize) is the easiest route to create your own little DDOS-ing botnet.

But all of this is pure speculation (although the UA matches the one used by WordPress HTTP API) off course. The only way to know for sure is to, for at least a sample of the flooding blogs, check what plugins they have in common. Doing so is frightfully easy using the NMAP HTTP WordPress Pugins script and if I am not mistaking Xavier is indeed looking into this.

But given the ease with which the NMAP-script can scan for WordPress plugins (there are similar scripts for e.g. Drupal modules), you might want to stop this from happening? I for one added this line in my WordPress .htaccess:

RedirectMatch 404 ^/wp-content/plugins/[^\/]*/$

Maybe you would even want to return a 404 for plugin readme.txt and index.html files as well, but I’ll consider that an assignment for you guys to chew over ;-)

A couple of days ago we implemented a CDN for a Drupal-based website, using MaxCDN/ NetDNA and the Drupal CDN module. We were very surprised to discover the site became … slower. It took us some time to identify the problem, but CSS turned out to be the culprit;

The supplier created separate CSS-file for each and every template using SASS, causing some automated duplication of CSS

Some of that CSS was not in the theme .info-file and wasn’t added using drupal_add_css either, but the link was hardcoded in the template-file

The CSS that was added the normal way (i.e. not hardcoded in the template) was picked up and modified by the CDN module (changing paths for e.g. images and fonts into URL’s pointing to the CDN)

CSS that was hardcoded in the template was not visible for the CDN-module, so the paths were not updated and still pointed to the origin webserver

Because of duplication of e.g. background-images and fonts, pointing at both the CDN and the origin-server, these assets were downloaded twice and the extra file-size resulted in a site that was slower with than without a CDN

Once we understood the problem, the solution was pretty simple;

clean up the CSS, avoiding to re-declare e.g. @font-face in multiple templates (resulting in a smaller CSS file download size as well)

add CSS using drupal_add_css (with the option not to aggregate, as IE8 might choke on the massive amount of CSS) for the CDN module to take that into account as well

I’ve contacted the developer (Pat’s a swell guy, really) and he answered he would look into honoring the DoNotTrack header, which he wrote he’d love to include in Q1 somewhere. In the mean time, if you have AddToAny on your site, you can already hide the Lockerz “Earn” tab. And if you’re on WordPress, you could install (or upgrade) WP DoNotTrack, which I’ve updated to stop the Lockerz tracking (make sure lockerz.com is your blacklist).

If there’s a Drupalista out there that uses AddToAny and would like to stop Lockerz tracking; I’d be happy to co-author a Drupal DoNotTrack module, do get in touch!

I attended Drupal Summit in Genk a couple of days ago and amidst the general “Drupal is the best thing since sliced bread” atmosphere, there were some interesting discussions about the platform’s maturity. Especially the presentations of Peter Van Den Broeck (for VRT) and Wouter Mertens (for competitor VMMA) seemed to be on opposite sides, with VMMA having multiple successful Drupal-sites in production and VRT struggling to get their projects finished, telling Captain Buytaert “Dries, we’re not there yet“. But underneath the surface and despite the differences (a dedicated team of sysadmins & developers at VMMA vs fixed price, project-based external development for VRT), both were talking about the same problems on a technical level; modules & performance.

The Drupal module community is a great bunch of enthusiastic developers, building an impressive number of modules that cover almost any feature one would want to have in a website. But module quality, support & compatibility varies enormously. Some modules seem to be true Rube Goldberg machines, providing tons of functionality that only few people need but which makes the the UI a usability-hell and the code complex, error-prone and possibly a real performance-hog.

And while we’re on the subject; performance doesn’t come out of the box and Drupal as such does not scale very well. Install it with a bunch of modules, generate a reasonable amount of page requests and you have a CPU-intensive system that generates a crapload of database-connections. Adding memcache between your Drupal & MySQL helps, as most requests will be handled from cache. And putting a caching reverse proxy (Varnish, Squid or even Apache’s mod_proxy+mod_cache if you insist) in front of your Drupal does miracles, serving visitors the same content without the need for Drupal to bootstrap. So sure, you can build a scalable solution that provides great performance, but one could say this is despite Drupal, not because of it. After all, when using Memcache & Varnish almost any CMS will have great performance, won’t it?

So yeah, Drupal can be a nice solution to your problem, but it does require more than just a superficial knowledge of how to install it together with some modules and a theme. Make sure there are smart people on your team or project, that have a profound knowledge of modules & module development and who know a lot about MySQL (and clustering, mirroring or master/slave setups), Memcache and Varnish (or Squid, forget about mod_cache if you can). You’re bound to run into some problems, as Peter Van Den Broeck confirmed, but with the right people and architecture your Drupal-project can indeed be the best thing since sliced bread.

Suppose you’re setting up a Drupal-based site for which you have to implement a caching reverse proxy and for reasons beyond your comprehension Varnish (or even Squid) are not an option. Oh no, you’re stuck with Apache’s mod_proxy and mod_cache! What should you do?

First of all, Drupal 6 doesn’t like reverse proxies. If you don’t want to wait for version 7, which should do better in this respect, you might want to look at Pressflow. This Drupal 6 “distro” has everything on board to work with reverse proxies. So install Pressflow (or try to apply this out of date diff to stock Drupal) and in the Performance-screen set “Caching Mode” to “External” and “Page Cache Maximum Age” to the number of minutes you consider a cached page valid. Voila, you’re done in Drupal (edit: almost, as you might also want to change the $base_url in sites/default/settings.php to reverse proxy URL after you configured Apache).

Next up: Apache! A simple configuration like this one should do the trick:

Darn, those Pressflow-guys seem to have read up on their RFC’s! And indeed, 2616 confirms that cache-control’s max-age overrules expires;

If a response includes both an Expires header and a max-age directive, the max-age directive overrides the Expires header, even if the Expires header is more restrictive. This rule allows an origin server to provide, for a given response, a longer expiration time to an HTTP/1.1 (or later) cache than to an HTTP/1.0 cache.

Mod_cache’s code seems to take a much simpler approach; at line 503 it decides not to cache based on an Expires-header in the past, totally dismissing the potential presence of cache-control’s max-age.

But you’re not interested in code which does or does not adhere to whatever RFC some spec-buffs came up with, you just want to cache your frigging’ Drupal-site! Well, fear not little hacker-boy, here’s some Apache-magic to cure your ailments, to be copy/pasted in the config before ProxyPass and ProxyPassReverse:

So there you have it, a rudimentary caching setup for Drupal (in the guise of Pressflow) using nothing but Apache’s mod_proxy and mod_cache. Now go do your homework and test and do some finetuning and test some more. Happy caching!

Update 02-2015: the information below does not reflect the way AddToAny works now and as such only has historical value. The comment by A2A’s developer below, explains what has been done between 2010 and 2015.