Controlling the majority of aspects related to the Apache webserver and its variants requires the utilization of the .htaccess file. In this guide, you will learn how to set up special error pages, redirects, password-protect directories, and other related aspects.
How to Use This Guide
This guide aims to bring you an exhaustive resource for utilizing the functionalities of .htaccess. If you are a complete novice to using .htaccess, starting with the “.htaccess Basics” below in the first chapter will help you learn better as a beginner.
On the other hand, if you are already aware of the subject and looking for tutorials or certain code samples, you can directly access the sub-section relevant to the topic you are searching for.
.htaccess Basics
Let us discuss some of the fundamental concepts related to .htaccess before learning different commands.
What Is The Meaning Of .htaccess?
A configuration file controls the responses of a server to different requests which we call .htaccess. A lot of web servers are compatible with the .htaccess file, including the Apache server that is used by many web hosts.
All .htaccess files work at the directory level and can override the configuration settings, at a global level, of all those .htaccess directives that have a place above them in the main directory tree.
How To Use .htaccess?
.htaccess is commonly used for securing websites or web pages by enabling password protection, redirecting URLs, boosting SEO using trailing slashes for URLs, and building custom error pages like the 404 error page.
For the SEO aspect, the webmaster chooses either to use or avoid using a trailing slash at the end of website URLs. Maintaining consistency in the use of trailing slashes helps boost SEO.
From where does the name .htaccess originate?
.htaccess is an abbreviation that expands to “HyperText Access”. The tool was originally utilized for controlling the access of users to the desired files on each directory, which led to this name.
A system administrator becomes capable of restricting access to the desired directories by using the httpd.conf settings of Apache via .htaccess. The administrator can specify the names and passwords of directory users in a corresponding .htpasswd file.
This was only the initial use of .htaccess files and today they are used for many other purposes too along with this initial functionality. We’ll cover these additional functions of .htaccess files in this detailed guide.
Where Is the .htaccess File?
Each folder of the server, theoretically, might have one .htaccess file. But, usually, you will find one .htaccess file in the folder carrying all of your website content i.e the root folder of your server. Such a folder is either labelled as www. or public_html.
When your website has multiple subdirectories under one directory, the .htaccess file usually lies in each of the subdirectories and also the root directory. The subdirectories are generally labeled as /sitename.
Why Am I Unable To Find .htaccess File?
There are “hidden files” in many file systems. Such files have a dot ( .
) at the beginning of their names and are generally hidden under the default settings.
However, you can find these hidden files easily by looking for an option of “show hidden files” in your File Manager or FTP client. This option sits at different places depending on the program you are using. You can find it under “Settings”, “Preferences”, “Folder Options” or “View”.
What If My Website Does Not Have a .htaccess File?
You must first ensure that you do not have a .htaccess
file by turning on the “show hidden files” option. Generally, these files are automatically created, so there are high chances that you might have one. However, in some cases, this might not be true.
You can create a .htaccess file by following these steps if you do not have one:
- Open the “plain text” editor for creating a new file.
- Save this newly created file in the
ASCII
format as .htaccess. While doing so, ensure that there aren’t any file extensions like.htaccess.txt
and similar. - Now upload this newly created .htaccess file to the desired directory via File Manager or FTP.
Error Handling
Error handling is among the easiest tasks that can be achieved by specifying error documents using different .htaccess
files.
What Is an Error Code?
A server will try responding to every request it receives. When the request comes from HTML pages, a document is delivered in response. On the other hand, when the request comes from a Content Management System or any other application, the webserver accesses the app and returns the output.
If the webserver is unable to respond to a request, an error gets generated. Individual error codes have been allotted to different kinds of errors. You must have encountered 404 errors online which are returned when the server is unable to find the document.
Apart from that, a server can return other numerous error codes, some of which are listed hereunder:
Server Errors
- 500 — Internal Server Error
- 501 — Not Implemented
- 502 — Bad Gateway
- 503 — Service Unavailable
- 504 — Gateway Timeout
- 505 — HTTP Version Not Supported.
Client Request Errors with their definitions
- 400 — Bad Request
- 401 — Authorization Required
- 402 — Payment Required (not used yet)
- 403 — Forbidden
- 404 — Not Found
- 405 — Method Not Allowed
- 406 — Not Acceptable (encoding)
- 407 — Proxy Authentication Required
- 408 — Request Timed Out
- 409 — Conflicting Request
- 410 — Gone
- 411 — Content Length Required
- 412 — Precondition Failed
- 413 — Request Entity Too Long
- 414 — Request URI Too Long
- 415 — Unsupported Media Type.
Default or Generic Error Handling
When it is not specified how to handle a specific error type, the server returns a default message and the browser then shows a generic message for all the unspecified errors. So, it is best to specify different errors.
How To Specify Error Documents?
You can handle errors by generating HTML documents for the error codes you wish to manage. To make them easier to remember, consider naming these HTML documents as to what these errors denote. For instance, name the document related to the 404 error as 404.html
or not-found.html
.
Once you are done with the HTML document generation part, specify the ones that the server should use corresponding to different kinds of errors. For instance, in a .htaccess
file, such specifications will look like this:
ErrorDocument 400 /errors/400.html
ErrorDocument 401 /errors/401.html
ErrorDocument 403 /errors/403.html
ErrorDocument 404 /errors/404.html
ErrorDocument 500 /errors/500.html
You must have noticed that a single directive occupies a single line to keep it simple. That’s it, you have learned it all.
.htaccess Alternatives For Handling Errors
Most web applications, WordPress, Drupal, and other CMS have their unique methods to handle these codes.
Password-Protecting Files Via .htaccess
.htaccess files were first created only to put restrictions on accessing some, or the other directories based on a specific user (thus got hypertext access as its name). Let us understand that part first:
.htpasswd
All the usernames with their respective passwords for their corresponding .htaccess
data are saved in a separate file named .htpasswd
Every single line has each one of it in the following form:
username:encryptedpassword
Say, for instance:
willyjones:R209sUY0j3rTW
That being said, the password that is stored in the respective file does not happen to be the real password needed for logging in. But it is what is called any password’s cryptographic hash.
To make it simpler, it is just encryption of a real password obtained by running the actual password through the encryption algorithm. The resultant password obtained is, thus, stored. While logging in every time, the user enters a password in the plain text which is churned through that encryption algorithm. The passwords tally when the plain-text input is correct, allowing the user to access the files.
This is termed as the more secure way of storing passwords; the reason being, for anyone attempting to break into your .htpasswd
data file, all they would get is a hashed password instead of the original one. And it is impossible to obtain the original password by using the hash one as the encryption works only one way- from original to hash.
There are many hashing algorithms for securing the passwords:
Secure hashing algorithms – It is advised to use any of the following
- bcrypt- Though painstakingly slow for hashing, it is the best option for security. It is backed by Nginx and Apache.
- md5- Apache uses this one as the default algorithm for hashing passwords currently. Nginx does not back it.
Insecure hashing algorithms- It is advised not to use the following ones:
- crypt()- It cannot be called a secure algorithm as it uses a default hashing rule.
- SHA along with Salted SHA are both termed as insecure.
Creating Passwords and Usernames over Command Line
With an SSH terminal or Command-Line, one can directly create a .htpasswd
file. Pair it up with their respective username and passwords easily.
The .htpasswd
data file can be made by using a simple command htpasswd
.
Use this command over the -c (create)
option for creating a brand new .htpasswd
file. The next step is to type the directory path. The path should not be the URL but the server’s actual path.
It also lets you add a user if you wish to.
> htpasswd -c /usr/local/etc/.htpasswd willyjones
A new file would, then, be created in the /etc/
directory with a record of the user ‘willyjones’. A prompt will, then, require you to add a password, and this password will be recorded with the encryption md5.
When a .htpasswd
file already exists at a specified location, you will not be able to create a new file. However, it will be added to the already existing file under a new user name.
If you wish to utilize the bcrypt algorithm instead of the md5 hashing algorithm, swap the –c
option with –b
option.
Hashing password without using Command Line
In case, you do not have access to an SSH terminal, command line, or are uncomfortable using it, create a .htpasswd
data file and fill it with the help of a simple text editor. Then simply upload it with a file manager or FTP.
But having taken that route, you would have to encrypt all the passwords yourself as, otherwise, a htpasswd
command has been doing that job for you.
For encrypting your password, use one of the many .htpasswrd
encrypting utilities accessible online. However, the best one happens to be the htpasswd
generator available at Aspirine.org here.
It offers you multiple options to set password strength and choose hashing algorithm. Simply copying the output generated and pasting it to the .htpasswd
data file would help.
Where to store the .htpasswd data file?
There is no need to keep individual .htpasswd
data files for all the corresponding .htaccess
files. The truth is that you should avoid doing it at all. Normally, you should keep just a single file for your main server directory or the entire hosting account.
Also, a .htpasswd
data file shall never be stored in a directory that can be accessed publicly. In other words, it should not be in www
or public_html
or a subdirectory. Rather it shall always be in a folder above any of these that can be accessed only from the main server.
Using .htpasswd over .htaccess
Every directory can be associated with a unique .htaccess
file of its own and a user group that has access to it.
Any of the users, including the ones that are not logging in, have default access to this directory plus all its files.
To restrict any user’s access to the .htaccess
file, the following code can be used:
AuthUserFile /usr/local/etc/.htpasswd AuthName "Name of Secure Area" AuthType Basicrequire valid-user
The file name and the path where the list of your passwords and usernames are stored create the first line. The next line mentions the name for the new secured area. You can fill any secure path here. The next line has an authentication type; ‘Basic’.
The
tag in the fourth line specifies the restrictions being added. Here, the access to POST or GET any file from the said directory is being shown. And within the
tag, a user list for allowing access to the files is added.
To sum up the above scenario, any user that has been added to the directory can access the files. In case you wish to stop or restrict one or a few users, add the specific name/names:
AuthUserFile /usr/local/etc/.htpasswd AuthName "Name of Secure Area" AuthType Basicrequire user willyjones require user jamessmith
Another way to grant access is to group all the users and grant access to the group. Add a file that mentions the group/groups and their respective users to exercise this option.
You can also name this group file .htgroups
which looks like this:
admin: willyjones jamessmith staff: jamessmith tinacorden
The next step is to add them to the .htaccess datafile:
AuthUserFile /usr/local/etc/.htpasswd AuthGroupFile /usr/local/etc/.htgroup AuthName "Admin Area" AuthType Basicrequire group admin
.htpasswd file alternatives
Restricting access to specific files on the main server using .htpasswd
and .htaccess
is feasible only when you have got multiple files that are, static. The necessity to have this feature can be traced back to the times when websites were nothing but a bunch of HTML pages and other such resources.
Today, the process of restricting and granting access to files has become easier with CMS or Content Management Systems like Drupal or WordPress. If you are one of the users of CMS, simply utilize the special in-built features meant to do the task easily.
How To Enable Server Side Includes?
Let us find out the meaning and usage of Server Side Includes.
The Meaning Of SSI
Server Side Includes or SSI is a scripting language that helps in embedding HTML documents or common codes to other documents. SSI allows the reuse of common elements like menus, sidebars, headers, and footers. Content Management Systems and website templates that we use today can be thought to have originated from SSI.
<!-- include virtual="header.shtml" -->
Variables and conditional directives like else
, if
, etc. are also a part of SSI. This aspect makes it a fully complete scripting language but at the same time makes it tougher. So a developer will certainly go for a robust and easier language like Perl or PHP if a project involves quite a large number of “Includes”.
How to Enable SSI?
In some cases, SSI is default-enabled by a web hosting server while this might not be true at all times. So, it can be enabled through the .htaccess
file in this manner:
AddType text/html .shtml
AddHandler server-parsed .shtml
Options Indexes FollowSymLinks Includes
SSI for files with the extension .shtml will be enabled by the above code.
Enabling SSI Over The .html
Files
The following directive can be added when enabling SSI on your .html
datafiles:
AddHandler server-parsed .html
This above-mentioned code will parse the HTML files thereby allowing you to utilize SSI and its features, without the world knowing its usage. Additionally, it provides you with the benefit of keeping the HTML data file extensions even if you alter any implementations later.
But this general parsing of all your HTML files also has a major disadvantage. It will lead to unnecessary server overhead which, in turn, will consume CPU resources and negatively impact your page load times as well. So it is advised not to parse all your HTML files when it is not needed.
SSI On The Home Page
.htaccess
file can help you use SSI only on the website’s home page when you decide against parsing all the HTML files.
By default, the webserver looks for the index.html
file when finding your home page. So if you choose not to parse any HTML files, consider naming your home page as index.shtml
so that SSI functions properly.
You will have to add the following code to achieve do that and let your server know where to find your home page:
DirectoryIndex index.shtml index.html
The above code informs the server that your main index file is index.shtml
while index.html
can be used only as a backup when the primary file is inaccessible.
IP Whitelisting and IP Blacklisting
.htaccess
can be used to restrict user access to your server. Such restrictions can be of two types:
- IP Blacklisting
- IP Whitelisting
Let us understand their meanings before knowing how to attempt the restrictions.
How to perform IP Blacklisting?
The following code will help you block the desired IP addresses. Don’t forget to replace the IP addresses with the ones you want to blacklist:
order allow,deny
deny from 192.168.3.4
deny from 789.56.4.90
allow from all
In the above code, the very first line directs the server to evaluate the allow
code first and the deny code thereafter. So all the traffic will be allowed by considering the allow from all
code first. Then the IP addresses corresponding to the deny code will be blocked.
It is important to write this line in the same order because if it is reversed and written as order deny,allow,
the allow directive will then override all the deny directives. It will nullify all the deny directives.
Also, you can block a full block of IP addresses that are creating problems. In the above code, the 3rd line does not include a complete address but the block. So all the IPs belonging to that block will be denied access to your website.
The deny from
directive can be used to block any number of IP addresses while including one per line.
How to perform IP Whitelisting?
Whitelisting is the exact opposite of blacklisting i.e. restricting all the visitors except a few desired IP addresses.
You must have guessed by now that the code will involve the reversal of the directive to deny everyone first and allow only the ones mentioned.
The following code will help you whitelist a few desired IP addresses. Don’t forget to replace the IP addresses with the ones you want to whitelist:
order deny,allow
deny from all
allow from 111.22.3.4
allow from 789.56.4.90
Blocking Actions
.htaccess allows you to block scrapers and bots by domain or referrer. Let us get deeper into the processes of both:
Blocking Users By Domain
Blocking visitors by domain is quite beneficial when you do not want a specific domain to bother you by changing its IP address.
But such a type of blocking is not functional when the user is capable of controlling his reverse-DNS mapping for the IP address.
The following code will allow you to block users by domain:
order allow,deny deny from abc.com allow from all
The above code works both for the main domain and its subdomains. So the traffic from xyz.abc.com also gets blocked.
Blocking Users using Referrer
Any website carrying a page link to your website is called a referrer when the visitor follows that link and comes to your site. Blocking by referrer does not function when a referrer is carrying hyperlinks that are, clickable.
Another important thing to understand before using this method is hotlinking. When an internet page links to pictures posted on your website, it is known as hotlinking. This practice consumes your account bandwidth plus it might even lead to copyright infringement without sending any traffic to your site.
In addition to pictures, such hotlinking can also be done with JS scripts, CSS files, or other such resources on your website. Though the majority of website owners do not bother about such hotlinking, however in some cases, it might seem abusive.
Also, sometimes clickable hyperlinks included in the text become troublesome like the ones included on hostile websites. When you are facing the above-mentioned problems, you can resort to blocking users by the referrer technique.
For using this code, your mod_rewrite module must be enabled. Generally, it is default-enabled by hosting providers but you must confirm it from your host before moving forward. If your host informs you that it is not enabled and cannot be done, you must consider changing your host to perform this function.
.htaccess code related to blocking by referrer works only with mod_rewrite.
You can use the following code for blocking traffic by using referrer:
RewriteEngine on RewriteCond % ^http://.*abc.com [NC,OR] RewriteCond % ^http://.*pqr.com [NC,OR] RewriteCond % ^http://.*xyz.com [NC] RewriteRule .* - [F]
It is a bit complicated, so let us understand it in detail here:
- The very first indicates that rewrite-related directives will follow.
- The second, third, and fourth lines block certain specific domains and you will have to replace the domain names (like abc.com) with the ones you want to block.
- Escape characters in the form of backward slashes have been used in the code above. The dot that we use in the code refers to something contained in RegEx and it must be escaped with a backward slash.
- The NC and OR used in brackets also denote certain directives. NC indicates that the corresponding matches are case insensitive. And the OR denotes the simple “or” which means that this rule is followed by another rule and so on. That is why you will notice that the last line does not include the OR directive.
- The closing line in the above code denotes the rewrite rule. [F] in this line refers to Forbidden. So all the referrers that you mention before this line will be forbidden and receive a 403 Client Request Error.
Blocking Scrapers and Bots
All website managers have to deal with the most annoying visitors to their sites i.e. bots, scrapers, and crawlers. They all eat up your bandwidth without benefitting you in any manner.
Such acts are performed to extract some information from your website and republish it following a cheap SEO practice.
Some bots are legitimate ones too, like the ones that belong to search engines. However, the majority of bots are unnecessary and can be compared to pests that consume your resources without providing any advantage to you.
Hundreds of bots have been identified and many originate over time. So it is impossible to block them all but their activity can be minimized by blocking the ones you can identify.
You can use the rewrite rules compiled at the following link from AskApache and successfully block over 400 bots that have already been identified.
How To Specify Default File?
When a URL has not specified a name for a file, most servers assume the request is being made for accessing the directory.
That is why Apache and many other servers will try to find the default file in the website’s root directory when a request for http://abc.com
is made.
By default, this file looks like index.html
. It is because, in the initial internet years, the websites were made to display documents. The main page of a website was merely used for indexing all the documents contained in that website.
But you can alter this default setting if you do not desire to have index.html
as your website’s default page or when you do not want to call your website homepage an index page. Let us learn how you can specify a default file for your directory.
How To Set A Default Page For The Directory?
The following code can be used to set a default page for your directory via .htaccess
:
DirectoryIndex [filename here]
You can fill in any file name to make it a default page for your directory. So if you desire to set your website homepage as the directory default page, you will write this code:
DirectoryIndex home.html
How To Set Numerous Default Pages?
It is possible to set multiple default pages for your directory. The following code will help you set such multiple default pages:
DirectoryIndex index.php index.shtml index.html
When you set multiple default pages, the server will first look for the very first page for displaying it as the default one. In case it is unable to find that page, it will search for the next page included in the code, and this will go on.
Are you thinking about the need of doing this?
You already know that .htaccess
impacts its main directory and all the subdirectories contained therein. And each subdirectory might consist of individual default page names.
When you add such a code to a .htaccess
datafile of your root directory, you can prevent the need to add these rules at each directory level. Adding the code in the root directory will make your task easier since it will impact all the directories and subdirectories.
Redirecting and Rewriting URL
The commonest use of a .htaccess
file can be found in URL redirects.
Whenever the URL belonging to a resource or document is changed, URL redirecting is put to action. The feature is most useful when a domain name is changed or a website is reorganized.
301 vs. 302 Redirects
The server can generate numerical error codes 301 and 302 on some occasions and these are considered as redirects by the browser.
301 stands for “Permanently Moved” whereas 302 stands for “Moved Temporarily”. You are advised to utilize 301 in most cases as it preserves the SEO equity of the old URL and maps it to your newly created page.
It also prompts most of the browsers to perform certain actions like updating their bookmarks and caching the mapping of new-from-old. Thus, whenever a user or a link tries to access the original URL, the browsers will simply furnish the newly created URL. This is exactly the result you’d desire, had the URL been changed permanently.
302 redirects are rarely used since one hardly changes a URL temporarily. There seems to be logic behind changing one’s URL permanently, though it is not advised. But a temporary change with a pre-planning of bringing it back to the old one seems to be a weird idea that must be avoided at all costs.
The examples mentioned in the following section hereafter will be using the commonest redirect, which is 301.
Redirect v/s Rewrite
To “change” any URL that has .htaccess
directives, one can choose one of the following two ways:
Redirect
Command.mod_rewrite
engine
When a redirect
command is used, a special message is sent to your browser specifying the URL to search for redirecting.
Usually, mod_rewrite
tends to “translate” a single URL (the requested one) to something that can be easily understood by the CMS or your file system. It, then, processes the request of a translated URL the same way the requested one would have been processed.
This typical way of translation goes unnoticed by the browser as if nothing happened and it is simply provided with the content page it requested.
You can also generate 301 redirects using the mod_rewrite
tool. It works just like the above-discussed redirect command plus provides an added set of options to set rules. That is to say that mod-rewrite
can perform tough pattern matching while offering varied rewriting commands, that cannot be performed by the redirect command.
Redirecting a Basic Page
The following code can be used to redirect a page to a different URL:
Redirect 301 /relative-url.html http://example.com/full-url.html
The above command can be understood in its four parts that are put in a single line but separated with single space:
- The first part is the command of redirect
- The next part specifies the redirection type (301 here means “Moved Permanently”)
- The third part is the relative or corresponding URL of the previous (old) page
- And last part is the full URL belonging to the intended (newly created) page
A ‘Relative” URL is the one corresponding to that directory that contains your .htaccess datafile. It usually is the root directory or webroot.
Hence if http://instance.com/blog.php
is shifted to http://blog.instance.com
, the following code will be used:
Redirect 301 /blog.php http://blog.instance.com
Redirect a huge section of your website
When you shift your whole directory while keeping the names of your pages intact, the best option is redirecting all the requests for that directory:
Redirect 301 /old-directory http://example.com/new-directory
Redirect the entire site
To move your entire site to a brand new URL, use the following code:
Redirect 301 / http://newurl.com
How To Redirect www traffic to a non-www page?
Many website owners have stopped using the famous www
subdomain these days.
www
denotes the world wide web and its usage in the website name started in the initial days of the internet. It wasn’t necessary to use it but people continued its use from the time when websites were used for storing personal documents and sharing them on the internet via the world wide web.
Now, many website owners have stopped using it but some internet users have the habit of typing www
. at the beginning of a URL, they are looking for. And when your website is skipping the use of www
, ensure that such visitors do reach your website.
For this code, you must ensure that mod_rewrite is installed by default by your hosting provider. Use the following code to redirect www to non-www:
Options +FollowSymlinks RewriteEngine on RewriteCond % ^www.abc.com [NC] RewriteRule ^(.*)$ http://abc.org/$1 [R=301,NC]
Caution!
Many mod_rewrite
and .htaccess
guides provide you with a variation to this code which is:
Options +FollowSymlinks RewriteEngine on RewriteCond % !^abc.com [NC] RewriteRule ^(.*)$ http://abc.org/$1 [R=301,NC]
Can you identify the problem in this variation?
It redirects all subdomains to the primary domain. So not just www.example.com
, but also blog.example.com
and admin.example.com
and anything else. This is probably not the behavior you want.
Redirecting to www
But what if you are using the www
subdomain?
You should probably set up a redirect to make sure people get to where they’re trying to go. Especially now that fewer people are likely to automatically add that www
to the beginning of URLs.
You just reverse the above code.
RewriteEngine On RewriteCond % ^example.com [NC] RewriteRule ^(.*) http://www.website.com/$1 [R=301,NC]
Should I Redirect 404 Errors to the Homepage?
Several guides on .htaccess
redirects include instructions on how to make 404 errors redirect to the home page.
This is a good example of how just because you can do something, it doesn’t mean you should do something.
Redirecting 404 errors to the site’s homepage is a terrible idea. It confuses visitors, who can’t figure out why they are seeing the front page of a site instead of a proper 404 error page.
All websites should have a custom 404 page which clearly explains to the user that the content couldn’t be found and, ideally, offers some search features to help the user find what they were looking for.
Why Use .htaccess
Instead of Alternatives?
You can set up redirect in PHP files, or with any other type of server-side scripting. You can also set them up within your Content Management System (which is basically the same thing).
But using .htaccess
is usually the fastest type of redirect. With PHP-based redirects, or other server-side scripting languages, the entire request must be completed, and the script actually interpreted before a redirect message is sent to the browser.
With .htaccess
redirects, the server responds directly to the request with the redirect message. This is much faster.
You should note, though — some content management systems actually manage redirects by updating the .htaccess
programatically. WordPress, for example, has redirect plugins that work this way. (And WP’s pretty URL system does this as well.)
This gives you the performance of using .htaccess
directly, while also giving you the convenience of management from within your application.
Hiding Your .htaccess File: Security Considerations
There is no reason that someone should be able to view your .htaccess
file from the web.
Moreover, there are some big reasons you should definitely not want people to see your .htaccess
file.
The biggest issue is that if you are using an .htpasswd
file, its location is spelled out in the .htaccess
file. Knowing where to find it makes it easier to find.
Moreover, as a general rule, you don’t want to provide the public with details about your implementation.
Rewrite rules, directory settings, security — all of the things that you use .htaccess
for — it is a good security practice to hide all of this behind-the-scenes at your web server. The more a hacker can learn about your system, the easier it is to compromise it.
It is very easy to hide your .htaccess
file from public view. Just add the following code:
<Files .htaccess>
order allow,deny
deny from all
</Files>
Enabling MIME types
MIME types are file types. They’re called MIME types because of their original association with email (MIME stands for “Multipurpose Internet Mail Extensions”). They aren’t just called “file types” because MIME implies a specific format for specifying the file type.
If you’ve ever authored an HTML document, you’ve likely specified a MIME type, even if you didn’t know it:
<style type="text/css" src="/style.css?x96620" />
The type
attribute refers to a specific MIME type.
MIME types on Your Server
Sometimes you’ll find that your web server isn’t configured to deliver a particular type of file. It just doesn’t work — requests for the file simply fail.
In most cases, you can fix this problem by adding the MIME type to your .htaccess
file.
AddType text/richtext rtx
This directive has three parts, each separated by a space:
- The
AddType
comman - The MIME type
- The file extension.
If you want to associate several different file extensions with the same MIME type, you can do that on a single line.
AddType image/jpeg jpeg jpg jpe JPG
Force Download by MIME Type
If you want all links to specific file types to launch as downloads, instead of being opened in the browser, you do that with the MIME type application/octet-stream
, like this:
AddType application/octet-stream pdf
Again, you can specify multiple file extensions with a single type:
AddType application/octet-stream pdf doc docx rtf
List of File Extensions and MIME Types
Here is a not-quite-complete list of file formats and associated MIME types.
If you are managing your own website, and you know what file types you publish resources in, then there is no need to paste this entire list into your .htaccess
file.
However, if you run a site that many other people are contributing and publishing content to, you may want to simply allow a large number of file types this way to make sure no one has a bad experience.
This is especially the case if you run a site where people might be specifically sharing a lot of files, for example a file sharing site, a project management application (where many files will often be attached to project), or a web app that handles email.
AddType application/macbinhex-40 hqx
AddType application/x-bcpio bcpio
AddType application/x-cpio cpio
AddType application/x-csh csh
AddType application/x-director dcr
AddType application/x-director dir
AddType application/x-director dxr
AddType application/x-dvi dvi
AddType application/x-gtar gtar
AddType application/x-hdf hdf
AddType application/x-httpd-cgi cgi
AddType application/x-latex latex
AddType application/x-mif mif
AddType application/x-netcdf nc cdf
AddType application/x-onlive sds
AddType application/x-ustar ustar
AddType application/x-wais-source src
AddType application/x-sh sh
AddType application/x-shar shar
AddType application/x-sv4cpio sv4cpio
AddType application/x-sv4crc sv4crc
AddType application/x-tar tar
AddType application/x-tcl tcl
AddType application/x-tex tex
AddType application/x-texinfo texinfo texi
AddType application/netalive net
AddType application/netalivelink nel
AddType application/octet-stream bin exe
AddType application/oda oda
AddType application/pdf pdf
AddType application/postscript ai eps ps
AddType application/rtf rtf
AddType application/zip zip
AddType audio/basic au snd
AddType application/x-troff t tr roff
AddType application/x-troff-man man
AddType application/x-troff-me me
AddType application/x-troff-ms ms
AddType audio/x-aiff aif aiff aifc
AddType audio/x-midi mid
AddType audio/x-pn-realaudio ram
AddType audio/x-wav wav
AddType image/gif gif GIF
AddType image/ief ief
AddType image/jpeg jpeg jpg jpe JPG
AddType image/tiff tiff tif
AddType image/x-cmu-raster ras
AddType image/x-portable-anymap pnm
AddType image/x-portable-bitmap pbm
AddType image/x-portable-graymap pgm
AddType image/x-portable-pixmap ppm
AddType image/x-rgb rgb
AddType image/x-xbitmap xbm
AddType image/x-xpixmap xpm
AddType image/x-xwindowdump xwd
AddType text/html html htm
AddType text/plain txt
AddType text/richtext rtx
AddType text/tab-separated-values tsv
AddType text/x-server-parsed-html shtml sht
AddType text/x-setext etx
AddType video/mpeg mpeg mpg mpe
AddType video/quicktime qt mov
AddType video/x-msvideo avi
AddType video/x-sgi-movie movie
AddType x-world/x-vrml wrl
Block Hotlinking
Hotlinking is the practice of linking to resources from other domains instead of uploading the content to your own server and serving it yourself.
Say you find an image on a website that you really like, and you want to use it on your site. Ignoring copyright issues for the moment — you could download the image, upload it to your website, and embed it on your page like normal.
<img src="https://yourdomain.com/image.jpg">
But if you were lazy, or trying to save bandwidth, or didn’t know how to upload a file, you could just embed it directly form the original file.
<img src="https://originaldomain.com/image.jpg">
That’s hotlinking. It also happens with CSS and JS files, but images are the most common.
Some websites/hosts don’t mind at all if you do this — you can hotlink images from Wikipedia without anyone being upset. And some websites encourage it in one form or another.
For example, JQuery provides their JS libraries via a CDN (Content Delivery Network), so you can hotlink directly to it without having to upload it and serve it from your own server.
But many web host consider hotlinking to be a form of bandwidth and resource stealing.
To be sure, if you are running a relatively small site, you can’t afford to have thousands, or tens of thousands, of requests being made every day for resources that have nothing to do with actual visitors to your site.
If you are having a problem with hotlinking, you can disable it with some mod_rewrite
rules added to your .htaccess
file.
RewriteEngine on RewriteCond % !^$ RewriteCond % !^http://(www.)?example.com/.*$ [NC] RewriteRule .(gif|jpg|jpeg|png|js|css)$ - [F]
Be sure to change example.com
in the third line to your actual domain name. This will catch any requests not coming from your domain, and then check if it matches one of the specified file extensions in the fourth line. If there is a match, the request fails.
If you want to add other file extensions, you can simply edit the last line.
Serving up Alternative Content
If you want to let the world know why their hotlinking has suddenly stopped working, you can replace hotlinked images with a special image with a message like, “We hate hotlinking!” or “Original Content Available at http://example.com”.
Instead of failing the request, you simply redirect it to the “special” image:
RewriteEngine on RewriteCond % !^$ RewriteCond % !^http://(www.)?example.com/.*$ [NC] RewriteRule .(gif|jpg)$ http://www.example.com/no-hotlinking.jpg [R,L]
If you really want to mess with people, you can redirect JavaScript or CSS files to special alternatives that may have unfortunate effects for the hotlinker. This is not recommended, however.
RewriteEngine on RewriteCond % !^$ RewriteCond % !^http://(www.)?example.com/.*$ [NC] RewriteRule .(js)$ http://www.example.com/break-everything.js [R,L] RewriteEngine on RewriteCond % !^$ RewriteCond % !^http://(www.)?example.com/.*$ [NC] RewriteRule .(css)$ http://www.example.com/super-ugly.css [R,L]
Disable or Enable Index
What happens if you have a directory full of documents or other resources, no index.html
file, and no default directory page specified in the .htaccess
file?
In many cases, the result will be a generic directory listing of all the files in the directory.
That’s right. If you have a folder in your hosting directory labeled /images
, and it has no index.html
page, when someone navigates to http://yousite.com/images
, they will be able to see a list of all the images on your site.
That’s the default behavior of most web servers, and it makes sense from the standpoint of the original conception of a website as simply a place to keep and share documents. But this is not the desired behavior for most sites.
Disabling Indexes
Many web hosting accounts will have disable this already as part of their global configuration. But not all do so.
If you need to disable automatically generated directory listings, doing so is easy:
Options -Indexes
Enabling Indexes
If your web server has disabled indexes as part of global configuration, but you do want them, you can enable them with the reverse of the above command.
Options +Indexes
Hiding some files from the Index
If you want to show directory listings, but you want to hide certain file types from the list, you can do that too.
IndexIgnore *.gif *.jpg
The *
is a wild-card chracter. The above directive will hide all files that have a .gif
or .jpg
extension. If you wanted to be more specific, you could:
IndexIgnore secret-image.jpg
Enabling CGI Everywhere
CGI, or Common Gateway Interface, is a server-side method for including non-HTML scripts (like Perl or SSI) in web pages.
Typically, CGI scripts are stored in a folder labeled /cgi-bin
. The webserver is configured to treat any resource in that directory as a script, rather than a page.
The problem with that is two-fold: URLs referencing CGI resources need to have /cgi-bin/
in them, which places implementation details into your URL — an anti-pattern to be avoided for a number of reasons.
A complex website may need a better organization structure than simply having a ton of scripts jammed into a single /cgi-bin
folder.
If you want your web server to parse CGI scripts no matter where they are found in your directory structure, just add the following to your .htaccess
file:
AddHandler cgi-script .cgi
Options +ExecCGI
If you have other file extensions you want processed as CGI scripts, you can add them in the first line.
Scripts as Source Code
Most of the time, you put scripts in your web directory because, well, you want them to be run as scripts.
But sometimes that isn’t what you want. Sometimes you want to display the source code to public visitors, instead of running the script.
This might be the case if you run a file sharing service or a code repository site, and you want people to see the source code and be able to download it, but the scripts are actually part of your site’s functionality.
This can be done in your .htaccess
file by removing the script handler for certain file types and replacing it with a handler for text.
RemoveHandler cgi-script .pl .cgi .php .py
AddType text/plain .pl .cgi .php .py
Alternatively, as mention previously, you could force files with these extensinos to be downloaded automatically, rather than displayed.
RemoveHandler cgi-script .pl .cgi .php .py
AddType application/octet-stream .pl .cgi .php .py
Be careful with either of these, though. If you only want some files to be displayed this way, but are still using these scripts for the rest of your website, your going to have a bad time if you put that directive into your web root’s .htaccess
file.
A better practice would be to place all such “display only” scripts into a single directory, and then place the directive into an .htaccess
file there in that folder.
Configuring PHP Settings
Sometimes you need to tweak PHP’s settings. The right way to do this is in a file called php.ini
.
Unfortunately, not all web hosting companies allow their customers to edit the php.ini
file. This is especially true of shared hosting providers, where a single installation of PHP may be running hundreds of web sites.
Fortunately, there’s a workaround — you can embed php.ini
rules into your .htaccess
file.
The syntax looks like:
php_value [setting name] [value]
So, for example, if you need to increase the max file upload size (a common issue), it is as easy as:
php_value upload_max_filesize 10M
Not all PHP settings can be specified in .htaccess
files. For example you can not disable_classes
this way.
For a complete list of all php.ini
settings, see the official php.ini directives guide.
How to Prevent Access to Your PHP include Files
There are several ways to prevent unauthorized access to your PHP includes files.
First, you can put them into a directory and set your .htaccess file to deny all access to that directory (ie, Deny from all
if you’re using the Apache HTTP Server). If someone does try to access the file, they will receive an HTTP 403 Forbidden response.
Alternatively, you can store these files outside the directory from which your website files are served. That is, if your webserver is serving files located in /srv/home, you can put your include files under /srv/home/includes. This makes the files inaccessible via URLs, though you can access and use them as follows: include 'PATH_TO_YOUR_FILE'
Finally, you can define a URL constant for the files you want accessible:
define('WEBSITE_URL', 'http://example.com');
Then, for the files that you don’t want accessed, include the following check:
if(!defined('WEBSITE_URL')) {
header($_SERVER["SERVER_PROTOCOL"] . "403 Forbidden");
exit;
}
How to Prevent Access to Your PHP ini Files
The way to prevent unauthorized access to your ini files is to edit your .htaccess file to deny access to the ini files (ie, Deny from all
if using Apache).
How to Set Your Server’s Time Zone
You can set your server’s time zone by specifying it in your .htaccess file. To do so, you will need to add the following line:
php_value date.timezone 'Region/Zone'
Make sure to replace Region/Zone with the time zone you’d prefer.
Save your file. You can test your changes by creating a PHP test file containing the following in the same directory as the .htaccess file:
<?php phpinfo(); ?>
Load the file in your browser, and search for the name of the directive – its Local Value column should display your new time zone setting.
When Not to Use .htaccess
Editing your .htaccess
file for the first time can give you sudden feeling of immense power over your web hosting environment. You suddenly feel like a sysadmin.
Unfortunately, this power can go to your head, and you may find yourself using the .htaccess
file in ways that aren’t really the best.
When you need to do something that seems like an .htaccess
sort of job, there’s basically two situations where you should put that directive somewhere else.
Further Upstream
Whenever possible, the types of directives you can place in an .htaccess
file are better off being place in the httpd.conf
file, which is a configuration settings file for the entire server.
Similarly, PHP settings more properly belong in the php.ini
file, and most other languages have similar configuration setting files.
Placing directives further upstream, in the httpd.conf
, php.ini
, or other language-specific configuration file allows those settings to be “baked-in” to the web server’s parsing engine. With .htaccess
, the directives have to be checked and interpreted with every single request.
If you have a low traffic site with only a handful of .htaccess
directives, this isn’t a big deal. But if you have a lot of traffic, and a lot of directives, the performance lag can really add up.
Unfortunately, many shared hosting providers do not allow customers to access the httpd.conf
or php.ini
files, forcing users to rely on the slower .htaccess
file.
This provides a double-penalty when compared to custom VPS configurations because shared hosting is also generally low-powered. This is one of the reasons that a site with respectable traffic should probably be on a VPS plan instead of shared hosting plan.
Further Downstream
If you are using a good Content Management System (CMS) such as WordPress or Drupal, some of the things you might do in an .htaccess
file — such as redirect URLs or block IP addresses — can be done from inside the application.
Often, this works in conjunction with the .htaccess
file, with the application programatically adding directives.
When this is available, it is usually best to accomplish these tasks from inside the application, rather then editing the .htaccess
file yourself. You are less likely to introduce bugs and incompatible directives if you use a well-tested, open-source plugin.
Troubleshooting
Messing around with your .htaccess
file can be great — but it can also cause your server to seize up and start delivering 500 Internal Server Error
messages.
Here’s a few ideas to help you through that.
Do One Thing At a Time
This should go without saying, but — sadly — it’s a lesson many of us have to learn over and over again.
Do one thing. Then test it. Then do another thing. Test that.
If you do several things all at once, and then something fails, you won’t know which directive is causing the problem.
Backup Your File Before Each Action
Along with doing only one thing at a time, you should save your file between each thing you are trying. Your saved archive needs to be restorable. This isn’t Microsoft Word where you can just Undo — you need a saved copy of your file.
You should always have the latest working version available in case you mess something up. Always, always, always have the ability to restore to a working version.
This is easiest if you some kind of source management system like git. You can commit after each change, and roll back if you run into any problems.
Check the Error Logs
If you do run into a problem, and you’re having a hard time figuring out why, check your Apache error logs. These often provide valuable information about where to look.
Use Developer Forums to Get Help
Developer forums and Q&A sites like StackOverflow are invaluable tools for even the most seasoned developers and sysadmins. And don’t forget Google. Often, the difference between a bad web master and great one isn’t knowing the answer, its knowing where to find the answer.
Common .htaccess Problems
Sometimes you made a typo. Sometimes you have an esoteric and confusing problem caused by a confluence of unpredictable factors.
Most problems, and the really frustrating ones, are the ones in the middle — the simple, everyday problems that are easy to fix if you just knew about them.
Here’s a few of those.
Bad Filename
There is only one way to spell .htaccess
— it has to begin with the dot, and it must be in all lowercase letters.
It seems dumb, but if your .htaccess
file isn’t doing what you expect, that should be the first thing you check.
.htaccess Disabled or Partly Disabled
Some shared hosting providers disable .htaccess
altogether. Others allow it, but restrict certain directives from being used — they’re just ignored if included.
Similarly, even on VPS plans or your own dedicated servers, .htaccess
might be disabled.
If you have access to the httpd.conf
file, or other server settings, you can check this yourself. If you find the directive AllowOverride None
, you found the culprit. Replace it with AllowOverride All
.
If you don’t have access to your httpd.conf
file (because you’re on shared hosting, for example), you may need to contact your hosting company’s tech support and see if they can enable it for you, or offer you suggestions on how to accomplish what you’re trying to do in a different way.
Conflicting or Overridden Directives
If you have multiple nested directories, it’s possible for each one to have its own .htaccess
file. Every .htaccess
file from the root, through each nested directory, applies — they are read in order, descending down the directory tree.
If you set something in your root directory, and then something in subdirectory overrides it, the directive in the .htaccess
file closest to the requested file will take precedence.
Also see the mod-rewrite cheat sheet!
.htaccess Frequently Asked Questions
What is .htaccess file in SEO?
The .htaccess file can be used to execute SEO-related tasks like redirects. Redirects can be used to avoid 404 error messages and to let search engine crawlers know which pages they should index. You can also set HTTP headers to improve page load speeds, which may boost your search engine ranking.
In addition, you can use .htaccess to enact a consistent trailing slash policy. This, combined with www and HTTPS rules, can help you avoid duplicate content, which can be penalized by Google.
How do I create a .htaccess file in WordPress?
To create an .htaccess file in WordPress, use this code:
# BEGIN WordPress RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] # END WordPress
Note that when you install WordPress, the .htaccess file is automatically created. However, a faulty plugin can corrupt an .htaccess file, resulting in a need to re-create the file.
Why can’t I see my .htaccess file?
If you can’t see your .htaccess file it’s because it doesn’t exist or it’s hidden. To force your FTP client to show these files, you’ll need to change your client settings (i.e., in FileZilla, go to Server > Force showing hidden files). If you’ve made this change and you still don’t see .htaccess, you will need to re-create it.
How many .htaccess files should I have?
Most websites do not need more than one .htaccess file. That’s because the .htaccess files allows you to make server configuration changes on a per-directory basis. However, when hosting multiples sites or complex applications some webmasters may use more than one file per site in order to execute advanced functions.
Where is .htaccess in the cPanel?
To see the .htaccess file, log in to your cPanel account. Then go to Files > File Manager. When asked to choose the directory, select Web Root and make sure that Show Hidden Files is checked. You should now be able to view your .htaccess file in cPanel.
What is the use of .htaccess file in CodeIgniter?
The .htaccess file can be used in conjunction with CodeIgniter to create search engine friendly URLs. By default, CodeIgniter URLs include the index.php file. By using .htaccess you can delete that default index.php file so that it doesn’t appear in all of your application’s URLs.