Recently Jason A. Donenfeld reported a simple vulnerability in W3 Total Cache on the Full Disclosure mailing list, which was picked up by the Security Ledger website, and then posted on Slashdot. The vulnerability is a simple Apache Httpd configuration oversight — plugins often create their own folders under ./wordpress/wp-content/ without considering that directory indexing might be turned on, or that files within that folder are located under a DocumentRoot, and thus available to anyone. Some configuration files are also vulnerable in this way — the wp-config.php file, for example. During the WordPress install, it is recommended that the wp-config.php be re-located one folder above ./wordpress/, to move it out of the DocumentRoot.
I recently added some disk caching for MySQL queries, WordPress objects, PHP opcode, and PHP web pages on my server. There are several different caching techniques and applications available, and memcached seems like one of the more popular ones. Right or wrong, it appears to be the default go-to for many developers these days.
Since I’m a SysAdmin by profession (with maybe a penchant for scripting and integration), I tend to have a more “systems” oriented approach — which led me to first consider, and then choose disk caching over memcached. In this post, I’ll outline the reasons I chose disk caching, and why in most circumstances it might be superior to memcached.
Over the past few weeks I’ve been looking at different solutions to improve the speed of my WordPress websites. The first step was to mirror and redirect the static content to another server (aka Content Delivery Network or CDN). I’m currently using a DreamHost VM, but I may look into using Amazon S3 as well. This is an easy way to save bandwidth, and off-load a web server that is configured for dynamic content (larger and slower). In the case of PHP and WordPress, there are several additional options available to improve local web server performance. I’ll describe the ones I’m currently using, including their expected impact to performance and short-comings. This article deals mainly with the local Apache Httpd and PHP configuration. There are additional infrastructure solutions that can improve performance, like using Nginx servers on the front, Varnish cache servers in the middle, and Apache Httpd on the back-end (for PHP and WordPress). This post is only about optimizing the Apache Httpd back-end. If you’re considering adding a Varnish server in front of Apache Httpd, you should probably avoid caching whole pages in Apache Httpd and leave that to the Varnish servers.
I’ve been looking for ways to improve the performance of my websites — several of them using PHP (WordPress), a few using mod_perl, and all running under the same Apache Httpd web server. The first thing I did was to sync all the static content to a Virtual Machine (VM) off-site, and redirect all requests for that content to the VM. Using redirects has several advantages, that (to me) outweigh the small disadvantage that all requests for static content still come to my web server, which then responds with a permanent redirect. The upside (to using a perl based rewrite map, for example) is that any change to the static content is immediately apparent to new visitors — excluding the usual browser cache issues. ;-)
I also wrote a script to check the Apache Httpd MPM config limits (prefork, worker, and event) and issue a warning or error message if those limits were set too high for the server’s memory. Writing this script made me realize just how much more memory each process was using since adding those PHP websites. Switching from the prefork MPM to the worker or event MPMs (where each process manages multiple threads / connections instead of just one) could have been one possible solution, but using PHP in a threaded environment is highly discouraged by the PHP team.
A little while ago I had to reboot a client’s VM because the web server forked too many processes. They were making use of PHP, but the web server had not been configured for the resulting larger process size. I searched for a tool that would analyze the size of running httpd processes, and project the impact of starting the maximum number of processes allowed by MaxClients or ServerLimit, but didn’t find anything, so ended-up writing my own.
The following check_httpd_limits.pl script compares the size of running Apache httpd processes, the configured prefork/worker/event MPM limits, and the server’s available memory. The script exits with a warning or error message if the configured limits exceed the server’s available memory.
check_httpd_limits.pl does not use any 3rd-party perl modules, unless the
--save/days/max command-line options are used, in which case you will need to have the DBD::SQLite module installed. It should work on any UNIX server that provides /proc/meminfo, /proc/*/exe, /proc/*/stat, and /proc/*/statm files. You will probably have to run the script as root for it to read the /proc/*/exe symbolic links.
Sometimes I’ll work on something just to see what it looks like when it’s done. I guess this Apache rewrite might be something like that — I wanted to change the WordPress search query from
/s/value, just to make the URL look a little prettier. :) There are probably a few ways to do this, and if you’d like to share some alternatives, feel free to post a comment.
There are two parts to this problem; The first, executing a search query from an
/s/value URL, is easily addressed by a rewrite and proxy command. The second problem — how to rewrite a regular search query, but not a proxied search query — is a little tricker. I decided to add an htproxy hostname to my domain with an IP of 127.0.0.1. Then in a rewrite condition, I check for the htproxy hostname, and skip the rewrite if it’s a proxied request. The htproxy hostname must be included in the website’s Apache config as a
Content Delivery Networks (CDN) have become very popular in the past several years. They offer an easy way to save bandwidth and bring content physically closer to end-users. CDNs offer a variety of services, though pricing and features are usually tailored to larger content providers. As a smaller provider myself with only an ADSL line to host my personal websites — and as a SysAdmin who prefers to host his own content — I decided to mirror my static content, and redirect traffic as I needed. The following describes a solution to keeping all of my content local, yet mirroring the static content for faster delivery.