Site: US UK AU |
Nexcess Blog

Useful Apache Rewrite Rules

April 23, 2011 6 Comments RSS Feed

Useful Apache Rewrite Rules
Apache’s rewrite engine is very powerful and often misunderstood. It can be fairly cryptic to work with and given that a mistake can take down your site it can be costly to debug. While I’ve tested the following rules thoroughly I’d recommend testing them yourself on a non-live site prior to putting into production.

Before using the following bits of code please make sure that you have rewrites enabled by using:

RewriteEngine On

This can be put in either a .htaccess file or in your virtual hosting configuration location.

Rewrite #1 – Forcing All Traffic To The “www” Version Of Your Site

RewriteCond %{HTTP_HOST} ^ [NC]
RewriteRule ^(.*)$$1 [L,R=301]

What the above does is matches all domains (%{HTTP_HOST} Apache mod_rewrite speak) that do not look like “”. The 2nd line then forces all of that traffic to with a 301 redirect (i.e. the HTTP code for “moved permanently”). The final bit to note here is that the /$1 at the end of the redirect domain tells Apache to append any additional path information. This means URLs like will be translated to:

Rewrite #2 – Forcing All Traffic To The “https” Version Of Your Site

RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$$1

Often you have sections of your site that you want to make sure cannot be accessible via non-secure means. That is, you want to force https (i.e. SSL only) access and disallow all non https access.

The first rule above says “match only if a https connection is not detected” and the second redirects to the https version of your site. There are many variations on this and the above is the simplest if you just want to redirect to your site with https.

Rewrite #3 – Forcing All Traffic To A Single Script

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule .* index.php [L]

The above is used often when you have a single “front door” script that handles all traffic to your site. This is common in newer web applications such as Word Press and Magento. The gist of above code goes as follows – If a file doesn’t exist with the same name as the requested file *and* a directory doesn’t exist with the same name *and* a symbolic link doesn’t exist then force all of the traffic to the index.php script *without* redirecting.

Rewrite #4 – Forcing All Traffic To A New Domain

RewriteRule ^(.+)$1 [R,L]

The above just redirects all traffic to the URL regardless of any other conditions. It works well if you’re moving your account to a new host and want to make sure all traffic goes to that new location with all of the path information intact.

You’ll notice that I used [R,L] here instead of [R=301,L] as I did above. The reason is because, by default, if you don’t specify the HTTP 3 digit status code it defaults to ‘302’. A 302 redirect means “moved temporarily” which is more desirable here since you’re just forcing traffic to a new location for a short duration (while DNS updates perhaps). The 302 tells Google and other apps that care that this is a temporary change while a 301 would denote that this is a permanent change.

A full list of HTTP status codes for redirection are available on Wikipedia List of HTTP status codes – 3xx Redirection

Rewrite #5 – Forcing All Foreign Traffic To Another Location

RewriteCond %{REMOTE_ADDR} !
RewriteRule .* [L]

Often we have clients that want to block a single IP from accessing their site (in this case IP We can do this via a variety of means but of the easiest for the client themselves to control is using rewrites to either deflect or block the traffic.

Another scenerio where this is useful is where you want to only allow your IP to see your site. This most commonly occurs during an upgrade where you have all foreign IPs redirected to single page (like a maintenance page) while you browse the site without obstruction.

Hope you find these useful!

Posted in: Linux