Obtaining the correct Client IP address when a Physical Load Balancer and a Web Server Configured With Proxy Plug-in Are Between The Client And Weblogic
- by adejuanc
Some Load Balancers like Big-IP have build in interoperability with
Weblogic Cluster, this means they know how Weblogic understand a header
named 'WL-Proxy-Client-IP' to identify the original client ip.The
problem comes when you have a Web Server configured with weblogic
plug-in between the Load Balancer and the back-end weblogic servers -
WL-Proxy-Client-IP this is not designed to go to Web server proxy
plug-in. The plug-in will not use a WL-Proxy-Client-IP header that came
in from the previous hop (which is this case is the Physical Load
Balancer but could be anything), in order to prevent IP spoofing,
therefore the plug-in won't pass on what Load Balancer has set for it.So unfortunately under this Architecture the header will be useless.
To get the client IP from Weblogic you need to configure extended log
format and create a custom field that gets the appropriate header
containing the IP of the client.On WLS versions prior to 10.3.3 use these instructions:You can also create user-defined fields for inclusion in an HTTP
access log file that uses the extended log format. To create a custom
field you identify the field in the ELF log file using the Fields
directive and then you create a matching Java class that generates the
desired output. You can create a separate Java class for each field, or
the Java class can output multiple fields. For a sample of the Java
source for such a class, seeJava Class for Creating a Custom ELF Field to
import weblogic.servlet.logging.CustomELFLogger;import weblogic.servlet.logging.FormatStringBuffer;import weblogic.servlet.logging.HttpAccountingInfo;/* This example outputs the X-Forwarded-For field into a custom field called MyOriginalClientIPField */public class MyOriginalClientIPField implements CustomELFLogger{ public void logField(HttpAccountingInfo metrics, FormatStringBuffer buff) { buff.appendValueOrDash(metrics.getHeader("X-Forwarded-For"); }}In this case we are using 'X-Forwarded-For' but it could be changed for the header that contains the data you need to use.Compile the class, jar it, and prepend it to the classpath.In order to compile and package the class:
1. Navigate to <WLS_HOME>/user_projects/domains/<SOME_DOMAIN>/bin2.
Set up an environment by executing: $ . ./setDomainEnv.sh This will
include weblogic.jar into classpath, in order to use any of the
libraries included under package weblogic.*3. Compile the class by copying the content of the code above and naming the file as:MyOriginalClientIPField.java4. Run javac to compile the class.$javac MyOriginalClientIPField.java5. Package the compiled class into a jar file by executing:$jar cvf0 MyOriginalClientIPField.jar MyOriginalClientIPField.classExpected output is:added manifestadding: MyOriginalClientIPField.class(in = 711) (out= 711)(stored 0%)6. This will produce a file called:MyOriginalClientIPField.jar
This way you will be able to get the real client IP when the request is passing through a Load Balancer and a Web server before reaching WLS.
Since 10.3.3 it is possible to configure a
specific header that WLS will check when getRemoteAddr is called. That
can be set on the WebServer Mbean. In this case, set that to be
X-Forwarded-For header coming from Load Balancer as well.