Using Mod Rewrite & Other htaccess Related Tips
This tutorial/tips list is going to look at some of the extremely useful things your htaccess file can be used for. From Mod Rewrite & Mod Security to altering your PHP.ini on the fly the possibilities are pretty much endless, so to help out here are some of the ones I use myself & have found to be the most useful.
Mod Rewrite
Some find the syntax very, very difficult to learn (me included), but Mod Rewrite is extremely useful for various things. The most useful usage I have come across is to redirect people to a nice maintenance page when you need to do some maintenance to your website. I even use this one myself for the very rare occasions I have to close the site for technical reasons.
Redirecting To A Maintenance Page
1 2 3 4 5 |
<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REMOTE_ADDR} !^000.000.000.000$ RewriteRule !^maintenance/.*$ /maintenance/ [R,L] </IfModule> |
Replace the 000.000.000.000
with your current IP address, make a folder in the root of your website called ‘maintenance’, put a html or php file called index
in there with a message on and you are done. Entering your IP address will allow you into your website (so you can perform the maintenance) while redirecting everyone else. When you have finished your maintenance just comment the code out & you can use it again at any time. To comment it out just do this:
1 2 3 4 5 6 |
# Remove hash to uncomment and go into maintenance mode #<IfModule mod_rewrite.c> # RewriteEngine On # RewriteCond %{REMOTE_ADDR} !^000.000.000.000$ # RewriteRule !^maintenance/.*$ /maintenance/ [R,L] #</IfModule> |
You can even add a comment like I have to remind you what the code does.
Blocking An IP
It’s sad, but sometimes a user of an IP address decides to abuse your website and cause you a lot of problems. What can you do? Well you can use the powerful Mod Rewrite to block an IP address. Rather than blocking it it actually just tells your server to send it somewhere else. I wouldn’t advise using this method, but it can be useful for other reasons. I’ll cover a more advisable way of blocking IP’s later.
1 2 3 4 5 |
<IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{REMOTE_ADDR} ^000.000.000.000$ RewriteRule ^(.*)$ http://google.com [R=302,L] </IfModule> |
That will redirect the IP you enter in place of 000.000.000.000
to Google. However, as I said before, I wouldn’t advise using it.
Other Uses For htaccess
There are other things you can do in your htaccess file. One of the most common is to stop index listing. You know the white screen you sometimes see that lists all the files in a directory. That can be a huge security violation. So here is the easy way to stop it:
1 |
Options -Indexes |
Some hosts automatically turn it off, but it doesn’t hurt to make sure.
Blocking An IP Address Revisit
I showed before how to block, well actually more redirect, an IP address that is abusing your site. Well here is how to actually block one:
1 2 3 4 5 6 |
<limit GET POST> order allow,Deny Deny from 000.000.000.000 Deny from 000.000.000.000 allow from all </Limit> |
You can list as many as you want, or if you replace a set of numbers with an asterisk (*) you can block a range of IP addresses. IP addresses that are blocked in this way will receive a HTTP 403 forbidden. To let those IP’s you have blocked know that they’ve been blocked you might want to use the following tip too.
Custom HTTP Error Pages
As I said to let those pesky IP addresses know you have blocked them for abuse, you can use a custom 403 error page. They work on a large number of hosts which have support for Mod Rewrite enabled, but you will need to check. To see if it works just place the code in your htaccess file & refresh, if you get a 500 error then your host probably doesn’t support them. It’s really simple:
1 |
ErrorDocument 403 /403.html |
Just replace the /403.html
with the path, from root, that you want the error to load. You can use it for any HTTP error code. Just replace the 403 with another, like 500, or even 404.
I hope this look at some of my favorite Mod Rewrite & htaccess related tips has helped you. If you have any questions let me know, or you can follow me on Twitter by clicking the big blue birds in the sidebar.
6 Comments
Marco Longoni
Dear Mr Robinson,
i’ve been googling to your blog as i was looking for the way to achieve the following goal.
I would like any 403 forbidden on my vhost based apache setup to be rewritten as a 404 not found error.
I can already do that with such a rule for a specific path (two rows with and without / 🙂
RewriteRule ^/WebSite/img$ /error/404_403.php
RewriteRule ^/WebSite/img/$ /error/404_403.php
Where /error/404_403.php is purposely a non-existant file.
What i want to achive is one global rule that leads to the same result.
Please note that is not enough to serve custom (existant) error pages, let’s say equal for a 403 and a 404 error, such as:
ErrorDocument 403 /error/existing_404_403.php
ErrorDocument 404 /error/existing_404_403.php
as with the appropriate curl flags (and with many other tools) a remote attacker would still be able to guess the filesystem structure (403=file exists)
Here you can see a curl of such a configuration:
< HTTP/1.1 403 Forbidden
< Date: Thu, 04 Nov 2010 14:42:52 GMT
< Server: Apache/2.2.8 (CentOS)
< X-Powered-By: PHP/5.2.10
< Content-Length: 202
< Connection: close
< Content-Type: text/html; charset=ISO-8859-1
<
404 Not Found
Not Found
The requested URL was not found on this server.
Please consider that in a 50 vhost setup, it would be very very difficult to perform such and hardening on a per/folder basis!
Thanks in advance and best regards
Marco Longoni
Paul Robinson
Hi Marco,
Please remember I’m not an expert on htaccess, I’m still learning myself. I’ll try my best to help you out though.
As far as I can tell (using the web & a few mod rewrite books I have) you can fake a 404 using
Redirect
andRedirectMatch
. However because they are rewrite rules if you add them globally (to your httpd file) any rewrite rules inside one of your virtual hosts will auto override them.I’ve tested it on my local VHosts server I use for testing websites before deployment and while using the
RedirectMatch
does have the desired 404 over 403 effect, the rewrite rules I have set up in one of the VHosts for CodeIgniter instantly overrides theRedirectMatch
.I noticed you posted on a few other sites, hopefully they might have a way round that problem, but I’m afraid that’s as far as I’ve been able to get on the problem. Sorry.
Marco Longoni
Thanks a lot for your quick reply, and for your interest in my post. There’s very few (almost nothing) about that in the Web.
This is really a particular request from my customer, as even in the PCI-DSS there is no mention about that fs structure guessing.
There are people kidding me on forums, they want to know if i got Top Secret stuff in my webserver…
Anyhow, achieving the goal with a per-vhost rule will be better than my actual situation (achieving the goal with a per-subfolder rule).
Will you please post the sample rule you used to make your tests?
Then, i’ll just have to solve eventual issues on vhosts that already have rewrite rules configured.
In a pre-production environment, you can also do such:
instruct the developers that they’ll have to use a leading dot for any resource that the remote user shouldn’t be able to access directly, such as the img folder folder for instance.
if they name all the “protected” resources with a leading ., then the sysadmin can handle it that way:
RedirectMatch 404 “.*\/\..*”
The problem is that here i’m in a production environment, with almost 50 vhost based sites configured, and i can’t ask the developers to remap any linked resource to a new path!
Anyway, for people setting up a brand new web server, the rule above will do the trick *PERFECTLY*.
Thanks a lot again Mr. Robinson for your precious help!
ML
Paul Robinson
This worked sparadically for me. It’s hopefully something you can work from though. If you can enable rewrite logging it may help you out. I would to check out the problems, but for some reason it won’t output any logs? I should really reinstall my local server. 😆
It basically checks to see if the requested file actually exists. If it doesn’t ‘!-f’ it passes through to the
RewriteMatch
if it does exist it does nothing.I hope that helps you in some way. Sorry I haven’t been able to help much further.
Marco Longoni
Thank you very much, keep up the good work!
ML
Paul Robinson
No problem.
Hope you get everything working well.