The Many Ways to Utilize the Power of the .htaccess File on Your Website

The htaccess file is a powerful file that can significantly control the behavior of your website. It can be used to secure your website, restrict site access, give redirect commands and perform several other functions.

 

Further reading:

6 Ways to Protect Your Website From Security Hacks

How to secure your website from attacks using the .htaccess file

How to Properly Use Redirects on Your Website

 

The .htaccess file controls how Apache interacts with your site. When an .htaccess file is placed in your domain’s directory, the .htaccess file is detected and executed by the Apache web server.

Generally, the .htaccess file is commonly used for the following:

  • Denying specific IPs to your site
  • Password protecting your site with an .htaccess file
  • Redirecting specific pages
  • Rewriting URLs
  • Custom error pages
 

Using an .htaccess file on your website is unlikely to cause any problems. However, it is possible for errors to occur if the rules entered into the file are incorrect which may cause your site to suddenly display a 500 error. If something like this occurs, you can comment out the rules/lines you have just added by placing a ‘#’ in front of each line. Repeat this until you find the line causing the error.

 

Further reading:

How website errors affect search engine rankings

Real Live Case: How We Addressed a Joomla White Screen Error on a Live Website

The Complete Guide to Troubleshoot and Fix the Most Common WordPress Errors

 

Creating an .htaccess file web server

You can create an .htaccess directly on your web server using an FTP client or SSH. If you're using an FTP client, make sure it has been configured to show hidden files. This is necessary since the .htaccess file begins with a period.

Make sure that when you create the .htaccess file you do NOT add a file extension. This file should only be titled .htaccess with no extension.

 

What permissions should the file have?

644 permissions are usually fine for an .htaccess file. When you create the file on the server, it should already have these permissions set, so there is most likely nothing to change.

 

Further reading:

WordPress Security: The SQL Injection

Top Three Best Safeguards for Every WordPress Website

15 Best Practices for Joomla Website Security

 

Where to put your .htaccess file?

Generally, you put the .htaccess file in your website's main directory. However, the location ultimately depends on what you're attempting to do with the .htaccess file.

The .htaccess file can control behavior for every directory under the folder it resides in. For this reason it can also be in your user's home directory. Again, it depends on what you're using the .htaccess file for.

 

Do I need to reload my server or website after creating my .htaccess file?

Your .htaccess file (and any changes that you make to it) should be reflected on the live site immediately. You do not need to reload your site's Apache service, although external caching services such as Cloudflare might need their caches flushed.

 

Further reading:

Recommended Caching Plugins for Your WordPress Website

 

What can I do with an .htaccess file?

There are several things you can do with an .htaccess file to customize your site.

 

Changing PHP settings in an .htaccess file

In some server configurations, it's possible to adjust your PHP settings within your .htaccess file. For example:

php_value  upload_max_filesize  600M

DreamHost does not allow this type of configuration. If you need to adjust your PHP settings, you must do so within a phprc file. View the following articles for information on how to create and configure this file.

 

How can I control file extensions with an .htaccess file?

Creating an .htaccess file on your DreamHost web server

View the following article for instructions on how to create an .htaccess file on your web server:

If the file already exists, update it (depending on if you're using an FTP client or SSH):

 

What to change in the examples below?

The examples below can be entered into your .htaccess file exactly as shown.

Only if the example contains a URL in bold should you change that to your actual URL. For example, if you see the domain 'example.com', change this to your own domain name.

Changing the file extension

This example allows you to use a .zig extension in addition to the regular .php extension. So, you could access a file at example.zig as well as example.php:

Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteRule ^(.+)\.zig$ /$1.php [NC,L]

 

Forcing other file extensions to load as PHPUsing an .htaccess file

To process files with PHP whose names don't end with ".php", you can use a directive in .htaccess.

For example, create a file named myfile.test with the following code:

<?php
echo ‘testing an extension using PHP’;
?>

The extension .test doesn’t exist. But, you can force it to run as PHP by adding this code to your .htaccess file:

AddHandler fcgid-script .test
FcgidWrapper "/dh/cgi-system/php72.cgi" .test

If you load the file in a browser, it will now load as a normal PHP file.

 

Removing the file extension

This example completely removes the file extension from your URL. So, example.php would appear as example. The following example is for .php files, but for any other type, just replace .php with your desired type and add those lines and extensions in the same way:

RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*index\ HTTP/
RewriteRule ^(.*)index$ http://example.com/$1 [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ http://example.com/$1 [L,R=301]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.+)\.php\ HTTP/
RewriteRule ^(.+)\.php$ http://example.com/$1 [L,R=301]
RewriteRule ^([a-z]+)$ /$1.php [L]

 

Allowing a file to load without the extension

This example does not automatically remove the file extension. However, it does allow the file to be loaded without the extension. So, if example.com/test.php exists, you can then load it as example.com/test:

Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+)$ /$1.php [L,QSA]

 

Redirecting all URLs

The following line redirects all URLs on your site to the new site.

Redirect 301 / https://example.com/

 

Redirecting a single URL

Using Redirect in an .htaccess file enables you to redirect users from an old page to a new page without having to keep the old page. For example, if you use index.html as your index file and then later rename index.html to home.html, you could set up a redirect to send users from index.html to home.html. For example:

Redirect to a local site file

Redirect /path/to/old/file/old.html /path/to/new/file/new.html

Redirect to an external site file

Redirect /path/to/old/file/old.html http://www.example.com/new/file/new.html

The first path

The first path to the old file must be a local UNIX path, NOT the full path. So, if the .htaccess file is in the directory /example.com, you would not include /home/username/example.com in the local UNIX path. The first / represents the example.com directory. If the old file was in that directory, you would follow the / with the old file name.

The second path

The second path to the new file can be a local UNIX path, but can also be a full URL to link to a page on a different server or the same server.

 

Examples of redirects

Redirect from a directory to an HTML file

RedirectMatch 301 ^/blog/about /blog/about.html

Redirect from an index.html file to a different directory

Redirect /index.html /new/

Redirect from index.html to default.html

Redirect /index.html /default.html

Redirect a local /private directory to another site's private directory

Redirect /private/ http://www.example.com/private/

Load a .gif file from a different site

Make sure the other site is something you own. You should never hotlink files from other websites.

Redirect /img/logo.gif http://www.example.com/images/logo.gif

Using Regular Expressions

If you want to use a Regular Expression to redirect something, use the RedirectMatch directive:

RedirectMatch "^/oldfile\.html/?$" "http://example.com/newfile.php"

Redirecting error messages

You can also redirect 404 errors. Instead of throwing a 404 page, this redirects to the homepage of the website.

ErrorDocument 404 http://example.com/

Redirecting an old directory to new directory

This redirects files in a old directory (/blog/archives) to a new directory (/archives). The file must exist in the new directory to function.

RewriteRule ^blog/archives/(.*)$ /newarchives/$1 [R=301,NC,L]

 

Redirect non-existing pages to index.php

If a visitor attempts to access a page that doesn't exist, they are presented with a 404 error. You can instead redirect any request to a non-existing page to your index.php file (or any index file) by adding the following code in your .htaccess:

Options +SymLinksIfOwnerMatch 
RewriteEngine On 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

If your index page isn't index.php, just change the last line to your actual index file. Then the visitor is redirected back to your home page.

 

Automatically loading a subdirectory

This example redirects the ROOT domain's URL to any subdirectory. In this example, it automatically loads example.com/subdir1:

RewriteEngine on
RewriteRule ^$ /subdir1/ [L]

 

Forcing www in the URL

RewriteEngine On
RewriteCond %{HTTP_HOST} ^example.com
RewriteRule (.*) http://www.example.com/$1 [R=301,L]

 

Removing www in the URL

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.example.com
RewriteRule (.*) http://example.com/$1 [R=301,L]

 

Rewriting a URL

This example rewrites a URL to another URL. This rewrites example.com/1.html to example.com/abc.php?id=1

Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([0-9]+).html /abc.php?id=$1 [QSA,L]

The following explains the rules above:

([0-9]+)

allows any digit, and only any digit, 1 or more times.

([a-z-]*)

allows any lowercase letter, plus “-” for word separation, 0 or more times. If you want it to support uppercase too, use “([a-zA-Z-]*). For example:

RewriteRule ^place/([a-zA-Z-]*).html /place/abc.php?id=$1 [QSA,L]

[QSA,L]

appends this to your internal scripting query string, and makes it the Last rewrite rule executed.

After using this method, you can retrieve the webpage with either address type. This is handy for retro-fitting a website that was not designed with mod_rewrite in mind. This is good because it does not destroy any bookmarks saved on users computers.

 

Rewriting non-existing links to index.php

The following redirects all links to files or folders that do not exist to index.php. However, if the file or directory does exist, it loads normally:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

 

How do I deny access to my site with an .htaccess file?

 

Deny access to files

Denying access to specific file extensions

The following code forces any file ending in .inc to throw a 403 Forbidden error when visited:

<Files ~ "\.inc$">  
Order Allow,Deny
Deny from All
</Files>

 

Denying access to "hidden" files

File names beginning with a dot are considered "hidden" by UNIX. Usually, you don't want to serve them to visitors.

Todhost already disallows retrieving '.htaccess' and '.htpasswd', but you can recursively deny all access to all hidden files by placing the following into a top-level .htaccess:

RedirectMatch 403 /\..*$

 

Deny access to folders

Denying access to a directory listing

If you don't have an index file in your directory, all of your files are listed in a directory list for anyone to view. The following code forces this directory listing to throw a 404 Forbidden error instead when visited:

Options -Indexes

 

Denying access during a specific hour of the day

If you wish to block access to files in a directory during a specific time of day, then you can do so by adding the following code to an .htaccess file:

RewriteEngine On
# If the hour is 16 (4 PM)
RewriteCond %{TIME_HOUR} ^16$
# Then deny all access
RewriteRule ^.*$ - [F,L]

If someone visits the directory anytime between 4:00 – 4:59 pm, a 500 Internal Server error is thrown. You can also specify multiple hours as well:

RewriteEngine On
# Multiple hour blocks
# If the hour is 4 PM or 5 PM or 8 AM
RewriteCond %{TIME_HOUR} ^16|17|08$
# Then deny all access
RewriteRule ^.*$ - [F,L]

 

Denying access to a directory

If you have a directory named blah that you want to block, but it can occur anywhere in your directory tree, use the following:

RewriteEngine On
RewriteRule (^|/)blah(/|$) - [F]

 

Denying access from specific IP addresses

If you have problems with certain visitors to your website, you can easily ban them. There are two different ways to ban visitors:

  • using their IP address, or
  • the domain name from which they are visiting.

Here's an example that denies a user by their IP address:

deny from 173.236.241.100

When the user tries to connect to your site from that specific IP, they see a 403 Forbidden page instead. If you want to block an entire block of IPs, just leave the last octet off. For example:

deny from 173.236.241.

This denies access from anyone using an IP in the range from 173.236.241.0 all the way up to 173.236.241.255.

The following link is a useful online tool that automatically generates an IP range for you:

 

Allowing access from a specific IP

If you need to deny access to your site to everyone while still allowing yourself or another specific IP address to visit it, you can use something like this:

order deny,allow
deny from all
allow from <YOUR_IP_ADDRESS>

 

Denying access from a specific domain

This denies access from anyone connecting to your site from www.example.com. If someone clicks on a link at example.com that redirects to your site, they then see a 403 Forbidden error:

SetEnvIfNoCase Referer "example.com" bad_referer
Order Allow,Deny
Allow from ALL
Deny from env=bad_referer

This example throws a 500 Internal Server Error for anyone linking from example.com:

RewriteEngine on
RewriteCond %{HTTP_REFERER} example\.com [NC,OR]
RewriteRule .* - [F]

The following example redirects any visitor connecting from example.com to google.com:

RewriteEngine On
RewriteCond %{HTTP_REFERER} ^http://example.com/
RewriteRule /* http://www.google.com [R,L]
 

Force your site to load securely with an .htaccess file

After you have added an SSL certificate to your domain, Todhost automatically redirects the URL visitors use to view your site from HTTP to HTTPS. The 'S' ensures that your connection is encrypted. For example:

  • https://example.com

There's nothing on your end you must update in order to force your site to use the secure URL. However, in some special cases, it may be necessary for you to create your own custom configuration file to force the redirect from HTTP to HTTPS.

Adding custom code is only necessary if your website requires specific code to force the redirect. If so, you will need to first disable the automatic redirect in your panel.

Once disabled, you can then proceed with adding your custom .htaccess file.

 

Forcing the domain to serve securely using HTTPS (for any site)

The following forces any http request to be rewritten using https. For example, the following code forces a request to http://example.com to load https://example.com. It also forces directly linked resources (images, css, etc.) to use https:

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
Header always set Content-Security-Policy "upgrade-insecure-requests;"

If this isn't working for you, first check your line endings. Copy/paste from your web browser into a text editor may not work right, so after pasting into your text editor you should delete each line break and add it back in (line break = return key).

 

Forcing HTTPS with WordPress

If your .htaccess file already contains some default WordPress code, enter the following above or below that code. Never enter code inside of the comment tags that start and end with:

# BEGIN WordPress
# END WordPress

It's possible for a visitor to enter in a direct HTTP URL on your WordPress site, even when an SSL certificate is active. To force any HTTP request to redirect to HTTPS, you can add code to your WordPress .htaccess file. There are two code options below for you to use. The first should work as shown, but if not, try option two instead.

Option #1

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
Header always set Content-Security-Policy "upgrade-insecure-requests;"

Full example including the default WordPress code

Below is what your .htaccess file looks like with both the new HTTPS code and existing WordPress code.

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
Header always set Content-Security-Policy "upgrade-insecure-requests;"

# BEGIN WordPress
# The directives (lines) between `BEGIN WordPress` and `END WordPress` are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Option #2

In this example, make sure to change 'example.com' to your actual domain name.

RewriteEngine On 
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L,NE]
Header always set Content-Security-Policy "upgrade-insecure-requests;"

Full example including the default WordPress code

Below is what your .htaccess file looks like with both the new HTTPS code and existing WordPress code.

RewriteEngine On 
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L,NE]
Header always set Content-Security-Policy "upgrade-insecure-requests;"

# BEGIN WordPress
# The directives (lines) between `BEGIN WordPress` and `END WordPress` are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

 

Troubleshooting

WordPress

This can also be an issue with WordPress as it requires URLs in the database to either use or or not use 'www' in order to operate correctly.

Infinite redirect error

Causes of the error

This error is usually caused because the HOME and SITE URL within WordPress is not configured correctly. For example, if your site is example.com, the Home and Site URL in your database should point to:

  • https://example.com

If the Home and Site URL add 'www' to the URL, it may appear like this in your database:

  • https://www.example.com

This will cause your site to redirect in a loop.

Other causes

There are a few other reasons your site could redirect.

Plugins

It's possible that a plugin you added to your site has cause the redirect. Try disabling your plugins to confirm if that is the cause.

.htaccess file

Your .htaccess file may have a redirect set up somewhere. Open the .htaccess file and view its contents. Look for anything redirecting your site to a different URL.

 

Resolving mixed content warnings

Even when your site is correctly redirecting to the secure URL, it's possible the browser will still throw a warning indicating that some resources such as links are pointed to the non-secure version. You can add additional code to your .htaccess file to resolves those warnings. View the following article for details.

 

Password protecting your site with an .htaccess file

Overview

Using the panel to password protect your site

The easiest way to password protect your site is to use the tool in the cPanel.

No access to your .htaccess and .htpasswd files

However, please note that if you use the panel option, the .htaccess and .htpasswd files will be owned by the server. This means you will not be able to manually edit either of these files if you need to. Additionally, these instructions will overwrite any existing .htaccess file. Make sure to backup your existing .htaccess file before beginning these steps.

If you only need to password protect your site and will need access to your .htaccess and .htpasswd file at any time in the future, you should manually create those files.

Creating the .htpasswd file

  1. Log into your server via SSH.
  2. Create an .htpasswd file in the directory you wish to password protect using the the htpasswd utility. For the first user, say user1, run the following:
    [server]$ htpasswd -c /home/username/example.com/.htpasswd user1
  3. Enter the password for the user. This creates a password for a user named 'user1'. The code in your .htpasswd file will show the encrypted password like this:
    user1:$apr1$bkS4zPQl$SyGLA9oP75L5uM5GHpe9A2
  4. Run it again (without the -c option) for any other users you wish to allow access to your directory.
  5. Set the permissions on this file to 644.
    [server]$ chmod 644 .htpasswd
    

 

Code examples to add to the .htaccess file

Protect an entire directory

This example password protects an entire website directory. Make sure to change the lines in bold to your actual file path while changing to your username and domain name.

#Protect Directory
AuthName "Dialog prompt"
AuthType Basic
AuthUserFile /home/username/example.com/.htpasswd
Require valid-user

Protect a single file

This example password protects a single file:

#Protect single file
<Files admin.php>
AuthName "Dialog prompt"
AuthType Basic
AuthUserFile /home/username/example.com/.htpasswd
Require valid-user
</Files>

Protect multiple files

This example protects multiple files:

#Protect multiple files
<FilesMatch "^(admin|staff).php$">
AuthName "Dialog prompt"
AuthType Basic
AuthUserFile /home/username/example.com/.htpasswd
Require valid-user
</FilesMatch>

 

Code to protect a WordPress subdirectory

Due to how WordPress routes all page requests, attempting to access a password protected subdirectory will throw a 404 Not Found error. To resolve this, you must an extra line to the .htaccess file to reference ErrorDocument.

This example protects a subdirectory named members.

ErrorDocument 401 default
    
#Protect Directory
AuthName "Dialog prompt"
AuthType Basic
AuthUserFile /home/username/example.com/members/.htpasswd
Require valid-user

 

Force SSL (HTTPS) on the login prompt

The following steps are not necessary if your site automatically redirects to HTTPS. This is the case for any SSL certificates added as of Sept 2020.

If you have an older SSL that is currently not redirecting automatically (without adding any custom code to your .htaccess file), please contact support for assistance.

By default, the login prompt you see is not encrypted. This means your password will be sent as plain text over http. In order to encrypt this login, you must add an SSL certificate to your domain. Once added, add the code below to force SSL when logging in.

This method prevents submission of an .htaccess password prompt on an unencrypted connection. If you wish to ensure that your server is only serving documents over an encrypted SSL channel, then you must use the SSLRequireSSL directive with the +StrictRequire Option enabled:

Step 1 — Adding code to your .htaccess file

Make sure the URL you enter next to SSLRequire is your site's base URL. Do not include 'www' in front of the URL if you're forcing 'www' to be removed in your panel.

If you're securing a subdirectory such as example.com/blog, this URL would still be 'example.com'.

Additionally, you can use any file you like for your 403 document. Below it is shown as 'error_redirect.php'. Change this to your chosen file.

SSLOptions +StrictRequire
SSLRequireSSL
SSLRequire %{HTTP_HOST} eq "example.com"

ErrorDocument 403 /error_redirect.php

<Files /error_redirect.php>
  AuthType none
</Files>

If you're only protecting a subdirectory

If you only want to protect a single subdirectory and not the whole site, specify the subdirectory in your .htaccess file as shown in the following code:

#Protect Directory
AuthName "Dialog prompt"
AuthType Basic
AuthUserFile /home/username/example.com/blog/.htpasswd
Require valid-user

SSLOptions +StrictRequire
SSLRequireSSL
SSLRequire %{HTTP_HOST} eq "www.example.com"

ErrorDocument 403 /blog/error_redirect.php

<Files /error_redirect.php>
  AuthType none
</Files>

If your site is on a server running Ubuntu 14 (Trusty), make sure to change the ErrorDocument line to the full URL path. For example:

ErrorDocument 403 https://example.com/blog/error_redirect.php

Step 2 — Add code to your error_redirect.php file

Now that your .htaccess will redirect to your error page, you must put some code into this error page to correctly redirect back to your secure login. Add the following PHP code.

<?php
  header("Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
?>

If you now try to log in, you''ll see both the URL and login prompt change to https://example.com.

Issue with renewing a 'Let's Encrypt' certificate

The code may cause a 'Let's Encrypt' certificate to not renew properly. If you have added a 'Let's Encrypt' certificate to your domain, make sure to disable the code below in your .htaccess file when your certificate is about to renew. Once renewed, you can re-enable the code below.

 

How do I prevent image hotlinking?

Overview

Hot linking or bandwidth stealing is a common problem. It happens when people link to files and images on a different server and display them on their own website; this uses the bandwidth of the original owner at their expense.

Adding code to your .htaccess file

By entering the lines below into an .htaccess file, you can prevent hotlinking to your website:

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?example.com/.*$ [NC]
RewriteRule \.(gif|jpg)$ http://www.example.com/hotlink.gif [R,L]

In the example above, change example.com to your website URL. This causes any hotlinked image to fail to load. You can change the last line to point to any image you like. This image should explain that hot linking is disabled on your server.

Here is another example:

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http://example.com.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.example.com.*$ [NC]
RewriteRule .*\.(gif|jpg|jpeg|bmp)$ http://www.example.com/stophotlinking.jpg [R,NC]

You can change the last line to point to any image you like. This image should explain that hotlinking is disabled on your server.

Share this post

Comments (0)

Powered by Simple Blog