How to restrict access by IP in Apache

Restricting access by IP in Apache shrinks the reachable surface area of admin panels, staging sites, and internal tools by allowing only trusted networks to hit specific URLs. It is a blunt instrument in the best way: fast to apply, hard to accidentally bypass, and great at stopping drive-by scans.

Apache 2.4+ enforces authorization with Require rules evaluated per request in the matching configuration context. The Require ip directive accepts single IPs, IPv4/IPv6 CIDR ranges, or multiple networks, and it is commonly placed inside <Directory> or <Location> blocks.

IP allowlists can misbehave behind reverse proxies or load balancers, because the address seen by Apache may be the proxy rather than the real client unless a trusted forwarded-IP setup (for example mod_remoteip) is in place. Apply restrictions narrowly, avoid mixing permissive Require all granted rules into the same protected context, and keep a recovery path (console or out-of-band access) in case access is blocked.

Steps to restrict access by IP in Apache:

  1. Identify the URL path or filesystem directory that should be reachable only from trusted addresses.

    Use <Location> for URL paths like /admin/, or <Directory> for filesystem paths like /var/www/html/admin.

  2. Create a dedicated configuration file for the restriction.
    $ sudoedit /etc/apache2/conf-available/restrict-admin-by-ip.conf

    On Ubuntu and Debian, /etc/apache2/conf-available keeps drop-in rules separate from /etc/apache2/sites-available.

  3. Add a Require ip rule for the protected path.
    <Location "/admin/">
        Require ip 192.0.2.40
    </Location>

    Examples use documentation ranges; replace them with real addresses or CIDR blocks for the trusted networks.

    Multiple Require lines are evaluated with logical OR by default; wrap requirements in <RequireAll> when combining IP allowlists with authentication directives.

    Behind a reverse proxy, Require ip matches the proxy address unless the real client IP is restored via a trusted-header configuration.

  4. Enable the new configuration snippet.
    $ sudo a2enconf restrict-admin-by-ip
    Enabling conf restrict-admin-by-ip.
    To activate the new configuration, you need to run:
      systemctl reload apache2
  5. Validate configuration syntax before reload.
    $ sudo apachectl configtest
    Syntax OK
  6. Reload Apache to apply the change.
    $ sudo systemctl reload apache2

    On RHEL-family systems, the unit is usually httpd.

    Reload applies immediately; a too-strict allowlist can block legitimate access to the protected path.

  7. Confirm the protected path returns a non-403 status from an allowed address.
    $ curl -I --interface 192.0.2.40 -H 'Host: host.example.net' http://192.0.2.40/admin/
    HTTP/1.1 200 OK
    Date: Sat, 10 Jan 2026 05:43:47 GMT
    Server: Apache/2.4.58 (Ubuntu)
    Last-Modified: Sat, 10 Jan 2026 05:43:47 GMT
    ETag: W/"9-6480220354b50"
    Accept-Ranges: bytes
    Content-Length: 9
    Content-Type: text/html

    Any non-403 status (200, 302, 401) indicates the request reached the protected resource.

  8. Confirm the protected path returns HTTP 403 from a disallowed address.
    $ curl -I -H 'Host: host.example.net' http://127.0.0.1/admin/
    HTTP/1.1 403 Forbidden
    Date: Sat, 10 Jan 2026 05:43:47 GMT
    Server: Apache/2.4.58 (Ubuntu)
    Content-Type: text/html; charset=iso-8859-1

    HTTP 403 confirms the IP restriction is enforced.