Apache Access Control
Overview
Apache access control can be configured using either the directory level .htaccess
files or apache2.conf
, the main Apache configuration. You can allow or deny based on partial or full IP addresses, subnets, domain names, and even environment variables such as user-agent string.
Allow, Deny, & Order
To give you some context as to what this looks like, Figure 1-1 is an example of a Directory directive in the apache2.conf
file.
There are three directives that you will use to configure access control. The Allow
directive identifies which hosts can access the directory. Conversely, the Deny
directive identifies which hosts will be denied access to the directory. The Order
directive sets the default state to be either a whitelist or a blacklist configuration.
An example use case for the Order
directive might be something like Figure 1-2. During the development, you take a whitelist approach by allowing only the subnets where the system administrator and developer hosts reside and deny all other hosts. When the site is finally ready to be released, you will reverse the order of the directives and allow all hosts, except for known bad actors, like in Figure 1-3.
Access Control Rules
The rules are relatively straight forward when evaluating for access control:
- All rules will be evaluated, regardless of an early match. This is counterintuitive if you’ve ever configured access control lists in firewalls.
- If the requesting host doesn’t match in either
Allow
orDeny
, the default action is taken. - The last directive is the default action.
- If you chose
Allow
,Deny
the default action is to deny if no match is found in either theAllow
orDeny
directives. - If you chose
Deny
,Allow
the default action is to allow if no match is found in either theDeny
orAllow
directives.
- If you chose
- There cannot be any whitespace between the
Allow
andDeny
directives being set (only a comma). The syntax isOrder Allow,Deny
orOrder Deny,Allow
. - Changes require a restart,
apache2ctl restart
Syntax for the Allow and Deny directives
To create an access control rule, follow these syntax rules:
- Use
from
before you designate the target of the rule (e.g.Allow from
orDeny from
). - The target can be full domain names (e.g.
Allow from post288.com
). - The target can be partial domain names (e.g.
Deny from .com
). - The target can be IPv4 or IPv6 addresses (e.g.
Deny from 13.37.13.37
). - The target can be partial IPv4 or IPv6 addresses (e.g.
Allow from 10.0.0
). - The target can be network/subnet mask (e.g.
Deny from 13.37.13.0/255.255.255.0
). - The target can be a CIDR notation (e.g.
Allow from 10.0.0.0/24
). - The target can be all (e.g.
Allow from all
). - The target can be an environment variable (e.g.
Allow from env=siprnet_user
).
In Figure 1-4, you can check your configuration files for syntax errors without starting the server by using sudo apache2ctl configtest
or just sudo apache2ctl -t
command line option.
Troubleshooting Example
You are in the development stage of building the website. No one (Deny from all
) but you (Allow from 111.2.3.45
) should have access to it. You have read this far and have implemented the Directory directive that you think will work similar to Figure 1-5.
You restart Apache2 so the changes you made take effect, by typing apache2ctl restart
. You hop over to the browser and receive an error like this is Figure 1-6.
You go back, triple check everything, character by character. You run the syntax check,
It returns with Syntax OK. Next step, you remember the logs. Maybe something in there will give you a clue.
You find an entry similar to Figure 1-7 in the error.log file.
It looks like you are getting denied by server configuration. You know it’s hitting the intended directive, because it listed it by the path (/var/www/html/devsite
). The IP address matches the Allow directive, so why is it being denied? Look at Figure 1-8.
The Directory
directive did match given the results you saw in the error.log file. Moving onto the diamond named, “Which Order ?”. You have chosen Allow,Deny
, so follow the branch down to the right.
<Directory /var/www/html/devsite/>
AllowOverride None
Order Allow,Deny
Allow from 111.2.3.45
Deny from all
</Directory>
At the “Evaluate Allow directives” box, look at the Allow from 111.2.3.45
rule.
<Directory /var/www/html/devsite/>
AllowOverride None
Order Allow,Deny
Allow from 111.2.3.45
Deny from all
</Directory>
That is considered a match because that is your IP address and it matches in the error.log
file. At the “Allow has a match ?” diamond, you take the Yes path since it was a match.
The Yes path brings you to the “Evaluate Deny directives” box. Here you have a Deny from all
rule.
<Directory /var/www/html/devsite/>
AllowOverride None
Order Allow,Deny
Allow from 111.2.3.45
Deny from all
</Directory>
If you are following along on the flow diagram. This is where the light bulb comes on over your head. The Deny from all
will always match. So, if you follow the Yes path again, you notice that your requests will always be rejected. In other words, the Allow from 111.222.33.44
entry will never matter as long as the Deny from all
rule is there and Deny is the default. In Figure 1-9, if you remove the Deny from all
rule, only requests from 111.2.3.45 will be accepted because it matches an Allow rule and no longer matches a Deny rule.
The other hosts will not match a Allow rule, nor a Deny rule, and will fall into the default action. In this case, the default action is a Deny. Save the apache2.conf
file and restart Apache. Verify this works by checking from the IP in the Allow from 111.2.3.45
rule and a different IP address.
Summary
You should now have a basic understanding of the rules and syntax using the Allow, Deny and Order directives. You will use that knowledge to block unwanted traffic. Refer back to the flow diagram and your log files when you are troubleshooting allowed and denied traffic.
CPE