How to rewrite url with mod_rewrite for Apache on Debian 8

In this tutorial, we will learn how to manage URL rewriting using Apache 2 and the module mod_rewrite… This module allows you to rewrite URLs in a cleaner manner by translating human readable paths into coded friendly query strings or redirecting URLs based on additional conditions.

This guide is divided into two parts. The first installs the sample website and shows a simple rewrite example. The second part contains two more in-depth examples of commonly used rewriting rules.


Following this tutorial, you will need:

  • One Debian 8 server installed with initial server setup.
  • Apache 2 installed on the server following the article how to install Linux, Apache, MySQL, PHP (LAMP) stack on Debian 8.

Step 1 – Enabling mod_rewrite

First, we need to activate mod_rewrite… It is available, but not included with a clean install of Apache 2.

sudo a2enmod rewrite

It activates the module or warns you that the module is already enabled. Restart Apache for the changes to take effect.

sudo systemctl restart apache2

mod_rewrite is now fully enabled. In the next step, we will create a file .htaccesswhich we’ll use to define the rewrite rules for the redirect.

Step 2 – Setting up .htaccess

Файл .htaccess allows us to change our rewrite rules without accessing server config files. For this reason, .htaccess is critical to the security of your web application. The period that precedes the file name ensures that the file is hidden.

Note Any rules that you will put in the file .htaccess can also be placed directly in server config files. Actually, official Apache documentation recommends using server config files rather than .htaccess because Apache processes them faster.

However, in this simple example, the performance gain will be negligible. Also, by setting the rules .htaccess convenient, especially with multiple websites on the same server. It does not require a server reboot for the changes to take effect, and it does not require superuser privileges to edit these rules, which simplifies maintenance and changes possible from unprivileged accounts. Some popular open source software such as WordPress and Joomla often rely on the file .htaccess in software to modify and create additional rules as required.

We will need to install and secure a few more settings before we can get started.

By default Apache disallows the use of the file .htaccess to apply the rewrite rules, so you first need to allow changes to the file. Open the default config file in Apache using nano or your favorite text editor.

sudo nano /etc/apache2/sites-available/000-default.conf

Inside this file you will find a block <VirtualHost *:80>starting from the first line. Inside this block, add the following new block so that your config file looks like this. Make sure all blocks are indented correctly.


<VirtualHost *:80>
    <Directory /var/www/html>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Require all granted

    . . .

Save and close the file. Restart Apache for the changes to take effect.

sudo systemctl restart apache2

Now create a file .htaccess in the web root directory.

sudo nano /var/www/html/.htaccess

Add this line at the top of the new file to activate overwrite.


RewriteEngine on

Save the file and exit.

You now have a live file .htaccessthat can be used to manage the routing rules of your web application. In the next step, we will create sample site files that we will use to demonstrate the rewrite rules.

Step 3 – Configuring URL Rewriting

Here we will set up basic URL rewriting, which converts URLs to real code paths. Specifically, we will allow users to access. http://your_server_ip/about

Let’s start by creating a file named about.html in the web root directory.

sudo nano /var/www/html/about.html

Copy the following HTML code to a file and then save and close it.


        <title>О нас</title>
        <h1>О нас</h1>

You can access the page http: //your_server_ip/about.html, but note that if you try to access http: // your_server_ip / about you will see an error 404 Not Found… But for users to access the page using about instead of rewriting the rules, this very functionality will allow.

RewriteRules observes the following format:

General structure of RewriteRule

RewriteRule pattern substitution [flags]
  • RewriteRule defines a directive.
  • pattern is a regular expression that matches the desired string from the URL, browser view types.
  • substitution this is the path to the real URL, that is, the path of the Apache file servers.
  • flags optional parameters that you can change how the rule works.

Open the file .htaccess

sudo nano /var/www/html/.htaccess

After the first line, add RewriteRule marked in red and save the file.


RewriteEngine on
RewriteRule ^about$ about.html [NC]

In this case, ^about$ this is a template, about.html it is a replacement, and [NC] is a flag. Our example uses several characters with special meanings:

  • indicates the beginning of the URL, after your_server_ip/
  • $ indicates the end of the URL.
  • about matches the string “about”.
  • about.html is the actual file that is being accessed by the user.
  • [NC] is a flag that makes the rule case insensitive.

Now, you should be able to access http: // your_server_ip / about in your browser. In fact, with the rule shown above, the following URLs will point to about.html:

  • http://your_server_ip/about, due to the definition of the rule.
  • http://your_server_ip/About, Since it is generally not case sensitive.
  • http://your_server_ip/about.htmlsince the original proper filename will always work.

Below will not be:

  • http://your_server_ip/about/because the rule is clearly stated that there can be nothing after about help $symbol.
  • http://your_server_ip/contactbecause it will not match the about line in the rule.

You now have a live file .htaccess with a simple rule of thumb, you can modify and expand to suit your needs. In the following sections, we’ll show two additional examples of the most commonly used directives.

Example 1 – Simplifying a query string with a RewriteRule

Web applications often use query strings that are appended to the URL using a question mark ( ?) after the address. Separate parameters are separated using the ampersand (&). Query strings can be used to pass additional data between individual application pages.

For example, search results pages written in PHP might use a URL like… In this example, two additional parameters pass an imaginary result.php application script: item with meaning shirt and author with meaning andreyex… The application can use the information in the query string to build the correct page for the visitor.

Apache rewrite rules are often used to simplify long and unsightly links like the one above into friendly URLs that are easier to type and interpret visually. In this example, we would like to simplify the link above to do and parameter values author and grayex to the previous address, but without the query string and script name.

Here’s one rule of thumb to implement this:

A simple example

RewriteRule ^shirt/andreyex$ results.php?item=shirt&author=andreyex [QSA]

shirt/andreyex are explicitly matched in the requested address and Apache has instructed to run instead results.php?item=shirt&author=andreyex

флаги [QSA] commonly used in rules[ перезаписи. Они говорят Apache, чтобы добавить любые дополнительные строки запроса к обслуживаемому URL. Без этого, дополнительная строка запроса будет отбрасываются.

Хотя этот метод позволяет достичь желаемого эффекта, как имя элемента и author жестко закодированы в правила. Это означает, что правило не будет работать для любыми другими предметами, например pants, или author, как destroyer.

Для того, чтобы сделать правило более общо, мы можем использовать регулярные выражения, чтобы соответствовать части исходного адреса и использовать те части в схеме замещения. Модифицированное правило будет выглядеть следующим образом :

Простой пример

RewriteRule ^([A-Za-z0-9]+) / (andreyex | destroyer | fall | spring) results.php? item = $ 1 & author = $ 2 [QSA]

The first group regex in parentheses matches a string containing alphanumeric characters and numbers like shirt или pants and stores the matched chunk as a variable $1… The second group of expressions in parentheses matches exactly andreyex, destroyer, fall or spring, and also stores the matched fragment as $2

The matched snippets are then into the resulting URL into variables item and author instead of hard shirt and andreyexthat we used before.

The above will transform, for example at… This example is also for the future, allowing multiple elements and author to be rewritten correctly using a single rule.

Example 2 – Adding a Condition Logically Using RewriteConds

The rewriting rules are not necessarily always evaluated one after the other without any restrictions. Directive RewriteCond allows us to add conditions to our rewrite rules to control when the rules are processed. RewriteConds observes the following format:

General structure of RewriteCond

RewriteCond TestString Condition [Flags]
  • RewriteCond defines the directive RewriteCond
  • TestString this is the tested string.
  • Condition it is a pattern or condition to match.
  • Flags optional parameters that can change the conditions and rating rules.

If has RewriteCond value is true, then RewriteRule will be reviewed immediately after. If this is not the case, then the rule will be dropped. Multiple RewriteCond can be used one after the other, and with default behavior, they should all evaluate to be true in the following rule for consideration.

As an example, let’s say you would like to redirect all requests for non-existent files and directories on your site back to the home page instead of showing the default error page. 404 Not Found… This can be achieved with the following rule conditions:

Redirect all requests for non-existent files and directories to the main page

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /

Considering the above:

  • %{REQUEST_FILENAME} this is the line to check. In this case, the requested file name, which is a system variable available for each request.
  • -f embedded in a condition that checks if the requested name exists on disk and is a file. ! - It is a negation operator. In combination !-f evaluates to true only if the specified name does not exist or is not a file.
  • The same way , !-d evaluates to true only if the specified name does not exist or is not a directory.

RewriteRule The last line will only take effect for requests for non-existent files and directories. RewriteRule By itself is very simple and redirects every request to site root.


mod_rewrite a useful Apache module that can be effectively used to provide human readable URLs. In this lesson, you learned how to use the directive RewriteRule to redirect URLs, including from the query string. You also learned about redirecting url using the directive RewriteCond

If you want to know more about mod_rewrite, look at introduction to mod_rewrite Apache and Apache official documentation for mod_rewrite