Restricting access to directories on Apache websites

There are many ways to go about restricting access to specific content within Apache. This article is simply going to show a couple of examples.

Some of these examples will show you how to restrict access to a directory with a username and password. For this guide, the htpasswd file will be placed in /etc/httpd/example-htpasswd. You can create a username and password for it by simply using the external third party site http://www.htaccesstools.com/htpasswd-generator or you can use the built in tool htpasswd.

A basic example for password protecting an entire website is below:

[root@web01 ~]# vim /etc/httpd/vhost.d/example.com.conf
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/vhosts/example.com
<Directory /var/www/vhosts/example.com>
	Options -Indexes +FollowSymLinks -MultiViews
	AllowOverride All

        # Password protect site
	AuthType Basic
	AuthName "Restricted"
	AuthUserFile /etc/httpd/example-htpasswd
	Require valid-user
</Directory>
...

If you wanted to only allow in specific IP’s or networks without a password and require everyone else on the internet to have a username/password:

[root@web01 ~]# vim /etc/httpd/vhost.d/example.com.conf
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/vhosts/example.com
<Directory /var/www/vhosts/example.com>
	Options -Indexes +FollowSymLinks -MultiViews
	AllowOverride All

	# Password protect site
	Allow from 127.0.0.1
	Allow from 1.2.3.4
	Allow from 192.168.1.0/24

	AuthType Basic
	AuthName "Restricted"
	AuthUserFile /etc/httpd/example-htpasswd
	Require valid-user

	# Allow password-less access for allowed IPs
	Satisfy any
</Directory>
...

Below is an example for password protecting WordPress’s wp-admin page via an .htaccess file:

[root@web01 ~]# vim /var/www/vhosts/example.com/wp-admin/.htaccess
# Password protect wp-admin
<Files admin-ajax.php>
    Order allow,deny
    Allow from all
    Satisfy any
</Files>
AuthType Basic
AuthName "Restricted"
AuthUserFile /etc/httpd/example-htpasswd
Require valid-user

Here is one to restrict access to a directory by only allowing in specific IP’s within example.com/admin:

[root@web01 ~]# vim /var/www/vhosts/example.com/admin/.htaccess
order deny,allow
deny from all
allow from 1.2.3.4
allow from 192.168.1.0/24

On Apache 2.4, here is how you can password protect an entire website excluding one URI. This is useful if you use something like CakePHP or Laravel where the physical directory doesn’t exist, it all just filters through the index.php file. In this example, any requests to example.com/test will not require a password, but anything else on example.com will require a username and password:

[root@web01 ~]# vim /etc/httpd/vhost.d/example.com.conf
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/vhosts/example.com/current/public
<Directory /var/www/vhosts/example.com/current/public>
	Options -Indexes +FollowSymLinks -MultiViews
	AllowOverride All
</Directory>

<Location "/">
	# Password protect site
	AuthType Basic
	AuthName "Restricted"
	AuthUserFile /etc/httpd/example-htpasswd
	Require valid-user

	# If the request goes to /test: bypass basic auth
	SetEnvIf Request_URI ^/test$ noauth=1
	Allow from env=REDIRECT_noauth
	Allow from env=noauth

	Order Deny,Allow
	Satisfy any
	Deny from all
</Location>
...

What happens when you want to password protect an aliased site? For instance, I have 2 domains, www.example1.com and www.example2.com. The www.example2.com is simply a ServerAlias defined within /etc/httpd/vhost.d/www.example1.com.conf. How can you go about password protecting www.example2.com without affecting www.example1.com? Simply add the following to the bottom of the .htaccess:

[root@web01 ~]# vim /var/www/vhosts/www.example.com/.htaccess
...
SetEnvIfNoCase Host example2\.com$ require_auth=true

AuthUserFile /etc/httpd/example2.com-htpasswd
AuthName "Password Protected"
AuthType Basic
Require valid-user
Order Deny,Allow
Satisfy any
Deny from all

Allow from env=!require_auth
...