HTAccess
Using .htaccess files
Following are some common uses for .htaccess
files.
All the Webarchitects, Ecohost and Ecodissident shared hosting servers are running Apache and allow the use of .htaccess
files to configure the server, however the Webarchitects and Ecodissident servers are set to only allow some directives for security reasons.
Custom Error Pages
Create static (or dynamic) error pages and then specify them in the .htaccess
file for the site, for example:
ErrorDocument 404 /404.html
The Webarchitects shared hosting servers have the following error documents set, these can be overridden as above.
ErrorDocument 404 /wsh/404.shtml ErrorDocument 401 /wsh/401.shtml ErrorDocument 500 /wsh/500.shtml ErrorDocument 403 /wsh/403.shtml
See the Apache documentation for more options and details.
Redirect based on hostname
If your hosting has several host names and you want to redirect people to different pages based on the hostname they used to access the site you can add something like this to you main .htaccess
file for the site:
# Redirect requests for http://www.example.org/old-page.html # to http://www.example.org/new-page.html <IfModule mod_rewrite.c> RewriteCond %{HTTP_HOST} ^www\.example\.org RewriteRule ^/old-page.html$ new-page.html [R,L] <IfModule>
Or to redirect everything from one domain to another:
# Redirect requests for http://www.example.org/ # to http://www.example.net/ <IfModule mod_rewrite.c> RewriteCond %{HTTP_HOST} ^www\.example\.org RewriteRule ^/?(.*) https://www.example.net/$1 [R,L] <IfModule>
Allowed Overides
On the older Webarchitects and Ecodissident shared hosting servers we don't have AllowOveride All
set, but have:
AllowOverride AuthConfig Indexes FileInfo Limit
On the newer servers running Apache 2.4 we have:
AllowOverride Options=Indexes,MultiViews,XBitHack,IncludesNOEXEC,ExecCGI AuthConfig FileInfo Limit Nonfatal=Override
Some web applications, like Drupal generate .htaccess
files which contain directires which are not allowed and this results in servers errors, so Options
lines and php settings need to be commented out, for more on this see the Drupal page.
Enforcing HTTPS
If your site has a valid SSL/TLS certificate you can use a .htaccess
file to ensure that the site is only accessed via HTTPS with the following directives:
# Redirect HTTP to HTTPS # https://wiki.apache.org/httpd/RewriteHTTPToHTTPS <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTTPS} !=on RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L] </IfModule> # Strict Transport Security Header, this prevents clients # with STS support from accessing the site using HTTP # https://stackoverflow.com/questions/24144552/how-to-set-hsts-header-from-htaccess-only-on-https Header set Strict-Transport-Security "max-age=31536000" env=HTTPS # You might want to consider using some of the following rules # but only do this if you know what your are doing and test them # first, they are only supported by some Apache versions # https://serverfault.com/a/668302 #SSLOptions +StrictRequire #SSLRequireSSL # Use the following if you only want the site to work with one domain name #SSLRequire %{HTTP_HOST} eq "example.org"
Or an approach using If
rather than mod_rewrite
:
<If "req('X-Forwarded-Proto') != 'https'"> RedirectMatch 301 ^(?!/\.well-known/acme-challenge/).* https://www.example.org.uk$0 </If>
Generating directory file listings
If you want Apache to generate a listing of files in a directory, like here for example, then add a .htaccess
file like this to the directory where you want the listing:
Options +Indexes DirectoryIndex some-file-that-does-not-exist.html
To customise the HTML and CSS you need to use the ReadmeName
and HeaderName
directives, to specify different HTML to be used for the top and bottom of the page,for example:
HeaderName /top.html ReadmeName /bot.html
For more information see the Apache Module mod_autoindex documentation.
Serve .html files using mod-php
If you have .html
files that have PHP in them you can force these to be processed as PHP by creating a .htaccess
file containing:
# Force .php .html and .htm files to be served as PHP by handler AddHandler x-httpd-php .php .html .htm <IfModule mod_rewrite.c> RewriteEngine on RewriteRule \.(html|htm|php)$ - [H=application/x-httpd-php] </IfModule> # Force .php .html and .htm files to be served as PHP by type AddType application/x-httpd-php .php .html .htm <IfModule mod_rewrite.c> RewriteEngine on RewriteRule \.(html|htm|php)$ - [T=application/x-httpd-php] </IfModule>
HTTP Basic Authentication
Password protecting a directory
To password protect a directory create a .htaccess
file (or if one already exists add to it) and put this in it (changing example
to your username):
AuthUserFile /home/example/private/.htpasswd AuthType Basic AuthName "My Private Directory" require valid-user
Password protecting a file
To password protect a specific file, for example wp-login.php
, add the following to your existing .htaccess
file or if it doesn’t exist create one with the following in it (changing /home/example
to the path to the private directory for your account):
<FilesMatch "wp-login.php"> AuthName "Authorised Users" AuthType Basic AuthUserFile /home/example/private/.htpasswd require valid-user </FilesMatch>
The AuthName
variable value can contain any plain text message you wish.
Password protecting a URL
The above two examples for password protecting a directory or file doesn't work with a content management system like Drupal which will allow you to login via http://example.org/user/login
, this isn't a file or a directory, it is a path appended to index.php
(env var PATH_INFO) or login via a query string, http://example.org/?q=user/login
, (env var QUERY_STRING). So you need a mod_rewrite
rule to catch the query string and a Location
rule to match the path:
<IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{QUERY_STRING} user/login [NC] RewriteRule .* http://%{HTTP_HOST}/user/login? [R=301,L] </IfModule> <LocationMatch "/user/login"> AuthName "Authorised Users" AuthType Basic AuthUserFile /home/example/private/.htpasswd require valid-user </LocationMatch>
Generating a .htpasswd file
After adding the directives to a .htaccess
file you need to generate a .htpasswd
and then upload it to your private directory, this is how to create the file via the command line on a computer with the htpasswd script installed (htpasswd is in the apache2-utils debian package) :
htpasswd -sc .htpasswd username
If you want to add a username / password to an existing file:
htpasswd -s .htpasswd username
If you don’t have access to the command line on a computer with htpasswd
installed then you can use a online service to generate a .htpasswd
file, or get in touch and we can help you.
Combining HTTPS and HTTP Authentication
With Apache, by default, a combination of a Redirect
from HTTP to HTTPS and HTTP Authentication and an initial request for the unencrypted version of the site will result in an unencrypted prompt for the username and password before the redirect to HTTPS. Clearly this isn't wanted for two reasons, first it means that the username and password are sent unencrypted and secondly the user is prompted twice for the username and password (the first time via HTTP and the second time via HTTPS).
See this thread, this thread and this thread for discussion about the issue and work-arounds. A solution that works:
The way to get around this is to use SSLRequireSSL
and a HTTPS 403
error document, for example:
# Force HTTPS before Authentication # https://serverfault.com/a/668302 SSLRequireSSL ErrorDocument 403 https://www.example.org/
Add the above before the access control directives.
And if you want to use the default Webarchitects error pages:
ErrorDocument 404 https://example.org/wsh/404.shtml ErrorDocument 403 https://example.org/wsh/403.shtml
Further reading
The Apache documentation:
- Authentication and Authorization
- Access Control
- Password Formats
- Apache Module mod_auth_basic
- htpasswd – Manage user files for basic authentication
Errors caused by .htaccess files
Some content management systems and plugins for example WordFence and Drupal generate .htaccess
files which contain Apache directives which we don't allow them to contain for security reasons, these are easy to track down by looking at the ~/logs/error.log
which you have access to.