.htaccess is a powerful tool that allows you to configure various settings for your website. It is commonly used on Apache web servers to control various aspects of website access and security. The file can be used to specify access control rules, rewrite URLs, and more.
Htaccess is short for Hypertext Access.
Some common uses of .htaccess
are:
- Setting up password protection for a directory or web page
- Redirecting URLs to different pages or domains
- Blocking access to specific IP addresses or ranges
The .htaccess
file is often placed in the root directory of a website. When a request to the web server is performed, Apache checks the .htaccess
file to see if there are any rules or directives that apply to the requested URL.
In this tutorial, we'll cover the basics of creating and editing the file and applying advanced configurations like URL rewriting, authentication, and caching.
Enabling .htaccess files
.htaccess
files are only utilized with an Apache webserver.
If you have not installed Apache on your AlphaVPS service, you can do so via the following commands:
- Debian/Ubuntu
sudo apt install apache2
- CentOS/AlmaLinux (RHEL-based distributions)
sudo yum install httpd
We will need to enable the use of .htaccess
files by modifying the configuration file of our Apache webserver. Depending on your OS, it is either found in the /etc/apache2
or /etc/httpd
directory. It is named either apache2.conf
or httpd.conf
.
Open the configuration via your preferred text editor.
nano /etc/apache2/apache2.conf
Locate the section that starts with <Directory>
and contains the directory path for the directory you want to allow .htaccess files in.
For example, if you want to allow .htaccess
files in the /var/www/html
directory, you would look for a section that looks like this:
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
The AllowOverride
line controls which directives in .htaccess
files are allowed to override the main Apache configuration. Change this line to All
to allow all directives in .htaccess files.
AllowOverride All
Save the configuration file, exit, and restart Apache via:
sudo systemctl restart apache2
Example .htaccess file
# Enable mod_rewrite
RewriteEngine On
# Redirect all traffic to HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Set default character set
AddDefaultCharset UTF-8
# Enable browser caching
ExpiresActive On
ExpiresDefault "access plus 1 month"
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
# Deny access to .htaccess and other sensitive files
<FilesMatch "^\.ht">
Order allow,deny
Deny from all
</FilesMatch>
# Password protect directory
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /path/to/.htpasswd
Require valid-user
Creating a file
As we noted, the .htaccess
file is usually located in the root directory of your website. The root directory is the top-level directory that contains all the files and subdirectories for your website.
Your website folders are usually stored in your web-root directory. It can be accessed by running:
cd /var/www
When you place the .htaccess file in the root directory of a website, it will apply to the entire website. If you place the file in a subdirectory, it will only apply to that directory and its subdirectories.
You can create a new .htaccess
file on your local computer and upload it with your other website files, or you can directly create it via the CLI by running:
sudo touch .htaccess
NOTE: Make sure that permissions are correctly set and that the file is in the desired directory. Do not forget the trailing .
in the name. This means that the file is hidden. The file can be properly visualized by adding the -h
flag to the ls
command.
ls -lah
Setting up password authentication
One of the most common use cases for .htaccess
is setting up access restrictions.
You will need to create a file named .htpasswd that contains the username and password for each user you want to allow access to the directory. You can use a tool like htpasswd
to generate the password file, or you can create it manually.
We will guide you through both options.
Manual creation
First, you will need to create a new empty file and name it .htpasswd
.
You can create it in a directory of your own preference, but you will need to point the path to it in your .htaccess
file. Make sure that it is a secure location inaccessible from the web.
The username and password are set in the file in the following format:
username:password
Of course, storing the data in plain text format is not a good idea at all. You can encrypt the password using the htpasswd
utility. To use htpasswd
to encrypt the password, run following command in your CLI:
htpasswd -nb username password
- username and password are variables for your actual values.
A similar output will be provided.
username:$apr1$gLn56B9N$q/va9eGI3DbC0yrtJdH4M.
Copy your output and replace the contents of .htpasswd
file with it.
Automatic creation
You can also create the .htpasswd
file via the htpasswd
utility.
Navigate to the desired directory and run the following command:
htpasswd -c .htpasswd username
- username is a variable for your actual value.
You will be prompted to add a password and confirm it.
Once this is done, the .htpasswd
file will be generated.
NOTE: The -c
flag creates the htpasswd
only if it is not already available in the specified directory. If the file is existing, you are able to use the htpasswd
utility to add additional users to that same file.
Configuration
You will need to add the following lines to your .htaccess
file:
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /path/to/.htpasswd
Require valid-user
/path/to/.htpasswd
needs to be replaced with the actual absolute path to your .htpasswd file.
Save, exit, and restart Apache again via the following command:
sudo systemctl restart apache2
In our case, we've put our .htaccess
file in a testdir
directory in our webroot.
Once we try to access our VPS via our IP and provide the path to our protected directory, we will be presented with a prompt for our credentials.
URL Rewriting
URL rewriting is a powerful feature of .htaccess
that allows you to modify the URLs of your website. This can be useful for improving the user experience, optimizing your site for search engines, or simplifying the structure of your site.
This .htaccess
functionality allows you to redirect URLs, hide file extensions, and many more.
URL rewriting is accomplished using the mod_rewrite
module in Apache.
You can enable mod_rewrite
by running the following command:
sudo a2enmod rewrite
Eventually, it can be disabled by running:
$ sudo a2dismod rewrite
URL redirecting
To configure URL redirecting using .htaccess, you can use the RewriteRule directive. Here is an example of how to redirect a URL via .htaccess
configuration:
RewriteEngine On
RewriteRule ^old-domain.com$ /new-domain.com [R=301,L]
old-domain
and new-domain
are variables for your own URLs.
You can redirect either a single page or a whole website. This is useful when you want to redirect your visitors after you have moved to a new domain or you have restructured your website's routes.
Status codes
HTTP status codes are returned by a server in response to a client request. They provide information about the status of the requested resource.
In our case, the status codes, which concern us are 301 & 302.
301 - indicates that the original URL has permanently moved to a new location, and search engines will update their index accordingly.
302 - indicates a temporary move, and search engines will continue to index the original URL.
How to redirect a page
You can redirect a single page to another one by adding these lines to your .htaccess
file.
RewriteEngine On
Redirect 301 /old-web-page.html https://www.example-web-site.com/new-web-page.html
As you can see, the structure can be modified to match your own preference.
In all cases, make sure that you replace old-web-page
, example-web-site
, and new-web-page
. Correct status codes are very important as well.
If you are willing to redirect your whole website to another one, your configuration would look like this:
RewriteEngine On
Redirect 301 https://www.old-example-web-site.com https://www.example-web-site.com
How to redirect a single URL
Add the following lines to your .htaccess
file and substitute the placeholder routes with your actual ones:
RewriteEngine On
RedirectMatch 301 /old-route/ /new-route/
Replace your actual routes with old-route
and new-route
. Specify the correct HTTP status code.
This will redirect any request for the /old-route/
URL path to the /new-route/
location with the specified HTTP status code. For example, a request to https://example.com/old-route/
would be redirected to https://example.com/new-route/
.
How to redirect a folder
You are also to redirect a request for a whole subdirectory/folder.
RewriteEngine On
RewriteRule ^/?old-folder/(.\*)$ /new-folder/$1 [R,L]
You need to replace your folder names.
Removing file extensions
A common .htaccess
use case is hiding file extensions. Basically, you will be able to transform example.com/catalog.html
to example.com/catalog
.
The benefits of removing the file extension are:
- Cleaner URLs, which are easier to type and remember.
- Make URLs more SEO keyword-friendly.
- You can hide technologies behind your website and change them without any visual changes to your URLs.
File extensions are removed from URLs by using the RewriteRule
directive with regular expressions to match URLs that include file extensions and redirect them to URLs without the extensions.
- Removing PHP file extensions
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [L,QSA]
- Removing HTML file extensions
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*)$ $1.html [L,QSA]
These rules use Apache's mod_rewrite module to rewrite URLs to include the .php
or .html
file extension when a request is sent to a URL without it. For example, if you request example.com/page
and there is a file called page.php
in the root directory of the website, this rule will rewrite the URL to example.com/page.php
.
Limiting IP Access
.htaccess
can also be used to allow or deny access to your website based on IP addresses or whole IP ranges.
This is possible after enabling the mod_authz_host
and mod_authz_core
modules for your Apache webserver.
You can do this by running the following commands:
sudo a2enmod authz_host
sudo a2enmod authz_core
After enabling the modules, restart Apache via:
sudo systemctl restart apache2
Once these modules are enabled, you can use .htaccess
to allow or deny access to your website based on IP addresses, as described in my previous answer.
Allowing IP access
You can allow access for a specific IP address by adding the following to your .htaccess
file:
order allow,deny
allow from "ip-address-here"
You are also able to specify a whole IP range with:
order allow,deny
allow from "ip-address-subnet-here"/"prefix-length"
Blocking IP access
You can block access for a specific IP address by adding the following to your .htaccess
file:
order deny,allow
deny from "ip-address-here"
A whole range can be specified with:
order deny,allow
deny from "ip-address-subnet-here"/"prefix-length"
Redirecting on error
You can use .htaccess
to redirect to a custom error page by using the ErrorDocument
directive. This directive allows you to specify a custom page to display in case of a specific error.
This can be done by adding the following lines to your .htaccess
files and replacing the page names with your own.
ErrorDocument 404 /error-404.html
ErrorDocument 500 /error-500.html
As you can see the directive allows you to specify a custom error page for different HTTP errors. You can specify multiple HTTP status codes.
For example, if error 404 was encountered, this would directly redirect us to our error-404.html
file, which is in the same directory, where you will provide your custom error message.