Woman cleaning blue wall with microfiber rag and cleaning spray.

If you’re looking to update a site in the coming year, one thing you should look at is updating the htaccess file. It’s one of the most powerful web files but it can also get overlooked. While you’re getting rid of the clutter, here are a few ways to simplify and bring this file up-to-date.

Upgrading the Redirect to HTTPS

If you’ve been running a sit for a while, redirecting all non-HTTPS traffic is an essential section of a .htaccess file.

# OK way to redirect to HTTPS
<IfModule mod_rewrite.c>
RewriteEngine On 
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ https://example.com/$1 [R,L]
</IfModule>

The problem with including the domain name is having to remember to update it every time you push from a test site or copying a site to your local machine.

Using the HOST variable as recommended by DreamHost in the version below makes it possible to set the redirect and forget it.

# Better way to redirect to HTTPS
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE] 
</IfModule>

Replacing Outdated Access Restrictions

So many tutorials out there still show instructions for Apache 2.2, evrg but Apache 2.4 uses a different (and much easier) way of restricting access and adding basic authentication.

For more technical details, see Apache’s documentation for Upgrading to 2.4 from 2.2.

The way to check which version of Apache you’re using depends on your hosting, so check your hosting provider’s help or documentation.

Restricting by IP

It’s time to replace the hard to remember directives like Order, Allow, Deny, Satisfy with the more simple “Require”.

Exclude all IPs, but allow 0.0.0.0:

# Outdated
order deny,allow
deny from all
allow from 0.0.0.0

# Updated
Require ip 0.0.0.0

Allow all IPs, but don’t allow 0.0.0.0:

# Outdated
Order allow,deny
Allow from all
Deny from 0.0.0.0

# Updated
Require not ip 0.0.0.0

Protecting the WordPress Login using Basic Authentication

The basic auth directives using “require valid-user” hasn’t changed, but there’s no need to drop a separate .htaccess file in the wp-admin folder.

If you’re feeling fancy or #complicated, you can combine RequireAll and RequireAny to add more specific conditions like IP addresses.

# Require the password AND require whitelisted IPs
AuthType Basic
AuthBasicProvider file
AuthUserFile "/path/to/myfile/.htpasswd"
AuthName "Members Area"
<RequireAll>
	Require valid-user
	<RequireAny>
		Require 0.0.0.0
		Require ip 1.1.1.1
	</RequireAny>
</RequireAll>

For example, if you want to restrict access to the WordPress admin to only whitelisted IPs, but you want to require the basic authentication password from all other IP addresses, use the example below:

# WordPress access requires the password OR the listed IP addresses.
<FilesMatch "(wp-login|xmlrpc)\.php">
	AuthType Basic
	AuthBasicProvider file
	AuthUserFile "/path/to/myfile/.htpasswd"
	AuthName "Members Area"
	<RequireAll>
		<RequireAny>
			Require valid-user
			Require ip 0.0.0.0
			Require ip 1.1.1.1
		</RequireAny>
	</RequireAll>
</FilesMatch>

Just be aware that if there is a ‘Require all granted’ statement somewhere in your file, this will override any rules here.

For example, if you use the iThemes Security plugin and basic auth no longer works, the ‘Require all granted’ that it adds in the .htaccess file is the culprit. On a side note, See this gist for a workaround: iThemes Security Banned Users Apache Fix.

Backward-Compatibility and Supporting Apache 2.2 and 2.4

For backward-compatibility, it also includes a module, mod_access_compat, so this is why the old directives aren’t breaking everything.

The problem is that mixing old directives with new ones could give you unpredictable results since the old directives take precedence over the new ones.

If you have to write .htaccess rules that have to support both Apache 2.4 and Apache 2.4, one way to solve this problem is to use a technique like this one found in the iThemes Security plugin’s Banned Host rules:

# Ban Hosts by IP Example
<IfModule mod_authz_core.c>
<RequireAll>
	Require all granted
	Require not ip 0.0.0.0
</RequireAll>
</IfModule>
<IfModule !mod_authz_core.c>
	Order allow,deny
	Allow from all
	Deny from 0.0.0.0
</IfModule>

I hope this helps. Good luck!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.