logo
Apache Lounge
Webmasters

 

About Forum Index Downloads Search Register Log in RSS X


Keep Server Online

If you find the Apache Lounge, the downloads and overall help useful, please express your satisfaction with a donation.

or

Bitcoin

A donation makes a contribution towards the costs, the time and effort that's going in this site and building.

Thank You! Steffen

Your donations will help to keep this site alive and well, and continuing building binaries. Apache Lounge is not sponsored.
Post new topic   Forum Index -> Apache View previous topic :: View next topic
Reply to topic   Topic: Reverse proxy IP whitelist
Author
Krillian



Joined: 17 Nov 2022
Posts: 5

PostPosted: Thu 17 Nov '22 11:31    Post subject: Reverse proxy IP whitelist Reply with quote

Hi,

I am trying to limit which IPs will be allowed to access the Proxy site. I understand that I can use the following between the <Proxy> tags

Order deny,allow
Deny from all
Allow from 127.0.0.1, 58.64.198.68
Satisfy any

But is it possible to have the IPs in a separate text file? If so, could you please point me to an example.

Also if the text file is updated with new IPs, will apache need to be restarted, or does it keep reading the text file while running, not just once during the start?

Thank you in advance!
Back to top
tangent
Moderator


Joined: 16 Aug 2020
Posts: 305
Location: UK

PostPosted: Sun 20 Nov '22 21:49    Post subject: Reply with quote

This is can be achieved using some mod_rewrite logic with a RewriteMap file, where client IPs are listed one per line in a key/value file, e.g.
Code:

# List of client IP addresses (IPV4) allowed access.
#
192.168.1.2   allow

Below is sample code, covering any site request, where the client IP address has been saved in variable CLIENT_IP (rather than REMOTE_ADDR). See this post for mod_rewrite logic to set this variable, and why REMOTE_ADDR can't always be trusted https://www.apachelounge.com/viewtopic.php?t=8951#41440.
Code:

# Define whitelist IPs map file
#
RewriteMap whitelist-ips txt:/apache24/conf/whitelist-ips.map

# Check if client IP is allowed access in the whitelist map file, and send a 403 response if not.
#
RewriteCond ${whitelist-ips:%{ENV:CLIENT_IP}|block} '(.+)'
RewriteCond %1 '!allow' [NC]
RewriteRule .* - [L,R=403]

You can obviously update the RewriteRule to restrict access to different site locations, etc.

Note as it stands this solution only works with IPv4 addresses, and doesn't support subnet ranges (though you could extend the logic to cope with them).

Re your other question over file updates, the answer is if Apache is running as a service/daemon, then it will automatically reload the map file if it gets updated. I have used similar map file concept in a production environment, with large map files, and it works well.

Hope this helps.
Back to top
Krillian



Joined: 17 Nov 2022
Posts: 5

PostPosted: Mon 21 Nov '22 14:00    Post subject: Reply with quote

Hi, thank you very much for your detailed response.

So it wasn't blocking anyone at first. Then I realized I probably need to add "RewriteEngine on" and it started blocking.

But now it makes no exception to IPs in the whitelist...

Checked and disable my ip6 in case that was the issue.

Are there any specifics to permissions of the map file? I've just put it in the same directory as the website config file. It definitely knows it's there, as if I remove it apache complains. But perhaps apache needs ownership of the file?
Back to top
tangent
Moderator


Joined: 16 Aug 2020
Posts: 305
Location: UK

PostPosted: Tue 22 Nov '22 0:17    Post subject: Reply with quote

Have you included the additional rewrite logic from post https://www.apachelounge.com/viewtopic.php?t=8951#41440, to set the CLIENT_IP variable based on REMOTE_ADDR, and possible upstream proxy?
Code:
RewriteCond %{REMOTE_ADDR} '^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$'
RewriteRule .* - [E=X_RA:%1,NE]

RewriteCond %{HTTP:X-Forwarded-For} '([\d\.]+)([,\s]*)' [NV]
RewriteRule .* - [E=CLIENT_IP:%1,NE,S=1]
RewriteCond %{ENV:X_RA} '(.+)'
RewriteRule .* - [E=CLIENT_IP:%1,NE]

If not, add the above before your whitelist code.

If things still don't work for you, then up the loglevel for mod_rewrite so you can see what's going on (in the error log file):
Code:
LogLevel rewrite:trace8

These are the relevant entries in my test server log file, where you can see the map file lookup, etc.
Code:
[Sun Nov 20 19:32:46.494457 2022] [rewrite:trace5] [pid 6616:tid 1880] mod_rewrite.c(486): [client 192.168.1.2:53546] 192.168.1.2 - - [192.168.1.2/sid#16fe3b82108][rid#16fe40fa2c0/initial] cache lookup OK: map=whitelist-ips[txt] key=192.168.1.2 -> val=allow, referer: https://192.168.1.2/
[Sun Nov 20 19:32:46.494457 2022] [rewrite:trace4] [pid 6616:tid 1880] mod_rewrite.c(486): [client 192.168.1.2:53546] 192.168.1.2 - - [192.168.1.2/sid#16fe3b82108][rid#16fe40fa2c0/initial] RewriteCond: input='allow' pattern='(.+)' => matched, referer: https://192.168.1.2/
[Sun Nov 20 19:32:46.494457 2022] [rewrite:trace4] [pid 6616:tid 1880] mod_rewrite.c(486): [client 192.168.1.2:53546] 192.168.1.2 - - [192.168.1.2/sid#16fe3b82108][rid#16fe40fa2c0/initial] RewriteCond: input='allow' pattern='!allow' [NC] => not-matched, referer: https://192.168.1.2/
Back to top
Krillian



Joined: 17 Nov 2022
Posts: 5

PostPosted: Mon 28 Nov '22 6:56    Post subject: Reply with quote

Ah, sorry missed that, all makes sense now.

Thank you very much!
Back to top
Krillian



Joined: 17 Nov 2022
Posts: 5

PostPosted: Mon 28 Nov '22 7:39    Post subject: Reply with quote

Last question (hopefully), is it possible to include a whole subnet with this method?

So for example if I wanted any IP from 192.168.0.1 to 192.168.0.254 to be whitelisted, would I need to enter each IP individually or is there something like 192.168.0.0/24 that would work?
Back to top
tangent
Moderator


Joined: 16 Aug 2020
Posts: 305
Location: UK

PostPosted: Mon 28 Nov '22 13:11    Post subject: Reply with quote

I sensed that might be your next question, since I previously faced the same dilemma. Handling subnets is more tricky.

Apache expressions https://httpd.apache.org/docs/current/expr.html are pretty powerful, and do support IP address/subnet matches using the -ipmatch function (both IPv4 and IPv6). So you can do things such as:
Code:
RewriteCond expr "! %{ENV:CLIENT_IP} -ipmatch '192.168.0.0/24'"
RewriteRule .* - [L,R=403]

If you want to check for more than one subnet, you need to reverse the logic and skip the redirect rule, e.g.
Code:
RewriteCond expr "%{ENV:CLIENT_IP} -ipmatch '192.168.0.0/24'" [OR]
RewriteCond expr "%{ENV:CLIENT_IP} -ipmatch '192.168.1.0/24'" [OR]
RewriteCond expr "%{ENV:CLIENT_IP} -ipmatch '192.168.2.0/24'"
RewriteRule .* - [S=1]
RewriteRule .* - [L,R=403]

However, I can't see a way to combine this expression capability with RewriteMap file lookups, so using this approach you'd have to hard code your subnets into the configuration, which means you can't change entries on the fly.

In the past I went with this compromise solution for IPv4 which allows for limited subnet lookup capability.
Code:
# Split the CLIENT_IP into octets.
#
RewriteCond %{ENV:CLIENT_IP} '^(\d+)\.(\d+)\.(\d+)\.(\d+)$'
RewriteRule .* - [E=IP_A:%1,E=IP_B:%2,E=IP_C:%3,E=IP_D:%4]

# Define whitelist IPs map file.
#
RewriteMap whitelist-ips txt:/apache24/conf/whitelist-ips.map

# Check if client IP or its boundary subnet is allowed access in the whitelist map file, and send a 403 response if not.
#
RewriteCond ${whitelist-ips:%{ENV:IP_A}.%{ENV:IP_B}.%{ENV:IP_C}.%{ENV:IP_D}|block} ^allow$ [NC,OR]
RewriteCond ${whitelist-ips:%{ENV:IP_A}.%{ENV:IP_B}.%{ENV:IP_C}.*|block} ^allow$ [NC,OR]
RewriteCond ${whitelist-ips:%{ENV:IP_A}.%{ENV:IP_B}.*.*|block} ^allow$ [NC,OR]
RewriteCond ${whitelist-ips:%{ENV:IP_A}.*.*.*|block} ^allow$ [NC]
RewriteRule .* - [S=1]
RewriteRule .* - [L,R=403]

With this logic you can have RewriteMap file entries of the form:
Code:
# List of client IP addresses and subnets (IPv4) allowed access.
# Use an asterisk to denote a boundary subnet octet.
#
192.168.1.65    allow   # Allow specific host
192.168.0.*     allow   # Allow specific Class C subnet
172.16.*.*      allow   # Allow specific Class B subnet
10.*.*.*        allow   # Allow specific Class A subnet

Hopefully, one of these options will cover your requirements.
Back to top
Krillian



Joined: 17 Nov 2022
Posts: 5

PostPosted: Wed 30 Nov '22 14:56    Post subject: Reply with quote

That is exactly what I needed. Again, thank you very much!
Back to top


Reply to topic   Topic: Reverse proxy IP whitelist View previous topic :: View next topic
Post new topic   Forum Index -> Apache