Search code examples
apachemod-rewrite

Apache 2.4 RewriteCond with expr / ipmatch on variable other than %{REMOTE_ADDR}


I have a web server behind a CDN. The client IP is passed as an HTTP header.

I can use the following to block a client IP address:

RewriteCond %{HTTP:CloudFront-Viewer-Address} ^123\.45\.67\.89(.*)$
RewriteRule ^(.*)$ - [F,L]

I believe the (.*)$ is required to match the port that may be included in %{HTTP:CloudFront-Viewer-Address}. I see the port (e.g. 127.0.0.1:1234) after %{HTTP:CloudFront-Viewer-Address} in access logs but not in rewrite logs. In rewrite logs, the port is appended to the CloudFront and load balancer addresses that precede the %{HTTP:CloudFront-Viewer-Address} but not the %{HTTP:CloudFront-Viewer-Address} itself.

A CGI program prints something like:

HTTP_CLOUDFRONT_VIEWER_ADDRESS --> 0000:0000:0000:0000:0000:0000:0000:0001:52325
HTTP_CLOUDFRONT_VIEWER_ADDRESS --> 127.0.0.1:45629

when I visit.

I'd like to use something like this:

RewriteCond expr "%{REMOTE_ADDR} -ipmatch '123.45.67.0/24'"
RewriteRule ^(.*)$ - [F,L]

to block a range of IPs, as seen here: https://perishablepress.com/apache-redirect-range-ip-addresses/

but it doesn't work.

I tried:

RewriteCond expr "%{HTTP:CloudFront-Viewer-Address} -ipmatch '123.45.67.0/24'"
RewriteRule ^(.*)$ - [F,L]

I'm not sure if it's because %{REMOTE_ADDR} is the only variable ipmatch can work on; or the port that may be included in my variable; or some other reason.

Assuming it's the port, and ipmatch can act on %{HTTP:CloudFront-Viewer-Address}, might removing the port from %{HTTP:CloudFront-Viewer-Address} allow this to work?

I tried to do it using suggestions here: https://www.reddit.com/r/apache/comments/11bxlxi/cidr_matching_rewrite_with_expr_ipmatch_remove/ but couldn't get it working.

Thanks for any suggestions!


Solution

  • The pattern I suggest here is to manipulate it up front with SetEnvIf and leave the result in an environment variable.

    SetEnvIf CloudFront-Viewer-Address (.*):\d+$ cf-v-a=$1
    RewriteCond expr "%{reqenv:cf-v-a} -ipmatch '123.45.67.0/24'"
    RewriteRule ^(.*)$ - [F,L]