Skip to content

HOWTO devops Apache2_password_protect

steveoro edited this page Apr 14, 2021 · 2 revisions

HOWTO: protect a full directory tree of Apache2 content behind login wall

References:

Prerequisites:

  • Ubuntu 18.04
  • A sudo user on the server
  • Apache2 web server
  • site secured with SSL

Install + setup

  $> sudo apt update
  $> sudo apt install apache2-utils

Create the password file:

  $> sudo htpasswd -c /etc/apache2/.htpasswd authuser1

This will ask you to supply and confirm a password for authuser1. If you want to add another user, then leave out the -c argument with htpasswd command.

You can see the user name and the encrypted password for each record by running: cat /etc/apache2/.htpasswd

Configuring Apache Password Authentication

Two possible options: VHost with Basic Auth directory configuration vs. .htaccess file.

Option 1: Configuring Access Control within the Virtual Host Definition (Preferred)

This will generally give better performance because it avoids the expense of reading distributed configuration files.

  $> sudo vi /etc/apache2/sites-enabled/default-ssl.conf

Authentication is done on a per-directory basis. To set up authentication, you will need to target the directory you wish to restrict with a <Directory ___> block.

You'll need to add Basic Auth to each directory group. Something like this:

<VirtualHost *:80>
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/html
  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined

  <Directory "/var/www/html">
      AuthType Basic
      AuthName "Restricted Content"
      AuthUserFile /etc/apache2/.htpasswd
      Require valid-user
  </Directory>
</VirtualHost>

In case you're operating a backend service running with a reverse proxy on an internal port, you can use an additional internal Proxy block instead of the Directory to restrict the proxied location with Basic Auth:

<VirtualHost *:80>
  ServerAdmin webmaster@localhost
  # (No DocumentRoot since this a reverse-proxy backend)
  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined

  ProxyTimeout      60
  ProxyPreserveHost	On
  ProxyPass         /   http://localhost:8080/
  ProxyPassReverse 	/   http://localhost:8080/

  <Proxy http://localhost:8080>
      Order deny,allow
      Allow from all
      Authtype Basic
      Authname "Restricted content"
      AuthUserFile /etc/apache2/.htpasswd
      Require valid-user
  </Proxy>
</VirtualHost>

Before restarting the web server, you can check the configuration with the following command:

  $> sudo apache2ctl configtest

If everything checks out and you get Syntax OK as output, you can restart the server to implement your password policy.

Since systemctl doesn’t display the outcome of all service management commands, we’ll use the the status to be sure the server is running:

  $> sudo systemctl restart apache2
  $> sudo systemctl status apache2

Option 2: Configuring Access Control with .htaccess Files

Apache can use .htaccess files in order to allow certain configuration items to be set within a content directory. Apache has to re-read these files on every request that involves the directory and this can impact performance.

Edit Apache configuration:

  $> sudo vi /etc/apache2/apache2.conf

Find the block for the /var/www directory that holds the document root. Turn on .htaccess processing by changing the AllowOverride directive within that block from None to All:

# [...]
<Directory /var/www/>
  Options Indexes FollowSymLinks
  AllowOverride All
  Require all granted
</Directory>
# [...]

Next, we need to add an .htaccess file to the directory we wish to restrict:

  $> sudo vi /var/www/html/.htaccess

Set the restricted content to require authuser1:

AuthType Basic
AuthName "This is RESTRICTED content"
AuthUserFile /etc/apache2/.htpasswd
Require authuser1

Restart the server:

  $> sudo systemctl restart apache2
  $> sudo systemctl restart apache2

Troubleshooting

The server can't read the password file

This happened on our Ubuntu 14 setup.

You may need to grant permission to the www-data user to be able to read the .htpasswd file:

  $> chown www-data:www-data /etc/apache2/.htpasswd
  $> chmod 0660 /etc/apache2/.htpasswd

The restricted app can't be accessed

If the new app under restricted content is installed on a different port, remember to open the port on the firewall as usual. Assuming the new port is '81':

  $> ufw status
  $> ufw allow 81/tcp
  $> ufw reload
  $> ufw status
Clone this wiki locally