WordPress 3 Security: Apache Modules


WordPress 3 Ultimate Security

WordPress 3 Ultimate Security

Protect your WordPress site and its network

        Read more about this book      

(For more resources on WordPress, see here.)

IP deny with mod_access

Apache offers a sure-fire way to lock down admin, care of the mod_access module.

Similar to cPanel's IP Deny Manager, the greater flexibility of hand-coding empowers us to allow or deny all but specified IP addresses, domains, hosts, and networks.

For now, we'll prevent access to the wp-admin directory pages for all IPs except yours.

Open an htaccess file in your wp-admin directory via your control panel or the terminal:

nano /path/to/WP-root/wp-admin/.htaccess

Add these lines, swapping the IP for yours:

order deny,allow
deny from all
allow from

Need access from more IPs? Just add more alongside the first one, single space separated.

But. If your IP address is dynamic, which very often it is, you may find this method a little too effective. If you do become locked out, cruise server-side to switch the IP.

What is my IP?

That old chestnut:

IP spoofing

A chestnut gone bad, denying alone won't protect against man-in-the-middle attacks, so if you got this farthinking that you could have avoided all the SSL stuff after all, no, you were right to do that.

No safeguard is a silver bullet. Deny syntax sure helps though, if you're not on the move.


Password protect directories

Password protection is a way to give access to a directory and its sub-tree to a selected few people and may be used, typically:

  • To house private files to which you need access from anywhere
  • By developers fine-tuning a new blog theme
  • For a client zone on a commercial site
  • As an extra layer of protection to, say, wp-login or phpMyAdmin

The procedure is to choose a directory, granting access to specified users. These privileged directory users are separate from, and should not be confused with, your server or WordPress users, the control being governed by Apache rather than by Linux or your WordPress database. That's a good thing, adding an independent tier of protection.

cPanel's Password Protect Directories

There are various ways to secure a directory, so let's start off with the regular control panel option, which in cPanel, is called Password Protect Directories:

  1. Browse to the target directory in File Manager, right-clicking and choosing Password Protect (or click through the panel icon if you like).
  2. Select the checkbox and give the directory a name to appear on the authentication screen.
  3. Save and you are redirected to a confirmation page.
  4. Click back to the previous page and add a username and password to access the folder.
  5. Save the newly authorized user.

Now you can surf to that folder or some file within, are asked for credentials, and can log in.

So what did we really just do there? Clicked on some shiny icons, added some details, and cPanel interacted a bit over far too many pages. Let's get geeky, it's worth it.


Authentication with mod_auth

When we protect a folder, cPanel uses Apache's mod_auth module to amend or create two hidden files, htaccess and passwd. htaccess lives in the folder to protect and passwd lives safely above the web root in the hush-hush htpasswd directory.

Using an example file, we can compare our control panel actions with those using the terminal, interacting directly with mod_auth. Cue screenshots, using cPanel we did this:

WordPress 3.0 Ultimate Security

And mod_auth creates the ruleset in the htaccess file, which we equally could just type:

AuthType Basic
AuthName "Protect me pretty please"
AuthUserFile "/home/USERNAME/.htpasswds/public_html/protectme/passwd"
Require valid-user

Then we did this:

WordPress 3.0 Ultimate Security

And mod_auth yawns a bit while it adds credentials to a password file:


(John's password is encrypted, server-side, but he logs in using the plaintext hackth!s.)

Now then. Two points. First, with the syntax learnt or duplicated, it's quicker to bin the middleman and just use the shell. More importantly, by directly chatting up Apache, we have a better array of security tools. To clarify, let's take this a step at a time.

The htaccess file

Before we look at the mod_auth syntax that goes in htaccess files, a quick aside ...

A quick shout out to htaccess, bless

We've met the hidden htaccess file already. It's essentially a convenient and versatile web configuration file that can be added to multiple directories.

The directives these files contain can equally be placed in other types of files such as those for our virtual hosts (which is tidier, all those directives from htaccess files being in one place). Uniquely, however, rules added in htaccess can be parsed immediately, or in other words, without the need to restart Apache. Feel the power!

One other thing about htaccess: you don't need root access to add or edit these files. Listen up, shared hosting people, this is very convenient because you don't have root access (to hack into your co-sharers directories!) to those configuration files, but you do have access to your own jailed (or chroot-ed) web files. And because htaccess files live with your files, you can tweak them at will.

Now back to using htaccess to store that mod_auth syntax ...

In this case, for any directory you want to protect, just add or append an htaccess file with your tailored mod_auth directives. Here's a closer look at the mod_auth syntax, beginning with its type:

AuthType Basic

Pretty basic then and more on that later. For when we navigate to the login page we want some kind of instructional message:

AuthName "Protect me pretty please"

Now the link to the directory's corresponding password file:

AuthUserFile "/home/USERNAME/.htpasswds/public_html/DIRECTORY-TOPROTECT/

And we'll specify to give access only to users recorded in the password file:

Require valid-user

So far so good. Carry on.

The passwd file

Often referred to as the htpasswd file, here's the syntax it houses:


johndoe is the authorized, or required user. L9c7m/hO16slA is the encrypted form of hackth!s , his password. We use a handy tool, also called htpasswd, to encrypt that.

Add as many usernames and passwords as you like to this file, each on a new line.

The file itself can live and be called whatever you like as long as the AuthUserFile directive corresponds. One thing though: the file should be located above your web root.



        Read more about this book      

(For more resources on WordPress, see here.)

Creating and editing password files

For terminal types with root access, creating a password file involves a simple command:

htpasswd -c ~/.passwd mary-beth

Let's break that down:

  • htpasswd is the programme doing the work
  • -c is the option to create a new file or overwrite an existing one (Easy tiger!)
  • ~/ is the equivalent of saying /home/USERNAME, importantly placing the file above your web root (just to reiterate that point)
  • . denotes the file to be hidden
  • passwd is the name of our new hidden password file
  • mary-beth is our user with a very pretty name

Having executed the command, you are prompted to enter and confirm a password for Mary-Beth. Were you to submit hackth!s, upon opening the file, you would see:


Now, say you want to add someone else. Just drop the -c option and make sure you do, otherwise you will overwrite the existing file:

htpasswd ~/.htpasswd someoneelse

And giving a password when prompted, someone else is listed too:


If you don't have root privileges, you can't use the htpasswd tool. Instead, you can create a password at a website with an embedded tool. Just Google htpasswd generator, and duly generated, paste the result into a htpasswd file, linked from the htaccess file.

Now, you may be wondering, what really is the advantage of editing files manually, because so far, the only saving is a few cPanel page loads. Fair point. Read on.

Creating group membership

Let's say you have a few users requiring access to various directories. For example, you may have several client zones. You need access to each, but want to allow clients to access only their files. Other people need access to some, but not to all of these places.

Using the control panel, again we would choose to password protect a particular directory, this time adding privileged users. We would laboriously create users, often the same ones and have to remember their passwords each time, for each directory. Behind the scenes, there are individual htaccesss files for each directory to protect, each calling a separate password file.

Similarly using the command line, we could have separate password files for each zone, but as we may surmise, this is a bit long-winded.

More efficient is to use an online generator, manually creating the file, else using the htpasswd tool to create a single password file in our home directory. This should be cross-referenced by a manually created group file, the two files being called by each protected directory's htaccess file. Sounds complex? It isn't. Here's the controlling htaccess ruleset:

AuthType Basic
AuthName "Welcome to the Whatnot Client Zone"
AuthUserFile "~/.htpasswd"
AuthGroupFile "~/.htgroup"
require group whatnot

The fundamentals are the same, except that now we are allowing access only to users within the single password file that are cross-referenced from the group whatnot, which is listed in the single groups file, htgroup. The htpassword file is familiar to us already:


And the group file looks like this, one group per line designating authorized users:

top-secret: mary-beth
whatnot: mary-beth dodgygeezer grafixsimon
someclient: mary-beth anna-web-guru grafixsimon

So we have added three groups manually, each with their own members whose credentials are cross-referenced from the password file.

Want another protected directory, and maybe another group? Simply add the htaccess referencing the group and add the group and its members to the groups file. If any users are new then add them to the password file.

So, whereas via the CP, we have password files for each directory, often duplicating users and their passwords, now we have a single password file to correspond with a single groups file. Much tidier.

But still, we have not arrived at the crux of why this manual editing is better. Trust me.

Basically, it's basic

The thing is, mod_auth's basic protection isn't ultimately, well, all that protective.

Basic encryption churns up passwords on the server, but sends them in plaintext, not only when first logging in, but with every subsequent request, and as such, is especially vulnerable to packet sniffing. Well-versed hackers may tell you this is about as safe as a Bernie Madoff investment plan.

Used with SSL, yes, the session sniffing problem is put to rest. Other issues remain though, such as if your server is compromised via creaky code. Given that scenario, the mod_auth security worry shifts to its weak key encryption. Basically, it lacks teeth.

What we have gained, however, is an overview of mod_auth and its related files that can be taken to more advanced, syntactically similar modules. We'll pass on a couple of these, instead consuming the ripe pick of Apache's key-bearing crop, mod_auth_digest.


Better passwords with mod_auth_digest

mod_auth_digest is less popular than its ailing older brother, mod_auth. That's because, as with other more advanced Apache password modules, it is not a cPanel option. This is a shame, or is that a sham?

Decent hosts do have the module enabled and available via terminal access.

So what is the difference? Digest is far more secure. The scoop is that passwords remain puzzled in transit and encryption is nasty. Compare a basic-encrypted password ...


... to that of auth_digest ...


'Nuff said.

One small caveat. Some senile browsers, including IE6, won't support it, at least without workarounds. Nowadays this is barely an issue but here's the spiel:

Let's set it up.

Those with a VPS or dedicated box will need to enable the module and restart Apache:

sudo a2enmod auth_digest
apache2ctl restart

Its use is strikingly similar to that of mod_auth. To create a password file, we do this:

htdigest -c ~/.htdigest_pw realm user
  • htdigest is the password creation tool, using MD5 encryption
  • -c is the option to create a new file or overwrite an existing one, so again be careful to drop this if you want to add a user without binning the file
  • ~/ is the equivalent of saying /home/USERNAME
  • . denotes the file to be hidden
  • htdigest_pw is the name of our new hidden password file
  • realm is a new variable here, but is actually the same as basic's AuthName.
  • user is the user to whom you wish to give access

So to create a new digest password file with a user called bobcat and a realm of Private:

htdigest -c ~/.htdigest_pw "Private Page" bobcat

Note that we have added quotes around the realm because there is more than one word. The password file looks like this:

bobcat:Private Page:21e0ac18dee801866e7deb7b9f4f4c61

So there are three sections rather than two, the middle one containing the realm name and each separated by a colon.

Fortunately again, the syntax for the accompanying ruleset is familiar and can be placed, for instance, in the htaccess file:

AuthType Digest
AuthName "Private Page"
AuthDigestFile /home/USERNAME/.htdigest_pw
Require user bobcat

Easily digestible groups

As with Basic, adding groups with Digest requires manually creating the file so, here for example, we'll echo a group with two members to a new file:

echo "admin: mary-beth bobcat" >> ~/.htdigest_groups

The ruleset for their group, accommodating the new variable, must be changed to this:

AuthType Digest
AuthName "Private Page"
AuthDigestFile /home/USERNAME/.htdigest_pw
AuthDigestGroupFile /home/USERNAME/.htdigest_groups
Require group admin

The directive AuthDigestGroupFile points to the groups file and that of Require now says that only the admin and group users are privileged.

That's it. Very, very similar to using regular, basic mod_auth, so if you aren't clear on anything, claw back to that section because the theory is the same.


More authentication methods

Apache's modular framework makes it easy to add or remove tools and a choice of modules can often be found to perform any given task.

Password protection is an area with a legion of choices. We have covered mod_auth because it is the basis of Apache authentication, easily used, and the simplest to understand, making a good introduction to its next of kin authentication modules. We have covered mod_auth_digest because it provides better security and is arguably best of breed for most of us. There are more.

Short of devoting this entire tome to further authentication modules, which by and large, work the same way as mod_auth and mod_auth_digest, it would, nonetheless, be amiss not to mention a few of them.

mod_auth_db and mod_auth_dbm

Two very similar authentication modules, db and dbm differ from auth and digest by storing passwords in database files (db and dbm files), rather than a regular text file. This has a great benefit: speed of data retrieval. If you have thousands of users and passwords, rather than Apache having to sift through one line at a time, this is an option to explore.


Another database-driven authentication system, auth_mysql is a trifle trickier to set up as it involves creating a basic MySQL database. Then again, our WordPress databases are infinitely more complex, so there's no real excuse there.

Again the syntax is very similar to the above systems. The exception is that this record must stipulate database details to make a connection:

AuthName "Should You Be Here, I Mean, Reeeaaally?"
AuthType Basic
AuthMySQLEnable On
AuthMySQLHost localhost
AuthMySQLUser someUser
AuthMySQLPassword prettyPassword
AuthMySQLDB dbName
AuthMySQLUserTable userTableName
AuthMySQLNameField userNameField
AuthMySQLPasswordField userPasswordField
AuthMySQLPwEncryption md5
AuthMySQLAuthoritative On
require valid-user

For those with thousands of users to data-crunch—and bearing in mind we know and love MySQL already and perhaps use phpMyAdmin too—mod_auth_mysql is the way to go.


Quick note for those oh-so-special types for whom MySQL just doesn't quite cut the mustard, instead having defected to PostgreSQL: rather than mod_auth_mysql, use mod_auth_pg95. Again, similar syntax et cetera-ra-ra-de-ra.


Yet more authentication methods

Yes, there are, but they require additional servers to run, and besides, aren't you getting just a tad bored of this section?

Best advice: Digest for most of us and MySQL for empires.


In this article we saw how to fill some gaps by restricting access and protecting specific web directories.

Further resources on this subject:

You've been reading an excerpt of:

WordPress 3 Ultimate Security

Explore Title