In this post I want to summarize some information about securing your Apache websites. This topic is well documented from the Apache Software Foundation.

By default we do not really need .htaccess to secure our Apache websites, in fact we should avoid to use it, you should prefer to configure all of these settings directly in the Apache config file or virtual host files.

The Apache config file by default is the /usr/local/etc/httpd/httpd.conf file.
In Debian GNU/Linux distributions like Ubuntu this is the /etc/apache2/apache2.conf file.

The benefit and only exception you should use a .htaccess file, is to give developers access to configure those settings without the need to provide them access to the central Apache config file itself.



Using .htaccess to secure Websites in Apache

To secure a website by using .htaccess, we need two files, a .htaccess file which is placed inside the web root folder, and a .htpasswd file which should explicit not be placed within the webserver’s URI space to prevent users from download it.

Each of the settings in the .htaccess file are effective in the root and all of its subfolder.

.htaccess files use the same syntax as the main configuration files.


In general, you should only use .htaccess files when you don’t have access to the main server configuration file. There is, for example, a common misconception that user authentication should always be done in .htaccess files, and, in more recent years, another misconception that mod_rewrite directives must go in .htaccess files. This is simply not the case. You can put user authentication configurations in the main server configuration, and this is, in fact, the preferred way to do things. Likewise, mod_rewrite directives work better, in many respects, in the main server configuration.

However, in general, use of .htaccess files should be avoided when possible. Any configuration that you would consider putting in a .htaccess file, can just as effectively be made in a section in your main server configuration file.

There are two main reasons to avoid the use of .htaccess files.

The first of these is performance. When AllowOverride is set to allow the use of .htaccess files, httpd will look in every directory for .htaccess files. Thus, permitting .htaccess files causes a performance hit, whether or not you actually even use them! Also, the .htaccess file is loaded every time a document is requested.

The second consideration is one of security. You are permitting users to modify server configuration, which may result in changes over which you have no control. Carefully consider whether you want to give your users this privilege. 

However, putting this configuration in your server configuration file will result in less of a performance hit, as the configuration is loaded once when httpd starts, rather than every time a file is requested.

The use of .htaccess files can be disabled completely by setting the AllowOverride directive to none:
AllowOverride None

Source: https://httpd.apache.org/docs/current/howto/htaccess.html

In order to enable and get the settings in your .htaccess file active, the Apache config file or virtual host file should allow to override settings by using the directive AllowOverride All as follows.

<Directory "/var/www/html">
	AllowOverride All
	Require all granted
    	</Directory>


In this case the settings from the .htaccess file will override same settings using in the native Apache config file for the specified directory.

To create the corresponding .htpasswd file you can use the htpasswd command (described below) in Linux or there are several websites outside which you can use to create both files.

A simple .htaccess file to secure your website and provide Basic authentication (username + password) will look like this.

As mentioned, the path of the corresponding .htpasswd file, including the username and encrypted password, should not be placed inside the web root folder defined in your Apache config or virtual host file.

Further as Basic authentication sent the password only in base64 encoding over the wire which can be easily converted into plaintext, you should only use it for secured SSL/TLS connections!

AuthName "Your Websitename"
AuthType Basic
AuthUserFile /var/www/.htpasswd
require valid-user



Using directly the Apache Configuration File to secure Websites in Apache

As mentioned by default you should prefer to configure the authentication settings directly in the Apache config file or virtual host file as follows for example. In this case we can also set the AllowOverride directive to None to completely disable the use of .htaccess.

AllowOverride Directive
https://httpd.apache.org/docs/current/mod/core.html#allowoverride

<Directory "/var/www//html">
        AllowOverride None
	AuthName "Your Websitename"
	AuthType Basic
	AuthUserFile /var/www/.htpasswd
	require valid-user
    	</Directory>


By default on Ubuntu, if you don’t configure the AllowOverride directive in your virtual host files, it is set to None in the central Apache config file, which can be checked in /etc/apache2/apache2.conf

# Sets the default security model of the Apache2 HTTPD server. It does
# not allow access to the root filesystem outside of /usr/share and /var/www.
# The former is used by web applications packaged in Debian,
# the latter may be used for local directories served by the web server. If
# your system is serving content from a sub-directory in /srv you must allow
# access here, or in any related virtual host.
<Directory />
	Options FollowSymLinks
	AllowOverride None
	Require all denied
</Directory>

<Directory /usr/share>
	AllowOverride None
	Require all granted
</Directory>

<Directory /var/www/>
	Options Indexes FollowSymLinks
	AllowOverride None
	Require all granted
</Directory>

#<Directory /srv/>
#	Options Indexes FollowSymLinks
#	AllowOverride None
#	Require all granted
#</Directory>


htpasswd Command

htpasswd is used to create and update the flat-files used to store usernames and password for basic authentication of HTTP users.

Resources available from the Apache HTTP server can be restricted to just the users listed in the files created by htpasswd. This program can only manage usernames and passwords stored in a flat-file.

htpasswd encrypts passwords using either bcrypt, a version of MD5 modified for Apache, SHA1, or the system’s crypt() routine. Files managed by htpasswd may contain a mixture of different encoding types of passwords; some user records may have bcrypt or MD5-encrypted passwords while others in the same file may have passwords encrypted with crypt().

Web password files such as those managed by htpasswd should not be within the Web server’s URI space — that is, they should not be fetchable with a browser.

This program is not safe as a setuid executable. Do not make it setuid. https://en.wikipedia.org/wiki/Setuid

When using the crypt() algorithm, note that only the first 8 characters of the password are used to form the password. If the supplied password is longer, the extra characters will be silently discarded.

The SHA encryption format does not use salting: for a given password, there is only one encrypted representation. The crypt() and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult.

The SHA and crypt() formats are insecure by today’s standards.

On the Windows platform, passwords encrypted with htpasswd are limited to no more than 255 characters in length. Longer passwords will be truncated to 255 characters.

The MD5 algorithm used by htpasswd is specific to the Apache software; passwords encrypted using it will not be usable with other Web servers. Usernames are limited to 255 bytes and may not include the character :.

Source: https://httpd.apache.org/docs/2.4/programs/htpasswd.html


Examples

As mentioned above, the password file should not be within the web server’s URI space. So the URI for the web server root in the example below should point to a different URI like /var/www/html/

Create a new password file. The user is prompted for the password. The password will be encrypted using the modified Apache MD5 algorithm. If the file does not exist, htpasswd will do nothing except return an error.
$ htpasswd -c /var/www/.htpasswd john

Adding or modifying password for user john
$ htpasswd /var/www/.htpasswd john

Remove user john
$ htpasswd -D /var/www/.htpasswd john

Verify password from user
$ htpasswd -vb /var/www/.htpasswd john <password to verify>


Using a specific encryption algorithm when adding a user. By default the modified Apache MD5 algorithm will be used as mentioned.

For bcrypt using -B
$ htpasswd -B /var/www/.htpasswd john

For MD5 using -m
$ htpasswd -m /var/www/.htpasswd john

For SHA using -s
$ htpasswd -s /var/www/.htpasswd john

For CRYPT using -d
$ htpasswd -d /var/www/.htpasswd john


Determine Encryption Algorithm from Password

There are five formats that Apache recognizes for basic-authentication passwords. Note that not all formats work on every platform:

You can derive from the prefix of the encrypted passwords which encryption algorithm was used.

As mentioned above, when using the htpasswd command to create a user and password, by default the modified Apache MD5 algorithm will be used.

bcrypt
“$2y$” + the result of the crypt_blowfish algorithm. See the APR source file crypt_blowfish.c for the details of the algorithm.

MD5
“$apr1$” + the result of an Apache-specific algorithm using an iterated (1,000 times) MD5 digest of various combinations of a random 32-bit salt and the password. See the APR source file apr_md5.c for the details of the algorithm.

SHA1
“{SHA}” + Base64-encoded SHA-1 digest of the password. Insecure.

CRYPT
Unix only. Uses the traditional Unix crypt(3) function with a randomly-generated 32-bit salt (only 12 bits used) and the first 8 characters of the password. Insecure.

PLAIN TEXT (i.e. unencrypted)
Windows & Netware only. Insecure.

Source: https://httpd.apache.org/docs/2.4/en/misc/password_encryptions.html





Access control

In Apache 2.2, access control based on client hostname, IP address, and other characteristics of client requests was done using the directives Order, Allow, Deny, and Satisfy..

In Apache 2.4, such access control is done in the same way as other authorization checks, using the new module mod_authz_host. The old access control idioms should be replaced by the new authentication mechanisms, although for compatibility with old configurations, the new module mod_access_compat is provided.

Mixing old and new directives
Mixing old directives like Order, Allow or Deny with new ones like Require is technically possible but discouraged. mod_access_compat was created to support configurations containing only old directives to facilitate the 2.4 upgrade. Please check the examples below to get a better idea about issues that might arise.


Upgrading to 2.4 from 2.2

In this example, there is no authentication and all requests are denied.
2.2 configuration
Order deny,allow
Deny from all

2.4 configuration
Require all denied


In this example, there is no authentication and all requests are allowed.
2.2 configuration
Order allow,deny
Allow from all


2.4 configuration
Require all granted


Source: http://httpd.apache.org/docs/current/upgrading.html


If you wish to restrict access to portions of your site based on the host address of your visitors, this is most easily done using mod_authz_host.

The Require provides a variety of different ways to allow or deny access to resources. In conjunction with the RequireAll, RequireAny, and RequireNone directives, these requirements may be combined in arbitrarily complex ways, to enforce whatever your access policy happens to be.

The Allow, Deny, and Order directives, provided by mod_access_compat, are deprecated and will go away in a future version. You should avoid using them, and avoid outdated tutorials recommending their use.

Source: http://httpd.apache.org/docs/current/howto/access.html


Authentication and Authorization

The password file should be placed somewhere not accessible from the web. This is so that folks cannot download the password file. For example, if your documents are served out of /usr/local/apache/htdocs, you might want to put the password file(s) in /usr/local/apache/passwd.

To create the file, use the htpasswd utility that came with Apache. This will be located in the bin directory of wherever you installed Apache. If you have installed Apache from a third-party package, it may be in your execution path.

Next, you’ll need to configure the server to request a password and tell the server which users are allowed access. You can do this either by editing the httpd.conf file or using an .htaccess file. For example, if you wish to protect the directory /usr/local/apache/htdocs/secret, you can use the following directives, either placed in the file /usr/local/apache/htdocs/secret/.htaccess, or placed in httpd.conf inside a section.

Let’s examine each of those directives individually. The AuthType directive selects the method that is used to authenticate the user. The most common method is Basic, and this is the method implemented by mod_auth_basic. It is important to be aware, however, that Basic authentication sends the password from the client to the server unencrypted. This method should therefore not be used for highly sensitive data, unless accompanied by mod_ssl. Apache supports one other authentication method: AuthType Digest. This method is implemented by mod_auth_digest and was intended to be more secure. This is no longer the case and the connection should be encrypted with mod_ssl instead.

The AuthName directive sets the Realm to be used in the authentication. The realm serves two major functions. First, the client often presents this information to the user as part of the password dialog box. Second, it is used by the client to determine what password to send for a given authenticated area.

So, for example, once a client has authenticated in the “Restricted Files” area, it will automatically retry the same password for any area on the same server that is marked with the “Restricted Files” Realm. Therefore, you can prevent a user from being prompted more than once for a password by letting multiple restricted areas share the same realm. Of course, for security reasons, the client will always need to ask again for the password whenever the hostname of the server changes.

The AuthBasicProvider is, in this case, optional, since file is the default value for this directive. You’ll need to use this directive if you are choosing a different source for authentication, such as mod_authn_dbm or mod_authn_dbd.

The AuthUserFile directive sets the path to the password file that we just created with htpasswd. If you have a large number of users, it can be quite slow to search through a plain text file to authenticate the user on each request. Apache also has the ability to store user information in fast database files. The mod_authn_dbm module provides the AuthDBMUserFile directive. These files can be created and manipulated with the dbmmanage and htdbm programs. Many other types of authentication options are available from third party modules.

Finally, the Require directive provides the authorization part of the process by setting the user that is allowed to access this region of the server. In the next section, we discuss various ways to use the Require directive.

AuthType Basic
AuthName "Restricted Files"
# (Following line optional)
AuthBasicProvider file
AuthUserFile "/usr/local/apache/passwd/passwords"
Require user rbowen


Source: https://httpd.apache.org/docs/2.4/howto/auth.html



apache2.conf File

On Ubuntu the following entry is enabled by default in the Apache config file, to tell Apache to look at the .htaccess file for access control information.

/etc/apache2/apache2.conf

When the server finds an .htaccess file (as specified by AccessFileName), it needs to know which directives declared in that file can override earlier configuration directives.

Only available in <Directory> sections

AllowOverride is valid only in <Directory> sections specified without regular expressions, not in <Location>, <DirectoryMatch> or <Files> or sections.

When this directive is set to None and AllowOverrideList is set to None, .htaccess files are completely ignored. In this case, the server will not even attempt to read .htaccess files in the filesystem.

When this directive is set to All, then any directive which has the .htaccess Context is allowed in .htaccess files.

<Directory "/var/www/html">
      AllowOverride All
</Directory>

Source: https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride





Also on Ubuntu and the Apache config file, by default access to the .htaccess and .htpasswd resp. all files with the prefix .ht is denied from being viewed by Web clients.

/etc/apache2/apache2.conf


Links

Authentication and Authorization
https://httpd.apache.org/docs/2.4/howto/auth.html

htpasswd – Manage user files for basic authentication
https://httpd.apache.org/docs/2.4/programs/htpasswd.html

Password Formats
https://httpd.apache.org/docs/2.4/en/misc/password_encryptions.html

Upgrading to 2.4 from 2.2
http://httpd.apache.org/docs/current/upgrading.html

Access Control
http://httpd.apache.org/docs/current/howto/access.html

.htaccess files
https://httpd.apache.org/docs/current/howto/htaccess.html