Dynamically protect wp-login.php across multiple domains with htpasswd

Some pages, such as wp-login.php, are often the target of brute force attempts. Each failed login attempt requires a database search so even if all of your users have a strong password, constant brute forcing can still have a detrimental effect on the server.

One workaround is to add another login prompt before the wp-login.php page using htpasswd as this is processed without a database hit. Generally the advice is to do this with each site’s .htaccess, but this is cumbersome and relies on a lot of duplicated code if there are many sites. Also, maybe you want some of the sites to share a password file, but not all of them.

The following instructions show how to use the Apache 2.4+ configuration to achieve the same functionality for every wp-login.php file (note that this is a regular expression, so dummy-wp-login.php.old would also be protected).

The instructions assume Debian, but as long as the conf-enabled folder exists and is included before the vhost configuration in the main apache.conf or httpd.conf file, this should work. Also this will only work with Apache 2.4 and not Apache 2.2 or earlier.

Firstly create your htpasswd file:

htpasswd -c /etc/apache2/htpasswd your-user

Next, create /etc/apache2/conf-available/htpasswd.conf with the following content (modified to suit your needs):

<FilesMatch wp-login.php>
    <If "%{HTTP_HOST} =~ /protecteddomain\.com/">
        AuthType Basic
        AuthName "Authentication Required"
        AuthUserfile /etc/apache2/htpasswd
        require valid-user
    </If>
    <If "%{HTTP_HOST} =~ /\.onlysubdomains\.com/">
        AuthType Basic
        AuthName "Authentication Required"
        AuthUserfile /etc/apache2/htpasswd
        require valid-user
    </If>
</FilesMatch>

Next load in the configuration:

ln -s /etc/apache2/conf-available/htpasswd.conf /etc/apache2/conf-enabled/htpasswd.conf

Double check there are no syntax errors:
apache2ctl configtest

Reload Apache:
apache2ctl reload

The above configuration is flexible and could also be used to IP restrict.