3

I've got mod_rpaf installed to get the user's IP address from the X-Forwarded-For header in PHP, Apache logs, etc.

Unfortunately, it looks like I have to explicitly set which IPs that header will be respected from via the RPAFproxy_ips setting.

Given that ELBs don't have a static IP, how can I tell mod_rpaf to accept the header from any IP, or even any 10.* IP?

2
  • Have you tried entering the entire list of possible IP addresses in mod_rpaf's conf file? My gut feeling is that this is bad and will cause excess latency but we won't know until we actually try. For that matter, do you know the entire list of possible IP addresses?
    – Ladadadada
    Nov 21, 2011 at 15:41
  • Amazon EC2 has more than a million IPs, so no. forums.aws.amazon.com/ann.jspa?annID=1252
    – ceejayoz
    Nov 21, 2011 at 15:53

3 Answers 3

5
+100

You can try to use mod_extract_forwarded instead of mod_rpaf — it supports MEFaccept all (and if you use RHEL/CentOS/other-clone, the package is already in EPEL). One downside of mod_extract_forwarded is that the X-Forwarded-For and Forwarded-For header names are hardcoded and not configurable like in mod_rpaf.

There is no support for IP ranges even in mod_extract_forwarded, but you may configure a firewall to allow direct access to Apache only from some IP ranges, or check the MEF_RPROXY_ADDR environment variable in mod_rewrite rules.


After some more thinking about this I found a problem with this mod_extract_forwarded config — while mod_rpaf does not support chains of multiple proxies and takes just the last address from the X-Forwarded-For header, mod_extract_forwarded attempts to support this and uses the last address which does not belong to the trusted proxy list (so that if the request has passed through multiple trusted proxies, the actual client address will be used instead of the second-to-last proxy address). Unfortunately, using MEFaccept all means that mod_extract_forwarded will trust all proxies, therefore if ELB proxies just append their data to the X-Forwarded-For header, and not replace it completely, clients could pass any spoofed IP by sending requests with their own X-Forwarded-For headers.

However, I have found yet another module to parse X-Forwarded-For headers. Recent (unstable) Apache versions have the mod_remoteip module, which apparently supports subnet masks for proxy addresses. There is a backport to Apache 2.2 and a spec file for Fedora; unfortunately, the request to include package in Fedora is stalled.

6
  • MEFaccept all sounds good, will give that a try - no risk as Amazon's firewalls will take care of outside traffic.
    – ceejayoz
    Nov 16, 2011 at 14:23
  • See the updated answer — there is a problem with this config which would enable clients to pass arbitrary spoofed IPs via X-Forwarded-For headers. Nov 16, 2011 at 18:32
  • Thanks. I think I'm probably comfortable about that - I'm not really using this for security so much as log analysis and troubleshooting. Not much of a reason for someone to spoof.
    – ceejayoz
    Nov 16, 2011 at 18:52
  • Then you will probably see lots of 192.168.x.x and similar addresses in your logs from proxies out there, which would not be very useful. Nov 16, 2011 at 19:18
  • There is a solution just for logging which does not require any extra modules; note that another suggested solution would have the same problem as mod_extract_forwarded — using the first address from X-Forwarded-For instead of the last one. But this won't help PHP. Nov 16, 2011 at 19:36
1

It doesn't look like you can, from a quick reading of the source. You could hack up the code pretty easily to just accept any source (by neutering the check at line 163 that looks like is_in_array(r->connection->remote_ip, cfg->proxy_ips) == 1, but that seems like a security risk.

Is there some way you can ask Amazon what the load balancers you are behind are at runtime? If so you could generate the config on the fly...

1
  • Unfortunately, the IP of an AWS ELB can change at any time.
    – ceejayoz
    Nov 16, 2011 at 14:21
0

I just discovered that CloudFlare have created their own Apache module for doing this sort of thing and it does support CIDR notation for ranges.

The IP addresses are hard-coded in the source code but since they provide the source code it's easy enough to add your own range in there.

A comment in the source code indicates that it was derived from mod_remoteip.c which is available in Apache 2.3 (or 2.5 depending on whether you look at the URL or the title of that page.).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .