Apache 2.4 restrict URL to certain IPs

I am trying to restrict a specific URL to be available outside the network only to specific IP addresses. When a user outside tries to access that URL and not from the list of IPs he should be redirected to the homepage.

This is what I've tried so far without any luck. The last part it redirects everyone to the homepage regardless of IP.

<Location "/secret">
#    <If "%{REMOTE_ADDR} != -ipmatch '123.123.123.123/255.255.255.255'">
#    Redirect 303 "/secret" /
#    </If>

RewriteCond "%{REMOTE_ADDR}" "!123\.123\.123\.123"
RewriteRule .* / [R,L]

LogLevel debug rewrite:trace6
</Location>

PS: the /secret URL is in fact a virtual URL and does not exist physically on the drive.


Solution 1:

Use Order,Deny and allow to specify who has access to your vhost or location.

<VirtualHost *:80>
    ServerName example.net
    DocumentRoot /docroot

    <Directory "/docroot">
        Order Deny,Allow
        Deny from all
        Allow from 10.10.10.10
        Allow from 10.10.11.0/24
    </Directory>   
</VirtualHost>

When it comes to redirecting, think about a custom error page. This is much more general, because every unauthorized access should provoke a 403 error and thus can be evaluated easily.

I never did this with apache, but use this strategie with nginx. For apache somethin like this should do:

ErrorDocument 403 http://homepage.example.com

Custom error documents are configured using the ErrorDocument directive, which may be used in global, virtualhost, or directory context. It may be used in .htaccess files if AllowOverride is set to FileInfo. (from the apache docs)

Solution 2:

The Order, Deny, and Allow options have been replaced in Apache 2.4 with

<Directory /var/www/mysite.com/htdocs/public>
    Require all granted
</Directory>

You can explicitly restrict addresses through the use of the following:

<Directory /var/www/mysite.com/htdocs/public>
    Require all granted
    Require not ip 192.168.0.1
</Directory>

The exact opposite is true as well, to restrict all and only allow a sub-set use the following:

<Directory /var/www/mysite.com/htdocs/public>
    Require host example.com
    Require ip 192.168.0.1
</Directory>

More information is available on the Apache 2.4 access control documentation.

In regards to your question (edited my own due to a lack of points to add a comment,) you should be able to simply set an ErrorDocument with the index set as the URL-path:

<Directory /var/www/mysite.com/htdocs/public>
    Require host example.com
    Require ip 192.168.0.1
    ErrorDocument 401 /index.html
</Directory>

Hope this helps!

Solution 3:

For Apache 2.4, you can use <RequireAny>. You can do it in a vhost or an .htaccess file....

SetEnvIF IP xxx.xxx.xxx.xxx AllowThisIP  # Or X-Real-IP
SetEnvIF IP yyy.yyy.yyy.yyy AllowThisIP
<RequireAny>
  Require env AllowThisIP
  Require host example.com
</RequireAny>

Apache docs https://httpd.apache.org/docs/2.4/mod/mod_authz_core.html#requireany