Using .htaccess with Apache on Azure Linux

8 minute read | By Anthony Salemo

This post will cover using .htaccess files with Apache HTTPD on Azure Linux offerings such as Azure Linux Virtual Machines and App Service Linux.

Overview

The .htaccess file is a file used by Apache’s HTTPD Web Server for configuration changes. This is a file that can be used across multiple locations - on a per-directory basis, and influences the behavior of the Web Server, depending on the configuration added in.

.htaccess files can only be used in Apache HTTPD environments. Servers not running Apache HTTPD will ignore this file - it will not be executed.

On Azure Linux Virtual Machines (or really, any Virtual Machine running Apache)

  • You’d need to install Apache’s HTTPD server
  • Enable Apache HTTPD to execute .htaccess files

On App Service Linux, Apache can run in the following scenarios:

  • With PHP 7.4 Blessed Images (or earlier)
  • With PHP 8.x Blessed Images when using the WEBSITES_DISABLE_FPM AppSetting
  • Custom Docker Images using Apache HTTPD server
  • Apache HTTPD on App Service Linux is already configured it act on .htaccess files, so no additional changes need to be made.

Some common use cases for using this file is:

  • non-www to www rewrites/redirects (or vice-versa)
  • HTTP to HTTPS redirects
  • Custom domain redirects (eg., site moved)
  • Content hosted in a sub directory
  • If httpd.conf or apache2.conf cannot be directly accessed

Linux Virtual Machines

Set up Apache

To use .htaccess files on a Virtual Machine, Apache HTTPD needs to be running. This example is using Ubuntu 20.04 (LTS).

  1. Install Apache HTTPD. After connecting to your Virtual Machine, run the following commands:
sudo apt-get update -yy && sudo apt-get install apache2 -yy
  1. Check if Apache HTTPD is running with:
sudo systemctl status apache2

This should show the following:

● apache2.service - The Apache HTTP Server
     Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2023-04-04 22:36:35 UTC; 1min 23s ago
       Docs: https://httpd.apache.org/docs/2.4/
   Main PID: 18699 (apache2)
      Tasks: 55 (limit: 4035)
     Memory: 8.8M
     CGroup: /system.slice/apache2.service
             ├─18699 /usr/sbin/apache2 -k start
             ├─18701 /usr/sbin/apache2 -k start
             └─18702 /usr/sbin/apache2 -k start
  1. At this point, if viewing the public IP address or your Virtual Machine (or FQDN), you should see the Apache2 Ubuntu Default Page.

NOTE: If using Azure Linux Virtual Machines, make sure ports 80 and/or 443 are opened on your Network Security Group (NSG), and that proper client traffic is allowed through - depending on whether or not you’re enabling SSL/TLS for Apache.

  1. Note, depending on the OS, your Apache installation path may differ. On Ubuntu, this should be under /etc/apache2 - other installations may have this under /etc/httpd

Enable .htaccess usage

With Apache HTTPD being installed, we can now enable the Web Server to read our .htaccess files.

Enable mod_rewrite

In your terminal, run the following commands:

sudo a2enmod rewrite
sudo systectl restart apache2

This will now enable the mod_rewrite module to do request rewriting. This is not enabled by default with Apache, so if you try to drop an .htaccess under your content directory, you’ll find your .htaccess file may not work.

Update sites-available

Lastly, you’ll need to update your 000-default.conf - this is located under /etc/apache2/sites-available. This is the default Virtual Host for non-TLS/SSL enabled Apache Web Servers. This is assuming there is no certificate added for this functionality yet.

Using a text editor like nano or vi, add the following commented section into your sites-available - the below example is a simplified 000-default.conf.

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        ### Add this block ####
        <Directory /var/www/html>
                Options Indexes FollowSymLinks
                AllowOverride All
                Require all granted
         </Directory>
</VirtualHost>

Lastly, run sudo systemctl reload apache2.

With this being done, you should now be able to utilize .htaccess files.

App Service Linux

App Service Linux can simply this process as mod_rewrite and the Directory directive for the default VirtualHost is already configured for Apache.

However, as called out in the overview section, Apache Web Servers only run on the following with App Service Linux:

  • With PHP 7.4 Blessed Images (or earlier)
  • With PHP 8.x Blessed Images when using the WEBSITES_DISABLE_FPM AppSetting (otherwise this defaults to NGINX)
  • Custom Docker Images using Apache HTTPD server

In this case, you can simply drop in an .htaccess file under /home/site/wwwroot (for Blessed Images) or where configured for your Custom Docker Image. This is only true for PHP “Blessed” Images

NOTE: For Custom Docker Images, the same logic will essentially apply as it does to Virtual Machines. Custom Docker Images are a customer responsibility, as this expects the image and application codebase to be maintained by the maintainer. Therefor, enabling Apache HTTPD with mod_rewrite and the correct Virtual Host set up is required still.

Examples

Redirect a single page

Redirect 301 /pagename.php http://www.myazureblog.com/pagename.html

Redirect an entire site

Redirect 301 / http://www.myazureblog.com/

Redirect an entire site to a sub folder

Redirect 301 / http://www.myazureblog.com/subfolder/

Redirect a sub folder to another site

Redirect 301 /subfolder http://www.myazureblog.com/

Redirect to different file extensions

This will redirect any file with the .html extension to use the same filename but use the .php extension instead.

RedirectMatch 301 (.*)\.html$ http://www.myazureblog.com$1.php

Redirect from old domain to new domain with full path and query string:

Options +FollowSymLinks
RewriteEngine On
RewriteRule ^(.*) http://www.myazureblog.com%{REQUEST_URI} [R=302,NC]

Turn off the DirectorySlash directive

This avoids Apaches default behavior to add a trailing slash and redirect when requesting a directory. If the request is seen as a directory & append a trailing slash to the request without browser redirect.

RewriteEngine On
DirectorySlash Off

RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !(.+)/$
RewriteRule ^(.*[^/])$ /$1/

Rewrite requests to a specific content directory

Certain frameworks serve content out of subdirectories, like Laravel (/public) and Yii (/web)

Serve content out of /public

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{REQUEST_URI} ^(.*)
    RewriteRule ^(.*)$ /public/$1 [NC,L,QSA]
</IfModule>

Serve content out of /web

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{REQUEST_URI} ^(.*)
    RewriteRule ^(.*)$ /web/$1 [NC,L,QSA]
</IfModule>

Rewrite requests from HTTP to HTTPS

RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Rewrite requests from non-wwww to www

RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Rewrite requests from www to non-wwww

RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Deny a specific IP address

Order Allow,Deny

Allow from [someIpAddress]

Deny from all

Deny a specific IP address while behind a proxy

You can make use of the X-Forwarded-For (XFF) header which will contain the “real” client IP making the address. This can be useful if being a proxy to avoid blocking certain users.

Else, the immediate IP address (i.e the proxy or last known IP) will be the one making the request which Apache will see.

Order Deny,Allow
Deny from all
SetEnvIf X-Forwarded-For "^1\.1\.1\.1" AllowAccess
Allow from env=AllowAccess

Potential issues

As convenient as .htaccess files are, they’re not completely recommended unless truly needed by the Apache HTTPD foundation - this can be read here.

Some reasons are:

  • Every time a document/file is requests from Apache HTTPD, it looks for a .htaccess file, in every single directory, that Apache is serving. This can cause performance issues if there are multiple .htaccess files as well.
  • Security - anyone changing this file has the ability to alter the way the HTTPD server is operating. It is better to change the httpd.conf or apache2.conf file (or Virtual Host files) where these can have specific permissions on it.

Troubleshooting

.htaccess is not being read

Validate the following:

  • That mod_rewrite is enabled and the VirtualHost is configured correctly with the correct content path. The .htaccess should be under a directory within this location.
  • That Apache was restarted after changing this configuration. If the .htaccess file itself was changed recently, reload Apache
  • That the .htaccess file has valid and correct syntax. If the logic is not correct in this file, it may silently fail.

Apache is not loading or starting

This can happen for various reasons, se sudo systemctl status apache to review the status and for any specific error messages.