RewriteMap hosts-allow txt:/conf/hosts-allow
RewriteCond "${hosts-allow:%{HTTP:X-REAL-IP}|NOT-FOUND}" "=NOT-FOUND"
RewriteRule ^/login/.* - [R]
There are a few issues here...
The X-REAL-IP
is unlikely to be set unless you are behind some kind of proxy server. However, X-REAL-IP
is non-standard, so unless you specifically know this is the header to check then this is going to be empty (the rewrite-map lookup will always fail).
Using the R
(redirect
) flag without specifying a substitution string (ie. -
) doesn't do anything.
The L
flag is omitted so processing continues anyway.
You've not explicitly stated the context in which these directives are being used (server, virtualhost, directory or .htaccess
), however, the pattern ^/login/.*
will only match in a server or virtualhost context.
RewriteCond %{REMOTE_ADDR} ^xxx\.xxx\.xxx\.xxx
RewriteCond %{HTTP_HOST} ^(m|www)\.example.com/login$ [NC]
RewriteRule ^/login(.*) [PT,L]
Again, there are a few issues here...
The HTTP_HOST
contains the requested hostname only (eg. www.example.com
), it does not contain the URL-path. So, the above condition that attempts to match against ^(m|www)\.example.com/login$
will never be successful.
UPDATE: However, do you need to check the requested hostname? Are you accepting requests to multiple hosts/domains and you need to differentiate?
You are also missing a substitution string (2nd argument) in the RewriteRule
directive. Well, [PT,L]
will be seen as the substitution string which will just "break".
<Location "/login" >
Order Deny,Allow
Deny from all
Allow from xxx.xxx.xxx.xxx
</Location >
I presume that the instruction on example.conf is override by mod_rewrite
Is mod_rewrite activated at the last of all other conf files ?
Well, mod_rewrite is actually processed early. And <Location>
sections are merged late. Not sure why this wouldn't have worked (without seeing the rest of your config), unless mod_rewrite was triggering an external redirect?
Try something like the following instead using mod_rewrite. This would need to go before existing mod_rewrite directives.
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^xxx\.xxx\.xxx\.xxx
RewriteRule ^/?login - [F]
Where xxx.xxx.xxx.xxx
is your (external) IP address.
This would serve a 403 Forbidden for any request that starts /login
from an IP address that is not the one stated.
Note that this will not work if your site is behind a proxy server, since REMOTE_ADDR
will always be the IP address of the proxy server, not the user making the request.
UPDATE: What should i do if the site is behid a proxy ?
You would need to know the method by which the proxy server is passing the client IP address. You can do this by analysing the HTTP request headers that are reaching your application server (or ask the manager of the proxy server).
The defacto standard is the X-Forwarded-For
HTTP request header (the standarized version is the Forwarded
header - but this is far less common currently). However, this could literally be anything, such as X-REAL-IP
that you used in your first example.
Note that the X-Forwarded-For
header is a comma-space separate list of the IP addresses. The client's IP address is first, followed by the IP address of each proxy server that the request passes through (if more than 1).
For example, modifying the above (mod_rewrite) example, this becomes:
RewriteCond %{HTTP:X-Forwarded-For} !^xxx\.xxx\.xxx\.xxx
RewriteRule ^/?login - [F]
But note that you should only use this method if you know your server is behind a proxy - since this is easily faked otherwise.