Symantec Access Management

 View Only

Adding X-Forwarded-For header to CA Access Gateway (CA Secure Proxy Server) 

Sep 28, 2014 09:52 PM

 

This article discusses how to implement the "X-Forwarded-For" header, in CA Secure Proxy Server as a custom SPS Filter, with coded example attached.

 

1.1 Introduction


The X-Forwarded-For (XFF) HTTP header field is a de facto standard for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or load balancer.  However this is not (yet) a built in feature for CA Secure Proxy Server.

 

 

There have been a number of requests for it over the last few years, from both customers and CA Services, I always thought it should be possible via an SPS Filter, and should not be too difficult to implement.  So after another request a few weeks ago, I spent a bit of time on the weekend to check that, and this is the result.

 

Here we show how to implement "X-Forwarded-For" header with the attached (fairly simple) custom java SPS filter.  The attached zip file contains: a prebuilt (JRE 1.6) jar file; samples of the SPS configuration file changes that are needed; as well as the java source code and simple build script.

 

The SPSForwardedForFilter implements a SPS filter (implementing a "preFilter" method),  the prefilter will looks up the IP address of the client, as identified by apache, and sets it the X-Forwarded-For header before passing the request onto the backend server.

The header then can be used by the backend server to identify the client IP address:

 

X-Forwarded-For: 192.168.10.14

 

If the X-Forward-For header already exists, then the filter can (optionally) append or overwrite the header.

 

X-Forwarded-For: clientIP, proxy1IP, proxy2IP, 192.168.10.14

 

The choice of overwrite or append will depend on your downstream environment, but you do need to be aware of the clients ability to add thier own initial X-Forwarded-For header in an attempt to spoof the original location.


For more details about X-Forwarded-For header see : X-Forwarded-For - Wikipedia, the free encyclopedia

 

 

1.2 Deploying the SPSForwardForFilter.jar file

The SPSForwardForFilter.jar file (compiled version provided in the zip file) needs to be copied into the CLASSPATH's used by the proxy-engine.  The easiest way to do that is to copy it into the Tomcat lib directory.  for example : 

          copy/y SPSForwardForFilter.jar C:\CA\secure-proxy\Tomcat\lib\


          cp SPSForwardForFilter.jar /opt/secure-proxy/Tomcat/lib/

 

1.3 Changes in Server.conf

 

Server.conf contains most of the proxy-engine configuration settings including some commented out examples of filters.  Using those, along with the sample provided in the sps-site-specific subdirectory of the zip file, as a guide we define a filter in the Server.conf file named “ForwardedForFilter” as follows:

filter.ForwardedForFilter.class=ForwardedForFilter

filter.ForwardedForFilter.init-param.debugTraceLevel="2"

 

Since the defaults are likely to be what you want anyway, these settings a commented out by default.


#filter.ForwardedForFilter.init-param.XForwardForHeaderName="X-Forwarded-For" # defaults to this.

#filter.ForwardedForFilter.init-param.mode="Append" # (Append|OverWrite) defaults to Append.

#filter.ForwardedForFilter.init-param.enabled="True" # (True|False) defaults to True.

 

 

1.4 Changes in proxyrules.xml

The proxyrules.xml describes which backend server the SPS will forward the request onto, we edit the proxyrules.xml file to add the use of the "ForwardedForFilter" filter and then the X-Forwarded-For header will be set whenever requests are forwarded to those backend servers.    The changes are as follows, as per the sample in the sps-site-specific subdirectory of the zip file

The changes are fairly simple, (also included in the sps-site-sepecific directory in the zip file) simply change :

    <nete:forward>http://backend.ca.com$0</nete:forward>

 

To:

  <nete:forward filter="ForwardedForFilter">http://backend.ca.com$0</nete:forward>

 

1.5  XForwardForFilter Parameter Values


The parameters for ForwardForFilter filter in server.conf are :

 

  • debugTraceLevel = 0|1|2|3
    A simple print to stdout trace facility higher level prints more details
  • XforwardForHeaderName = “X-Forwarded-For”
    Identifies the name of the header that will be set in the HTTP request sent onto the backend server (usually the default value "X-Forwarded-For" will be what you require)
  • mode = Append | Overwrite
    Identifies what to do if an X-Forward-For header already exists.  The default is to Append which adds the IP address we captured to the chain of prior proxies.  But if the prior server is not a trusted server, then Overwrite may be a better choice for youe situation.
  • enabled = True | False
    Just a quick way to enable|disable the filter via configuration. The default is enabled so it is set to true.

 

1.6 Verify that it is working correctly.

The best way to verify the result is to enable httpclient logging, via editing server.conf, and change the setitng : httpclientlogging="yes".  Then you can view the request as it is passed onto the backend : Chopping out the extra stuff, you should see the request to the backend, now contians the X-Forwarded-For header : 


>> "GET /us/default.aspx HTTP/1.1[\r][\n]"

>> "Accept-Language: en-US[\r][\n]"

>> "connection: Keep-Alive[\r][\n]"

>> "content-length: 0[\r][\n]"

>> "accept: image/jpeg, image/gif, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */*[\r][\n]"

>> "Accept-Encoding: gzip, deflate[\r][\n]"

>> "user-agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729)[\r][\n]"

>> "X-Forwarded-For: 192.168.10.121[\r][\n]"
>> "Host: www.ca.com[\r][\n]"

>> "[\r][\n]"

 

1.6 Coding the custom SPSFIlter

The code requires is very simple, in the custom SPSFilter, we create a doPreFilter() method, to manipulate the request prior to it being sent to the backend.  Within the method we use the normal tomcat/Java Servlet method to get the client IP address which has been passed from Apache and then set the X-Forwarded-For header:

/**

* Prefilter process to update the X-Forwarded-For: header.

*/

public void doPreFilter(ProxyRequest prequest, ProxyResponse presponse) throws ProxyFilterException {

      ....

    String remoteAddr = prequest.getOriginalRequest().getRemoteAddr();

    ....

    prequest.setHeader("X-Forwarded-For", remoteAddr);

    ....

  }

The real code is only slightly more complex, doing some logging and be able to work with the header when it already exists. 



1.7 Compiling Source Code

The zip file contains the source code is in filter/src subdirectory, and there is also a sample build script: build.bat and build.sh file provided.

The build process is fairly simple, to compile you just need to edit the build.bat/build.sh file, verify or update the location of the SDK install,

set JAVA_HOME=C:\Program Files\Java\jdk1.6.0_31\


And then run the build script.  That will create the SPSForwadedForFilter.jar file.  Often it
is easiest to do the build on the SPS machine itself, since then you are ensured of having a compatable JRE version.

 

 

The following disclaimer applies to all code uploaded to the CA Security Community site,

 

Folders may contain scripts, tools and documents ('Files') for the CA SiteMinder solutions from CA Technologies.  This content has been uploaded by fellow community members and has not been checked, tested, or approved by CA Technologies (or anyone else).  NEITHER CA, INC. NOR ANY OF ITS SUBSIDIARIES AND AFFILIATES (CA's) NOR ANY COMMUNITY MEMBER SHALL BE LIABLE TO THE OTHER OR ANY OTHER MEMBER OR THIRD PARTY FOR DIRECT, CONSEQUENTIAL, INCIDENTAL, INDIRECT AND/OR SPECIAL DAMAGES FOR ANY CLAIMS ARISING FROM OR IN ANY WAY CONNECTED WITH YOUR DECISION TO ACCESS OR USE ANY SUCH FILES, EVEN IF THE POSSIBILITY OF SUCH DAMAGES IS, OR SHOULD HAVE BEEN, KNOWN. THESE FILES ARE PROVIDED AS IS WITHOUT ANY warranty or representation of any kind express or implied including without limitation Any Implied warranty of merchantability/satisfactory quality, fitness for a particular purpose or non-infringment. Your usage of any such Files is at your own risk. You are solely responsible for testing such Files prior to implementing them in either a test or production environment. We encourage you to check for any documentation (if provided) by looking in the document comments or on the message boards for a corresponding thread for additional information (if available). It is recommended to deploy/implement in a test or QA environment before implementing in a production environment. Such Files are not covered by CA's Support Policy and Terms. CA will not under any circumstances support them.  



Source sample .tar.gz attached

Cheers – Mark O'Donohue - [ mark.odonohue@ca.com. ]

 

Statistics
0 Favorited
28 Views
1 Files
0 Shares
8 Downloads
Attachment(s)
zip file
sps-filter-x-forward-for.zip   113 KB   1 version
Uploaded - May 29, 2019

Tags and Keywords

Comments

Dec 03, 2018 05:00 PM

Just a note that I should set X-Forwarded-Proto as well 

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto 

 

In this sample code at some point

 

Cheers - Mark

Jul 23, 2018 09:45 PM

Hi Jeff

 

There is good chance I could have implemented it all in apache code :-) 

 

For what you want I expect too that you can do a bunch in httpd.conf with mod_header.  Here was an IP allow/disallow list (see in the comments) implemented in apache part of SPS: 

White or Blacklisting Capability in Access Gateway - within Product 

 

I also had an implementation of SPS / load balancer - using sps filters - which was a bit messy in setting the cookie for sticky load balancing - - but I think too I could do that simpler now using some parts of apache mod_headers. 

 

But I think what you want can be done similar to the IP allow/disallow lists, probably to set a header for internal / external access or do some other action.

 

Cheers - Mark

Jul 23, 2018 09:31 PM

Hi Mark,

Always enjoy reading your posts... very helpful.    

 

Working on a related use case where SPS needs to evaluate incoming requests to determine whether the client is on the company's network.   In the case they are, the request would go through unaltered.  If the user is not on the company network the user would be redirected to a dummy resource protected with MFA.   Reading through this post it appears the intent is to pass or modify the x-forwarded-for header to the backend, and not related to decisions on routing with proxyrules.xml.  (is this accurate?)

Do you have any examples of a proxyrules.xml where x-forwarded-for is used to make decisions whether the client is internal/external to a company's network?   I'm guessing this could get very messy if they are spread across myriad subnets.    In this particular instance we are leaning toward using F5 (since they already do this today for other applications), but we are considering doing it entirely at the SPS level to keep everything in-house so to speak...

 

-JM

Nov 20, 2014 08:07 AM

Thanks Mark!!

Related Entries and Links

No Related Resource entered.