Using .htaccess with Apache on Azure Linux
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).
- Install Apache HTTPD. After connecting to your Virtual Machine, run the following commands:
sudo apt-get update -yy && sudo apt-get install apache2 -yy
- 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
- 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.
- 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.