Using X-Forwarded-For To Report IP Address In FusionReactor 5
Posted January 8, 2014 at 9:44 AM by Ben Nadel
Really quick blog post here about FusionReactor 5. If your ColdFusion application lives behind a load-balancer, it's possible that the load-balancer will report the user's remote IP address as the local IP address behind the load-balancer. In such cases, the load-balancer will add an additional header, like "X-Forwarded-For," in to make the actual user IP address of the incoming request available to your application. In FusionReactor 5, you can configure the "Proxy" settings to use this X-Forwarded-For (or True-Client-Ip) header when rendering the metrics interfaces:
| || || |
| || |
| || || |
This makes analyzing the incoming requests a bit easier.
- Wanted: Full-Time ColdFusion Developer at Intoria Internet Architects
- Cold Fusion Senior Developer at Edge Information Management
- Back-End Web Developer-Information Technologist at Michigan State University
- ColdFusion Developer at Nonfat Media
- Mid-to-Senior Level Web Application Developer at SiteVision, Inc.
It's also possible to enter your own proxy header name into the field if you are not using the common ones of X-Forwarded-For or True-Client-Ip.
Oh nice! I didn't realize it was a combo-box. I thought it was just a select menu. Great stuff!
Is it possible, when using a load balancer, to get coldfusion to use the true IP versus the load balancer ip so i can restrict who sees the robust exception info?
@Jeff, the following feedback is from David Stockton who works in the Fusion Team:
To my knowledge this isn't possible through CF configuration.
You can use an Apache module ( mod_extract_forwarded - http://www.openinfo.co.uk/apache/ ) to have it make all other Apache modules think the value of X-Forwarded-For HTTP header is the real client IP (i.e. then CF will see the true IPs) but I'm not sure if there's a similar IIS tool.
I believe mod_rpaf ( http://www.stderr.net/apache/rpaf/ ) can also do this for Apache but mod_extract_forwarded is available as an RPM for CentOS in the EPEL repository so it's a bit simpler to get going.
I am using IIS. Basically I want to be able to enable debugging, but since the CFADMIN only sees the load balancer IP, enabling debugging allows the robust exception info to be displayed to the entire world, which is obviously a bad idea.
How do people handle this? I can't be the only one out there experiencing this issue.
I generally turn off the robust debugging in production. That said, your "localhost" should always have the right IP 127.0.0.1. So, if you can put a host-file entry to point back to the same machine, at least you can RDP in and run it in Firefox or something on the machine.
Other than that, what I'll usually do, when I'm in a jam, is add dump-code for a specific user or IP address:
- <cfif listFind( "126.96.36.199", normalizedIpAddress )>
- <cfdump var="#query#" />
- <cfabort />
... that kind of stuff.
Actually when you hit your server locally on a machine that has multiple IP addresses (as most servers), you will many times see in CGI.REMOTE_ADDR an address other than the loopback 127.0.0.1
Most Servlet Containers (e.g. Tomcat, Jetty, etc.) have a built in option to accept the X-Forwarded-For header and translate it internally (that of course should be limited to trusted proxy IPs like 127.0.0.1)
In Tomcat, for example, you can enable that feature by adding the following element to the Host element:
- <Valve className="org.apache.catalina.valves.RemoteIpValve" protocolHeader="X-Forwarded-Proto" remoteIpHeader="X-Forwarded-For" protocolHeaderHttpsValue="https" />
Enabling this Valve, and setting up the web server to pass the headers "X-Forwarded-For" and "X-Forwarded-Proto" will allow Tomcat to pass the correct values for CGI.REMOTE_ADDR and CGI.SERVER_PORT_SECURE to ColdFusion/Railo.
I guess I'm not explaining myself properly.
What I'm trying to do is trick or configure the CF10 Administrator > Debugging and Logging > Enabled Request Debugging Output to use the x-forwarded-for as opposed to the remote_addr so I can use server debugging without that information being made visible to the public.
Since CF10 uses Tomcat for a Servlet Container, you can add the snippet I posted above to Tomcat/conf/server.xml in the Host element and then CF10 should set CGI.REMOTE_ADDR to the value from x-forwarded-for.
I see a c:\coldfusion10\cfusion\runtime\conf\server.xml
is this the same file?
Probably. If that is the only server.xml file you can find then yes.
I use Railo myself so I'm not sure about the ColdFusion setup exactly, but this comes from Tomcat so it is before ColdFusion/Railo even get the information, and is therefore the same in both setups.
When I do a #cgi.x-forwarded-proto# I get
The value '' cannot be converted to a number.
Do you have a link somewhere for configuring IIS to pass this properly?
I did not expect CGI.X-FORWARDED-FOR to work as it isn't even a valid variable name, and shouldn't go into the CGI scope anyway.
If anything, it should be passed as a http header. See http://www.bennadel.com/blog/1425-Getting-Header-Values-From-A-ColdFusion-Request.htm
I am not sure how to do that in IIS/ColdFusion because the connector should take care of that, and since it is a standard header I expect it to work out of the box. I'm not sure what ColdFusion uses for a connector nowadays. It's been a while since I used ColdFusion.
I meant CGI.X-FORWARDED-PROTO
Anyway, in the CGI scope it should appear as CGI.SERVER_PORT_SECURE
That did it! Thanks!
That's really cool stuff - I had no idea you could configure the CF server (or the underlying J2E server, I guess) to translate the address. Excellent tip!
The one thing to keep in mind is that at the end of the day ColdFusion, Railo, and OpenBD are simply Java Servlets, and they run inside a Java Servlet Container (e.g. Tomcat, Jetty, etc).
So you can do with these engines anything you can do with a Java Servlet.
Glad it helped,
I vaguely understand that, from a philosophical level. My problem is that I just have very little working understanding of Java Servlets. This is something I hope to understand better at some point.