As a web administrator, you may find it valuable to restrict some parts of a website from visitors, whether temporarily or on a permanent basis. While web applications may provide their own authentication and authorization methods, you can also rely on the web server itself to restrict access if these are inadequate or unavailable.
This tutorial will walk you through password-protecting assets on an Apache web server running on Ubuntu 20.04. This will provide your server with an extra layer of security.
To complete this tutorial, you will need:
One Ubuntu 20.04 server set up with a non-root user with sudo
privileges and firewall enabled. You can do this by following the Ubuntu 20.04 initial server setup guide.
The Apache web server installed on your Ubuntu server. If you haven’t already set one up, the How To Install the Apache Web Server on Ubuntu 20.04 tutorial can guide you. Be sure to complete Step 5 and have a virtual host file for your domain. This tutorial will refer to your_domain as an example throughout and use /etc/apache2/sites-available/your_domain.conf
for the virtual host file.
Your virtual host secured with SSL. Setting this up depends on whether you have a domain name for your site.
If you would like to set up a domain (optional), you can do so by purchasing a domain name on Namecheap, get one free on Freenom, or use the domain registrar of your choice. Additionally, you will need both of the following DNS records set up for your server. Follow this introduction to DigitalOcean DNS for details on how to add them.
your_domain
pointing to your server’s public IP address.www.your_domain
pointing to your server’s public IP address.Once you’ve completed these prerequisites, log into your server as the sudo
user and continue to the first step.
Let’s begin by updating our server and installing a package that we’ll need. In order to complete this tutorial, we will be using a utility called htpasswd
, part of the apache2-utils
package, to create the file and manage the username and passwords needed to access restricted content.
First, update your server’s package index:
- sudo apt update
Then install the Apache utilities package:
- sudo apt install apache2-utils
With this installed, you now have access to the htpasswd
command.
The htpasswd
command allows you to create a password file that Apache can use to authenticate users. You’ll create a hidden file for this purpose called .htpasswd
within your /etc/apache2
configuration directory.
The first time you use this utility, you need to add the -c
option to create the specified .htpasswd
file. Here, we specify a username (sammy
in this example) at the end of the command to create a new entry within the file:
- sudo htpasswd -c /etc/apache2/.htpasswd sammy
You will be asked to supply and confirm a password for the user.
Leave out the -c
argument for any additional users you wish to add, as in the following example, so you don’t overwrite the file:
- sudo htpasswd /etc/apache2/.htpasswd another_user
If you check the contents of the file, it will contain the username and the encrypted password for each record:
- cat /etc/apache2/.htpasswd
Outputsammy:$apr1$eponJaBR$9uyVIRpDpbHoseI.hS1cq/
another_user:$apr1$dDXiQxte$RGn3CVfFLQOPf5lSJgNvV1
Now you have your users and passwords in a format that Apache can read.
In this step, you need to configure Apache to check the .htpasswd
file before serving your protected content. You can do this in one of two ways: either directly in a site’s virtual host file or by placing .htaccess
files in the directories that need restriction. It’s generally best to use the virtual host file, but if you need to allow non-root users to manage their own access restrictions, refer to the second option to check the restrictions into version control alongside the website, or have a web application using .htaccess
files for other purposes already.
Note: You can perform the following options for any active virtual hosts. If you’re using your own, be sure to change any commands and values to reflect your configuration.
Choose the option that best suits your needs.
The first option is to edit the Apache configuration and add password protection to the virtual host file. This will generally give better performance because it avoids the expense of reading distributed configuration files. This option requires access to the configuration, which isn’t always available, but when you do have access, it’s recommended.
Begin by opening up the virtual host file that you wish to add a restriction to. For our example, we’ll be using the /etc/apache2/sites-available/your_domain.conf
file that holds the virtual host. Open up the file with a command-line text editor such as nano
:
- sudo nano /etc/apache2/sites-available/your_domain.conf
Inside, with the comments stripped, the file should look similar to the following:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName your_domain
ServerAlias www.your_domain
DocumentRoot /var/www/your_domain
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
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. In our example, we’ll restrict the entire document root, but you can modify this listing to only target a specific directory within the web space:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName your_domain
ServerAlias www.your_domain
DocumentRoot /var/www/your_domain
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory "/var/www/your_domain">
</Directory>
</VirtualHost>
Within this directory block, specify that you are setting up Basic
authentication. For the AuthName
, choose a realm name that will be displayed to the user when prompting for credentials. Use the AuthUserFile
directive to point Apache to the password file you created. Finally, make it a requirement that only a valid-user
may access this resource, which means anyone who can verify their identity with a password will be allowed in:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
ServerName your_domain
ServerAlias www.your_domain
DocumentRoot /var/www/your_domain
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory "/var/www/your_domain">
AuthType Basic
AuthName "Restricted Content"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Directory>
</VirtualHost>
Save and close the file when you are finished. If you are using nano
, you can do so by pressing CTRL + X
followed by Y
then ENTER
.
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:
- sudo systemctl restart apache2
Since systemctl
doesn’t display the outcome of all service management commands, use the the status
command to be sure the server is running:
- sudo systemctl status apache2
Output● apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor prese>
Active: active (running) since Fri 2022-04-29 17:12:24 UTC; 4s ago
Docs: https://httpd.apache.org/docs/2.4/
Process: 4493 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SU>
Main PID: 4514 (apache2)
Tasks: 55 (limit: 9508)
Memory: 5.8M
CGroup: /system.slice/apache2.service
├─4514 /usr/sbin/apache2 -k start
├─4516 /usr/sbin/apache2 -k start
└─4517 /usr/sbin/apache2 -k start
Now, the directory you specified should be password protected.
Apache can use .htaccess
files in order to allow certain configuration items to be set within a content directory. Since Apache has to re-read these files on every request that involves the directory, which can negatively impact performance, Option 1 is preferred, but if you are already using .htaccess
file or need to allow non-root users to manage restrictions, .htaccess
files make sense.
To enable password protection using .htaccess
files, open the main Apache configuration file with a command-line text editor such as nano
:
- sudo nano /etc/apache2/apache2.conf
Find the <Directory>
block for the /var/www/
directory that holds the document root. Update this line to reflect your document root. Next, turn on .htaccess
processing by changing the AllowOverride
directive within that block from None
to All
. The contents of this <Directory>
block will now read as follows:
. . .
<Directory /var/www/your_domain>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
. . .
Save and close the file when you are finished.
Next, add a .htaccess
file to the directory you wish to restrict. In our demonstration, we’ll restrict the entire document root (the entire website) which is based at /var/www/your_domain
, but you can place this file in any directory where you wish to restrict access:
- sudo nano /var/www/your_domain/.htaccess
Within this file, specify that you want to set up Basic
authentication. For the AuthName
, choose a realm name that will be displayed to the user when prompting for credentials. Use the AuthUserFile
directive to point Apache to the password file we created. Finally, you will require a valid-user
to access this resource, which means anyone who can verify their identity with a password will be allowed in:
AuthType Basic
AuthName "Restricted Content"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
Save and close the file. Restart the web server to password protect all content in or below the directory with the .htaccess
file:
- sudo systemctl restart apache2
Then run systemctl status
to verify the success of the restart:
- sudo systemctl status apache2
Output● apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor prese>
Active: active (running) since Fri 2022-04-29 17:18:17 UTC; 3s ago
Docs: https://httpd.apache.org/docs/2.4/
Process: 4721 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SU>
Main PID: 4744 (apache2)
Tasks: 55 (limit: 9508)
Memory: 5.9M
CGroup: /system.slice/apache2.service
├─4744 /usr/sbin/apache2 -k start
├─4745 /usr/sbin/apache2 -k start
└─4746 /usr/sbin/apache2 -k start
The directory you specified should now be password protected.
To confirm that your content is protected, try to access your restricted content in a web browser by navigating to https://your_domain_or_server_IP
.
You will be presented with a username and password prompt that looks like the following:
If you enter the correct credentials, you will be allowed to access the content. If you enter the wrong credentials or hit “Cancel”, you will receive the “Unauthorized” error page:
You’ve now set up basic authentication for your site.
There is much more that you can do with Apache configuration and .htaccess
. To learn more about the flexibility and power available in Apache configuration, try one of the following tutorials:
For a better understanding of the main configuration file, read the section about Getting Familiar with Important Apache Files and Directories in our Apache installation guide.
Learn more about how to set up virtual host files in Apache
Learn about rewriting URLs, customizing error pages like the previous “Unauthorized” message, or including common elements on all your pages with Server Side Includes in our guide How To Use the .htaccess File.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
For me this only worked after I put the configuration directives of <Directory> outside of the </VirtualHost> clause in the virtualhost config file (not within as shown in the picture).