Apache: Restrict access by IP address
Crude way to stop an attack in case of an emergency.
Keep in mind that this is a static configuration, which is not very effective against adversarial attacks when an attacker constantly changes their tactics.
This guide does not cover managing .htaccess
file.
Locating config files
Before applying the changes we need to find the location of the config files. The location can vary depending on the way Apache was been installed. To look for the configuration we can run the following command:
apachectl -S
# or
apache2ctl -S
and look for ServerRoot
# apachectl -S
VirtualHost configuration:
ServerRoot: "/usr/local/apache2"
...
Alternatively we can run the following command and look for the location of the bin
directory.
which httpd ; which apache ; which apache2
The usual places where the configuration is stored is
/etc/apache2/
/etc/httpd/
/etc/httpd/conf
/usr/local/apache2
/opt/apache2 # usually if installed from source
C:\Program Files\Apache Software Foundation\Apache2.4\ # Windows
/usr/local/etc/httpd/ # Mac OS
The virtual host configuration can be found in the conf
folder under extra/httpd-vhosts.conf
or /etc/apache2/sites-available/000-default.conf
or /etc/apache2/sites-available/example.conf
.
Restricting a single IP
The module that supports the following directives is mod_authz_host
.
These are the examples of configuration on the directory level:
<Directory "/opt/www/dir">
...
<RequireAll>
Require all granted
Require not ip 8.8.8.8
</RequireAll>
</Directory>
On the virtual host level:
<VirtualHost *:80>
...
<Location "/">
<RequireAll>
Require all granted
Require not ip 8.8.8.8
</RequireAll>
</Location>
</VirtualHost>
On the endpoint level:
<VirtualHost *:80>
...
<Location "/login"> # notice endpoint here
<RequireAll>
Require all granted
Require not ip 8.8.8.8
</RequireAll>
</Location>
</VirtualHost>
Managing a denylist
To store denylist in a file we can use Include
directory:
<RequireAll>
Require all granted
Include /etc/apache2/denylist.conf
</RequireAll>
The denylist.conf
can contain each directive divided by a newline.
# cat denylist.conf
Require not ip 8.8.8.8
Require not ip 9.9.9.9
Restrict multiple IPs
The directive supports providing multiple IPs along with CIDR ranges and partial IPs.
# single IP
Require not ip 8.8.8.8
# multiple IPs
Require not ip 8.8.8.1 8.8.8.2 8.8.8.3
# partial IP
Require not ip 192.168
# CIDR range
Require not ip 9.9.9.0/24
Error message
The default error message is a 403 Forbidden
.
# curl localhost:8080
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
</body></html>
Applying configuration
There are many different ways to apply and reload the configuration depending on the way Apache was installed. The following example should restart the server gracefully.
apachectl configtest
# or
httpd -M
# or
apache2 -M
to test the configuration.
apachectl -k graceful
# or
/etc/init.d/httpd graceful
# or
/sbin/service httpd graceful
# or
/etc/init.d/apache2 reload
# or
sudo service apache2 reload
# or for Windows
httpd.exe -k restart
# or
apache.exe -k restart
to reload.